diff --git a/eth_utils/decorators.py b/eth_utils/decorators.py index 0268be25..df660aaa 100644 --- a/eth_utils/decorators.py +++ b/eth_utils/decorators.py @@ -4,9 +4,15 @@ Any, Callable, Dict, - Optional, + Generic, Type, TypeVar, + Union, +) + +from typing_extensions import ( + Concatenate, + ParamSpec, ) from .types import ( @@ -14,17 +20,18 @@ ) T = TypeVar("T") +P = ParamSpec("P") -class combomethod: - def __init__(self, method: Callable[..., Any]) -> None: +class combomethod(Generic[P, T]): + def __init__(self, method: Callable[Concatenate[Any, P], T]) -> None: self.method = method def __get__( - self, obj: Optional[T] = None, objtype: Optional[Type[T]] = None - ) -> Callable[..., Any]: + self, obj: object = None, objtype: Union[type, None] = None + ) -> Callable[P, T]: @functools.wraps(self.method) - def _wrapper(*args: Any, **kwargs: Any) -> Any: + def _wrapper(*args: P.args, **kwargs: P.kwargs) -> T: if obj is not None: return self.method(obj, *args, **kwargs) else: diff --git a/newsfragments/236.feature.rst b/newsfragments/236.feature.rst new file mode 100644 index 00000000..58ff3c81 --- /dev/null +++ b/newsfragments/236.feature.rst @@ -0,0 +1 @@ +Improve type hints for decorator combomethod. diff --git a/setup.py b/setup.py index d4bc2309..52b3d479 100644 --- a/setup.py +++ b/setup.py @@ -55,6 +55,7 @@ url="https://github.com/ethereum/eth-utils", include_package_data=True, install_requires=[ + "typing_extensions", "eth-hash>=0.3.1", "eth-typing>=5.0.0", "toolz>0.8.2;implementation_name=='pypy'",