From d257f141b1499e8725910a603403e66d4c36441b Mon Sep 17 00:00:00 2001 From: Benedikt Bartscher Date: Wed, 8 Jul 2026 20:28:22 +0200 Subject: [PATCH] some typing nits --- .../src/reflex_base/components/field.py | 8 ++--- .../src/reflex_base/event/__init__.py | 2 +- .../reflex_base/plugins/shared_tailwind.py | 11 ++++--- .../reflex-base/src/reflex_base/vars/base.py | 30 ++++++++++++------- tests/units/test_prerequisites.py | 15 +++++----- tests/units/test_state.py | 8 +++-- 6 files changed, 43 insertions(+), 31 deletions(-) diff --git a/packages/reflex-base/src/reflex_base/components/field.py b/packages/reflex-base/src/reflex_base/components/field.py index 413b29d062c..30041e6d97a 100644 --- a/packages/reflex-base/src/reflex_base/components/field.py +++ b/packages/reflex-base/src/reflex_base/components/field.py @@ -110,11 +110,11 @@ def _collect_inherited_fields(cls, bases: tuple[type, ...]) -> dict[str, Any]: # Collect inherited fields from base classes for base in bases[::-1]: - if hasattr(base, "_inherited_fields"): - inherited_fields.update(base._inherited_fields) + if (fields := getattr(base, "_inherited_fields", None)) is not None: + inherited_fields.update(fields) for base in bases[::-1]: - if hasattr(base, "_own_fields"): - inherited_fields.update(base._own_fields) + if (fields := getattr(base, "_own_fields", None)) is not None: + inherited_fields.update(fields) return inherited_fields diff --git a/packages/reflex-base/src/reflex_base/event/__init__.py b/packages/reflex-base/src/reflex_base/event/__init__.py index ff94adde754..956ad826437 100644 --- a/packages/reflex-base/src/reflex_base/event/__init__.py +++ b/packages/reflex-base/src/reflex_base/event/__init__.py @@ -705,7 +705,7 @@ class EventChain(EventActionsMixin): args_spec: Callable | Sequence[Callable] | None = dataclasses.field(default=None) - invocation: Var | None = dataclasses.field(default=None) + invocation: FunctionVar | None = dataclasses.field(default=None) @classmethod def create( diff --git a/packages/reflex-base/src/reflex_base/plugins/shared_tailwind.py b/packages/reflex-base/src/reflex_base/plugins/shared_tailwind.py index 62180093ee6..e1318ff5e62 100644 --- a/packages/reflex-base/src/reflex_base/plugins/shared_tailwind.py +++ b/packages/reflex-base/src/reflex_base/plugins/shared_tailwind.py @@ -1,7 +1,6 @@ """Tailwind CSS configuration types for Reflex plugins.""" import dataclasses -from collections.abc import Mapping from copy import deepcopy from typing import Any, Literal, TypedDict @@ -108,7 +107,7 @@ def tailwind_config_js_template( imports = [ plugin["import"] for plugin in plugins - if isinstance(plugin, Mapping) and "import" in plugin + if not isinstance(plugin, str) and "import" in plugin ] # Generate import statements for destructured imports @@ -119,12 +118,12 @@ def tailwind_config_js_template( # Generate plugin imports plugin_imports = [] for i, plugin in enumerate(plugins, 1): - if isinstance(plugin, Mapping) and "call" not in plugin: + if isinstance(plugin, str): + plugin_imports.append(f"import plugin{i} from {json.dumps(plugin)};") + elif "call" not in plugin: plugin_imports.append( f"import plugin{i} from {json.dumps(plugin['name'])};" ) - elif not isinstance(plugin, Mapping): - plugin_imports.append(f"import plugin{i} from {json.dumps(plugin)};") plugin_imports_lines = "\n".join(plugin_imports) @@ -136,7 +135,7 @@ def tailwind_config_js_template( # Generate plugin array plugin_list = [] for i, plugin in enumerate(plugins, 1): - if isinstance(plugin, Mapping) and "call" in plugin: + if not isinstance(plugin, str) and "call" in plugin: args_part = "" if "args" in plugin: args_part = json.dumps(plugin["args"]) diff --git a/packages/reflex-base/src/reflex_base/vars/base.py b/packages/reflex-base/src/reflex_base/vars/base.py index f7212bef821..024d0f4efe2 100644 --- a/packages/reflex-base/src/reflex_base/vars/base.py +++ b/packages/reflex-base/src/reflex_base/vars/base.py @@ -3516,12 +3516,22 @@ def __get__( @overload def __get__( - self: Field[list[V]] - | Field[set[V]] - | Field[list[V] | None] - | Field[set[V] | None], - instance: None, - owner: Any, + self: Field[list[V]], instance: None, owner: Any + ) -> ArrayVar[Sequence[V]]: ... + + @overload + def __get__( + self: Field[set[V]], instance: None, owner: Any + ) -> ArrayVar[Sequence[V]]: ... + + @overload + def __get__( + self: Field[list[V] | None], instance: None, owner: Any + ) -> ArrayVar[Sequence[V]]: ... + + @overload + def __get__( + self: Field[set[V] | None], instance: None, owner: Any ) -> ArrayVar[Sequence[V]]: ... @overload @@ -3667,11 +3677,11 @@ def __new__( ) for base in bases[::-1]: - if hasattr(base, "__inherited_fields__"): - inherited_fields.update(base.__inherited_fields__) + if (fields := getattr(base, "__inherited_fields__", None)) is not None: + inherited_fields.update(fields) for base in bases[::-1]: - if hasattr(base, "__own_fields__"): - inherited_fields.update(base.__own_fields__) + if (fields := getattr(base, "__own_fields__", None)) is not None: + inherited_fields.update(fields) for key, value in [ (key, value) diff --git a/tests/units/test_prerequisites.py b/tests/units/test_prerequisites.py index 63a298f78f6..cf8854b80f4 100644 --- a/tests/units/test_prerequisites.py +++ b/tests/units/test_prerequisites.py @@ -1339,14 +1339,12 @@ def test_extract_package_name(): assert js_runtimes._extract_package_name("@scope/pkg@1.2.3") == "@scope/pkg" -def test_cached_procedure(): +def test_cached_procedure(tmp_path: Path): call_count = 0 - temp_file = tempfile.mktemp() + temp_file = tmp_path / "no_args_cache" - @cached_procedure( - cache_file_path=lambda: Path(temp_file), payload_fn=lambda: "constant" - ) + @cached_procedure(cache_file_path=lambda: temp_file, payload_fn=lambda: "constant") def _function_with_no_args(): nonlocal call_count call_count += 1 @@ -1358,10 +1356,10 @@ def _function_with_no_args(): call_count = 0 - another_temp_file = tempfile.mktemp() + another_temp_file = tmp_path / "some_args_cache" @cached_procedure( - cache_file_path=lambda: Path(another_temp_file), + cache_file_path=lambda: another_temp_file, payload_fn=lambda *args, **kwargs: f"{repr(args), repr(kwargs)}", ) def _function_with_some_args(*args, **kwargs): @@ -1380,7 +1378,8 @@ def _function_with_some_args(*args, **kwargs): call_count = 0 @cached_procedure( - cache_file_path=lambda: Path(tempfile.mktemp()), payload_fn=lambda: "constant" + cache_file_path=lambda: tmp_path / f"fresh_{uuid.uuid4().hex}", + payload_fn=lambda: "constant", ) def _function_with_no_args_fn(): nonlocal call_count diff --git a/tests/units/test_state.py b/tests/units/test_state.py index b0aaf6e022f..98a9f6e1744 100644 --- a/tests/units/test_state.py +++ b/tests/units/test_state.py @@ -1535,11 +1535,14 @@ def dep_v(self) -> int: @pytest.mark.parametrize("use_partial", [True, False]) -def test_cached_var_depends_on_event_handler(use_partial: bool): +def test_cached_var_depends_on_event_handler( + use_partial: bool, monkeypatch: pytest.MonkeyPatch +): """A cached var that calls an event handler calculates deps correctly. Args: use_partial: if true, replace the EventHandler with functools.partial + monkeypatch: The pytest monkeypatch fixture. """ counter = 0 @@ -1557,7 +1560,8 @@ def cached_x_side_effect(self) -> int: return counter if use_partial: - HandlerState.handler = functools.partial(HandlerState.handler.fn) # pyright: ignore [reportFunctionMemberAccess] + handler_fn = HandlerState.event_handlers["handler"].fn + monkeypatch.setattr(HandlerState, "handler", functools.partial(handler_fn)) assert isinstance(HandlerState.handler, functools.partial) else: assert isinstance(HandlerState.handler, EventHandler)