diff --git a/aiogram/dispatcher/event/handler.py b/aiogram/dispatcher/event/handler.py index bac21309..08052fd3 100644 --- a/aiogram/dispatcher/event/handler.py +++ b/aiogram/dispatcher/event/handler.py @@ -3,15 +3,17 @@ from dataclasses import dataclass, field from functools import partial from typing import Any, Awaitable, Callable, Dict, List, Tuple, Union +from aiogram.dispatcher.filters.base import BaseFilter + CallbackType = Callable[[Any], Awaitable[Any]] SyncFilter = Callable[[Any], Any] AsyncFilter = Callable[[Any], Awaitable[Any]] -FilterType = Union[SyncFilter, AsyncFilter] +FilterType = Union[SyncFilter, AsyncFilter, BaseFilter] @dataclass class CallableMixin: - callback: Callable[[Any], Any] + callback: Callable awaitable: bool = field(init=False) spec: inspect.FullArgSpec = field(init=False) diff --git a/aiogram/dispatcher/event/observer.py b/aiogram/dispatcher/event/observer.py index aee259e5..7f221fb4 100644 --- a/aiogram/dispatcher/event/observer.py +++ b/aiogram/dispatcher/event/observer.py @@ -7,7 +7,7 @@ from pydantic import ValidationError from ..filters.base import BaseFilter from .handler import CallbackType, FilterObject, FilterType, HandlerObject -if TYPE_CHECKING: +if TYPE_CHECKING: # pragma: no cover from aiogram.dispatcher.router import Router @@ -87,7 +87,7 @@ class TelegramEventObserver(EventObserver): yield filter_ registry.append(filter_) - def register(self, callback: CallbackType, *filters: FilterType, **bound_filters): + def register(self, callback: CallbackType, *filters: FilterType, **bound_filters: Any): resolved_filters = self.resolve_filters(bound_filters) return super().register(callback, *filters, *resolved_filters) diff --git a/aiogram/dispatcher/filters/base.py b/aiogram/dispatcher/filters/base.py index 4d12cb69..e49db340 100644 --- a/aiogram/dispatcher/filters/base.py +++ b/aiogram/dispatcher/filters/base.py @@ -1,13 +1,23 @@ from abc import ABC, abstractmethod -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, Union from pydantic import BaseModel class BaseFilter(ABC, BaseModel): - @abstractmethod - async def __call__(self, *args, **kwargs) -> Union[bool, Dict[str, Any]]: - pass + if TYPE_CHECKING: # pragma: no cover + # This checking type-hint is needed because mypy checks validity of overrides and raises: + # error: Signature of "__call__" incompatible with supertype "BaseFilter" [override] + # https://mypy.readthedocs.io/en/latest/error_code_list.html#check-validity-of-overrides-override + + __call__: Any + else: # pragma: no cover + + @abstractmethod + async def __call__( + self, *args: Any, **kwargs: Any + ) -> Callable[[Any], Awaitable[Union[bool, Dict[str, Any]]]]: + pass def __await__(self): return self.__call__