Kaynağa Gözat

Access parent state vars from substate (#207)

Nikhil Rao 2 yıl önce
ebeveyn
işleme
2543e48a30
4 değiştirilmiş dosya ile 44 ekleme ve 7 silme
  1. 3 3
      poetry.lock
  2. 1 1
      pynecone/components/component.py
  3. 24 1
      pynecone/state.py
  4. 16 2
      tests/test_state.py

+ 3 - 3
poetry.lock

@@ -605,14 +605,14 @@ plugins = ["importlib-metadata"]
 
 [[package]]
 name = "pyright"
-version = "1.1.286"
+version = "1.1.287"
 description = "Command line wrapper for pyright"
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "pyright-1.1.286-py3-none-any.whl", hash = "sha256:b80761f303bf437d764b2d194b06f07fb4ed38960d7f3a8b2f7f41da37aced70"},
-    {file = "pyright-1.1.286.tar.gz", hash = "sha256:2bbf82114ac3838c31c91d1c32abe4858259bff094465cadff55eac465250f1b"},
+    {file = "pyright-1.1.287-py3-none-any.whl", hash = "sha256:0c760edbd40eb4f763027f742de2cb29c1d8320880e5f6ad85fc89db43fe6871"},
+    {file = "pyright-1.1.287.tar.gz", hash = "sha256:806a4af328dc1f2b6688147528c71393f0cf241eb1214d6e9a7fb1ef5caa2327"},
 ]
 
 [package.dependencies]

+ 1 - 1
pynecone/components/component.py

@@ -443,7 +443,7 @@ class CustomComponent(Component):
                 value = Var.create(value, is_string=type(value) is str)
             self.props[utils.to_camel_case(key)] = value
 
-    def __eq__(self, other) -> bool:
+    def __eq__(self, other: Any) -> bool:
         """Check if the component is equal to another.
 
         Args:

+ 24 - 1
pynecone/state.py

@@ -30,7 +30,7 @@ class State(Base, ABC):
     # The computed vars of the class.
     computed_vars: ClassVar[Dict[str, ComputedVar]] = {}
 
-    # vars inherited by the parent state.
+    # Vars inherited by the parent state.
     inherited_vars: ClassVar[Dict[str, Var]] = {}
 
     # The parent state.
@@ -257,13 +257,36 @@ class State(Base, ABC):
             field.required = False
             field.default = default_value
 
+    def __getattribute__(self, name: str) -> Any:
+        """Get the state var.
+
+        If the var is inherited, get the var from the parent state.
+
+        Args:
+            name: The name of the var.
+
+        Returns:
+            The value of the var.
+        """
+        # Get the var from the parent state.
+        if name in super().__getattribute__("inherited_vars"):
+            return getattr(super().__getattribute__("parent_state"), name)
+        return super().__getattribute__(name)
+
     def __setattr__(self, name: str, value: Any):
         """Set the attribute.
 
+        If the attribute is inherited, set the attribute on the parent state.
+
         Args:
             name: The name of the attribute.
             value: The value of the attribute.
         """
+        # Set the var on the parent state.
+        if name in self.inherited_vars:
+            setattr(self.parent_state, name, value)
+            return
+
         # Set the attribute.
         super().__setattr__(name, value)
 

+ 16 - 2
tests/test_state.py

@@ -405,10 +405,24 @@ def test_set_child_attribute(test_state, child_state, grandchild_state):
     """
     test_state.num1 = 10
     assert test_state.num1 == 10
+    assert child_state.num1 == 10
+    assert grandchild_state.num1 == 10
+
+    grandchild_state.num1 = 5
+    assert test_state.num1 == 5
+    assert child_state.num1 == 5
+    assert grandchild_state.num1 == 5
+
     child_state.value = "test"
     assert child_state.value == "test"
-    grandchild_state.value2 = "test2"
-    assert grandchild_state.value2 == "test2"
+    assert grandchild_state.value == "test"
+
+    grandchild_state.value = "test2"
+    assert child_state.value == "test2"
+    assert grandchild_state.value == "test2"
+
+    grandchild_state.value2 = "test3"
+    assert grandchild_state.value2 == "test3"
 
 
 def test_get_substate(test_state, child_state, child_state2, grandchild_state):