From fd6c7d5307923f22d75417928c26a2f7948908d8 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 29 Apr 2021 13:08:20 +0100 Subject: [PATCH 1/3] Show frame.f_lineno as None, rather than -1, if there is no line number. --- Lib/test/test_exceptions.py | 11 ++++++++++- Objects/frameobject.c | 8 +++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 590935cb6cd624..3810108e356637 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -2081,7 +2081,10 @@ def lineno_after_raise(self, f, line): while t.tb_next: t = t.tb_next frame = t.tb_frame - self.assertEqual(frame.f_lineno-frame.f_code.co_firstlineno, line) + if line is None: + self.assertEqual(frame.f_lineno, line) + else: + self.assertEqual(frame.f_lineno-frame.f_code.co_firstlineno, line) def test_lineno_after_raise_simple(self): def simple(): @@ -2153,6 +2156,12 @@ def after_with(): pass self.lineno_after_raise(after_with, 2) + def test_missing_lineno_shows_as_none(self): + def f(): + 1/0 + self.lineno_after_raise(f, 1) + f.__code__ = f.__code__.replace(co_linetable=b'\x04\x80\xff\x80') + self.lineno_after_raise(f, None) if __name__ == '__main__': unittest.main() diff --git a/Objects/frameobject.c b/Objects/frameobject.c index b0487c2b68811b..74d2f9268f0e53 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -53,7 +53,13 @@ PyFrame_GetLineNumber(PyFrameObject *f) static PyObject * frame_getlineno(PyFrameObject *f, void *closure) { - return PyLong_FromLong(PyFrame_GetLineNumber(f)); + int lineno = PyFrame_GetLineNumber(f); + if (lineno < 0) { + Py_RETURN_NONE; + } + else { + return PyLong_FromLong(PyFrame_GetLineNumber(f)); + } } static PyObject * From 9bd01865679cb68a6967eb0107d955d5a5b22cf3 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 29 Apr 2021 13:13:33 +0100 Subject: [PATCH 2/3] Add NEWS --- .../Core and Builtins/2021-04-29-13-11-44.bpo-43933.mvoV6O.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2021-04-29-13-11-44.bpo-43933.mvoV6O.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-04-29-13-11-44.bpo-43933.mvoV6O.rst b/Misc/NEWS.d/next/Core and Builtins/2021-04-29-13-11-44.bpo-43933.mvoV6O.rst new file mode 100644 index 00000000000000..8d11a8cb3dab3d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-04-29-13-11-44.bpo-43933.mvoV6O.rst @@ -0,0 +1,3 @@ +If the current position in a frame has no line number then set the f_lineno +attribute to None, instead of -1, to conform to PEP 626. This should not +normally be possible, but might occur in some unusual circumstances. From 275291608cc364e5e6e35ea26540a08ad846cbbb Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 29 Apr 2021 19:02:37 +0100 Subject: [PATCH 3/3] Don't recompute line number. --- Objects/frameobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 74d2f9268f0e53..5920ed86fd9230 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -58,7 +58,7 @@ frame_getlineno(PyFrameObject *f, void *closure) Py_RETURN_NONE; } else { - return PyLong_FromLong(PyFrame_GetLineNumber(f)); + return PyLong_FromLong(lineno); } }