diff --git a/aiogram/dispatcher/event/handler.py b/aiogram/dispatcher/event/handler.py index 2b71eed5..f20c986b 100644 --- a/aiogram/dispatcher/event/handler.py +++ b/aiogram/dispatcher/event/handler.py @@ -21,19 +21,22 @@ CallbackType = Callable[..., Any] class CallableMixin: callback: CallbackType awaitable: bool = field(init=False) - spec: inspect.FullArgSpec = field(init=False) + params: set[str] = field(init=False) + varkw: bool = field(init=False) def __post_init__(self) -> None: callback = inspect.unwrap(self.callback) self.awaitable = inspect.isawaitable(callback) or inspect.iscoroutinefunction(callback) - self.spec = inspect.getfullargspec(callback) + spec = inspect.getfullargspec(callback) + self.params = {*spec.args, *spec.kwonlyargs} + self.varkw = spec.varkw is not None def _prepare_kwargs(self, kwargs: Dict[str, Any]) -> Dict[str, Any]: - if self.spec.varkw: + if self.varkw: return kwargs return { - k: v for k, v in kwargs.items() if k in self.spec.args or k in self.spec.kwonlyargs + k: kwargs[k] for k in self.params if k in kwargs } async def call(self, *args: Any, **kwargs: Any) -> Any: diff --git a/tests/test_dispatcher/test_event/test_handler.py b/tests/test_dispatcher/test_event/test_handler.py index f7000d8e..0c59aff4 100644 --- a/tests/test_dispatcher/test_event/test_handler.py +++ b/tests/test_dispatcher/test_event/test_handler.py @@ -1,5 +1,5 @@ import functools -from typing import Any, Dict, Union +from typing import Any, Dict, Union, Callable import pytest from magic_filter import F as A @@ -61,9 +61,9 @@ class TestCallableMixin: pytest.param(SyncCallable(), {"self", "foo", "bar", "baz"}), ], ) - def test_init_args_spec(self, callback, args): + def test_init_args_spec(self, callback: Callable, args: set[str]): obj = CallableMixin(callback) - assert set(obj.spec.args) == args + assert set(obj.params) == args def test_init_decorated(self): def decorator(func): @@ -85,9 +85,9 @@ class TestCallableMixin: obj1 = CallableMixin(callback1) obj2 = CallableMixin(callback2) - assert set(obj1.spec.args) == {"foo", "bar", "baz"} + assert set(obj1.params) == {"foo", "bar", "baz"} assert obj1.callback == callback1 - assert set(obj2.spec.args) == {"foo", "bar", "baz"} + assert set(obj2.params) == {"foo", "bar", "baz"} assert obj2.callback == callback2 @pytest.mark.parametrize( @@ -124,7 +124,12 @@ class TestCallableMixin: ), ], ) - def test_prepare_kwargs(self, callback, kwargs, result): + def test_prepare_kwargs( + self, + callback: Callable, + kwargs: Dict[str, Any], + result: Dict[str, Any] + ): obj = CallableMixin(callback) assert obj._prepare_kwargs(kwargs) == result