[Python-checkins] bpo-17735: inspect.findsource now raises OSError when co_lineno is out of range (GH-23633)
taleinat
webhook-mailer at python.org
Fri Dec 4 17:42:07 EST 2020
https://github.com/python/cpython/commit/d1f07419c7560ed3ba52ba4f667f4eec9b5fe95d
commit: d1f07419c7560ed3ba52ba4f667f4eec9b5fe95d
branch: 3.9
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: taleinat <532281+taleinat at users.noreply.github.com>
date: 2020-12-05T00:41:58+02:00
summary:
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 2e0760bb2edb595050aff82f236cd32b44d3dfb3)
Co-authored-by: Irit Katriel <iritkatriel at yahoo.com>
files:
A Misc/NEWS.d/next/Library/2020-12-03-22-22-24.bpo-17735.Qsaaue.rst
M Lib/inspect.py
M Lib/test/test_inspect.py
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 6ca91e401a5ea..18bed9028ed8a 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -864,7 +864,12 @@ def findsource(object):
lnum = object.co_firstlineno - 1
pat = re.compile(r'^(\s*def\s)|(\s*async\s+def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
while lnum > 0:
- if pat.match(lines[lnum]): break
+ 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.py b/Lib/test/test_inspect.py
index 05485a0bc0575..d9e26a3033667 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -710,6 +710,17 @@ def test_findsource_without_filename(self):
self.assertRaises(IOError, inspect.findsource, co)
self.assertRaises(IOError, inspect.getsource, co)
+ def test_findsource_with_out_of_bounds_lineno(self):
+ mod_len = len(inspect.getsource(mod))
+ src = '\n' * 2* mod_len + "def f(): pass"
+ co = compile(src, mod.__file__, "exec")
+ g, l = {}, {}
+ eval(co, g, l)
+ func = l['f']
+ self.assertEqual(func.__code__.co_firstlineno, 1+2*mod_len)
+ with self.assertRaisesRegex(IOError, "lineno is out of bounds"):
+ inspect.findsource(func)
+
def test_getsource_on_method(self):
self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
diff --git a/Misc/NEWS.d/next/Library/2020-12-03-22-22-24.bpo-17735.Qsaaue.rst b/Misc/NEWS.d/next/Library/2020-12-03-22-22-24.bpo-17735.Qsaaue.rst
new file mode 100644
index 0000000000000..655781e3d2edd
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-12-03-22-22-24.bpo-17735.Qsaaue.rst
@@ -0,0 +1,4 @@
+:func:`inspect.findsource` now raises :exc:`OSError` instead of
+:exc:`IndexError` when :attr:`co_lineno` of a code object is greater than the
+file length. This can happen, for example, when a file is edited after it was
+imported. PR by Irit Katriel.
More information about the Python-checkins
mailing list