4040from 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