From 6a68d189a316678190f05bbc678aad7a426a9451 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Thu, 3 Dec 2020 22:17:31 +0000 Subject: [PATCH 1/3] bpo-17735: inspect.findsource raises OsError instead of IndexError when co_lineno is larger than length of file (can happen if file was updated since import) --- Lib/inspect.py | 7 ++++++- Lib/test/test_inspect.py | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index 073a79d97acd2d..9150ac104dcb73 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -868,7 +868,12 @@ def findsource(object): lnum = object.co_firstlineno - 1 pat = re.compile(r'^(\s*def\s)|(\s*async\s+def\s)|(.*(? 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 172e6bf6cd8a63..c81d828b57ece9 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -712,6 +712,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) From 497385a45d9f4ca4589ff04eb89c1d36c7d85a32 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 3 Dec 2020 22:22:25 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2020-12-03-22-22-24.bpo-17735.Qsaaue.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-12-03-22-22-24.bpo-17735.Qsaaue.rst 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 00000000000000..b2d0479caa62ac --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-12-03-22-22-24.bpo-17735.Qsaaue.rst @@ -0,0 +1 @@ +:func:`inspect.findsource` raises OsError instead of IndexError when co_lineno of code object is larger than the file length (can happen if the file was edited after the module was imported). \ No newline at end of file From 41ca25647e5e1d7754007871c92d4ed74038bac2 Mon Sep 17 00:00:00 2001 From: Tal Einat <532281+taleinat@users.noreply.github.com> Date: Fri, 4 Dec 2020 22:46:50 +0200 Subject: [PATCH 3/3] reword NEWS entry --- .../next/Library/2020-12-03-22-22-24.bpo-17735.Qsaaue.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 index b2d0479caa62ac..655781e3d2eddb 100644 --- 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 @@ -1 +1,4 @@ -:func:`inspect.findsource` raises OsError instead of IndexError when co_lineno of code object is larger than the file length (can happen if the file was edited after the module was imported). \ No newline at end of file +: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.