optimized CallableMixin

This commit is contained in:
RootShinobi 2023-11-04 20:03:44 +02:00
parent 228a86afdc
commit 32d5f79a25
2 changed files with 18 additions and 10 deletions

View file

@ -21,19 +21,22 @@ 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
k: kwargs[k] for k in self.params if k in kwargs
}
async def call(self, *args: Any, **kwargs: Any) -> Any:

View file

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