diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2020-12-04 21:44:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-04 21:44:53 (GMT) |
commit | a4e7d5f750e06e31a80a83c2af02b1a40cecd0ff (patch) | |
tree | f2ffb6db1be56eea428b87f1b04fe83482dd60cb /Lib | |
parent | 3b14f18205b17d1634e21bd7bc48152247590d9f (diff) | |
download | cpython-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.py | 7 | ||||
-rw-r--r-- | Lib/test/test_inspect.py | 11 |
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) |