Răsfoiți Sursa

state: `get_value` unwraps MutableProxy first (#1887)

Masen Furer 1 an în urmă
părinte
comite
418f9ad569
2 a modificat fișierele cu 34 adăugiri și 0 ștergeri
  1. 15 0
      reflex/state.py
  2. 19 0
      tests/test_state.py

+ 15 - 0
reflex/state.py

@@ -1008,6 +1008,21 @@ class State(Base, ABC, extra=pydantic.Extra.allow):
         self.dirty_vars = set()
         self.dirty_vars = set()
         self.dirty_substates = set()
         self.dirty_substates = set()
 
 
+    def get_value(self, key: str) -> Any:
+        """Get the value of a field (without proxying).
+
+        The returned value will NOT track dirty state updates.
+
+        Args:
+            key: The key of the field.
+
+        Returns:
+            The value of the field.
+        """
+        if isinstance(key, MutableProxy):
+            return super().get_value(key.__wrapped__)
+        return super().get_value(key)
+
     def dict(self, include_computed: bool = True, **kwargs) -> dict[str, Any]:
     def dict(self, include_computed: bool = True, **kwargs) -> dict[str, Any]:
         """Convert the object to a dictionary.
         """Convert the object to a dictionary.
 
 

+ 19 - 0
tests/test_state.py

@@ -29,6 +29,7 @@ from reflex.state import (
     StateUpdate,
     StateUpdate,
 )
 )
 from reflex.utils import prerequisites
 from reflex.utils import prerequisites
+from reflex.utils.format import json_dumps
 from reflex.vars import BaseVar, ComputedVar
 from reflex.vars import BaseVar, ComputedVar
 
 
 from .states import GenState
 from .states import GenState
@@ -2091,6 +2092,24 @@ def test_duplicate_substate_class(duplicate_substate):
         duplicate_substate()
         duplicate_substate()
 
 
 
 
+class Foo(Base):
+    """A class containing a list of str."""
+
+    tags: List[str] = ["123", "456"]
+
+
+def test_json_dumps_with_mutables():
+    """Test that json.dumps works with Base vars inside mutable types."""
+
+    class MutableContainsBase(State):
+        items: List[Foo] = [Foo()]
+
+    dict_val = MutableContainsBase().dict()
+    assert isinstance(dict_val["items"][0], dict)
+    val = json_dumps(dict_val)
+    assert val == '{"is_hydrated": false, "items": [{"tags": ["123", "456"]}]}'
+
+
 def test_reset_with_mutables():
 def test_reset_with_mutables():
     """Calling reset should always reset fields to a copy of the defaults."""
     """Calling reset should always reset fields to a copy of the defaults."""
     default = [[0, 0], [0, 1], [1, 1]]
     default = [[0, 0], [0, 1], [1, 1]]