8000 gh-117281: Change weakref repr() to fully qualified name (#117285) · python/cpython@8ef9892 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8ef9892

Browse files
authored
gh-117281: Change weakref repr() to fully qualified name (#117285)
Use the fully qualified type name in repr() of weakref.ref and weakref.proxy types. Fix a crash in proxy_repr() when the reference is dead. Add also test_ref_repr() and test_proxy_repr().
1 parent 8987a5c commit 8ef9892

File tree

2 files changed

+57
-8
lines changed

2 files changed

+57
-8
lines changed

Lib/test/test_weakref.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,33 @@ def test_basic_ref(self):
116116
del o
117117
repr(wr)
118118

119+
@support.cpython_only
120+
def test_ref_repr(self):
121+
obj = C()
122+
ref = weakref.ref(obj)
123+
self.assertRegex(repr(ref),
124+
rf"<weakref at 0x[0-9a-fA-F]+; "
125+
rf"to '{C.__module__}.{C.__qualname__}' "
126+
rf"at 0x[0-9a-fA-F]+>")
127+
128+
obj = None
129+
gc_collect()
130+
self.assertRegex(repr(ref),
131+
rf'<weakref at 0x[0-9a-fA-F]+; dead>')
132+
133+
# test type with __name__
134+
class WithName:
135+
@property
136+
def __name__(self):
137+
return "custom_name"
138+
139+
obj2 = WithName()
140+
ref2 = weakref.ref(obj2)
141+
self.assertRegex(repr(ref2),
142+
rf"<weakref at 0x[0-9a-fA-F]+; "
143+
rf"to '{WithName.__module__}.{WithName.__qualname__}' "
144+
rf"at 0x[0-9a-fA-F]+ \(custom_name\)>")
145+
119146
def test_repr_failure_gh99184(self):
120147
class MyConfig(dict):
121148
def __getattr__(self, x):
@@ -195,6 +222,20 @@ def check(proxy):
195222
self.assertRaises(ReferenceError, bool, ref3)
196223
self.assertEqual(self.cbcalled, 2)
197224

225+
@support.cpython_only
226+
def test_proxy_repr(self):
227+
obj = C()
228+
ref = weakref.proxy(obj, self.callback)
229+
self.assertRegex(repr(ref),
230+
rf"<weakproxy at 0x[0-9a-fA-F]+; "
231+
rf"to '{C.__module__}.{C.__qualname__}' "
232+
rf"at 0x[0-9a-fA-F]+>")
233+
234+
obj = None
235+
gc_collect()
236+
self.assertRegex(repr(ref),
237+
rf'<weakproxy at 0x[0-9a-fA-F]+; dead>')
238+
198239
def check_basic_ref(self, factory):
199240
o = factory()
200241
ref = weakref.ref(o)

Objects/weakrefobject.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,13 @@ weakref_repr(PyObject *self)
177177
PyObject *repr;
178178
if (name == NULL || !PyUnicode_Check(name)) {
179179
repr = PyUnicode_FromFormat(
180-
"<weakref at %p; to '%s' at %p>",
181-
self, Py_TYPE(obj)->tp_name, obj);
180+
"<weakref at %p; to '%T' at %p>",
181+
self, obj, obj);
182182
}
183183
else {
184184
repr = PyUnicode_FromFormat(
185-
"<weakref at %p; to '%s' at %p (%U)>",
186-
self, Py_TYPE(obj)->tp_name, obj, name);
185+
"<weakref at %p; to '%T' at %p (%U)>",
186+
self, obj, obj, name);
187187
}
188188
Py_DECREF(obj);
189189
Py_XDECREF(name);
@@ -471,10 +471,18 @@ static PyObject *
471471
proxy_repr(PyObject *proxy)
472472
{
473473
PyObject *obj = _PyWeakref_GET_REF(proxy);
474-
PyObject *repr = PyUnicode_FromFormat(
475-
"<weakproxy at %p to %s at %p>",
476-
proxy, Py_TYPE(obj)->tp_name, obj);
477-
Py_DECREF(obj);
474+
PyObject *repr;
475+
if (obj != NULL) {
476+
repr = PyUnicode_FromFormat(
477+
"<weakproxy at %p; to '%T' at %p>",
478+
proxy, obj, obj);
479+
Py_DECREF(obj);
480+
}
481+
else {
482+
repr = PyUnicode_FromFormat(
483+
"<weakproxy at %p; dead>",
484+
proxy);
485+
}
478486
return repr;
479487
}
480488

0 commit comments

Comments
 (0)
0