mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Fix getting callback params on py3.14+
Add 1741.bugfix.rst
This commit is contained in:
parent
1e4a650171
commit
37a5eee31c
3 changed files with 33 additions and 5 deletions
3
CHANGES/1741.bugfix.rst
Normal file
3
CHANGES/1741.bugfix.rst
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
`inspect.getfullargspec(callback)` can't process callback if it's arguments have "ForwardRef" annotations in Py3.14+
|
||||
|
||||
This PR replaces the old way with `inspect.signature(callback)` and add `annotation_format = annotationlib.Format.FORWARDREF` argument to it if runtime python version >=3.14.
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import asyncio
|
||||
import inspect
|
||||
import sys
|
||||
import warnings
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass, field
|
||||
|
|
@ -27,9 +28,33 @@ class CallableObject:
|
|||
def __post_init__(self) -> None:
|
||||
callback = inspect.unwrap(self.callback)
|
||||
self.awaitable = inspect.isawaitable(callback) or inspect.iscoroutinefunction(callback)
|
||||
spec = inspect.getfullargspec(callback)
|
||||
self.params = {*spec.args, *spec.kwonlyargs}
|
||||
self.varkw = spec.varkw is not None
|
||||
|
||||
kwargs: dict[str, Any] = {}
|
||||
if sys.version_info >= (3, 14):
|
||||
import annotationlib
|
||||
|
||||
kwargs["annotation_format"] = annotationlib.Format.FORWARDREF
|
||||
|
||||
try:
|
||||
signature = inspect.signature(callback, **kwargs)
|
||||
except (ValueError, TypeError): # pragma: no cover
|
||||
self.params = set()
|
||||
self.varkw = False
|
||||
return
|
||||
|
||||
self.params = {
|
||||
p.name
|
||||
for p in signature.parameters.values()
|
||||
if p.kind
|
||||
in (
|
||||
inspect.Parameter.POSITIONAL_ONLY,
|
||||
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
||||
inspect.Parameter.KEYWORD_ONLY,
|
||||
)
|
||||
}
|
||||
self.varkw = any(
|
||||
p.kind == inspect.Parameter.VAR_KEYWORD for p in signature.parameters.values()
|
||||
)
|
||||
|
||||
def _prepare_kwargs(self, kwargs: dict[str, Any]) -> dict[str, Any]:
|
||||
if self.varkw:
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ class TestCallableObject:
|
|||
pytest.param(callback1, {"foo", "bar", "baz"}),
|
||||
pytest.param(callback2, {"foo", "bar", "baz"}),
|
||||
pytest.param(callback3, {"foo"}),
|
||||
pytest.param(TestFilter(), {"self", "foo", "bar", "baz"}),
|
||||
pytest.param(SyncCallable(), {"self", "foo", "bar", "baz"}),
|
||||
pytest.param(TestFilter(), {"foo", "bar", "baz"}),
|
||||
pytest.param(SyncCallable(), {"foo", "bar", "baz"}),
|
||||
],
|
||||
)
|
||||
def test_init_args_spec(self, callback: Callable, args: Set[str]):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue