diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index 5db4c65bdb8d..20b612123c2a 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -72,6 +72,9 @@ WRAPPER_UPDATES: tuple[Literal["__dict__"]] class _Wrapped(Generic[_PWrapped, _RWrapped, _PWrapper, _RWapper]): __wrapped__: Callable[_PWrapped, _RWrapped] def __call__(self, *args: _PWrapper.args, **kwargs: _PWrapper.kwargs) -> _RWapper: ... + # as with ``Callable``, we'll assume that these attributes exist + __name__: str + __qualname__: str class _Wrapper(Generic[_PWrapped, _RWrapped]): def __call__(self, f: Callable[_PWrapper, _RWapper]) -> _Wrapped[_PWrapped, _RWrapped, _PWrapper, _RWapper]: ... diff --git a/test_cases/stdlib/check_functools.py b/test_cases/stdlib/check_functools.py index 327e60faa07d..4ec828832731 100644 --- a/test_cases/stdlib/check_functools.py +++ b/test_cases/stdlib/check_functools.py @@ -1,10 +1,31 @@ from __future__ import annotations import sys +from functools import wraps +from typing import Callable, TypeVar +from typing_extensions import ParamSpec, assert_type + +P = ParamSpec("P") +T_co = TypeVar("T_co", covariant=True) + + +def my_decorator(func: Callable[P, T_co]) -> Callable[P, T_co]: + @wraps(func) + def wrapper(*args: P.args, **kwargs: P.kwargs) -> T_co: + print(args) + return func(*args, **kwargs) + + # verify that the wrapped function has all these attributes + wrapper.__annotations__ = func.__annotations__ + wrapper.__doc__ = func.__doc__ + wrapper.__module__ = func.__module__ + wrapper.__name__ = func.__name__ + wrapper.__qualname__ = func.__qualname__ + return wrapper + if sys.version_info >= (3, 8): from functools import cached_property - from typing_extensions import assert_type class A: def __init__(self, x: int):