Skip to content

Commit

Permalink
Allow bound method as event handler (#4348)
Browse files Browse the repository at this point in the history
* subtract 1 arg if the method is a bound method

* fix it early in user_args

* only bound methods pls

* add test
  • Loading branch information
benedikt-bartscher authored Nov 21, 2024
1 parent ecb5265 commit e0984aa
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
4 changes: 4 additions & 0 deletions reflex/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,10 @@ def check_fn_match_arg_spec(
EventFnArgMismatch: Raised if the number of mandatory arguments do not match
"""
user_args = inspect.getfullargspec(user_func).args
# Drop the first argument if it's a bound method
if inspect.ismethod(user_func) and user_func.__self__ is not None:
user_args = user_args[1:]

user_default_args = inspect.getfullargspec(user_func).defaults
number_of_user_args = len(user_args) - number_of_bound_args
number_of_user_default_args = len(user_default_args) if user_default_args else 0
Expand Down
15 changes: 15 additions & 0 deletions tests/units/test_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest

import reflex as rx
from reflex.event import (
Event,
EventChain,
Expand Down Expand Up @@ -439,3 +440,17 @@ def _args_spec(value: Var[int]) -> tuple[Var[int]]:
# Ensure chain carries _var_data
chain_var = Var.create(EventChain(events=[S.s(S.x)], args_spec=_args_spec))
assert chain_var._get_all_var_data() == S.x._get_all_var_data()


def test_event_bound_method() -> None:
class S(BaseState):
@event
def e(self, arg: str):
print(arg)

class Wrapper:
def get_handler(self, arg: str):
return S.e(arg)

w = Wrapper()
_ = rx.input(on_change=w.get_handler)

0 comments on commit e0984aa

Please sign in to comment.