]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-137477: Fix inspect.getblock() for generator expressions (GH-137488) (GH...
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 20 Aug 2025 13:43:28 +0000 (16:43 +0300)
committerGitHub <noreply@github.com>
Wed, 20 Aug 2025 13:43:28 +0000 (13:43 +0000)
This fixes also inspect.getsourcelines() and inspect.getsource().
(cherry picked from commit eae9d7de1c45a64076a926d53672823e6ae1777d)

Lib/inspect.py
Lib/test/test_inspect/inspect_fodder2.py
Lib/test/test_inspect/test_inspect.py
Misc/NEWS.d/next/Library/2025-08-06-23-16-42.gh-issue-137477.bk6BDV.rst [new file with mode: 0644]

index de2fe7e1ae0f6d345fdf1a53f4f0073079f50802..5b3e63ce44e2e0b0de290e807c97c4671e023e33 100644 (file)
@@ -1159,7 +1159,7 @@ class BlockFinder:
     """Provide a tokeneater() method to detect the end of a code block."""
     def __init__(self):
         self.indent = 0
-        self.islambda = False
+        self.singleline = False
         self.started = False
         self.passline = False
         self.indecorator = False
@@ -1168,19 +1168,22 @@ class BlockFinder:
 
     def tokeneater(self, type, token, srowcol, erowcol, line):
         if not self.started and not self.indecorator:
+            if type == tokenize.INDENT or token == "async":
+                pass
             # skip any decorators
-            if token == "@":
+            elif token == "@":
                 self.indecorator = True
-            # look for the first "def", "class" or "lambda"
-            elif token in ("def", "class", "lambda"):
-                if token == "lambda":
-                    self.islambda = True
+            else:
+                # For "def" and "class" scan to the end of the block.
+                # For "lambda" and generator expression scan to
+                # the end of the logical line.
+                self.singleline = token not in ("def", "class")
                 self.started = True
             self.passline = True    # skip to the end of the line
         elif type == tokenize.NEWLINE:
             self.passline = False   # stop skipping when a NEWLINE is seen
             self.last = srowcol[0]
-            if self.islambda:       # lambdas always end at the first NEWLINE
+            if self.singleline:
                 raise EndOfBlock
             # hitting a NEWLINE when in a decorator without args
             # ends the decorator
index 43fda6622537fc71688d7e65ddbe778d83470033..1de283f672d362cdb60e36388c0e9822dbbd52cf 100644 (file)
@@ -369,3 +369,23 @@ class dc364:
 # line 369
 dc370 = dataclasses.make_dataclass('dc370', (('x', int), ('y', int)))
 dc371 = dataclasses.make_dataclass('dc370', (('x', int), ('y', int)), module=__name__)
+
+import inspect
+import itertools
+
+# line 376
+ge377 = (
+    inspect.currentframe()
+    for i in itertools.count()
+)
+
+# line 382
+def func383():
+    # line 384
+    ge385 = (
+        inspect.currentframe()
+        for i in itertools.count()
+    )
+    return ge385
+
+pass # end of file
index 977c3d07252d04e420edb0a4a7ed9d746bab794b..e51ff58041921e2714a98d2539789f51caf07389 100644 (file)
@@ -1187,12 +1187,18 @@ class TestBuggyCases(GetSourceBase):
         self.addCleanup(asyncio.set_event_loop_policy, None)
         self.assertSourceEqual(asyncio.run(mod2.func225()), 226, 227)
         self.assertSourceEqual(mod2.cls226, 231, 235)
+        self.assertSourceEqual(mod2.cls226.func232, 232, 235)
         self.assertSourceEqual(asyncio.run(mod2.cls226().func232()), 233, 234)
 
     def test_class_definition_same_name_diff_methods(self):
         self.assertSourceEqual(mod2.cls296, 296, 298)
         self.assertSourceEqual(mod2.cls310, 310, 312)
 
+    def test_generator_expression(self):
+        self.assertSourceEqual(next(mod2.ge377), 377, 380)
+        self.assertSourceEqual(next(mod2.func383()), 385, 388)
+
+
 class TestNoEOL(GetSourceBase):
     def setUp(self):
         self.tempdir = TESTFN + '_dir'
diff --git a/Misc/NEWS.d/next/Library/2025-08-06-23-16-42.gh-issue-137477.bk6BDV.rst b/Misc/NEWS.d/next/Library/2025-08-06-23-16-42.gh-issue-137477.bk6BDV.rst
new file mode 100644 (file)
index 0000000..a6e097e
--- /dev/null
@@ -0,0 +1,2 @@
+Fix :func:`!inspect.getblock`, :func:`inspect.getsourcelines` and
+:func:`inspect.getsource` for generator expressions.