Skip to content

Commit ce66189

Browse files
authored
Allow calling event handlers with keyword arguments (#5124)
* Allow calling event handlers with keyword arguments * why is upload so weird
1 parent 44232fb commit ce66189

File tree

3 files changed

+33
-12
lines changed

3 files changed

+33
-12
lines changed

pyi_hashes.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"reflex/components/core/debounce.pyi": "76d857eb814bc64625860a5f43e8b230",
2121
"reflex/components/core/html.pyi": "b12117b42ef79ee90b6b4dec50baeb86",
2222
"reflex/components/core/sticky.pyi": "c65131cf7c2312c68e1fddaa0cc27150",
23-
"reflex/components/core/upload.pyi": "6fb89607ec8f8c1971f0dbd3453901eb",
23+
"reflex/components/core/upload.pyi": "16bf18a95d830184a1ae6c177e91e529",
2424
"reflex/components/datadisplay/__init__.pyi": "cf087efa8b3960decc6b231cc986cfa9",
2525
"reflex/components/datadisplay/code.pyi": "3d8f0ab4c2f123d7f80d15c7ebc553d9",
2626
"reflex/components/datadisplay/dataeditor.pyi": "1b762071001161e4fdd1285263c33bb3",

reflex/components/core/upload.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
EventHandler,
2424
EventSpec,
2525
call_event_fn,
26+
call_event_handler,
2627
parse_args_spec,
2728
run_script,
2829
)
@@ -265,17 +266,12 @@ def create(cls, *children, **props) -> Component:
265266
upload_props["on_drop"] = upload_file(upload_props["id"])
266267
else:
267268
on_drop = upload_props["on_drop"]
268-
if isinstance(on_drop, Callable):
269+
if isinstance(on_drop, (EventHandler, EventSpec)):
270+
# Call the lambda to get the event chain.
271+
on_drop = call_event_handler(on_drop, _on_drop_spec)
272+
elif isinstance(on_drop, Callable):
269273
# Call the lambda to get the event chain.
270274
on_drop = call_event_fn(on_drop, _on_drop_spec)
271-
if isinstance(on_drop, EventSpec):
272-
# Update the provided args for direct use with on_drop.
273-
on_drop = on_drop.with_args(
274-
args=tuple(
275-
cls._update_arg_tuple_for_on_drop(arg_value)
276-
for arg_value in on_drop.args
277-
),
278-
)
279275
upload_props["on_drop"] = on_drop
280276

281277
input_props_unique_name = get_unique_variable_name()

reflex/event.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from reflex.utils.types import (
4141
ArgsSpec,
4242
GenericType,
43+
Unset,
4344
safe_issubclass,
4445
typehint_issubclass,
4546
)
@@ -202,13 +203,14 @@ def is_background(self) -> bool:
202203
"""
203204
return getattr(self.fn, BACKGROUND_TASK_MARKER, False)
204205

205-
def __call__(self, *args: Any) -> EventSpec:
206+
def __call__(self, *args: Any, **kwargs: Any) -> EventSpec:
206207
"""Pass arguments to the handler to get an event spec.
207208
208209
This method configures event handlers that take in arguments.
209210
210211
Args:
211212
*args: The arguments to pass to the handler.
213+
**kwargs: The keyword arguments to pass to the handler.
212214
213215
Returns:
214216
The event spec, containing both the function and args.
@@ -220,11 +222,34 @@ def __call__(self, *args: Any) -> EventSpec:
220222

221223
# Get the function args.
222224
fn_args = list(inspect.signature(self.fn).parameters)[1:]
225+
226+
if not isinstance(
227+
repeated_arg := next(
228+
(kwarg for kwarg in kwargs if kwarg in fn_args[: len(args)]), Unset()
229+
),
230+
Unset,
231+
):
232+
raise EventHandlerTypeError(
233+
f"Event handler {self.fn.__name__} received repeated argument {repeated_arg}."
234+
)
235+
236+
if not isinstance(
237+
extra_arg := next(
238+
(kwarg for kwarg in kwargs if kwarg not in fn_args), Unset()
239+
),
240+
Unset,
241+
):
242+
raise EventHandlerTypeError(
243+
f"Event handler {self.fn.__name__} received extra argument {extra_arg}."
244+
)
245+
246+
fn_args = fn_args[: len(args)] + list(kwargs)
247+
223248
fn_args = (Var(_js_expr=arg) for arg in fn_args)
224249

225250
# Construct the payload.
226251
values = []
227-
for arg in args:
252+
for arg in [*args, *kwargs.values()]:
228253
# Special case for file uploads.
229254
if isinstance(arg, FileUpload):
230255
return arg.as_event_spec(handler=self)

0 commit comments

Comments
 (0)