Fix infinite recursion when a substate named "state" has a computed var (#2778)
* test_potentially_dirty_substates: when a state named State should be computed Catch a regression introduced in 0.4.3a1 * _potentially_dirty_substates: qualify substate name When looking up substate classes, ensure the qualified name is used to avoid issues with same-named substates.
This commit is contained in:
parent
7725c48fb7
commit
c8dfb74995
@ -1505,14 +1505,13 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
"""
|
"""
|
||||||
# _always_dirty_substates need to be fetched to recalc computed vars.
|
# _always_dirty_substates need to be fetched to recalc computed vars.
|
||||||
fetch_substates = set(
|
fetch_substates = set(
|
||||||
cls.get_class_substate(tuple(substate_name.split(".")))
|
cls.get_class_substate((cls.get_name(), *substate_name.split(".")))
|
||||||
for substate_name in cls._always_dirty_substates
|
for substate_name in cls._always_dirty_substates
|
||||||
)
|
)
|
||||||
# Substates with cached vars also need to be fetched.
|
|
||||||
for dependent_substates in cls._substate_var_dependencies.values():
|
for dependent_substates in cls._substate_var_dependencies.values():
|
||||||
fetch_substates.update(
|
fetch_substates.update(
|
||||||
set(
|
set(
|
||||||
cls.get_class_substate(tuple(substate_name.split(".")))
|
cls.get_class_substate((cls.get_name(), *substate_name.split(".")))
|
||||||
for substate_name in dependent_substates
|
for substate_name in dependent_substates
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -2719,3 +2719,28 @@ async def test_get_state(mock_app: rx.App, token: str):
|
|||||||
"computed": "",
|
"computed": "",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Save a reference to the rx.State to shadow the name State for testing.
|
||||||
|
RxState = State
|
||||||
|
|
||||||
|
|
||||||
|
def test_potentially_dirty_substates():
|
||||||
|
"""Test that potentially_dirty_substates returns the correct substates.
|
||||||
|
|
||||||
|
Even if the name "State" is shadowed, it should still work correctly.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class State(RxState):
|
||||||
|
@ComputedVar
|
||||||
|
def foo(self) -> str:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
class C1(State):
|
||||||
|
@ComputedVar
|
||||||
|
def bar(self) -> str:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
assert RxState._potentially_dirty_substates() == {State}
|
||||||
|
assert State._potentially_dirty_substates() == {C1}
|
||||||
|
assert C1._potentially_dirty_substates() == set()
|
||||||
|
Loading…
Reference in New Issue
Block a user