diff --git a/CHANGELOG.md b/CHANGELOG.md index 24dd74663..e5bc7e1c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Don't forget to remove deprecated code on each major release! - Added support for inline JavaScript as event handlers or other attributes that expect a callable via `reactpy.types.InlineJavaScript` - Event functions can now call `event.preventDefault()` and `event.stopPropagation()` methods directly on the event data object, rather than using the `@event` decorator. - Event data now supports accessing properties via dot notation (ex. `event.target.value`). +- Added support for partial functions in EventHandler - Added `reactpy.types.Event` to provide type hints for the standard `data` function argument (for example `def on_click(event: Event): ...`). - Added `asgi` and `jinja` installation extras (for example `pip install reactpy[asgi, jinja]`). - Added `reactpy.executors.asgi.ReactPy` that can be used to run ReactPy in standalone mode via ASGI. diff --git a/src/reactpy/core/events.py b/src/reactpy/core/events.py index ab7d639f5..c1dec839c 100644 --- a/src/reactpy/core/events.py +++ b/src/reactpy/core/events.py @@ -3,7 +3,7 @@ import dis import inspect from collections.abc import Callable, Sequence -from functools import lru_cache +from functools import lru_cache, partial from types import CodeType from typing import Any, Literal, cast, overload @@ -107,6 +107,9 @@ def __init__( while hasattr(func_to_inspect, "__wrapped__"): func_to_inspect = func_to_inspect.__wrapped__ + if isinstance(func_to_inspect, partial): + func_to_inspect = func_to_inspect.func + found_prevent_default, found_stop_propagation = _inspect_event_handler_code( func_to_inspect.__code__ ) diff --git a/tests/test_core/test_events.py b/tests/test_core/test_events.py index 52b515308..811482e8b 100644 --- a/tests/test_core/test_events.py +++ b/tests/test_core/test_events.py @@ -1,6 +1,7 @@ import pytest import reactpy +from functools import partial from reactpy import component, html from reactpy.core.events import ( EventHandler, @@ -348,6 +349,16 @@ def handler(event: Event): assert eh.stop_propagation is True +def test_detect_both_when_handler_is_partial(): + def handler(event: Event, *, extra_param): + event.preventDefault() + event.stopPropagation() + + eh = EventHandler(partial(handler, extra_param="extra_value")) + assert eh.prevent_default is True + assert eh.stop_propagation is True + + def test_no_detect(): def handler(event: Event): pass