Skip to content

Commit e0984aa

Browse files
Allow bound method as event handler (reflex-dev#4348)
* subtract 1 arg if the method is a bound method * fix it early in user_args * only bound methods pls * add test
1 parent ecb5265 commit e0984aa

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

reflex/event.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,10 @@ def check_fn_match_arg_spec(
13461346
EventFnArgMismatch: Raised if the number of mandatory arguments do not match
13471347
"""
13481348
user_args = inspect.getfullargspec(user_func).args
1349+
# Drop the first argument if it's a bound method
1350+
if inspect.ismethod(user_func) and user_func.__self__ is not None:
1351+
user_args = user_args[1:]
1352+
13491353
user_default_args = inspect.getfullargspec(user_func).defaults
13501354
number_of_user_args = len(user_args) - number_of_bound_args
13511355
number_of_user_default_args = len(user_default_args) if user_default_args else 0

tests/units/test_event.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import pytest
44

5+
import reflex as rx
56
from reflex.event import (
67
Event,
78
EventChain,
@@ -439,3 +440,17 @@ def _args_spec(value: Var[int]) -> tuple[Var[int]]:
439440
# Ensure chain carries _var_data
440441
chain_var = Var.create(EventChain(events=[S.s(S.x)], args_spec=_args_spec))
441442
assert chain_var._get_all_var_data() == S.x._get_all_var_data()
443+
444+
445+
def test_event_bound_method() -> None:
446+
class S(BaseState):
447+
@event
448+
def e(self, arg: str):
449+
print(arg)
450+
451+
class Wrapper:
452+
def get_handler(self, arg: str):
453+
return S.e(arg)
454+
455+
w = Wrapper()
456+
_ = rx.input(on_change=w.get_handler)

0 commit comments

Comments
 (0)