diff --git a/aiogram/dispatcher/event/handler.py b/aiogram/dispatcher/event/handler.py index 37a9ecb7..7937d209 100644 --- a/aiogram/dispatcher/event/handler.py +++ b/aiogram/dispatcher/event/handler.py @@ -64,6 +64,7 @@ class FilterObject(CallableMixin): class HandlerObject(CallableMixin): callback: HandlerType filters: Optional[List[FilterObject]] = None + flags: Dict[str, Any] = field(default_factory=dict) def __post_init__(self) -> None: super(HandlerObject, self).__post_init__() diff --git a/aiogram/dispatcher/event/telegram.py b/aiogram/dispatcher/event/telegram.py index fd9ba63a..5535bb3e 100644 --- a/aiogram/dispatcher/event/telegram.py +++ b/aiogram/dispatcher/event/telegram.py @@ -175,16 +175,25 @@ class TelegramEventObserver: return bound_filters def register( - self, callback: HandlerType, *filters: FilterType, **bound_filters: Any + self, + callback: HandlerType, + *filters: FilterType, + flags: Optional[Dict[str, Any]] = None, + **bound_filters: Any, ) -> HandlerType: """ Register event handler """ + if flags is None: + flags = {} resolved_filters = self.resolve_filters(filters, bound_filters, ignore_default=False) + for resolved_filter in resolved_filters: + resolved_filter.update_handler_flags(flags=flags) self.handlers.append( HandlerObject( callback=callback, filters=[FilterObject(filter_) for filter_ in chain(resolved_filters, filters)], + flags=flags, ) ) return callback @@ -222,7 +231,7 @@ class TelegramEventObserver: for handler in self.handlers: result, data = await handler.check(event, **kwargs) if result: - kwargs.update(data) + kwargs.update(data, handler=handler) try: wrapped_inner = self._wrap_middleware( self._resolve_middlewares(), handler.call @@ -234,14 +243,14 @@ class TelegramEventObserver: return UNHANDLED def __call__( - self, *args: FilterType, **bound_filters: Any + self, *args: FilterType, flags: Optional[Dict[str, Any]] = None, **bound_filters: Any ) -> Callable[[CallbackType], CallbackType]: """ Decorator for registering event handlers """ def wrapper(callback: CallbackType) -> CallbackType: - self.register(callback, *args, **bound_filters) + self.register(callback, *args, flags=flags, **bound_filters) return callback return wrapper diff --git a/aiogram/dispatcher/filters/base.py b/aiogram/dispatcher/filters/base.py index 769e887c..d2bb99cf 100644 --- a/aiogram/dispatcher/filters/base.py +++ b/aiogram/dispatcher/filters/base.py @@ -32,6 +32,9 @@ class BaseFilter(ABC, BaseModel): """ pass + def update_handler_flags(self, flags: Dict[str, Any]) -> None: + pass + def __await__(self): # type: ignore # pragma: no cover # Is needed only for inspection and this method is never be called return self.__call__ diff --git a/aiogram/dispatcher/filters/command.py b/aiogram/dispatcher/filters/command.py index 0e46c1ec..03cb41c7 100644 --- a/aiogram/dispatcher/filters/command.py +++ b/aiogram/dispatcher/filters/command.py @@ -38,6 +38,10 @@ class Command(BaseFilter): command_magic: Optional[MagicFilter] = None """Validate command object via Magic filter after all checks done""" + def update_handler_flags(self, flags: Dict[str, Any]) -> None: + commands = flags.setdefault("commands", []) + commands.append(self) + @validator("commands", always=True) def _validate_commands( cls, value: Union[Sequence[CommandPatterType], CommandPatterType]