mirror of https://github.com/python/cpython
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().
This commit is contained in:
parent
8987a5c809
commit
8ef98924d3
|
@ -116,6 +116,33 @@ class ReferencesTestCase(TestBase):
|
||||||
del o
|
del o
|
||||||
repr(wr)
|
repr(wr)
|
||||||
|
|
||||||
|
@support.cpython_only
|
||||||
|
def test_ref_repr(self):
|
||||||
|
obj = C()
|
||||||
|
ref = weakref.ref(obj)
|
||||||
|
self.assertRegex(repr(ref),
|
||||||
|
rf"<weakref at 0x[0-9a-fA-F]+; "
|
||||||
|
rf"to '{C.__module__}.{C.__qualname__}' "
|
||||||
|
rf"at 0x[0-9a-fA-F]+>")
|
||||||
|
|
||||||
|
obj = None
|
||||||
|
gc_collect()
|
||||||
|
self.assertRegex(repr(ref),
|
||||||
|
rf'<weakref at 0x[0-9a-fA-F]+; dead>')
|
||||||
|
|
||||||
|
# test type with __name__
|
||||||
|
class WithName:
|
||||||
|
@property
|
||||||
|
def __name__(self):
|
||||||
|
return "custom_name"
|
||||||
|
|
||||||
|
obj2 = WithName()
|
||||||
|
ref2 = weakref.ref(obj2)
|
||||||
|
self.assertRegex(repr(ref2),
|
||||||
|
rf"<weakref at 0x[0-9a-fA-F]+; "
|
||||||
|
rf"to '{WithName.__module__}.{WithName.__qualname__}' "
|
||||||
|
rf"at 0x[0-9a-fA-F]+ \(custom_name\)>")
|
||||||
|
|
||||||
def test_repr_failure_gh99184(self):
|
def test_repr_failure_gh99184(self):
|
||||||
class MyConfig(dict):
|
class MyConfig(dict):
|
||||||
def __getattr__(self, x):
|
def __getattr__(self, x):
|
||||||
|
@ -195,6 +222,20 @@ class ReferencesTestCase(TestBase):
|
||||||
self.assertRaises(ReferenceError, bool, ref3)
|
self.assertRaises(ReferenceError, bool, ref3)
|
||||||
self.assertEqual(self.cbcalled, 2)
|
self.assertEqual(self.cbcalled, 2)
|
||||||
|
|
||||||
|
@support.cpython_only
|
||||||
|
def test_proxy_repr(self):
|
||||||
|
obj = C()
|
||||||
|
ref = weakref.proxy(obj, self.callback)
|
||||||
|
self.assertRegex(repr(ref),
|
||||||
|
rf"<weakproxy at 0x[0-9a-fA-F]+; "
|
||||||
|
rf"to '{C.__module__}.{C.__qualname__}' "
|
||||||
|
rf"at 0x[0-9a-fA-F]+>")
|
||||||
|
|
||||||
|
obj = None
|
||||||
|
gc_collect()
|
||||||
|
self.assertRegex(repr(ref),
|
||||||
|
rf'<weakproxy at 0x[0-9a-fA-F]+; dead>')
|
||||||
|
|
||||||
def check_basic_ref(self, factory):
|
def check_basic_ref(self, factory):
|
||||||
o = factory()
|
o = factory()
|
||||||
ref = weakref.ref(o)
|
ref = weakref.ref(o)
|
||||||
|
|
|
@ -177,13 +177,13 @@ weakref_repr(PyObject *self)
|
||||||
PyObject *repr;
|
PyObject *repr;
|
||||||
if (name == NULL || !PyUnicode_Check(name)) {
|
if (name == NULL || !PyUnicode_Check(name)) {
|
||||||
repr = PyUnicode_FromFormat(
|
repr = PyUnicode_FromFormat(
|
||||||
"<weakref at %p; to '%s' at %p>",
|
"<weakref at %p; to '%T' at %p>",
|
||||||
self, Py_TYPE(obj)->tp_name, obj);
|
self, obj, obj);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
repr = PyUnicode_FromFormat(
|
repr = PyUnicode_FromFormat(
|
||||||
"<weakref at %p; to '%s' at %p (%U)>",
|
"<weakref at %p; to '%T' at %p (%U)>",
|
||||||
self, Py_TYPE(obj)->tp_name, obj, name);
|
self, obj, obj, name);
|
||||||
}
|
}
|
||||||
Py_DECREF(obj);
|
Py_DECREF(obj);
|
||||||
Py_XDECREF(name);
|
Py_XDECREF(name);
|
||||||
|
@ -471,10 +471,18 @@ static PyObject *
|
||||||
proxy_repr(PyObject *proxy)
|
proxy_repr(PyObject *proxy)
|
||||||
{
|
{
|
||||||
PyObject *obj = _PyWeakref_GET_REF(proxy);
|
PyObject *obj = _PyWeakref_GET_REF(proxy);
|
||||||
PyObject *repr = PyUnicode_FromFormat(
|
PyObject *repr;
|
||||||
"<weakproxy at %p to %s at %p>",
|
if (obj != NULL) {
|
||||||
proxy, Py_TYPE(obj)->tp_name, obj);
|
repr = PyUnicode_FromFormat(
|
||||||
Py_DECREF(obj);
|
"<weakproxy at %p; to '%T' at %p>",
|
||||||
|
proxy, obj, obj);
|
||||||
|
Py_DECREF(obj);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
repr = PyUnicode_FromFormat(
|
||||||
|
"<weakproxy at %p; dead>",
|
||||||
|
proxy);
|
||||||
|
}
|
||||||
return repr;
|
return repr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue