diff --git a/Lib/inspect.py b/Lib/inspect.py index 31ac888126b..e165937e448 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1160,7 +1160,6 @@ def __init__(self): self.started = False self.passline = False self.indecorator = False - self.decoratorhasargs = False self.last = 1 self.body_col0 = None @@ -1175,13 +1174,6 @@ def tokeneater(self, type, token, srowcol, erowcol, line): self.islambda = True self.started = True self.passline = True # skip to the end of the line - elif token == "(": - if self.indecorator: - self.decoratorhasargs = True - elif token == ")": - if self.indecorator: - self.indecorator = False - self.decoratorhasargs = False elif type == tokenize.NEWLINE: self.passline = False # stop skipping when a NEWLINE is seen self.last = srowcol[0] @@ -1189,7 +1181,7 @@ def tokeneater(self, type, token, srowcol, erowcol, line): raise EndOfBlock # hitting a NEWLINE when in a decorator without args # ends the decorator - if self.indecorator and not self.decoratorhasargs: + if self.indecorator: self.indecorator = False elif self.passline: pass diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/inspect_fodder2.py index e7d4b53ebef..2dc49817087 100644 --- a/Lib/test/inspect_fodder2.py +++ b/Lib/test/inspect_fodder2.py @@ -259,3 +259,17 @@ def all_markers_with_args_and_kwargs(a, b, /, c, d, *args, e, f, **kwargs): #line 259 def all_markers_with_defaults(a, b=1, /, c=2, d=3, *, e=4, f=5): pass + +# line 263 +def deco_factory(**kwargs): + def deco(f): + @wraps(f) + def wrapper(*a, **kwd): + kwd.update(kwargs) + return f(*a, **kwd) + return wrapper + return deco + +@deco_factory(foo=(1 + 2), bar=lambda: 1) +def complex_decorated(foo=0, bar=lambda: 0): + return foo + bar() diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 3f5c299ce68..2b7977b1648 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -886,6 +886,12 @@ def test_class(self): self.assertSourceEqual(self.fodderModule.X, 1, 2) +class TestComplexDecorator(GetSourceBase): + fodderModule = mod2 + + def test_parens_in_decorator(self): + self.assertSourceEqual(self.fodderModule.complex_decorated, 273, 275) + class _BrokenDataDescriptor(object): """ A broken data descriptor. See bug #1785. diff --git a/Misc/NEWS.d/next/Library/2022-11-21-16-24-01.gh-issue-83035.qZIujU.rst b/Misc/NEWS.d/next/Library/2022-11-21-16-24-01.gh-issue-83035.qZIujU.rst new file mode 100644 index 00000000000..629d9aefb2d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-11-21-16-24-01.gh-issue-83035.qZIujU.rst @@ -0,0 +1 @@ +Fix :func:`inspect.getsource` handling of decorator calls with nested parentheses.