summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2020-12-04 21:44:53 (GMT)
committerGitHub <noreply@github.com>2020-12-04 21:44:53 (GMT)
commita4e7d5f750e06e31a80a83c2af02b1a40cecd0ff (patch)
treef2ffb6db1be56eea428b87f1b04fe83482dd60cb /Lib
parent3b14f18205b17d1634e21bd7bc48152247590d9f (diff)
downloadcpython-a4e7d5f750e06e31a80a83c2af02b1a40cecd0ff.zip
cpython-a4e7d5f750e06e31a80a83c2af02b1a40cecd0ff.tar.gz
cpython-a4e7d5f750e06e31a80a83c2af02b1a40cecd0ff.tar.bz2
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@yahoo.com>
Diffstat (limited to 'Lib')
-rw-r--r--Lib/inspect.py7
-rw-r--r--Lib/test/test_inspect.py11
2 files changed, 17 insertions, 1 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 95144a9..7ffc7d3 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -837,7 +837,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 39248e7..b81af87 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -713,6 +713,17 @@ class TestBuggyCases(GetSourceBase):
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)