From 636a46ce4f46f1e79e136826d85937079185eb26 Mon Sep 17 00:00:00 2001 From: thomas chaton Date: Mon, 21 Nov 2022 18:39:51 +0000 Subject: [PATCH] [App] Enable properties for the Lightning flow (#15750) (cherry picked from commit 5cfb176214c293ff9e589d9747adc9d8f85b47a8) --- src/lightning_app/CHANGELOG.md | 3 ++ src/lightning_app/core/flow.py | 6 +++- tests/tests_app/core/test_lightning_app.py | 33 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/lightning_app/CHANGELOG.md b/src/lightning_app/CHANGELOG.md index c0062d63bb9f1..f1a975c2bb93f 100644 --- a/src/lightning_app/CHANGELOG.md +++ b/src/lightning_app/CHANGELOG.md @@ -47,6 +47,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Fixed catimage import ([#15712](https://github.com/Lightning-AI/lightning/pull/15712)) - Parse all lines in app file looking for shebangs to run commands ([#15714](https://github.com/Lightning-AI/lightning/pull/15714)) +- Fixed setting property to the LightningFlow ([#15750](https://github.com/Lightning-AI/lightning/pull/15750)) + + ## [1.8.1] - 2022-11-10 diff --git a/src/lightning_app/core/flow.py b/src/lightning_app/core/flow.py index ac8a7ff325049..18b6fd40f756a 100644 --- a/src/lightning_app/core/flow.py +++ b/src/lightning_app/core/flow.py @@ -110,7 +110,11 @@ def name(self): """Return the current LightningFlow name.""" return self._name or "root" - def __setattr__(self, name, value): + def __setattr__(self, name: str, value: Any) -> None: + attr = getattr(self.__class__, name, None) + if isinstance(attr, property) and attr.fset is not None: + return attr.fset(self, value) + from lightning_app.structures import Dict, List if ( diff --git a/tests/tests_app/core/test_lightning_app.py b/tests/tests_app/core/test_lightning_app.py index 1b438f14632bb..4f2c0d8a50358 100644 --- a/tests/tests_app/core/test_lightning_app.py +++ b/tests/tests_app/core/test_lightning_app.py @@ -1108,3 +1108,36 @@ def test_cloud_compute_binding(): with pytest.raises(Exception, match="A Cloud Compute can be assigned only to a single Work"): FlowCC() + + +class FlowValue(LightningFlow): + def __init__(self): + super().__init__() + self._value = None + self._has_found = False + + @property + def value(self): + return self._value + + @value.setter + def value(self, value): + self._value = value + + def run(self): + if self.value is None: + self.value = True + + def __setattr__(self, name, value): + if name == "_value" and value is True: + self._has_found = True + super().__setattr__(name, value) + + +def test_lightning_flow_properties(): + """Validates setting properties to the LightningFlow properly calls property.fset.""" + + flow = FlowValue() + assert not flow._has_found + flow.run() + assert flow._has_found