|
@@ -4,7 +4,6 @@ from __future__ import annotations
|
|
|
|
|
|
import dataclasses
|
|
import dataclasses
|
|
import inspect
|
|
import inspect
|
|
-import sys
|
|
|
|
import types
|
|
import types
|
|
import urllib.parse
|
|
import urllib.parse
|
|
from base64 import b64encode
|
|
from base64 import b64encode
|
|
@@ -39,6 +38,7 @@ from typing_extensions import (
|
|
)
|
|
)
|
|
|
|
|
|
from reflex import constants
|
|
from reflex import constants
|
|
|
|
+from reflex.constants.compiler import CompileVars, Hooks, Imports
|
|
from reflex.constants.state import FRONTEND_EVENT_STATE
|
|
from reflex.constants.state import FRONTEND_EVENT_STATE
|
|
from reflex.utils import console, format
|
|
from reflex.utils import console, format
|
|
from reflex.utils.exceptions import (
|
|
from reflex.utils.exceptions import (
|
|
@@ -245,7 +245,7 @@ class EventHandler(EventActionsMixin):
|
|
raise EventHandlerTypeError(
|
|
raise EventHandlerTypeError(
|
|
f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
|
f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
|
) from e
|
|
) from e
|
|
- payload = tuple(zip(fn_args, values))
|
|
|
|
|
|
+ payload = tuple(zip(fn_args, values, strict=False))
|
|
|
|
|
|
# Return the event spec.
|
|
# Return the event spec.
|
|
return EventSpec(
|
|
return EventSpec(
|
|
@@ -265,7 +265,7 @@ class EventSpec(EventActionsMixin):
|
|
"""
|
|
"""
|
|
|
|
|
|
# The event handler.
|
|
# The event handler.
|
|
- handler: EventHandler = dataclasses.field(default=None) # type: ignore
|
|
|
|
|
|
+ handler: EventHandler = dataclasses.field(default=None) # pyright: ignore [reportAssignmentType]
|
|
|
|
|
|
# The handler on the client to process event.
|
|
# The handler on the client to process event.
|
|
client_handler_name: str = dataclasses.field(default="")
|
|
client_handler_name: str = dataclasses.field(default="")
|
|
@@ -339,7 +339,7 @@ class EventSpec(EventActionsMixin):
|
|
raise EventHandlerTypeError(
|
|
raise EventHandlerTypeError(
|
|
f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
|
f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
|
) from e
|
|
) from e
|
|
- new_payload = tuple(zip(fn_args, values))
|
|
|
|
|
|
+ new_payload = tuple(zip(fn_args, values, strict=False))
|
|
return self.with_args(self.args + new_payload)
|
|
return self.with_args(self.args + new_payload)
|
|
|
|
|
|
|
|
|
|
@@ -542,7 +542,7 @@ class JavasciptKeyboardEvent:
|
|
shiftKey: bool = False # noqa: N815
|
|
shiftKey: bool = False # noqa: N815
|
|
|
|
|
|
|
|
|
|
-def input_event(e: Var[JavascriptInputEvent]) -> Tuple[Var[str]]:
|
|
|
|
|
|
+def input_event(e: ObjectVar[JavascriptInputEvent]) -> Tuple[Var[str]]:
|
|
"""Get the value from an input event.
|
|
"""Get the value from an input event.
|
|
|
|
|
|
Args:
|
|
Args:
|
|
@@ -563,7 +563,9 @@ class KeyInputInfo(TypedDict):
|
|
shift_key: bool
|
|
shift_key: bool
|
|
|
|
|
|
|
|
|
|
-def key_event(e: Var[JavasciptKeyboardEvent]) -> Tuple[Var[str], Var[KeyInputInfo]]:
|
|
|
|
|
|
+def key_event(
|
|
|
|
+ e: ObjectVar[JavasciptKeyboardEvent],
|
|
|
|
+) -> Tuple[Var[str], Var[KeyInputInfo]]:
|
|
"""Get the key from a keyboard event.
|
|
"""Get the key from a keyboard event.
|
|
|
|
|
|
Args:
|
|
Args:
|
|
@@ -573,7 +575,7 @@ def key_event(e: Var[JavasciptKeyboardEvent]) -> Tuple[Var[str], Var[KeyInputInf
|
|
The key from the keyboard event.
|
|
The key from the keyboard event.
|
|
"""
|
|
"""
|
|
return (
|
|
return (
|
|
- e.key,
|
|
|
|
|
|
+ e.key.to(str),
|
|
Var.create(
|
|
Var.create(
|
|
{
|
|
{
|
|
"alt_key": e.altKey,
|
|
"alt_key": e.altKey,
|
|
@@ -581,7 +583,7 @@ def key_event(e: Var[JavasciptKeyboardEvent]) -> Tuple[Var[str], Var[KeyInputInf
|
|
"meta_key": e.metaKey,
|
|
"meta_key": e.metaKey,
|
|
"shift_key": e.shiftKey,
|
|
"shift_key": e.shiftKey,
|
|
},
|
|
},
|
|
- ),
|
|
|
|
|
|
+ ).to(KeyInputInfo),
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
@@ -591,7 +593,7 @@ def no_args_event_spec() -> Tuple[()]:
|
|
Returns:
|
|
Returns:
|
|
An empty tuple.
|
|
An empty tuple.
|
|
"""
|
|
"""
|
|
- return () # type: ignore
|
|
|
|
|
|
+ return ()
|
|
|
|
|
|
|
|
|
|
# These chains can be used for their side effects when no other events are desired.
|
|
# These chains can be used for their side effects when no other events are desired.
|
|
@@ -654,9 +656,9 @@ def passthrough_event_spec( # pyright: ignore[reportInconsistentOverload]
|
|
return values
|
|
return values
|
|
|
|
|
|
inner_type = tuple(Var[event_type] for event_type in event_types)
|
|
inner_type = tuple(Var[event_type] for event_type in event_types)
|
|
- return_annotation = Tuple[inner_type] # type: ignore
|
|
|
|
|
|
+ return_annotation = Tuple[inner_type]
|
|
|
|
|
|
- inner.__signature__ = inspect.signature(inner).replace( # type: ignore
|
|
|
|
|
|
+ inner.__signature__ = inspect.signature(inner).replace( # pyright: ignore [reportFunctionMemberAccess]
|
|
parameters=[
|
|
parameters=[
|
|
inspect.Parameter(
|
|
inspect.Parameter(
|
|
f"ev_{i}",
|
|
f"ev_{i}",
|
|
@@ -738,7 +740,7 @@ class FileUpload:
|
|
# Call the lambda to get the event chain.
|
|
# Call the lambda to get the event chain.
|
|
events = call_event_fn(
|
|
events = call_event_fn(
|
|
on_upload_progress, self.on_upload_progress_args_spec
|
|
on_upload_progress, self.on_upload_progress_args_spec
|
|
- ) # type: ignore
|
|
|
|
|
|
+ )
|
|
else:
|
|
else:
|
|
raise ValueError(f"{on_upload_progress} is not a valid event handler.")
|
|
raise ValueError(f"{on_upload_progress} is not a valid event handler.")
|
|
if isinstance(events, Var):
|
|
if isinstance(events, Var):
|
|
@@ -1058,13 +1060,13 @@ def download(
|
|
|
|
|
|
is_data_url = (data.js_type() == "string") & (
|
|
is_data_url = (data.js_type() == "string") & (
|
|
data.to(str).startswith("data:")
|
|
data.to(str).startswith("data:")
|
|
- ) # type: ignore
|
|
|
|
|
|
+ )
|
|
|
|
|
|
# If it's a data: URI, use it as is, otherwise convert the Var to JSON in a data: URI.
|
|
# If it's a data: URI, use it as is, otherwise convert the Var to JSON in a data: URI.
|
|
- url = cond( # type: ignore
|
|
|
|
|
|
+ url = cond(
|
|
is_data_url,
|
|
is_data_url,
|
|
data.to(str),
|
|
data.to(str),
|
|
- "data:text/plain," + data.to_string(), # type: ignore
|
|
|
|
|
|
+ "data:text/plain," + data.to_string(),
|
|
)
|
|
)
|
|
elif isinstance(data, bytes):
|
|
elif isinstance(data, bytes):
|
|
# Caller provided bytes, so base64 encode it as a data: URI.
|
|
# Caller provided bytes, so base64 encode it as a data: URI.
|
|
@@ -1083,7 +1085,8 @@ def download(
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
-def _callback_arg_spec(eval_result):
|
|
|
|
|
|
+# This function seems unused. Check if we still need it. If not, remove in 0.7.0
|
|
|
|
+def _callback_arg_spec(eval_result: Any):
|
|
"""ArgSpec for call_script callback function.
|
|
"""ArgSpec for call_script callback function.
|
|
|
|
|
|
Args:
|
|
Args:
|
|
@@ -1188,7 +1191,7 @@ def run_script(
|
|
return call_function(ArgsFunctionOperation.create((), javascript_code), callback)
|
|
return call_function(ArgsFunctionOperation.create((), javascript_code), callback)
|
|
|
|
|
|
|
|
|
|
-def get_event(state, event):
|
|
|
|
|
|
+def get_event(state: BaseState, event: str):
|
|
"""Get the event from the given state.
|
|
"""Get the event from the given state.
|
|
|
|
|
|
Args:
|
|
Args:
|
|
@@ -1201,7 +1204,7 @@ def get_event(state, event):
|
|
return f"{state.get_name()}.{event}"
|
|
return f"{state.get_name()}.{event}"
|
|
|
|
|
|
|
|
|
|
-def get_hydrate_event(state) -> str:
|
|
|
|
|
|
+def get_hydrate_event(state: BaseState) -> str:
|
|
"""Get the name of the hydrate event for the state.
|
|
"""Get the name of the hydrate event for the state.
|
|
|
|
|
|
Args:
|
|
Args:
|
|
@@ -1238,7 +1241,7 @@ def call_event_handler(
|
|
|
|
|
|
#noqa: DAR401
|
|
#noqa: DAR401
|
|
"""
|
|
"""
|
|
- event_spec_args = parse_args_spec(event_spec) # type: ignore
|
|
|
|
|
|
+ event_spec_args = parse_args_spec(event_spec)
|
|
|
|
|
|
if isinstance(event_callback, EventSpec):
|
|
if isinstance(event_callback, EventSpec):
|
|
check_fn_match_arg_spec(
|
|
check_fn_match_arg_spec(
|
|
@@ -1348,7 +1351,7 @@ def call_event_handler(
|
|
if delayed_exceptions:
|
|
if delayed_exceptions:
|
|
raise delayed_exceptions[0]
|
|
raise delayed_exceptions[0]
|
|
|
|
|
|
- return event_callback(*event_spec_args) # type: ignore
|
|
|
|
|
|
+ return event_callback(*event_spec_args)
|
|
|
|
|
|
|
|
|
|
def unwrap_var_annotation(annotation: GenericType):
|
|
def unwrap_var_annotation(annotation: GenericType):
|
|
@@ -1360,7 +1363,7 @@ def unwrap_var_annotation(annotation: GenericType):
|
|
Returns:
|
|
Returns:
|
|
The unwrapped annotation.
|
|
The unwrapped annotation.
|
|
"""
|
|
"""
|
|
- if get_origin(annotation) is Var and (args := get_args(annotation)):
|
|
|
|
|
|
+ if get_origin(annotation) in (Var, ObjectVar) and (args := get_args(annotation)):
|
|
return args[0]
|
|
return args[0]
|
|
return annotation
|
|
return annotation
|
|
|
|
|
|
@@ -1582,7 +1585,7 @@ def fix_events(
|
|
if not isinstance(e, EventSpec):
|
|
if not isinstance(e, EventSpec):
|
|
raise ValueError(f"Unexpected event type, {type(e)}.")
|
|
raise ValueError(f"Unexpected event type, {type(e)}.")
|
|
name = format.format_event_handler(e.handler)
|
|
name = format.format_event_handler(e.handler)
|
|
- payload = {k._js_expr: v._decode() for k, v in e.args} # type: ignore
|
|
|
|
|
|
+ payload = {k._js_expr: v._decode() for k, v in e.args}
|
|
|
|
|
|
# Filter router_data to reduce payload size
|
|
# Filter router_data to reduce payload size
|
|
event_router_data = {
|
|
event_router_data = {
|
|
@@ -1626,12 +1629,12 @@ class EventVar(ObjectVar, python_types=EventSpec):
|
|
@dataclasses.dataclass(
|
|
@dataclasses.dataclass(
|
|
eq=False,
|
|
eq=False,
|
|
frozen=True,
|
|
frozen=True,
|
|
- **{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
|
|
|
|
+ slots=True,
|
|
)
|
|
)
|
|
class LiteralEventVar(VarOperationCall, LiteralVar, EventVar):
|
|
class LiteralEventVar(VarOperationCall, LiteralVar, EventVar):
|
|
"""A literal event var."""
|
|
"""A literal event var."""
|
|
|
|
|
|
- _var_value: EventSpec = dataclasses.field(default=None) # type: ignore
|
|
|
|
|
|
+ _var_value: EventSpec = dataclasses.field(default=None) # pyright: ignore [reportAssignmentType]
|
|
|
|
|
|
def __hash__(self) -> int:
|
|
def __hash__(self) -> int:
|
|
"""Get the hash of the var.
|
|
"""Get the hash of the var.
|
|
@@ -1687,7 +1690,7 @@ class EventChainVar(BuilderFunctionVar, python_types=EventChain):
|
|
@dataclasses.dataclass(
|
|
@dataclasses.dataclass(
|
|
eq=False,
|
|
eq=False,
|
|
frozen=True,
|
|
frozen=True,
|
|
- **{"slots": True} if sys.version_info >= (3, 10) else {},
|
|
|
|
|
|
+ slots=True,
|
|
)
|
|
)
|
|
# Note: LiteralVar is second in the inheritance list allowing it act like a
|
|
# Note: LiteralVar is second in the inheritance list allowing it act like a
|
|
# CachedVarOperation (ArgsFunctionOperation) and get the _js_expr from the
|
|
# CachedVarOperation (ArgsFunctionOperation) and get the _js_expr from the
|
|
@@ -1695,7 +1698,7 @@ class EventChainVar(BuilderFunctionVar, python_types=EventChain):
|
|
class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainVar):
|
|
class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainVar):
|
|
"""A literal event chain var."""
|
|
"""A literal event chain var."""
|
|
|
|
|
|
- _var_value: EventChain = dataclasses.field(default=None) # type: ignore
|
|
|
|
|
|
+ _var_value: EventChain = dataclasses.field(default=None) # pyright: ignore [reportAssignmentType]
|
|
|
|
|
|
def __hash__(self) -> int:
|
|
def __hash__(self) -> int:
|
|
"""Get the hash of the var.
|
|
"""Get the hash of the var.
|
|
@@ -1719,13 +1722,16 @@ class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainV
|
|
|
|
|
|
Returns:
|
|
Returns:
|
|
The created LiteralEventChainVar instance.
|
|
The created LiteralEventChainVar instance.
|
|
|
|
+
|
|
|
|
+ Raises:
|
|
|
|
+ ValueError: If the invocation is not a FunctionVar.
|
|
"""
|
|
"""
|
|
arg_spec = (
|
|
arg_spec = (
|
|
value.args_spec[0]
|
|
value.args_spec[0]
|
|
if isinstance(value.args_spec, Sequence)
|
|
if isinstance(value.args_spec, Sequence)
|
|
else value.args_spec
|
|
else value.args_spec
|
|
)
|
|
)
|
|
- sig = inspect.signature(arg_spec) # type: ignore
|
|
|
|
|
|
+ sig = inspect.signature(arg_spec) # pyright: ignore [reportArgumentType]
|
|
if sig.parameters:
|
|
if sig.parameters:
|
|
arg_def = tuple((f"_{p}" for p in sig.parameters))
|
|
arg_def = tuple((f"_{p}" for p in sig.parameters))
|
|
arg_def_expr = LiteralVar.create([Var(_js_expr=arg) for arg in arg_def])
|
|
arg_def_expr = LiteralVar.create([Var(_js_expr=arg) for arg in arg_def])
|
|
@@ -1736,10 +1742,21 @@ class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainV
|
|
arg_def_expr = Var(_js_expr="args")
|
|
arg_def_expr = Var(_js_expr="args")
|
|
|
|
|
|
if value.invocation is None:
|
|
if value.invocation is None:
|
|
- invocation = FunctionStringVar.create("addEvents")
|
|
|
|
|
|
+ invocation = FunctionStringVar.create(
|
|
|
|
+ CompileVars.ADD_EVENTS,
|
|
|
|
+ _var_data=VarData(
|
|
|
|
+ imports=Imports.EVENTS,
|
|
|
|
+ hooks={Hooks.EVENTS: None},
|
|
|
|
+ ),
|
|
|
|
+ )
|
|
else:
|
|
else:
|
|
invocation = value.invocation
|
|
invocation = value.invocation
|
|
|
|
|
|
|
|
+ if invocation is not None and not isinstance(invocation, FunctionVar):
|
|
|
|
+ raise ValueError(
|
|
|
|
+ f"EventChain invocation must be a FunctionVar, got {invocation!s} of type {invocation._var_type!s}."
|
|
|
|
+ )
|
|
|
|
+
|
|
return cls(
|
|
return cls(
|
|
_js_expr="",
|
|
_js_expr="",
|
|
_var_type=EventChain,
|
|
_var_type=EventChain,
|
|
@@ -1858,7 +1875,7 @@ class EventCallback(Generic[P, T]):
|
|
value4: V4 | Var[V4],
|
|
value4: V4 | Var[V4],
|
|
) -> EventCallback[Q, T]: ...
|
|
) -> EventCallback[Q, T]: ...
|
|
|
|
|
|
- def __call__(self, *values) -> EventCallback: # type: ignore
|
|
|
|
|
|
+ def __call__(self, *values) -> EventCallback: # pyright: ignore [reportInconsistentOverload]
|
|
"""Call the function with the values.
|
|
"""Call the function with the values.
|
|
|
|
|
|
Args:
|
|
Args:
|
|
@@ -1867,17 +1884,17 @@ class EventCallback(Generic[P, T]):
|
|
Returns:
|
|
Returns:
|
|
The function with the values.
|
|
The function with the values.
|
|
"""
|
|
"""
|
|
- return self.func(*values) # type: ignore
|
|
|
|
|
|
+ return self.func(*values) # pyright: ignore [reportCallIssue, reportReturnType]
|
|
|
|
|
|
@overload
|
|
@overload
|
|
def __get__(
|
|
def __get__(
|
|
- self: EventCallback[P, T], instance: None, owner
|
|
|
|
|
|
+ self: EventCallback[P, T], instance: None, owner: Any
|
|
) -> EventCallback[P, T]: ...
|
|
) -> EventCallback[P, T]: ...
|
|
|
|
|
|
@overload
|
|
@overload
|
|
- def __get__(self, instance, owner) -> Callable[P, T]: ...
|
|
|
|
|
|
+ def __get__(self, instance: Any, owner: Any) -> Callable[P, T]: ...
|
|
|
|
|
|
- def __get__(self, instance, owner) -> Callable: # type: ignore
|
|
|
|
|
|
+ def __get__(self, instance: Any, owner: Any) -> Callable:
|
|
"""Get the function with the instance bound to it.
|
|
"""Get the function with the instance bound to it.
|
|
|
|
|
|
Args:
|
|
Args:
|
|
@@ -1888,9 +1905,9 @@ class EventCallback(Generic[P, T]):
|
|
The function with the instance bound to it
|
|
The function with the instance bound to it
|
|
"""
|
|
"""
|
|
if instance is None:
|
|
if instance is None:
|
|
- return self.func # type: ignore
|
|
|
|
|
|
+ return self.func
|
|
|
|
|
|
- return partial(self.func, instance) # type: ignore
|
|
|
|
|
|
+ return partial(self.func, instance)
|
|
|
|
|
|
|
|
|
|
G = ParamSpec("G")
|
|
G = ParamSpec("G")
|
|
@@ -1941,7 +1958,7 @@ class EventNamespace(types.SimpleNamespace):
|
|
@staticmethod
|
|
@staticmethod
|
|
def __call__(
|
|
def __call__(
|
|
func: None = None, *, background: bool | None = None
|
|
func: None = None, *, background: bool | None = None
|
|
- ) -> Callable[[Callable[Concatenate[BASE_STATE, P], T]], EventCallback[P, T]]: ...
|
|
|
|
|
|
+ ) -> Callable[[Callable[Concatenate[BASE_STATE, P], T]], EventCallback[P, T]]: ... # pyright: ignore [reportInvalidTypeVarUse]
|
|
|
|
|
|
@overload
|
|
@overload
|
|
@staticmethod
|
|
@staticmethod
|
|
@@ -1984,7 +2001,7 @@ class EventNamespace(types.SimpleNamespace):
|
|
"Background task must be async function or generator."
|
|
"Background task must be async function or generator."
|
|
)
|
|
)
|
|
setattr(func, BACKGROUND_TASK_MARKER, True)
|
|
setattr(func, BACKGROUND_TASK_MARKER, True)
|
|
- return func # type: ignore
|
|
|
|
|
|
+ return func # pyright: ignore [reportReturnType]
|
|
|
|
|
|
if func is not None:
|
|
if func is not None:
|
|
return wrapper(func)
|
|
return wrapper(func)
|