Browse Source

computed var default to cache=True (#4194)

* computed var default to cache=True

* fix lifespan integration tests

* fix redis test
Thomas Brandého 4 months ago
parent
commit
6e546526b4

+ 0 - 1
reflex/state.py

@@ -1200,7 +1200,6 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
                 fget=func,
                 auto_deps=False,
                 deps=["router"],
-                cache=True,
                 _js_expr=param,
                 _var_data=VarData.from_state(cls),
             )

+ 4 - 13
reflex/vars/base.py

@@ -1838,7 +1838,7 @@ class ComputedVar(Var[RETURN_TYPE]):
         self,
         fget: Callable[[BASE_STATE], RETURN_TYPE],
         initial_value: RETURN_TYPE | types.Unset = types.Unset(),
-        cache: bool = False,
+        cache: bool = True,
         deps: Optional[List[Union[str, Var]]] = None,
         auto_deps: bool = True,
         interval: Optional[Union[int, datetime.timedelta]] = None,
@@ -2253,7 +2253,7 @@ if TYPE_CHECKING:
 def computed_var(
     fget: None = None,
     initial_value: Any | types.Unset = types.Unset(),
-    cache: bool = False,
+    cache: bool = True,
     deps: Optional[List[Union[str, Var]]] = None,
     auto_deps: bool = True,
     interval: Optional[Union[datetime.timedelta, int]] = None,
@@ -2266,7 +2266,7 @@ def computed_var(
 def computed_var(
     fget: Callable[[BASE_STATE], RETURN_TYPE],
     initial_value: RETURN_TYPE | types.Unset = types.Unset(),
-    cache: bool = False,
+    cache: bool = True,
     deps: Optional[List[Union[str, Var]]] = None,
     auto_deps: bool = True,
     interval: Optional[Union[datetime.timedelta, int]] = None,
@@ -2278,7 +2278,7 @@ def computed_var(
 def computed_var(
     fget: Callable[[BASE_STATE], Any] | None = None,
     initial_value: Any | types.Unset = types.Unset(),
-    cache: Optional[bool] = None,
+    cache: bool = True,
     deps: Optional[List[Union[str, Var]]] = None,
     auto_deps: bool = True,
     interval: Optional[Union[datetime.timedelta, int]] = None,
@@ -2304,15 +2304,6 @@ def computed_var(
         ValueError: If caching is disabled and an update interval is set.
         VarDependencyError: If user supplies dependencies without caching.
     """
-    if cache is None:
-        cache = False
-        console.deprecate(
-            "Default non-cached rx.var",
-            "the default value will be `@rx.var(cache=True)` in a future release. "
-            "To retain uncached var, explicitly pass `@rx.var(cache=False)`",
-            deprecation_version="0.6.8",
-            removal_version="0.7.0",
-        )
     if cache is False and interval is not None:
         raise ValueError("Cannot set update interval without caching.")
 

+ 10 - 7
tests/integration/test_computed_vars.py

@@ -22,22 +22,22 @@ def ComputedVars():
         count: int = 0
 
         # cached var with dep on count
-        @rx.var(cache=True, interval=15)
+        @rx.var(interval=15)
         def count1(self) -> int:
             return self.count
 
         # cached backend var with dep on count
-        @rx.var(cache=True, interval=15, backend=True)
+        @rx.var(interval=15, backend=True)
         def count1_backend(self) -> int:
             return self.count
 
         # same as above but implicit backend with `_` prefix
-        @rx.var(cache=True, interval=15)
+        @rx.var(interval=15)
         def _count1_backend(self) -> int:
             return self.count
 
         # explicit disabled auto_deps
-        @rx.var(interval=15, cache=True, auto_deps=False)
+        @rx.var(interval=15, auto_deps=False)
         def count3(self) -> int:
             # this will not add deps, because auto_deps is False
             print(self.count1)
@@ -45,16 +45,19 @@ def ComputedVars():
             return self.count
 
         # explicit dependency on count var
-        @rx.var(cache=True, deps=["count"], auto_deps=False)
+        @rx.var(deps=["count"], auto_deps=False)
         def depends_on_count(self) -> int:
             return self.count
 
         # explicit dependency on count1 var
-        @rx.var(cache=True, deps=[count1], auto_deps=False)
+        @rx.var(deps=[count1], auto_deps=False)
         def depends_on_count1(self) -> int:
             return self.count
 
-        @rx.var(deps=[count3], auto_deps=False, cache=True)
+        @rx.var(
+            deps=[count3],
+            auto_deps=False,
+        )
         def depends_on_count3(self) -> int:
             return self.count
 

+ 3 - 3
tests/integration/test_dynamic_routes.py

@@ -74,16 +74,16 @@ def DynamicRoute():
     class ArgState(rx.State):
         """The app state."""
 
-        @rx.var
+        @rx.var(cache=False)
         def arg(self) -> int:
             return int(self.arg_str or 0)
 
     class ArgSubState(ArgState):
-        @rx.var(cache=True)
+        @rx.var
         def cached_arg(self) -> int:
             return self.arg
 
-        @rx.var(cache=True)
+        @rx.var
         def cached_arg_str(self) -> str:
             return self.arg_str
 

+ 3 - 3
tests/integration/test_lifespan.py

@@ -36,7 +36,7 @@ def LifespanApp():
         print("Lifespan global started.")
         try:
             while True:
-                lifespan_task_global += inc  # pyright: ignore[reportUnboundVariable]
+                lifespan_task_global += inc  # pyright: ignore[reportUnboundVariable, reportPossiblyUnboundVariable]
                 await asyncio.sleep(0.1)
         except asyncio.CancelledError as ce:
             print(f"Lifespan global cancelled: {ce}.")
@@ -45,11 +45,11 @@ def LifespanApp():
     class LifespanState(rx.State):
         interval: int = 100
 
-        @rx.var
+        @rx.var(cache=False)
         def task_global(self) -> int:
             return lifespan_task_global
 
-        @rx.var
+        @rx.var(cache=False)
         def context_global(self) -> int:
             return lifespan_context_global
 

+ 7 - 7
tests/integration/test_media.py

@@ -22,31 +22,31 @@ def MediaApp():
                 img.format = format  # type: ignore
             return img
 
-        @rx.var(cache=True)
+        @rx.var
         def img_default(self) -> Image.Image:
             return self._blue()
 
-        @rx.var(cache=True)
+        @rx.var
         def img_bmp(self) -> Image.Image:
             return self._blue(format="BMP")
 
-        @rx.var(cache=True)
+        @rx.var
         def img_jpg(self) -> Image.Image:
             return self._blue(format="JPEG")
 
-        @rx.var(cache=True)
+        @rx.var
         def img_png(self) -> Image.Image:
             return self._blue(format="PNG")
 
-        @rx.var(cache=True)
+        @rx.var
         def img_gif(self) -> Image.Image:
             return self._blue(format="GIF")
 
-        @rx.var(cache=True)
+        @rx.var
         def img_webp(self) -> Image.Image:
             return self._blue(format="WEBP")
 
-        @rx.var(cache=True)
+        @rx.var
         def img_from_url(self) -> Image.Image:
             img_url = "https://picsum.photos/id/1/200/300"
             img_resp = httpx.get(img_url, follow_redirects=True)

+ 4 - 4
tests/units/test_app.py

@@ -908,7 +908,7 @@ class DynamicState(BaseState):
         """Increment the counter var."""
         self.counter = self.counter + 1
 
-    @computed_var(cache=True)
+    @computed_var
     def comp_dynamic(self) -> str:
         """A computed var that depends on the dynamic var.
 
@@ -1549,11 +1549,11 @@ def test_app_with_valid_var_dependencies(compilable_app: tuple[App, Path]):
         base: int = 0
         _backend: int = 0
 
-        @computed_var(cache=True)
+        @computed_var()
         def foo(self) -> str:
             return "foo"
 
-        @computed_var(deps=["_backend", "base", foo], cache=True)
+        @computed_var(deps=["_backend", "base", foo])
         def bar(self) -> str:
             return "bar"
 
@@ -1565,7 +1565,7 @@ def test_app_with_invalid_var_dependencies(compilable_app: tuple[App, Path]):
     app, _ = compilable_app
 
     class InvalidDepState(BaseState):
-        @computed_var(deps=["foolksjdf"], cache=True)
+        @computed_var(deps=["foolksjdf"])
         def bar(self) -> str:
             return "bar"
 

+ 31 - 43
tests/units/test_state.py

@@ -202,7 +202,7 @@ class GrandchildState(ChildState):
 class GrandchildState2(ChildState2):
     """A grandchild state fixture."""
 
-    @rx.var(cache=True)
+    @rx.var
     def cached(self) -> str:
         """A cached var.
 
@@ -215,7 +215,7 @@ class GrandchildState2(ChildState2):
 class GrandchildState3(ChildState3):
     """A great grandchild state fixture."""
 
-    @rx.var
+    @rx.var(cache=False)
     def computed(self) -> str:
         """A computed var.
 
@@ -796,7 +796,7 @@ async def test_process_event_simple(test_state):
 
     # The delta should contain the changes, including computed vars.
     assert update.delta == {
-        TestState.get_full_name(): {"num1": 69, "sum": 72.14, "upper": ""},
+        TestState.get_full_name(): {"num1": 69, "sum": 72.14},
         GrandchildState3.get_full_name(): {"computed": ""},
     }
     assert update.events == []
@@ -823,7 +823,7 @@ async def test_process_event_substate(test_state, child_state, grandchild_state)
     assert child_state.value == "HI"
     assert child_state.count == 24
     assert update.delta == {
-        TestState.get_full_name(): {"sum": 3.14, "upper": ""},
+        # TestState.get_full_name(): {"sum": 3.14, "upper": ""},
         ChildState.get_full_name(): {"value": "HI", "count": 24},
         GrandchildState3.get_full_name(): {"computed": ""},
     }
@@ -839,7 +839,7 @@ async def test_process_event_substate(test_state, child_state, grandchild_state)
     update = await test_state._process(event).__anext__()
     assert grandchild_state.value2 == "new"
     assert update.delta == {
-        TestState.get_full_name(): {"sum": 3.14, "upper": ""},
+        # TestState.get_full_name(): {"sum": 3.14, "upper": ""},
         GrandchildState.get_full_name(): {"value2": "new"},
         GrandchildState3.get_full_name(): {"computed": ""},
     }
@@ -989,7 +989,7 @@ class InterdependentState(BaseState):
     v1: int = 0
     _v2: int = 1
 
-    @rx.var(cache=True)
+    @rx.var
     def v1x2(self) -> int:
         """Depends on var v1.
 
@@ -998,7 +998,7 @@ class InterdependentState(BaseState):
         """
         return self.v1 * 2
 
-    @rx.var(cache=True)
+    @rx.var
     def v2x2(self) -> int:
         """Depends on backend var _v2.
 
@@ -1007,7 +1007,7 @@ class InterdependentState(BaseState):
         """
         return self._v2 * 2
 
-    @rx.var(cache=True, backend=True)
+    @rx.var(backend=True)
     def v2x2_backend(self) -> int:
         """Depends on backend var _v2.
 
@@ -1016,7 +1016,7 @@ class InterdependentState(BaseState):
         """
         return self._v2 * 2
 
-    @rx.var(cache=True)
+    @rx.var
     def v1x2x2(self) -> int:
         """Depends on ComputedVar v1x2.
 
@@ -1025,7 +1025,7 @@ class InterdependentState(BaseState):
         """
         return self.v1x2 * 2  # type: ignore
 
-    @rx.var(cache=True)
+    @rx.var
     def _v3(self) -> int:
         """Depends on backend var _v2.
 
@@ -1034,7 +1034,7 @@ class InterdependentState(BaseState):
         """
         return self._v2
 
-    @rx.var(cache=True)
+    @rx.var
     def v3x2(self) -> int:
         """Depends on ComputedVar _v3.
 
@@ -1239,7 +1239,7 @@ def test_computed_var_cached():
     class ComputedState(BaseState):
         v: int = 0
 
-        @rx.var(cache=True)
+        @rx.var
         def comp_v(self) -> int:
             nonlocal comp_v_calls
             comp_v_calls += 1
@@ -1264,15 +1264,15 @@ def test_computed_var_cached_depends_on_non_cached():
     class ComputedState(BaseState):
         v: int = 0
 
-        @rx.var
+        @rx.var(cache=False)
         def no_cache_v(self) -> int:
             return self.v
 
-        @rx.var(cache=True)
+        @rx.var
         def dep_v(self) -> int:
             return self.no_cache_v  # type: ignore
 
-        @rx.var(cache=True)
+        @rx.var
         def comp_v(self) -> int:
             return self.v
 
@@ -1304,14 +1304,14 @@ def test_computed_var_depends_on_parent_non_cached():
     counter = 0
 
     class ParentState(BaseState):
-        @rx.var
+        @rx.var(cache=False)
         def no_cache_v(self) -> int:
             nonlocal counter
             counter += 1
             return counter
 
     class ChildState(ParentState):
-        @rx.var(cache=True)
+        @rx.var
         def dep_v(self) -> int:
             return self.no_cache_v  # type: ignore
 
@@ -1357,7 +1357,7 @@ def test_cached_var_depends_on_event_handler(use_partial: bool):
         def handler(self):
             self.x = self.x + 1
 
-        @rx.var(cache=True)
+        @rx.var
         def cached_x_side_effect(self) -> int:
             self.handler()
             nonlocal counter
@@ -1393,7 +1393,7 @@ def test_computed_var_dependencies():
         def testprop(self) -> int:
             return self.v
 
-        @rx.var(cache=True)
+        @rx.var
         def comp_v(self) -> int:
             """Direct access.
 
@@ -1402,7 +1402,7 @@ def test_computed_var_dependencies():
             """
             return self.v
 
-        @rx.var(cache=True, backend=True)
+        @rx.var(backend=True)
         def comp_v_backend(self) -> int:
             """Direct access backend var.
 
@@ -1411,7 +1411,7 @@ def test_computed_var_dependencies():
             """
             return self.v
 
-        @rx.var(cache=True)
+        @rx.var
         def comp_v_via_property(self) -> int:
             """Access v via property.
 
@@ -1420,7 +1420,7 @@ def test_computed_var_dependencies():
             """
             return self.testprop
 
-        @rx.var(cache=True)
+        @rx.var
         def comp_w(self):
             """Nested lambda.
 
@@ -1429,7 +1429,7 @@ def test_computed_var_dependencies():
             """
             return lambda: self.w
 
-        @rx.var(cache=True)
+        @rx.var
         def comp_x(self):
             """Nested function.
 
@@ -1442,7 +1442,7 @@ def test_computed_var_dependencies():
 
             return _
 
-        @rx.var(cache=True)
+        @rx.var
         def comp_y(self) -> List[int]:
             """Comprehension iterating over attribute.
 
@@ -1451,7 +1451,7 @@ def test_computed_var_dependencies():
             """
             return [round(y) for y in self.y]
 
-        @rx.var(cache=True)
+        @rx.var
         def comp_z(self) -> List[bool]:
             """Comprehension accesses attribute.
 
@@ -2027,10 +2027,6 @@ async def test_state_proxy(grandchild_state: GrandchildState, mock_app: rx.App):
     assert mcall.args[0] == str(SocketEvent.EVENT)
     assert mcall.args[1] == StateUpdate(
         delta={
-            parent_state.get_full_name(): {
-                "upper": "",
-                "sum": 3.14,
-            },
             grandchild_state.get_full_name(): {
                 "value2": "42",
             },
@@ -2053,7 +2049,7 @@ class BackgroundTaskState(BaseState):
         super().__init__(**kwargs)
         self.router_data = {"simulate": "hydrate"}
 
-    @rx.var
+    @rx.var(cache=False)
     def computed_order(self) -> List[str]:
         """Get the order as a computed var.
 
@@ -3040,10 +3036,6 @@ async def test_get_state(mock_app: rx.App, token: str):
     grandchild_state.value2 = "set_value"
 
     assert test_state.get_delta() == {
-        TestState.get_full_name(): {
-            "sum": 3.14,
-            "upper": "",
-        },
         GrandchildState.get_full_name(): {
             "value2": "set_value",
         },
@@ -3081,10 +3073,6 @@ async def test_get_state(mock_app: rx.App, token: str):
     child_state2.value = "set_c2_value"
 
     assert new_test_state.get_delta() == {
-        TestState.get_full_name(): {
-            "sum": 3.14,
-            "upper": "",
-        },
         ChildState2.get_full_name(): {
             "value": "set_c2_value",
         },
@@ -3139,7 +3127,7 @@ async def test_get_state_from_sibling_not_cached(mock_app: rx.App, token: str):
 
         child3_var: int = 0
 
-        @rx.var
+        @rx.var(cache=False)
         def v(self):
             pass
 
@@ -3210,8 +3198,8 @@ def test_potentially_dirty_substates():
         def bar(self) -> str:
             return ""
 
-    assert RxState._potentially_dirty_substates() == {State}
-    assert State._potentially_dirty_substates() == {C1}
+    assert RxState._potentially_dirty_substates() == set()
+    assert State._potentially_dirty_substates() == set()
     assert C1._potentially_dirty_substates() == set()
 
 
@@ -3226,7 +3214,7 @@ def test_router_var_dep() -> None:
     class RouterVarDepState(RouterVarParentState):
         """A state with a router var dependency."""
 
-        @rx.var(cache=True)
+        @rx.var
         def foo(self) -> str:
             return self.router.page.params.get("foo", "")
 
@@ -3421,7 +3409,7 @@ class MixinState(State, mixin=True):
     _backend: int = 0
     _backend_no_default: dict
 
-    @rx.var(cache=True)
+    @rx.var
     def computed(self) -> str:
         """A computed var on mixin state.
 

+ 4 - 4
tests/units/test_state_tree.py

@@ -42,7 +42,7 @@ class SubA_A_A_A(SubA_A_A):
 class SubA_A_A_B(SubA_A_A):
     """SubA_A_A_B is a child of SubA_A_A."""
 
-    @rx.var(cache=True)
+    @rx.var
     def sub_a_a_a_cached(self) -> int:
         """A cached var.
 
@@ -117,7 +117,7 @@ class TreeD(Root):
 
     d: int
 
-    @rx.var
+    @rx.var(cache=False)
     def d_var(self) -> int:
         """A computed var.
 
@@ -156,7 +156,7 @@ class SubE_A_A_A_A(SubE_A_A_A):
 
     sub_e_a_a_a_a: int
 
-    @rx.var
+    @rx.var(cache=False)
     def sub_e_a_a_a_a_var(self) -> int:
         """A computed var.
 
@@ -183,7 +183,7 @@ class SubE_A_A_A_D(SubE_A_A_A):
 
     sub_e_a_a_a_d: int
 
-    @rx.var(cache=True)
+    @rx.var
     def sub_e_a_a_a_d_var(self) -> int:
         """A computed var.
 

+ 2 - 8
tests/units/test_var.py

@@ -1814,10 +1814,7 @@ def cv_fget(state: BaseState) -> int:
     ],
 )
 def test_computed_var_deps(deps: List[Union[str, Var]], expected: Set[str]):
-    @computed_var(
-        deps=deps,
-        cache=True,
-    )
+    @computed_var(deps=deps)
     def test_var(state) -> int:
         return 1
 
@@ -1835,10 +1832,7 @@ def test_computed_var_deps(deps: List[Union[str, Var]], expected: Set[str]):
 def test_invalid_computed_var_deps(deps: List):
     with pytest.raises(TypeError):
 
-        @computed_var(
-            deps=deps,
-            cache=True,
-        )
+        @computed_var(deps=deps)
         def test_var(state) -> int:
             return 1