better computed var static deps (#4729)
* better computed var static deps * typing and usability improvements for computed var static dependencies
This commit is contained in:
parent
2b7e4d6b4e
commit
d6e08e90a8
@ -1983,7 +1983,7 @@ class ComputedVar(Var[RETURN_TYPE]):
|
||||
_initial_value: RETURN_TYPE | types.Unset = dataclasses.field(default=types.Unset())
|
||||
|
||||
# Explicit var dependencies to track
|
||||
_static_deps: dict[str, set[str]] = dataclasses.field(default_factory=dict)
|
||||
_static_deps: dict[str | None, set[str]] = dataclasses.field(default_factory=dict)
|
||||
|
||||
# Whether var dependencies should be auto-determined
|
||||
_auto_deps: bool = dataclasses.field(default=True)
|
||||
@ -2053,39 +2053,72 @@ class ComputedVar(Var[RETURN_TYPE]):
|
||||
|
||||
object.__setattr__(self, "_update_interval", interval)
|
||||
|
||||
_static_deps = {}
|
||||
if isinstance(deps, dict):
|
||||
# Assume a dict is coming from _replace, so no special processing.
|
||||
_static_deps = deps
|
||||
elif deps is not None:
|
||||
for dep in deps:
|
||||
if isinstance(dep, Var):
|
||||
state_name = (
|
||||
all_var_data.state
|
||||
if (all_var_data := dep._get_all_var_data())
|
||||
and all_var_data.state
|
||||
else None
|
||||
)
|
||||
if all_var_data is not None:
|
||||
var_name = all_var_data.field_name
|
||||
else:
|
||||
var_name = dep._js_expr
|
||||
_static_deps.setdefault(state_name, set()).add(var_name)
|
||||
elif isinstance(dep, str) and dep != "":
|
||||
_static_deps.setdefault(None, set()).add(dep)
|
||||
else:
|
||||
raise TypeError(
|
||||
"ComputedVar dependencies must be Var instances or var names (non-empty strings)."
|
||||
)
|
||||
object.__setattr__(
|
||||
self,
|
||||
"_static_deps",
|
||||
_static_deps,
|
||||
self._calculate_static_deps(deps),
|
||||
)
|
||||
object.__setattr__(self, "_auto_deps", auto_deps)
|
||||
|
||||
object.__setattr__(self, "_fget", fget)
|
||||
|
||||
def _calculate_static_deps(
|
||||
self,
|
||||
deps: Union[List[Union[str, Var]], dict[str | None, set[str]]] | None = None,
|
||||
) -> dict[str | None, set[str]]:
|
||||
"""Calculate the static dependencies of the computed var from user input or existing dependencies.
|
||||
|
||||
Args:
|
||||
deps: The user input dependencies or existing dependencies.
|
||||
|
||||
Returns:
|
||||
The static dependencies.
|
||||
"""
|
||||
if isinstance(deps, dict):
|
||||
# Assume a dict is coming from _replace, so no special processing.
|
||||
return deps
|
||||
_static_deps = {}
|
||||
if deps is not None:
|
||||
for dep in deps:
|
||||
_static_deps = self._add_static_dep(dep, _static_deps)
|
||||
return _static_deps
|
||||
|
||||
def _add_static_dep(
|
||||
self, dep: Union[str, Var], deps: dict[str | None, set[str]] | None = None
|
||||
) -> dict[str | None, set[str]]:
|
||||
"""Add a static dependency to the computed var or existing dependency set.
|
||||
|
||||
Args:
|
||||
dep: The dependency to add.
|
||||
deps: The existing dependency set.
|
||||
|
||||
Returns:
|
||||
The updated dependency set.
|
||||
|
||||
Raises:
|
||||
TypeError: If the computed var dependencies are not Var instances or var names.
|
||||
"""
|
||||
if deps is None:
|
||||
deps = self._static_deps
|
||||
if isinstance(dep, Var):
|
||||
state_name = (
|
||||
all_var_data.state
|
||||
if (all_var_data := dep._get_all_var_data()) and all_var_data.state
|
||||
else None
|
||||
)
|
||||
if all_var_data is not None:
|
||||
var_name = all_var_data.field_name
|
||||
else:
|
||||
var_name = dep._js_expr
|
||||
deps.setdefault(state_name, set()).add(var_name)
|
||||
elif isinstance(dep, str) and dep != "":
|
||||
deps.setdefault(None, set()).add(dep)
|
||||
else:
|
||||
raise TypeError(
|
||||
"ComputedVar dependencies must be Var instances or var names (non-empty strings)."
|
||||
)
|
||||
return deps
|
||||
|
||||
@override
|
||||
def _replace(
|
||||
self,
|
||||
@ -2106,6 +2139,8 @@ class ComputedVar(Var[RETURN_TYPE]):
|
||||
Raises:
|
||||
TypeError: If kwargs contains keys that are not allowed.
|
||||
"""
|
||||
if "deps" in kwargs:
|
||||
kwargs["deps"] = self._calculate_static_deps(kwargs["deps"])
|
||||
field_values = {
|
||||
"fget": kwargs.pop("fget", self._fget),
|
||||
"initial_value": kwargs.pop("initial_value", self._initial_value),
|
||||
|
Loading…
Reference in New Issue
Block a user