diff --git a/Lib/inspect.py b/Lib/inspect.py index 183e67fabf966e..c1e915ea70b852 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1002,6 +1002,15 @@ def findsource(object): lnum = object.co_firstlineno - 1 if lnum >= len(lines): raise OSError('lineno is out of bounds') + pat = re.compile(r'^(\s*def\s)|(\s*class\s)|(\s*async\s+def\s)|(.*(? 0: + try: + line = lines[lnum] + except IndexError: + raise OSError('lineno is out of bounds') + if pat.match(line): + break + lnum = lnum - 1 return lines, lnum raise OSError('could not find code object') diff --git a/Lib/test/test_inspect/inspect_fodder2.py b/Lib/test/test_inspect/inspect_fodder2.py index 43fda6622537fc..3988e437da1609 100644 --- a/Lib/test/test_inspect/inspect_fodder2.py +++ b/Lib/test/test_inspect/inspect_fodder2.py @@ -369,3 +369,11 @@ class dc364: # line 369 dc370 = dataclasses.make_dataclass('dc370', (('x', int), ('y', int))) dc371 = dataclasses.make_dataclass('dc370', (('x', int), ('y', int)), module=__name__) + +# line 373 +from inspect import currentframe +def generator_frame(): + loops = ( + currentframe() for _ in [0] + ) + return list(loops)[0] diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index 30e01b8cd87a75..1bdda5fe14d477 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -1195,6 +1195,11 @@ def test_class_definition_same_name_diff_methods(self): self.assertSourceEqual(mod2.cls296, 296, 298) self.assertSourceEqual(mod2.cls310, 310, 312) + def test_generator_frame(self): + frame = mod2.generator_frame() + assert frame is not None + self.assertSourceEqual(frame, 375, 379) + class TestNoEOL(GetSourceBase): def setUp(self): self.tempdir = TESTFN + '_dir'