Skip to content

Commit cc623eb

Browse files
committed
fix: Adding tests. Refactoring. Bot comments solved.
1 parent 3bcac1c commit cc623eb

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed

reflex/state.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,7 +2059,13 @@ def _dirty_computed_vars(
20592059
if include_backend or not self.computed_vars[cvar]._backend
20602060
}
20612061

2062-
def __skip_serialization(self) -> bool:
2062+
@property
2063+
def _skip_serialization(self) -> bool:
2064+
"""Whether to skip serialization for this state.
2065+
2066+
Override in a subclass to skip sending state updates to the frontend.
2067+
Useful e.g. for permission/role-based state visibility.
2068+
"""
20632069
return False
20642070

20652071
def get_delta(self) -> Delta:
@@ -2070,7 +2076,7 @@ def get_delta(self) -> Delta:
20702076
"""
20712077
delta = {}
20722078

2073-
if self.__skip_serialization():
2079+
if self._skip_serialization:
20742080
return delta
20752081

20762082
self._mark_dirty_computed_vars()
@@ -2209,7 +2215,7 @@ def dict(
22092215
Returns:
22102216
The object as a dictionary.
22112217
"""
2212-
if not initial and self.__skip_serialization():
2218+
if not initial and self._skip_serialization:
22132219
return {}
22142220

22152221
if include_computed:

tests/units/test_state.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4470,3 +4470,66 @@ async def test_rebind_mutable_proxy(mock_app: rx.App, token: str) -> None:
44704470
assert state.data["a"] == [2, 3]
44714471
# Object identity persists across serialization, so data["b"] is also mutated.
44724472
assert state.data["b"] == [2, 3]
4473+
4474+
4475+
class NormalState(rx.State):
4476+
value: rx.Field[int] = rx.field(42)
4477+
4478+
4479+
class SkippedState(NormalState):
4480+
skipped_value: rx.Field[int] = rx.field(43)
4481+
4482+
@property
4483+
def _skip_serialization(self) -> bool:
4484+
return True
4485+
4486+
4487+
class SkippedSubState(SkippedState):
4488+
substate_value: rx.Field[int] = rx.field(44)
4489+
4490+
4491+
def test_default_skip_serialization_is_false():
4492+
state = NormalState(_reflex_internal_init=True)
4493+
assert state._skip_serialization is False
4494+
4495+
4496+
def test_subclass_override_is_respected():
4497+
"""Subclass override must actually take effect."""
4498+
assert SkippedState(_reflex_internal_init=True)._skip_serialization is True
4499+
assert NormalState(_reflex_internal_init=True)._skip_serialization is False
4500+
4501+
4502+
def test_dict_contains_value_by_default():
4503+
state = NormalState(_reflex_internal_init=True)
4504+
state_dict = str(state.dict())
4505+
assert "42" in state_dict
4506+
assert "43" not in state_dict
4507+
assert "44" not in state_dict
4508+
4509+
4510+
def test_dict_empty_when_skip_serialization():
4511+
state = SkippedState(_reflex_internal_init=True)
4512+
assert state.dict() == {}
4513+
4514+
4515+
def test_get_delta_contains_value_after_change():
4516+
state = NormalState(_reflex_internal_init=True)
4517+
state.value = 99
4518+
state_delta = str(state.get_delta())
4519+
assert "99" in state_delta
4520+
assert "43" not in state_delta
4521+
assert "44" not in state_delta
4522+
4523+
4524+
def test_get_delta_empty_when_skip_serialization():
4525+
state = SkippedState(_reflex_internal_init=True)
4526+
state.skipped_value = 99
4527+
assert state.get_delta() == {}
4528+
4529+
4530+
def test_substate_of_skipped_parent_is_also_skipped():
4531+
"""Substates of a skipped parent are also skipped, even without overriding _skip_serialization."""
4532+
state = SkippedSubState(_reflex_internal_init=True)
4533+
state.substate_value = 99
4534+
assert state.get_delta() == {}
4535+
assert state.dict() == {}

0 commit comments

Comments
 (0)