Skip to content

Commit d6e08e9

Browse files
better computed var static deps (#4729)
* better computed var static deps * typing and usability improvements for computed var static dependencies
1 parent 2b7e4d6 commit d6e08e9

File tree

1 file changed

+61
-26
lines changed

1 file changed

+61
-26
lines changed

reflex/vars/base.py

+61-26
Original file line numberDiff line numberDiff line change
@@ -1983,7 +1983,7 @@ class ComputedVar(Var[RETURN_TYPE]):
19831983
_initial_value: RETURN_TYPE | types.Unset = dataclasses.field(default=types.Unset())
19841984

19851985
# Explicit var dependencies to track
1986-
_static_deps: dict[str, set[str]] = dataclasses.field(default_factory=dict)
1986+
_static_deps: dict[str | None, set[str]] = dataclasses.field(default_factory=dict)
19871987

19881988
# Whether var dependencies should be auto-determined
19891989
_auto_deps: bool = dataclasses.field(default=True)
@@ -2053,39 +2053,72 @@ def __init__(
20532053

20542054
object.__setattr__(self, "_update_interval", interval)
20552055

2056-
_static_deps = {}
2057-
if isinstance(deps, dict):
2058-
# Assume a dict is coming from _replace, so no special processing.
2059-
_static_deps = deps
2060-
elif deps is not None:
2061-
for dep in deps:
2062-
if isinstance(dep, Var):
2063-
state_name = (
2064-
all_var_data.state
2065-
if (all_var_data := dep._get_all_var_data())
2066-
and all_var_data.state
2067-
else None
2068-
)
2069-
if all_var_data is not None:
2070-
var_name = all_var_data.field_name
2071-
else:
2072-
var_name = dep._js_expr
2073-
_static_deps.setdefault(state_name, set()).add(var_name)
2074-
elif isinstance(dep, str) and dep != "":
2075-
_static_deps.setdefault(None, set()).add(dep)
2076-
else:
2077-
raise TypeError(
2078-
"ComputedVar dependencies must be Var instances or var names (non-empty strings)."
2079-
)
20802056
object.__setattr__(
20812057
self,
20822058
"_static_deps",
2083-
_static_deps,
2059+
self._calculate_static_deps(deps),
20842060
)
20852061
object.__setattr__(self, "_auto_deps", auto_deps)
20862062

20872063
object.__setattr__(self, "_fget", fget)
20882064

2065+
def _calculate_static_deps(
2066+
self,
2067+
deps: Union[List[Union[str, Var]], dict[str | None, set[str]]] | None = None,
2068+
) -> dict[str | None, set[str]]:
2069+
"""Calculate the static dependencies of the computed var from user input or existing dependencies.
2070+
2071+
Args:
2072+
deps: The user input dependencies or existing dependencies.
2073+
2074+
Returns:
2075+
The static dependencies.
2076+
"""
2077+
if isinstance(deps, dict):
2078+
# Assume a dict is coming from _replace, so no special processing.
2079+
return deps
2080+
_static_deps = {}
2081+
if deps is not None:
2082+
for dep in deps:
2083+
_static_deps = self._add_static_dep(dep, _static_deps)
2084+
return _static_deps
2085+
2086+
def _add_static_dep(
2087+
self, dep: Union[str, Var], deps: dict[str | None, set[str]] | None = None
2088+
) -> dict[str | None, set[str]]:
2089+
"""Add a static dependency to the computed var or existing dependency set.
2090+
2091+
Args:
2092+
dep: The dependency to add.
2093+
deps: The existing dependency set.
2094+
2095+
Returns:
2096+
The updated dependency set.
2097+
2098+
Raises:
2099+
TypeError: If the computed var dependencies are not Var instances or var names.
2100+
"""
2101+
if deps is None:
2102+
deps = self._static_deps
2103+
if isinstance(dep, Var):
2104+
state_name = (
2105+
all_var_data.state
2106+
if (all_var_data := dep._get_all_var_data()) and all_var_data.state
2107+
else None
2108+
)
2109+
if all_var_data is not None:
2110+
var_name = all_var_data.field_name
2111+
else:
2112+
var_name = dep._js_expr
2113+
deps.setdefault(state_name, set()).add(var_name)
2114+
elif isinstance(dep, str) and dep != "":
2115+
deps.setdefault(None, set()).add(dep)
2116+
else:
2117+
raise TypeError(
2118+
"ComputedVar dependencies must be Var instances or var names (non-empty strings)."
2119+
)
2120+
return deps
2121+
20892122
@override
20902123
def _replace(
20912124
self,
@@ -2106,6 +2139,8 @@ def _replace(
21062139
Raises:
21072140
TypeError: If kwargs contains keys that are not allowed.
21082141
"""
2142+
if "deps" in kwargs:
2143+
kwargs["deps"] = self._calculate_static_deps(kwargs["deps"])
21092144
field_values = {
21102145
"fget": kwargs.pop("fget", self._fget),
21112146
"initial_value": kwargs.pop("initial_value", self._initial_value),

0 commit comments

Comments
 (0)