From 60c96e8c664a19aea8fb91d7a0f915083bac3a79 Mon Sep 17 00:00:00 2001 From: Masen Furer Date: Fri, 27 Mar 2026 14:32:35 -0700 Subject: [PATCH 1/2] reflex.event: revert future annotation changes Go back to string-based annotations, to unbreak reflex-web --- reflex/event.py | 72 ++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/reflex/event.py b/reflex/event.py index a9f1d06cffa..887976df909 100644 --- a/reflex/event.py +++ b/reflex/event.py @@ -1,7 +1,5 @@ """Define event classes to connect the frontend and backend.""" -from __future__ import annotations - import dataclasses import inspect import sys @@ -101,7 +99,7 @@ def substate_token(self) -> str: UPLOAD_FILES_CLIENT_HANDLER = "uploadFiles" -def _handler_name(handler: EventHandler) -> str: +def _handler_name(handler: "EventHandler") -> str: """Get a stable fully qualified handler name for errors. Args: @@ -115,7 +113,7 @@ def _handler_name(handler: EventHandler) -> str: return handler.fn.__qualname__ -def resolve_upload_handler_param(handler: EventHandler) -> tuple[str, Any]: +def resolve_upload_handler_param(handler: "EventHandler") -> tuple[str, Any]: """Validate and resolve the UploadFile list parameter for a handler. Args: @@ -154,7 +152,7 @@ def resolve_upload_handler_param(handler: EventHandler) -> tuple[str, Any]: raise UploadValueError(msg) -def resolve_upload_chunk_handler_param(handler: EventHandler) -> tuple[str, type]: +def resolve_upload_chunk_handler_param(handler: "EventHandler") -> tuple[str, type]: """Validate and resolve the UploadChunkIterator parameter for a handler. Args: @@ -336,7 +334,7 @@ def is_background(self) -> bool: """ return getattr(self.fn, BACKGROUND_TASK_MARKER, False) - def __call__(self, *args: Any, **kwargs: Any) -> EventSpec: + def __call__(self, *args: Any, **kwargs: Any) -> "EventSpec": """Pass arguments to the handler to get an event spec. This method configures event handlers that take in arguments. @@ -446,7 +444,7 @@ def __init__( object.__setattr__(self, "client_handler_name", client_handler_name) object.__setattr__(self, "args", args or ()) - def with_args(self, args: tuple[tuple[Var, Var], ...]) -> EventSpec: + def with_args(self, args: tuple[tuple[Var, Var], ...]) -> "EventSpec": """Copy the event spec, with updated args. Args: @@ -462,7 +460,7 @@ def with_args(self, args: tuple[tuple[Var, Var], ...]) -> EventSpec: event_actions=self.event_actions.copy(), ) - def add_args(self, *args: Var) -> EventSpec: + def add_args(self, *args: Var) -> "EventSpec": """Add arguments to the event spec. Args: @@ -553,7 +551,7 @@ def __call__(self, *args, **kwargs) -> EventSpec: class EventChain(EventActionsMixin): """Container for a chain of events that will be executed in order.""" - events: Sequence[EventSpec | EventVar | FunctionVar | EventCallback] = ( + events: "Sequence[EventSpec | EventVar | FunctionVar | EventCallback]" = ( dataclasses.field(default_factory=list) ) @@ -564,11 +562,11 @@ class EventChain(EventActionsMixin): @classmethod def create( cls, - value: EventType, + value: "EventType", args_spec: ArgsSpec | Sequence[ArgsSpec], key: str | None = None, **event_chain_kwargs, - ) -> EventChain | Var: + ) -> "EventChain | Var": """Create an event chain from a variety of input types. Args: @@ -1483,7 +1481,7 @@ def download( def call_script( javascript_code: str | Var[str], - callback: EventType[Any] | None = None, + callback: "EventType[Any] | None" = None, ) -> EventSpec: """Create an event handler that executes arbitrary javascript code. @@ -1524,7 +1522,7 @@ def call_script( def call_function( javascript_code: str | Var, - callback: EventType[Any] | None = None, + callback: "EventType[Any] | None" = None, ) -> EventSpec: """Create an event handler that executes arbitrary javascript code. @@ -1560,7 +1558,7 @@ def call_function( def run_script( javascript_code: str | Var, - callback: EventType[Any] | None = None, + callback: "EventType[Any] | None" = None, ) -> EventSpec: """Create an event handler that executes arbitrary javascript code. @@ -1578,7 +1576,7 @@ def run_script( return call_function(ArgsFunctionOperation.create((), javascript_code), callback) -def get_event(state: BaseState, event: str): +def get_event(state: "BaseState", event: str): """Get the event from the given state. Args: @@ -1591,7 +1589,7 @@ def get_event(state: BaseState, event: str): return f"{state.get_name()}.{event}" -def get_hydrate_event(state: BaseState) -> str: +def get_hydrate_event(state: "BaseState") -> str: """Get the name of the hydrate event for the state. Args: @@ -1944,7 +1942,7 @@ def call_event_fn( fn: Callable, arg_spec: ArgsSpec | Sequence[ArgsSpec], key: str | None = None, -) -> list[EventSpec | FunctionVar | EventVar]: +) -> "list[EventSpec | FunctionVar | EventVar]": """Call a function to a list of event specs. The function should return a single event-like value or a heterogeneous @@ -2151,7 +2149,7 @@ def create( cls, value: EventSpec | EventHandler, _var_data: VarData | None = None, - ) -> LiteralEventVar: + ) -> "LiteralEventVar": """Create a new LiteralEventVar instance. Args: @@ -2238,7 +2236,7 @@ def create( cls, value: EventChain, _var_data: VarData | None = None, - ) -> LiteralEventChainVar: + ) -> "LiteralEventChainVar": """Create a new LiteralEventChainVar instance. Args: @@ -2361,39 +2359,39 @@ def __init__(self, func: Callable[[Any, Unpack[P]], Any]): @overload def __call__( - self: EventCallback[Unpack[Q]], - ) -> EventCallback[Unpack[Q]]: ... + self: "EventCallback[Unpack[Q]]", + ) -> "EventCallback[Unpack[Q]]": ... @overload def __call__( - self: EventCallback[V, Unpack[Q]], value: V | Var[V] - ) -> EventCallback[Unpack[Q]]: ... + self: "EventCallback[V, Unpack[Q]]", value: V | Var[V] + ) -> "EventCallback[Unpack[Q]]": ... @overload def __call__( - self: EventCallback[V, V2, Unpack[Q]], + self: "EventCallback[V, V2, Unpack[Q]]", value: V | Var[V], value2: V2 | Var[V2], - ) -> EventCallback[Unpack[Q]]: ... + ) -> "EventCallback[Unpack[Q]]": ... @overload def __call__( - self: EventCallback[V, V2, V3, Unpack[Q]], + self: "EventCallback[V, V2, V3, Unpack[Q]]", value: V | Var[V], value2: V2 | Var[V2], value3: V3 | Var[V3], - ) -> EventCallback[Unpack[Q]]: ... + ) -> "EventCallback[Unpack[Q]]": ... @overload def __call__( - self: EventCallback[V, V2, V3, V4, Unpack[Q]], + self: "EventCallback[V, V2, V3, V4, Unpack[Q]]", value: V | Var[V], value2: V2 | Var[V2], value3: V3 | Var[V3], value4: V4 | Var[V4], - ) -> EventCallback[Unpack[Q]]: ... + ) -> "EventCallback[Unpack[Q]]": ... - def __call__(self, *values) -> EventCallback: # pyright: ignore [reportInconsistentOverload] + def __call__(self, *values) -> "EventCallback": # pyright: ignore [reportInconsistentOverload] """Call the function with the values. Args: @@ -2406,11 +2404,11 @@ def __call__(self, *values) -> EventCallback: # pyright: ignore [reportInconsis @overload def __get__( - self: EventCallback[Unpack[P]], instance: None, owner: Any - ) -> EventCallback[Unpack[P]]: ... + self: "EventCallback[Unpack[P]]", instance: None, owner: Any + ) -> "EventCallback[Unpack[P]]": ... @overload - def __get__(self, instance: Any, owner: Any) -> Callable[[Unpack[P]]]: ... + def __get__(self, instance: Any, owner: Any) -> "Callable[[Unpack[P]]]": ... def __get__(self, instance: Any, owner: Any) -> Callable: """Get the function with the instance bound to it. @@ -2434,19 +2432,19 @@ class LambdaEventCallback(Protocol[Unpack[P]]): __code__: types.CodeType @overload - def __call__(self: LambdaEventCallback[()]) -> Any: ... + def __call__(self: "LambdaEventCallback[()]") -> Any: ... @overload - def __call__(self: LambdaEventCallback[V], value: Var[V], /) -> Any: ... + def __call__(self: "LambdaEventCallback[V]", value: "Var[V]", /) -> Any: ... @overload def __call__( - self: LambdaEventCallback[V, V2], value: Var[V], value2: Var[V2], / + self: "LambdaEventCallback[V, V2]", value: Var[V], value2: Var[V2], / ) -> Any: ... @overload def __call__( - self: LambdaEventCallback[V, V2, V3], + self: "LambdaEventCallback[V, V2, V3]", value: Var[V], value2: Var[V2], value3: Var[V3], From 12333b626def8bf0ef7199478c60873e1f1e1bd4 Mon Sep 17 00:00:00 2001 From: Masen Furer Date: Fri, 27 Mar 2026 14:44:06 -0700 Subject: [PATCH 2/2] exclude reflex-docgen from reflex-web integration test this allows the test to run with the actual proposed reflex version instead of replacing it back to main --- .github/workflows/integration_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 464de2e4cb4..7c3340d911e 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -128,7 +128,7 @@ jobs: working-directory: ./reflex-web run: | uv pip compile pyproject.toml --no-annotate --no-header --no-deps --output-file requirements.txt - grep -ivE "reflex " requirements.txt > requirements.txt.tmp && mv requirements.txt.tmp requirements.txt + grep -ivE "reflex(-docgen)? " requirements.txt > requirements.txt.tmp && mv requirements.txt.tmp requirements.txt - name: Install Requirements for reflex-web working-directory: ./reflex-web run: uv pip install -r requirements.txt