8000 bpo-32468: Better frame repr() (#5067) · python/cpython@1470914 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1470914

Browse files
authored
bpo-32468: Better frame repr() (#5067)
bpo-32468: Better frame repr()
1 parent 0a37a30 commit 1470914

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

Lib/test/test_frame.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import re
12
import types
23
import unittest
34
import weakref
@@ -159,5 +160,45 @@ def test_locals_clear_locals(self):
159160
self.assertEqual(inner.f_locals, {})
160161

161162

163+
class ReprTest(unittest.TestCase):
164+
"""
165+
Tests for repr(frame).
166+
"""
167+
168+
def test_repr(self):
169+
def outer():
170+
x = 5
171+
y = 6
172+
def inner():
173+
z = x + 2
174+
1/0
175+
t = 9
176+
return inner()
177+
178+
offset = outer.__code__.co_firstlineno
179+
try:
180+
outer()
181+
except ZeroDivisionError as e:
182+
tb = e.__traceback__
183+
frames = []
184+
while tb:
185+
frames.append(tb.tb_frame)
186+
tb = tb.tb_next
187+
else:
188+
self.fail("should have raised")
189+
190+
f_this, f_outer, f_inner = frames
191+
file_repr = re.escape(repr(__file__))
192+
self.assertRegex(repr(f_this),
193+
r"^<frame at 0x[0-9a-fA-F]+, file %s, line %d, code test_repr>$"
194+
% (file_repr, offset + 23))
195+
self.assertRegex(repr(f_outer),
196+
r"^<frame at 0x[0-9a-fA-F]+, file %s, line %d, code outer>$"
197+
% (file_repr, offset + 7))
198+
self.assertRegex(repr(f_inner),
199+
r"^<frame at 0x[0-9a-fA-F]+, file %s, line %d, code inner>$"
200+
% (file_repr, offset + 5))
201+
202+
162203
if __name__ == "__main__":
163204
unittest.main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve frame repr() to mention filename, code name and current line number.

Objects/frameobject.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,15 @@ frame_sizeof(PyFrameObject *f)
547547
PyDoc_STRVAR(sizeof__doc__,
548548
"F.__sizeof__() -> size of F in memory, in bytes");
549549

550+
static PyObject *
551+
frame_repr(PyFrameObject *f)
552+
{
553+
int lineno = PyFrame_GetLineNumber(f);
554+
return PyUnicode_FromFormat(
555+
"<frame at %p, file %R, line %d, code %S>",
556+
f, f->f_code->co_filename, lineno, f->f_code->co_name);
557+
}
558+
550559
static PyMethodDef frame_methods[] = {
551560
{"clear", (PyCFunction)frame_clear, METH_NOARGS,
552561
clear__doc__},
@@ -565,7 +574,7 @@ PyTypeObject PyFrame_Type = {
565574
0, /* tp_getattr */
566575
0, /* tp_setattr */
567576
0, /* tp_reserved */
568-
0, /* tp_repr */
577+
(reprfunc)frame_repr, /* tp_repr */
569578
0, /* tp_as_number */
570579
0, /* tp_as_sequence */
571580
0, /* tp_as_mapping */

0 commit comments

Comments
 (0)
0