Skip to content

Commit 9737829

Browse files
committed
bpo-29858: inspect.signature includes bound argument for wrappers around decorated bound methods
1 parent df82808 commit 9737829

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

Lib/inspect.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2171,7 +2171,10 @@ def _signature_from_callable(obj, *,
21712171

21722172
# Was this function wrapped by a decorator?
21732173
if follow_wrapper_chains:
2174-
obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")))
2174+
# Unwrap until it has a explicit signature
2175+
# or it is a MethodType - we need to process it individually
2176+
obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")
2177+
or isinstance(f, types.MethodType)))
21752178
if isinstance(obj, types.MethodType):
21762179
# If the unwrapped object is a *method*, we might want to
21772180
# skip its first parameter (self).

Lib/test/test_inspect.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2470,8 +2470,6 @@ def foo(a): pass
24702470
self.assertEqual(str(inspect.signature(foo)), '(a)')
24712471

24722472
def test_signature_on_decorated(self):
2473-
import functools
2474-
24752473
def decorator(func):
24762474
@functools.wraps(func)
24772475
def wrapper(*args, **kwargs) -> int:
@@ -2483,6 +2481,8 @@ class Foo:
24832481
def bar(self, a, b):
24842482
pass
24852483

2484+
bar = decorator(Foo().bar)
2485+
24862486
self.assertEqual(self.signature(Foo.bar),
24872487
((('self', ..., ..., "positional_or_keyword"),
24882488
('a', ..., ..., "positional_or_keyword"),
@@ -2501,6 +2501,11 @@ def bar(self, a, b):
25012501
# from "func" to "wrapper", hence no
25022502
# return_annotation
25032503

2504+
self.assertEqual(self.signature(bar),
2505+
((('a', ..., ..., "positional_or_keyword"),
2506+
('b', ..., ..., "positional_or_keyword")),
2507+
...))
2508+
25042509
# Test that we handle method wrappers correctly
25052510
def decorator(func):
25062511
@functools.wraps(func)

0 commit comments

Comments
 (0)