Skip to content

bpo-46873: Fix inspect.getsource - Count parentheses open/close in decorators #31605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -1174,9 +1174,13 @@ def __init__(self):
self.started = False
self.passline = False
self.indecorator = False
self.decoratorhasargs = False
self.last = 1
self.body_col0 = None
self._decoratorhasargs_count = 0

@property
def decoratorhasargs(self):
return bool(self._decoratorhasargs_count)

def tokeneater(self, type, token, srowcol, erowcol, line):
if not self.started and not self.indecorator:
Expand All @@ -1191,11 +1195,12 @@ def tokeneater(self, type, token, srowcol, erowcol, line):
self.passline = True # skip to the end of the line
elif token == "(":
if self.indecorator:
self.decoratorhasargs = True
self._decoratorhasargs_count += 1
elif token == ")":
if self.indecorator:
self.indecorator = False
self.decoratorhasargs = False
self._decoratorhasargs_count -= 1
if not self.decoratorhasargs:
self.indecorator = False
elif type == tokenize.NEWLINE:
self.passline = False # stop skipping when a NEWLINE is seen
self.last = srowcol[0]
Expand Down
9 changes: 9 additions & 0 deletions Lib/test/inspect_fodder3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# line 1
def wrap_many(*foo):
def wrapper(func):
return func
return wrapper

@wrap_many(lambda: bool(True), lambda: True)
def func8():
return 9
7 changes: 7 additions & 0 deletions Lib/test/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from test.support.script_helper import assert_python_ok, assert_python_failure
from test import inspect_fodder as mod
from test import inspect_fodder2 as mod2
from test import inspect_fodder3 as mod3
from test import support
from test import inspect_stock_annotations
from test import inspect_stringized_annotations
Expand Down Expand Up @@ -673,6 +674,12 @@ def test_getsource_unwrap(self):
def test_decorator_with_lambda(self):
self.assertSourceEqual(mod2.func114, 113, 115)

class TestDecoratorsMulti(GetSourceBase):
fodderModule = mod3

def test_decorator_with_multiple_lambdas_with_calls(self):
self.assertSourceEqual(mod3.func8, 7, 9)

class TestOneliners(GetSourceBase):
fodderModule = mod2
def test_oneline_lambda(self):
Expand Down