diff --git a/aiogram/dispatcher/event/telegram.py b/aiogram/dispatcher/event/telegram.py index a468816c..cb4039c7 100644 --- a/aiogram/dispatcher/event/telegram.py +++ b/aiogram/dispatcher/event/telegram.py @@ -101,17 +101,14 @@ class TelegramEventObserver: ) return wrapped_outer(event, data) + def check_root_filters(self, event: TelegramObject, **kwargs: Any) -> Any: + return self._handler.check(event, **kwargs) + async def trigger(self, event: TelegramObject, **kwargs: Any) -> Any: """ Propagate event to handlers and stops propagation on first match. - Handler will be called when all its filters is pass. + Handler will be called when all its filters are pass. """ - # Check globally defined filters before any other handler will be checked - result, data = await self._handler.check(event, **kwargs) - if not result: - return REJECTED - kwargs.update(data) - for handler in self.handlers: result, data = await handler.check(event, **kwargs) if result: diff --git a/aiogram/dispatcher/router.py b/aiogram/dispatcher/router.py index 423b7173..4dd4284f 100644 --- a/aiogram/dispatcher/router.py +++ b/aiogram/dispatcher/router.py @@ -125,8 +125,17 @@ class Router: ) -> Any: response = UNHANDLED if observer: + # Check globally defined filters before any other handler will be checked. + # This check is placed here instead of `trigger` method to add possibility + # to pass context to handlers from global filters. + result, data = await observer.check_root_filters(event, **kwargs) + if not result: + return UNHANDLED + kwargs.update(data) + response = await observer.trigger(event, **kwargs) - if response is REJECTED: + if response is REJECTED: # pragma: no cover + # Possible only if some handler returns REJECTED return UNHANDLED if response is not UNHANDLED: return response diff --git a/examples/context_addition_from_filter.py b/examples/context_addition_from_filter.py index e4eca517..40338940 100644 --- a/examples/context_addition_from_filter.py +++ b/examples/context_addition_from_filter.py @@ -4,7 +4,6 @@ from aiogram import Router from aiogram.filters import Filter from aiogram.types import Message, User - router = Router(name=__name__) @@ -28,6 +27,4 @@ class HelloFilter(Filter): async def my_handler( message: Message, name: str # Now we can accept "name" as named parameter ) -> Any: - return message.answer( - "Hello, {name}!".format(name=name) - ) + return message.answer("Hello, {name}!".format(name=name)) diff --git a/examples/multibot.py b/examples/multibot.py index 82fac4a1..d5dbe5fc 100644 --- a/examples/multibot.py +++ b/examples/multibot.py @@ -4,6 +4,7 @@ from os import getenv from typing import Any, Dict, Union from aiohttp import web +from finite_state_machine import form_router from aiogram import Bot, Dispatcher, F, Router from aiogram.client.session.aiohttp import AiohttpSession @@ -18,7 +19,6 @@ from aiogram.webhook.aiohttp_server import ( TokenBasedRequestHandler, setup_application, ) -from finite_state_machine import form_router main_router = Router() diff --git a/tests/test_dispatcher/test_event/test_telegram.py b/tests/test_dispatcher/test_event/test_telegram.py index 973fa17c..8976b2ff 100644 --- a/tests/test_dispatcher/test_event/test_telegram.py +++ b/tests/test_dispatcher/test_event/test_telegram.py @@ -5,7 +5,7 @@ from typing import Any, Dict, NoReturn, Optional, Union import pytest from pydantic import BaseModel -from aiogram.dispatcher.event.bases import REJECTED, SkipHandler +from aiogram.dispatcher.event.bases import SkipHandler, UNHANDLED from aiogram.dispatcher.event.handler import HandlerObject from aiogram.dispatcher.event.telegram import TelegramEventObserver from aiogram.dispatcher.router import Router @@ -13,6 +13,7 @@ from aiogram.exceptions import UnsupportedKeywordArgument from aiogram.filters import Filter from aiogram.types import Chat, Message, User + # TODO: Test middlewares in routers tree @@ -220,8 +221,8 @@ class TestTelegramEventObserver: r1.message.register(handler) r2.message.register(handler) - assert await r1.message.trigger(None) is REJECTED - assert await r2.message.trigger(None) is None + assert await r1.propagate_event("message", None) is UNHANDLED + assert await r2.propagate_event("message", None) is None async def test_global_filter_in_nested_router(self): r1 = Router() @@ -234,4 +235,4 @@ class TestTelegramEventObserver: r1.message.filter(lambda evt: False) r2.message.register(handler) - assert await r1.message.trigger(None) is REJECTED + assert await r1.message.trigger(None) is UNHANDLED