Skip to content

Commit d76259a

Browse files
authored
Add __name__ to _Wrapped in functools (#9835)
1 parent 45f0a5e commit d76259a

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

stdlib/functools.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ WRAPPER_UPDATES: tuple[Literal["__dict__"]]
7272
class _Wrapped(Generic[_PWrapped, _RWrapped, _PWrapper, _RWapper]):
7373
__wrapped__: Callable[_PWrapped, _RWrapped]
7474
def __call__(self, *args: _PWrapper.args, **kwargs: _PWrapper.kwargs) -> _RWapper: ...
75+
# as with ``Callable``, we'll assume that these attributes exist
76+
__name__: str
77+
__qualname__: str
7578

7679
class _Wrapper(Generic[_PWrapped, _RWrapped]):
7780
def __call__(self, f: Callable[_PWrapper, _RWapper]) -> _Wrapped[_PWrapped, _RWrapped, _PWrapper, _RWapper]: ...

test_cases/stdlib/check_functools.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
11
from __future__ import annotations
22

33
import sys
4+
from functools import wraps
5+
from typing import Callable, TypeVar
6+
from typing_extensions import ParamSpec, assert_type
7+
8+
P = ParamSpec("P")
9+
T_co = TypeVar("T_co", covariant=True)
10+
11+
12+
def my_decorator(func: Callable[P, T_co]) -> Callable[P, T_co]:
13+
@wraps(func)
14+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T_co:
15+
print(args)
16+
return func(*args, **kwargs)
17+
18+
# verify that the wrapped function has all these attributes
19+
wrapper.__annotations__ = func.__annotations__
20+
wrapper.__doc__ = func.__doc__
21+
wrapper.__module__ = func.__module__
22+
wrapper.__name__ = func.__name__
23+
wrapper.__qualname__ = func.__qualname__
24+
return wrapper
25+
426

527
if sys.version_info >= (3, 8):
628
from functools import cached_property
7-
from typing_extensions import assert_type
829

930
class A:
1031
def __init__(self, x: int):

0 commit comments

Comments
 (0)