Merge remote-tracking branch 'origin/dev-3.x' into dev-3.x

This commit is contained in:
JRoot Junior 2023-11-14 02:54:34 +02:00
commit 2f1ae0a686
No known key found for this signature in database
GPG key ID: 738964250D5FF6E2
8 changed files with 23 additions and 16 deletions

1
CHANGES/1353.doc.rst Normal file
View file

@ -0,0 +1 @@
Minor typo correction in middleware docs.

1
CHANGES/1357.misc.rst Normal file
View file

@ -0,0 +1 @@
Speeded up CallableMixin processing by caching references to nested objects and simplifying kwargs assembly.

1
CHANGES/1360.bugfix.rst Normal file
View file

@ -0,0 +1 @@
Added current handler to filters, so that flags can be retrieved from it.

View file

@ -4,7 +4,7 @@ import inspect
import warnings
from dataclasses import dataclass, field
from functools import partial
from typing import Any, Callable, Dict, List, Optional, Tuple
from typing import Any, Callable, Dict, List, Optional, Tuple, Set
from magic_filter.magic import MagicFilter as OriginalMagicFilter
@ -21,20 +21,21 @@ 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
}
return {k: kwargs[k] for k in self.params if k in kwargs}
async def call(self, *args: Any, **kwargs: Any) -> Any:
wrapped = partial(self.callback, *args, **self._prepare_kwargs(kwargs))

View file

@ -109,9 +109,10 @@ class TelegramEventObserver:
Handler will be called when all its filters are pass.
"""
for handler in self.handlers:
kwargs["handler"] = handler
result, data = await handler.check(event, **kwargs)
if result:
kwargs.update(data, handler=handler)
kwargs.update(data)
try:
wrapped_inner = self.outer_middleware.wrap_middlewares(
self._resolve_middlewares(),

View file

@ -53,7 +53,7 @@ Class based session middleware
.. note::
this middlewware is already implemented inside aiogram, so, if you want to use it you can
this middleware is already implemented inside aiogram, so, if you want to use it you can
just import it :code:`from aiogram.client.session.middlewares.request_logging import RequestLogging`

View file

@ -36,6 +36,7 @@ from aiogram.methods import (
UnpinChatMessage,
)
from aiogram.types import (
UNSET_PARSE_MODE,
Animation,
Audio,
Chat,
@ -75,7 +76,6 @@ from aiogram.types import (
VideoNote,
Voice,
WebAppData,
UNSET_PARSE_MODE,
)
from aiogram.types.message import ContentType, Message

View file

@ -1,5 +1,5 @@
import functools
from typing import Any, Dict, Union
from typing import Any, Dict, Union, Callable, Set
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,9 @@ 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