Skip to content

Commit 2997f39

Browse files
gh-83035: handle decorator with nested parens in inspect.getsource (GH-99654)
(cherry picked from commit 68e4129) Co-authored-by: Carl Meyer <[email protected]>
1 parent 2b97ddd commit 2997f39

File tree

4 files changed

+22
-9
lines changed

4 files changed

+22
-9
lines changed

Lib/inspect.py

+1-9
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,6 @@ def __init__(self):
11751175
self.started = False
11761176
self.passline = False
11771177
self.indecorator = False
1178-
self.decoratorhasargs = False
11791178
self.last = 1
11801179
self.body_col0 = None
11811180

@@ -1190,21 +1189,14 @@ def tokeneater(self, type, token, srowcol, erowcol, line):
11901189
self.islambda = True
11911190
self.started = True
11921191
self.passline = True # skip to the end of the line
1193-
elif token == "(":
1194-
if self.indecorator:
1195-
self.decoratorhasargs = True
1196-
elif token == ")":
1197-
if self.indecorator:
1198-
self.indecorator = False
1199-
self.decoratorhasargs = False
12001192
elif type == tokenize.NEWLINE:
12011193
self.passline = False # stop skipping when a NEWLINE is seen
12021194
self.last = srowcol[0]
12031195
if self.islambda: # lambdas always end at the first NEWLINE
12041196
raise EndOfBlock
12051197
# hitting a NEWLINE when in a decorator without args
12061198
# ends the decorator
1207-
if self.indecorator and not self.decoratorhasargs:
1199+
if self.indecorator:
12081200
self.indecorator = False
12091201
elif self.passline:
12101202
pass

Lib/test/inspect_fodder2.py

+14
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,17 @@ def all_markers_with_args_and_kwargs(a, b, /, c, d, *args, e, f, **kwargs):
259259
#line 259
260260
def all_markers_with_defaults(a, b=1, /, c=2, d=3, *, e=4, f=5):
261261
pass
262+
263+
# line 263
264+
def deco_factory(**kwargs):
265+
def deco(f):
266+
@wraps(f)
267+
def wrapper(*a, **kwd):
268+
kwd.update(kwargs)
269+
return f(*a, **kwd)
270+
return wrapper
271+
return deco
272+
273+
@deco_factory(foo=(1 + 2), bar=lambda: 1)
274+
def complex_decorated(foo=0, bar=lambda: 0):
275+
return foo + bar()

Lib/test/test_inspect.py

+6
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,12 @@ def test_class(self):
886886
self.assertSourceEqual(self.fodderModule.X, 1, 2)
887887

888888

889+
class TestComplexDecorator(GetSourceBase):
890+
fodderModule = mod2
891+
892+
def test_parens_in_decorator(self):
893+
self.assertSourceEqual(self.fodderModule.complex_decorated, 273, 275)
894+
889895
class _BrokenDataDescriptor(object):
890896
"""
891897
A broken data descriptor. See bug #1785.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix :func:`inspect.getsource` handling of decorator calls with nested parentheses.

0 commit comments

Comments
 (0)