From dd6feff13fb9e840fc38c989a7e52544403134d7 Mon Sep 17 00:00:00 2001 From: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:45:24 +0200 Subject: [PATCH] Get attribute access type fix (#3803) * add failing test * catch unhandled NotImplementedError --- reflex/utils/types.py | 7 ++++- tests/test_attribute_access_type.py | 46 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/reflex/utils/types.py b/reflex/utils/types.py index a5e4eccda2..6c21aa6797 100644 --- a/reflex/utils/types.py +++ b/reflex/utils/types.py @@ -240,9 +240,14 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None """ from reflex.model import Model - attr = getattr(cls, name, None) + try: + attr = getattr(cls, name, None) + except NotImplementedError: + attr = None + if hint := get_property_hint(attr): return hint + if ( hasattr(cls, "__fields__") and name in cls.__fields__ diff --git a/tests/test_attribute_access_type.py b/tests/test_attribute_access_type.py index 0813a5e62d..0d490ec1e2 100644 --- a/tests/test_attribute_access_type.py +++ b/tests/test_attribute_access_type.py @@ -94,6 +94,15 @@ def str_or_int_property(self) -> Union[str, int]: """ return self.name + @hybrid_property + def first_label(self) -> Optional[SQLALabel]: + """First label property. + + Returns: + First label + """ + return self.labels[0] if self.labels else None + class ModelClass(rx.Model): """Test reflex model.""" @@ -125,6 +134,15 @@ def str_or_int_property(self) -> Union[str, int]: """ return self.name + @property + def first_label(self) -> Optional[SQLALabel]: + """First label property. + + Returns: + First label + """ + return self.labels[0] if self.labels else None + class BaseClass(rx.Base): """Test rx.Base class.""" @@ -156,6 +174,15 @@ def str_or_int_property(self) -> Union[str, int]: """ return self.name + @property + def first_label(self) -> Optional[SQLALabel]: + """First label property. + + Returns: + First label + """ + return self.labels[0] if self.labels else None + class BareClass: """Bare python class.""" @@ -187,6 +214,15 @@ def str_or_int_property(self) -> Union[str, int]: """ return self.name + @property + def first_label(self) -> Optional[SQLALabel]: + """First label property. + + Returns: + First label + """ + return self.labels[0] if self.labels else None + @attrs.define class AttrClass: @@ -219,6 +255,15 @@ def str_or_int_property(self) -> Union[str, int]: """ return self.name + @property + def first_label(self) -> Optional[SQLALabel]: + """First label property. + + Returns: + First label + """ + return self.labels[0] if self.labels else None + @pytest.fixture( params=[ @@ -254,6 +299,7 @@ def cls(request: pytest.FixtureRequest) -> type: pytest.param("dict_str_str", Dict[str, str], id="Dict[str, str]"), pytest.param("str_property", str, id="str_property"), pytest.param("str_or_int_property", Union[str, int], id="str_or_int_property"), + pytest.param("first_label", Optional[SQLALabel], id="first_label"), ], ) def test_get_attribute_access_type(cls: type, attr: str, expected: GenericType) -> None: