Skip to content

Commit a4e7d5f

Browse files
bpo-17735: inspect.findsource now raises OSError when co_lineno is out of range (GH-23633)
This can happen when a file was edited after it was imported. (cherry picked from commit 2e0760b) Co-authored-by: Irit Katriel <[email protected]>
1 parent 3b14f18 commit a4e7d5f

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

Lib/inspect.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,12 @@ def findsource(object):
837837
lnum = object.co_firstlineno - 1
838838
pat = re.compile(r'^(\s*def\s)|(\s*async\s+def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
839839
while lnum > 0:
840-
if pat.match(lines[lnum]): break
840+
try:
841+
line = lines[lnum]
842+
except IndexError:
843+
raise OSError('lineno is out of bounds')
844+
if pat.match(line):
845+
break
841846
lnum = lnum - 1
842847
return lines, lnum
843848
raise OSError('could not find code object')

Lib/test/test_inspect.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,17 @@ def test_findsource_without_filename(self):
713713
self.assertRaises(IOError, inspect.findsource, co)
714714
self.assertRaises(IOError, inspect.getsource, co)
715715

716+
def test_findsource_with_out_of_bounds_lineno(self):
717+
mod_len = len(inspect.getsource(mod))
718+
src = '\n' * 2* mod_len + "def f(): pass"
719+
co = compile(src, mod.__file__, "exec")
720+
g, l = {}, {}
721+
eval(co, g, l)
722+
func = l['f']
723+
self.assertEqual(func.__code__.co_firstlineno, 1+2*mod_len)
724+
with self.assertRaisesRegex(IOError, "lineno is out of bounds"):
725+
inspect.findsource(func)
726+
716727
def test_getsource_on_method(self):
717728
self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
718729

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
:func:`inspect.findsource` now raises :exc:`OSError` instead of
2+
:exc:`IndexError` when :attr:`co_lineno` of a code object is greater than the
3+
file length. This can happen, for example, when a file is edited after it was
4+
imported. PR by Irit Katriel.

0 commit comments

Comments
 (0)