]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-42116: Fix inspect.getsource handling of trailing comments (GH-23630)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 4 Dec 2020 20:20:09 +0000 (12:20 -0800)
committerGitHub <noreply@github.com>
Fri, 4 Dec 2020 20:20:09 +0000 (12:20 -0800)
(cherry picked from commit 6e1eec71f59c344fb23c7977061dc2c97b77d51b)

Co-authored-by: Irit Katriel <iritkatriel@yahoo.com>
Lib/inspect.py
Lib/test/inspect_fodder.py
Lib/test/test_inspect.py
Misc/NEWS.d/next/Library/2020-12-03-15-42-32.bpo-42116.yIwroP.rst [new file with mode: 0644]

index e8ea8c221f8288abe750d27e5e69010f869aac80..95144a97b41f252e89186aea9116bf59f6f4935d 100644 (file)
@@ -899,6 +899,7 @@ class BlockFinder:
         self.indecorator = False
         self.decoratorhasargs = False
         self.last = 1
+        self.body_col0 = None
 
     def tokeneater(self, type, token, srowcol, erowcol, line):
         if not self.started and not self.indecorator:
@@ -930,6 +931,8 @@ class BlockFinder:
         elif self.passline:
             pass
         elif type == tokenize.INDENT:
+            if self.body_col0 is None and self.started:
+                self.body_col0 = erowcol[1]
             self.indent = self.indent + 1
             self.passline = True
         elif type == tokenize.DEDENT:
@@ -939,6 +942,10 @@ class BlockFinder:
             #  not e.g. for "if: else:" or "try: finally:" blocks)
             if self.indent <= 0:
                 raise EndOfBlock
+        elif type == tokenize.COMMENT:
+            if self.body_col0 is not None and srowcol[1] >= self.body_col0:
+                # Include comments if indented at least as much as the block
+                self.last = srowcol[0]
         elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
             # any other token on the same indentation level end the previous
             # block as well, except the pseudo-tokens COMMENT and NL.
index 96a0257bfdf03e2371a28178e7bd71b1d278aa9b..e1287a315901cf6b0249b452393eab32281dd97b 100644 (file)
@@ -91,3 +91,25 @@ class Callable:
 
 custom_method = Callable().as_method_of(42)
 del Callable
+
+# line 95
+class WhichComments:
+  # line 97
+    # before f
+    def f(self):
+      # line 100
+        # start f
+        return 1
+        # line 103
+        # end f
+       # line 105
+    # after f
+
+    # before asyncf - line 108
+    async def asyncf(self):
+        # start asyncf
+        return 2
+        # end asyncf
+       # after asyncf - line 113
+    # end of WhichComments - line 114
+  # after WhichComments - line 115
index ad93f304827fbaf1aec2006652f459bc4f71375d..39248e7802485b2ba7bf8597907bf4266a1eb648 100644 (file)
@@ -392,6 +392,7 @@ class TestRetrievingSourceCode(GetSourceBase):
                           ('ParrotDroppings', mod.ParrotDroppings),
                           ('StupidGit', mod.StupidGit),
                           ('Tit', mod.MalodorousPervert),
+                          ('WhichComments', mod.WhichComments),
                          ])
         tree = inspect.getclasstree([cls[1] for cls in classes])
         self.assertEqual(tree,
@@ -405,7 +406,8 @@ class TestRetrievingSourceCode(GetSourceBase):
                             [(mod.FesteringGob, (mod.MalodorousPervert,
                                                     mod.ParrotDroppings))
                              ]
-                            ]
+                            ],
+                            (mod.WhichComments, (object,),)
                            ]
                           ])
         tree = inspect.getclasstree([cls[1] for cls in classes], True)
@@ -417,7 +419,8 @@ class TestRetrievingSourceCode(GetSourceBase):
                             [(mod.FesteringGob, (mod.MalodorousPervert,
                                                     mod.ParrotDroppings))
                              ]
-                            ]
+                            ],
+                            (mod.WhichComments, (object,),)
                            ]
                           ])
 
@@ -647,6 +650,18 @@ class TestOneliners(GetSourceBase):
         # as argument to another function.
         self.assertSourceEqual(mod2.anonymous, 55, 55)
 
+class TestBlockComments(GetSourceBase):
+    fodderModule = mod
+
+    def test_toplevel_class(self):
+        self.assertSourceEqual(mod.WhichComments, 96, 114)
+
+    def test_class_method(self):
+        self.assertSourceEqual(mod.WhichComments.f, 99, 104)
+
+    def test_class_async_method(self):
+        self.assertSourceEqual(mod.WhichComments.asyncf, 109, 112)
+
 class TestBuggyCases(GetSourceBase):
     fodderModule = mod2
 
@@ -3970,8 +3985,8 @@ def foo():
 
 def test_main():
     run_unittest(
-        TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
-        TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
+        TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBlockComments,
+        TestBuggyCases, TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
         TestGetcallargsFunctions, TestGetcallargsMethods,
         TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
         TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
diff --git a/Misc/NEWS.d/next/Library/2020-12-03-15-42-32.bpo-42116.yIwroP.rst b/Misc/NEWS.d/next/Library/2020-12-03-15-42-32.bpo-42116.yIwroP.rst
new file mode 100644 (file)
index 0000000..febda89
--- /dev/null
@@ -0,0 +1 @@
+Fix handling of trailing comments by :func:`inspect.getsource`.
\ No newline at end of file