From 65dda293245a9888524c3906ecb9402dc551c7a4 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 11 Jul 2026 02:24:13 +0000 Subject: [PATCH 1/4] Bypass f-string tag round-trip for var operation operands Interpolating a var into an f-string hashes it, permanently registers it in the module-global _global_vars dict (which never evicts - a memory leak, worst under dev hot-reload), and emits a tag that the return expression's __post_init__ regex-decodes back out. For operands of a @var_operation this round-trip is pure overhead (~30-40% of op construction): the operation merges operand VarData directly from _args. var_operation now suppresses tagging on its operands (ref-counted, so nested operations on the same var can't clear an outer suppression early) while the body runs. Vars created inside the body still tag normally, so their VarData keeps flowing through the return expression. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Jy8uHH11KircGa2MbTrR8g --- .../reflex-base/src/reflex_base/vars/base.py | 33 ++++++++- tests/units/vars/test_base.py | 69 ++++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/packages/reflex-base/src/reflex_base/vars/base.py b/packages/reflex-base/src/reflex_base/vars/base.py index 8cdeeb8cd64..4641dbf673f 100644 --- a/packages/reflex-base/src/reflex_base/vars/base.py +++ b/packages/reflex-base/src/reflex_base/vars/base.py @@ -930,6 +930,13 @@ def __format__(self, format_spec: str) -> str: Returns: The formatted var. """ + # Operands of a running ``var_operation`` body interpolate as their + # raw JS expression: their VarData flows through the operation's + # ``_args``, so the tag round-trip (and its permanent ``_global_vars`` + # entry) is pure overhead there. See ``var_operation``. + if self.__dict__.get("_format_without_tagging"): + return self._js_expr + hashed_var = hash(self) _global_vars[hashed_var] = self @@ -1941,10 +1948,34 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> Var[T]: for key, value in kwargs.items() } + operands = [*args_vars.values(), *kwargs_vars.values()] + # Suppress f-string tagging for the operands while the body runs: + # their VarData reaches the operation through ``_args`` below, so the + # tag round-trip (hash + permanent ``_global_vars`` entry + regex + # decode of the return expression) is pure overhead. The suppression + # is ref-counted so a nested operation on the same var cannot clear + # an outer suppression early; vars created inside the body still tag + # normally and keep contributing VarData via the return expression. + for operand in operands: + operand_dict = operand.__dict__ + operand_dict["_format_without_tagging"] = ( + operand_dict.get("_format_without_tagging", 0) + 1 + ) + try: + return_var = func(*args_vars.values(), **kwargs_vars) # pyright: ignore [reportCallIssue] + finally: + for operand in operands: + operand_dict = operand.__dict__ + remaining = operand_dict["_format_without_tagging"] - 1 + if remaining: + operand_dict["_format_without_tagging"] = remaining + else: + del operand_dict["_format_without_tagging"] + return CustomVarOperation.create( name=func.__name__, args=tuple(list(args_vars.items()) + list(kwargs_vars.items())), - return_var=func(*args_vars.values(), **kwargs_vars), # pyright: ignore [reportCallIssue, reportReturnType] + return_var=return_var, # pyright: ignore [reportArgumentType] ).guess_type() return wrapper diff --git a/tests/units/vars/test_base.py b/tests/units/vars/test_base.py index e4d7e363e3c..9eb665a6722 100644 --- a/tests/units/vars/test_base.py +++ b/tests/units/vars/test_base.py @@ -1,7 +1,16 @@ from collections.abc import Mapping, Sequence import pytest -from reflex_base.vars.base import computed_var, figure_out_type +from reflex_base.utils.imports import ImportVar +from reflex_base.vars.base import ( + Var, + VarData, + _global_vars, + computed_var, + figure_out_type, + var_operation, + var_operation_return, +) from reflex.state import State @@ -66,6 +75,64 @@ class FancyTestStrVar(Var, python_types=FancyTestStr): ) +def test_var_operation_does_not_register_global_vars() -> None: + """Internal var operations bypass the f-string tag round-trip. + + Regression: each operand interpolation hashed the var and permanently + registered it in the module-global ``_global_vars`` (a memory leak, + worst under hot-reload), then the return expression regex-decoded the + tag back out. Operand VarData already flows through + ``CustomVarOperation._args``. + """ + lhs = Var( + _js_expr="tag_bypass_lhs", + _var_data=VarData(imports={"op-lib": [ImportVar(tag="thing")]}), + ).to(int) + + before = len(_global_vars) + result = lhs + 1 + assert len(_global_vars) == before + + # The suppression flag does not persist on the operand after the op. + assert "_format_without_tagging" not in lhs.__dict__ + + # Operand VarData still reaches the merged operation VarData via _args. + var_data = result._get_all_var_data() + assert var_data is not None + assert dict(var_data.imports)["op-lib"] == (ImportVar(tag="thing"),) + assert str(result) == "(tag_bypass_lhs + 1)" + + # Formatting outside an operation still registers (and tags) as before. + formatted = f"{lhs}" + assert len(_global_vars) == before + 1 + assert formatted != str(lhs) + + +def test_var_operation_body_created_vars_keep_var_data() -> None: + """Vars created inside an operation body still contribute their VarData. + + Only the operands bypass tagging; a var constructed inside the body is + not carried by ``_args``, so it must keep flowing through the tagged + return expression. + """ + from reflex_base.vars.number import NumberVar + + @var_operation + def op_with_derived(value: NumberVar): + derived = Var( + _js_expr="derivedHelper", + _var_data=VarData(imports={"derived-lib": [ImportVar(tag="helper")]}), + ) + return var_operation_return(f"({value} + {derived})", var_type=int) + + result = op_with_derived(Var(_js_expr="a").to(int)) + + var_data = result._get_all_var_data() + assert var_data is not None + assert dict(var_data.imports)["derived-lib"] == (ImportVar(tag="helper"),) + assert str(result) == "(a + derivedHelper)" + + def test_computed_var_replace() -> None: class StateTest(State): @computed_var(cache=True) From e71be0843756a24efdd738217abd7e69e05e0770 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 11 Jul 2026 02:24:49 +0000 Subject: [PATCH 2/4] Add news fragment for var operation tag bypass Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Jy8uHH11KircGa2MbTrR8g --- packages/reflex-base/news/6747.performance.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/reflex-base/news/6747.performance.md diff --git a/packages/reflex-base/news/6747.performance.md b/packages/reflex-base/news/6747.performance.md new file mode 100644 index 00000000000..f74ea9384d8 --- /dev/null +++ b/packages/reflex-base/news/6747.performance.md @@ -0,0 +1 @@ +`@var_operation` operands no longer pay the f-string tag round-trip (hash + permanent `_global_vars` registration + regex decode), cutting ~30-40% of var-operation construction cost and stopping internal operations from growing the never-evicting `_global_vars` dict. From 7b99834beeabce0f03a1856694b1ae35d496550f Mon Sep 17 00:00:00 2001 From: Masen Furer Date: Mon, 13 Jul 2026 14:55:21 -0700 Subject: [PATCH 3/4] Apply suggestion from @greptile-apps[bot] Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- packages/reflex-base/src/reflex_base/vars/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/reflex-base/src/reflex_base/vars/base.py b/packages/reflex-base/src/reflex_base/vars/base.py index 4641dbf673f..07594c3d400 100644 --- a/packages/reflex-base/src/reflex_base/vars/base.py +++ b/packages/reflex-base/src/reflex_base/vars/base.py @@ -935,7 +935,7 @@ def __format__(self, format_spec: str) -> str: # ``_args``, so the tag round-trip (and its permanent ``_global_vars`` # entry) is pure overhead there. See ``var_operation``. if self.__dict__.get("_format_without_tagging"): - return self._js_expr + return str(self) hashed_var = hash(self) From 5f75b20c48fff328344e9a21b0a0134b45146d36 Mon Sep 17 00:00:00 2001 From: Alek Petuskey Date: Fri, 17 Jul 2026 18:38:30 -0700 Subject: [PATCH 4/4] Appease pyright on operand __dict__ tag suppression --- packages/reflex-base/src/reflex_base/vars/base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/reflex-base/src/reflex_base/vars/base.py b/packages/reflex-base/src/reflex_base/vars/base.py index 07594c3d400..364c37165bb 100644 --- a/packages/reflex-base/src/reflex_base/vars/base.py +++ b/packages/reflex-base/src/reflex_base/vars/base.py @@ -1958,7 +1958,7 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> Var[T]: # normally and keep contributing VarData via the return expression. for operand in operands: operand_dict = operand.__dict__ - operand_dict["_format_without_tagging"] = ( + operand_dict["_format_without_tagging"] = ( # pyright: ignore[reportIndexIssue] operand_dict.get("_format_without_tagging", 0) + 1 ) try: @@ -1968,9 +1968,9 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> Var[T]: operand_dict = operand.__dict__ remaining = operand_dict["_format_without_tagging"] - 1 if remaining: - operand_dict["_format_without_tagging"] = remaining + operand_dict["_format_without_tagging"] = remaining # pyright: ignore[reportIndexIssue] else: - del operand_dict["_format_without_tagging"] + del operand_dict["_format_without_tagging"] # pyright: ignore[reportIndexIssue] return CustomVarOperation.create( name=func.__name__,