Cache ComputedVar fixup for dynamic route vars (#952)
This commit is contained in:
parent
9ea1a64d22
commit
b4e534cc97
@ -484,7 +484,10 @@ class State(Base, ABC, extra=pydantic.Extra.allow):
|
||||
func = arglist_factory(param)
|
||||
else:
|
||||
continue
|
||||
cls.computed_vars[param] = func.set_state(cls) # type: ignore
|
||||
# link dynamically created ComputedVar to this state class for dep determination
|
||||
func.__objclass__ = cls
|
||||
func.fget.__name__ = param
|
||||
cls.vars[param] = cls.computed_vars[param] = func.set_state(cls) # type: ignore
|
||||
setattr(cls, param, func)
|
||||
|
||||
def __getattribute__(self, name: str) -> Any:
|
||||
@ -537,7 +540,7 @@ class State(Base, ABC, extra=pydantic.Extra.allow):
|
||||
super().__setattr__(name, value)
|
||||
|
||||
# Add the var to the dirty list.
|
||||
if name in self.vars:
|
||||
if name in self.vars or name in self.computed_var_dependencies:
|
||||
self.dirty_vars.add(name)
|
||||
self.mark_dirty()
|
||||
|
||||
|
@ -857,6 +857,10 @@ class ComputedVar(Var, property):
|
||||
|
||||
Returns:
|
||||
A set of variable names accessed by the given obj.
|
||||
|
||||
Raises:
|
||||
RuntimeError: if this ComputedVar does not have a reference to the class
|
||||
it is attached to. (Assign var.__objclass__ manually to workaround.)
|
||||
"""
|
||||
d = set()
|
||||
if obj is None:
|
||||
@ -876,6 +880,10 @@ class ComputedVar(Var, property):
|
||||
if self_is_top_of_stack and instruction.opname == "LOAD_ATTR":
|
||||
d.add(instruction.argval)
|
||||
elif self_is_top_of_stack and instruction.opname == "LOAD_METHOD":
|
||||
if not hasattr(self, "__objclass__"):
|
||||
raise RuntimeError(
|
||||
f"ComputedVar {self.name!r} is not bound to a State subclass.",
|
||||
)
|
||||
d.update(self.deps(obj=getattr(self.__objclass__, instruction.argval)))
|
||||
self_is_top_of_stack = False
|
||||
return d
|
||||
|
@ -105,6 +105,25 @@ def test_add_page_set_route(app: App, index_page, windows_platform: bool):
|
||||
assert set(app.pages.keys()) == {"test"}
|
||||
|
||||
|
||||
def test_add_page_set_route_dynamic(app: App, index_page, windows_platform: bool):
|
||||
"""Test adding a page with dynamic route variable to an app.
|
||||
|
||||
Args:
|
||||
app: The app to test.
|
||||
index_page: The index page.
|
||||
windows_platform: Whether the system is windows.
|
||||
"""
|
||||
route = "/test/[dynamic]"
|
||||
if windows_platform:
|
||||
route.lstrip("/").replace("/", "\\")
|
||||
assert app.pages == {}
|
||||
app.add_page(index_page, route=route)
|
||||
assert set(app.pages.keys()) == {"test/[dynamic]"}
|
||||
assert "dynamic" in app.state.computed_vars
|
||||
assert app.state.computed_vars["dynamic"].deps() == {"router_data"}
|
||||
assert "router_data" in app.state().computed_var_dependencies
|
||||
|
||||
|
||||
def test_add_page_set_route_nested(app: App, index_page, windows_platform: bool):
|
||||
"""Test adding a page to an app.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user