]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-17735: inspect.findsource now raises OSError when co_lineno is out of range ...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 4 Dec 2020 21:44:53 +0000 (13:44 -0800)
committerGitHub <noreply@github.com>
Fri, 4 Dec 2020 21:44:53 +0000 (13:44 -0800)
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>
Lib/inspect.py
Lib/test/test_inspect.py
Misc/NEWS.d/next/Library/2020-12-03-22-22-24.bpo-17735.Qsaaue.rst [new file with mode: 0644]

index 95144a97b41f252e89186aea9116bf59f6f4935d..7ffc7d31bd8a6a9b64c24f6057092f82a1fada29 100644 (file)
@@ -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')
index 39248e7802485b2ba7bf8597907bf4266a1eb648..b81af87e5661b521cc82eb83b525c1cec22605a4 100644 (file)
@@ -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)
 
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 (file)
index 0000000..655781e
--- /dev/null
@@ -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.