Skip to content

Commit 81ac030

Browse files
bpo-42116: Fix inspect.getsource handling of trailing comments (GH-23630)
(cherry picked from commit 6e1eec7) Co-authored-by: Irit Katriel <[email protected]>
1 parent c7cf66d commit 81ac030

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed

Lib/inspect.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,7 @@ def __init__(self):
926926
self.indecorator = False
927927
self.decoratorhasargs = False
928928
self.last = 1
929+
self.body_col0 = None
929930

930931
def tokeneater(self, type, token, srowcol, erowcol, line):
931932
if not self.started and not self.indecorator:
@@ -957,6 +958,8 @@ def tokeneater(self, type, token, srowcol, erowcol, line):
957958
elif self.passline:
958959
pass
959960
elif type == tokenize.INDENT:
961+
if self.body_col0 is None and self.started:
962+
self.body_col0 = erowcol[1]
960963
self.indent = self.indent + 1
961964
self.passline = True
962965
elif type == tokenize.DEDENT:
@@ -966,6 +969,10 @@ def tokeneater(self, type, token, srowcol, erowcol, line):
966969
# not e.g. for "if: else:" or "try: finally:" blocks)
967970
if self.indent <= 0:
968971
raise EndOfBlock
972+
elif type == tokenize.COMMENT:
973+
if self.body_col0 is not None and srowcol[1] >= self.body_col0:
974+
# Include comments if indented at least as much as the block
975+
self.last = srowcol[0]
969976
elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
970977
# any other token on the same indentation level end the previous
971978
# block as well, except the pseudo-tokens COMMENT and NL.

Lib/test/inspect_fodder.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,25 @@ def as_method_of(self, obj):
9191

9292
custom_method = Callable().as_method_of(42)
9393
del Callable
94+
95+
# line 95
96+
class WhichComments:
97+
# line 97
98+
# before f
99+
def f(self):
100+
# line 100
101+
# start f
102+
return 1
103+
# line 103
104+
# end f
105+
# line 105
106+
# after f
107+
108+
# before asyncf - line 108
109+
async def asyncf(self):
110+
# start asyncf
111+
return 2
112+
# end asyncf
113+
# after asyncf - line 113
114+
# end of WhichComments - line 114
115+
# after WhichComments - line 115

Lib/test/test_inspect.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ def test_getclasses(self):
388388
('ParrotDroppings', mod.ParrotDroppings),
389389
('StupidGit', mod.StupidGit),
390390
('Tit', mod.MalodorousPervert),
391+
('WhichComments', mod.WhichComments),
391392
])
392393
tree = inspect.getclasstree([cls[1] for cls in classes])
393394
self.assertEqual(tree,
@@ -401,7 +402,8 @@ def test_getclasses(self):
401402
[(mod.FesteringGob, (mod.MalodorousPervert,
402403
mod.ParrotDroppings))
403404
]
404-
]
405+
],
406+
(mod.WhichComments, (object,),)
405407
]
406408
])
407409
tree = inspect.getclasstree([cls[1] for cls in classes], True)
@@ -413,7 +415,8 @@ def test_getclasses(self):
413415
[(mod.FesteringGob, (mod.MalodorousPervert,
414416
mod.ParrotDroppings))
415417
]
416-
]
418+
],
419+
(mod.WhichComments, (object,),)
417420
]
418421
])
419422

@@ -644,6 +647,18 @@ def test_anonymous(self):
644647
# as argument to another function.
645648
self.assertSourceEqual(mod2.anonymous, 55, 55)
646649

650+
class TestBlockComments(GetSourceBase):
651+
fodderModule = mod
652+
653+
def test_toplevel_class(self):
654+
self.assertSourceEqual(mod.WhichComments, 96, 114)
655+
656+
def test_class_method(self):
657+
self.assertSourceEqual(mod.WhichComments.f, 99, 104)
658+
659+
def test_class_async_method(self):
660+
self.assertSourceEqual(mod.WhichComments.asyncf, 109, 112)
661+
647662
class TestBuggyCases(GetSourceBase):
648663
fodderModule = mod2
649664

@@ -4016,8 +4031,8 @@ def test_getsource_reload(self):
40164031

40174032
def test_main():
40184033
run_unittest(
4019-
TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
4020-
TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
4034+
TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBlockComments,
4035+
TestBuggyCases, TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
40214036
TestGetcallargsFunctions, TestGetcallargsMethods,
40224037
TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
40234038
TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix handling of trailing comments by :func:`inspect.getsource`.

0 commit comments

Comments
 (0)