Content from global filters (#1267)

* Move global filters check placement into router to add chance to pass context from global filters into handlers in the same way as it possible in other places

* Added changelog
This commit is contained in:
Alex Root Junior 2023-08-14 22:18:11 +03:00 committed by GitHub
parent 577b44cdc1
commit 8ff992bf1d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 23 additions and 17 deletions

2
CHANGES/1266.bugfix.rst Normal file
View file

@ -0,0 +1,2 @@
Moved global filters check placement into router to add chance to pass context from global filters
into handlers in the same way as it possible in other places

View file

@ -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:

View file

@ -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

View file

@ -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))

View file

@ -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()

View file

@ -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