Selaa lähdekoodia

add Objectvar.get, Closes #4928 (#4956)

* add Objectvar.get, wip #4928

* ObjectVar.get always returns a Var

* minor cleanup

* use getitem instead of getattr for ObjectVar.get
benedikt-bartscher 2 kuukautta sitten
vanhempi
säilyke
8996929a26
2 muutettua tiedostoa jossa 52 lisäystä ja 0 poistoa
  1. 23 0
      reflex/vars/object.py
  2. 29 0
      tests/integration/test_var_operations.py

+ 23 - 0
reflex/vars/object.py

@@ -221,6 +221,29 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=Mapping):
             return self.__getattr__(key)
             return self.__getattr__(key)
         return ObjectItemOperation.create(self, key).guess_type()
         return ObjectItemOperation.create(self, key).guess_type()
 
 
+    def get(self, key: Var | Any, default: Var | Any | None = None) -> Var:
+        """Get an item from the object.
+
+        Args:
+            key: The key to get from the object.
+            default: The default value if the key is not found.
+
+        Returns:
+            The item from the object.
+        """
+        from reflex.components.core.cond import cond
+
+        if default is None:
+            default = Var.create(None)
+
+        value = self.__getitem__(key)  # pyright: ignore[reportUnknownVariableType,reportAttributeAccessIssue,reportUnknownMemberType]
+
+        return cond(  # pyright: ignore[reportUnknownVariableType]
+            value,
+            value,
+            default,
+        )
+
     # NoReturn is used here to catch when key value is Any
     # NoReturn is used here to catch when key value is Any
     @overload
     @overload
     def __getattr__(  # pyright: ignore [reportOverlappingOverload]
     def __getattr__(  # pyright: ignore [reportOverlappingOverload]

+ 29 - 0
tests/integration/test_var_operations.py

@@ -18,6 +18,8 @@ def VarOperations():
 
 
     class Object(rx.Base):
     class Object(rx.Base):
         name: str = "hello"
         name: str = "hello"
+        optional_none: str | None = None
+        optional_str: str | None = "hello"
 
 
     class Person(TypedDict):
     class Person(TypedDict):
         name: str
         name: str
@@ -47,6 +49,7 @@ def VarOperations():
         people: rx.Field[list[Person]] = rx.field(
         people: rx.Field[list[Person]] = rx.field(
             [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}]
             [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}]
         )
         )
+        obj: rx.Field[Object] = rx.field(Object())
 
 
     app = rx.App(_state=rx.State)
     app = rx.App(_state=rx.State)
 
 
@@ -713,6 +716,27 @@ def VarOperations():
                 rx.text.span(f"{rx.Var.create(13212312312.1231231):_.2f}"),
                 rx.text.span(f"{rx.Var.create(13212312312.1231231):_.2f}"),
                 id="float_format_underscore_2f",
                 id="float_format_underscore_2f",
             ),
             ),
+            # ObjectVar
+            rx.box(
+                rx.text(VarOperationState.obj.name),
+                id="obj_name",
+            ),
+            rx.box(
+                rx.text(VarOperationState.obj.optional_none),
+                id="obj_optional_none",
+            ),
+            rx.box(
+                rx.text(VarOperationState.obj.optional_str),
+                id="obj_optional_str",
+            ),
+            rx.box(
+                rx.text(VarOperationState.obj.get("optional_none")),
+                id="obj_optional_none_get_none",
+            ),
+            rx.box(
+                rx.text(VarOperationState.obj.get("optional_none", "foo")),
+                id="obj_optional_none_get_foo",
+            ),
         )
         )
 
 
 
 
@@ -936,6 +960,11 @@ def test_var_operations(driver, var_operations: AppHarness):
         ("float_format_underscore_0f", "13_212_312_312"),
         ("float_format_underscore_0f", "13_212_312_312"),
         ("float_format_underscore_1f", "13_212_312_312.1"),
         ("float_format_underscore_1f", "13_212_312_312.1"),
         ("float_format_underscore_2f", "13_212_312_312.12"),
         ("float_format_underscore_2f", "13_212_312_312.12"),
+        ("obj_name", "hello"),
+        ("obj_optional_none", ""),
+        ("obj_optional_str", "hello"),
+        ("obj_optional_none_get_none", ""),
+        ("obj_optional_none_get_foo", "foo"),
     ]
     ]
 
 
     for tag, expected in tests:
     for tag, expected in tests: