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:
Masen Furer 2024-03-04 13:13:08 -08:00
parent 7725c48fb7
commit c8dfb74995
No known key found for this signature in database
GPG Key ID: B0008AD22B3B3A95
2 changed files with 27 additions and 3 deletions

View File

@ -1505,14 +1505,13 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
"""
# _always_dirty_substates need to be fetched to recalc computed vars.
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
)
# Substates with cached vars also need to be fetched.
for dependent_substates in cls._substate_var_dependencies.values():
fetch_substates.update(
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
)
)

View File

@ -2719,3 +2719,28 @@ async def test_get_state(mock_app: rx.App, token: str):
"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()