diff --git a/packages/reflex-base/src/reflex_base/components/field.py b/packages/reflex-base/src/reflex_base/components/field.py index bcf054c6a32..233d37a9e9b 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 7f6c6ffe43e..4f569138a1d 100644 --- a/packages/reflex-base/src/reflex_base/event/__init__.py +++ b/packages/reflex-base/src/reflex_base/event/__init__.py @@ -946,7 +946,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 7379273b164..c5e7b41d8d0 100644 --- a/packages/reflex-base/src/reflex_base/plugins/shared_tailwind.py +++ b/packages/reflex-base/src/reflex_base/plugins/shared_tailwind.py @@ -2,7 +2,6 @@ import dataclasses import logging -from collections.abc import Mapping from copy import deepcopy from typing import Any, Literal, NotRequired, TypedDict @@ -111,7 +110,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 @@ -122,12 +121,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) @@ -139,7 +138,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 0671d80c917..a1aa2a1260c 100644 --- a/packages/reflex-base/src/reflex_base/vars/base.py +++ b/packages/reflex-base/src/reflex_base/vars/base.py @@ -4285,12 +4285,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 diff --git a/tests/units/test_prerequisites.py b/tests/units/test_prerequisites.py index 09b49edefac..7c575d11ec8 100644 --- a/tests/units/test_prerequisites.py +++ b/tests/units/test_prerequisites.py @@ -2295,14 +2295,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 @@ -2314,10 +2312,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): @@ -2336,7 +2334,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 5f6fd7cceff..883db31398b 100644 --- a/tests/units/test_state.py +++ b/tests/units/test_state.py @@ -2149,11 +2149,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 @@ -2178,7 +2181,8 @@ class MethodPartial(functools.partial): def __get__(self, instance: Any, owner: Any = None) -> Any: return self if instance is None else MethodType(self, instance) - HandlerState.handler = MethodPartial(HandlerState.handler.fn) # pyright: ignore [reportFunctionMemberAccess] + handler_fn = HandlerState.event_handlers["handler"].fn + monkeypatch.setattr(HandlerState, "handler", MethodPartial(handler_fn)) assert isinstance(HandlerState.handler, functools.partial) else: assert isinstance(HandlerState.handler, EventHandler)