]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-117281: Change weakref repr() to fully qualified name (#117285)
authorVictor Stinner <vstinner@python.org>
Wed, 3 Apr 2024 10:18:05 +0000 (12:18 +0200)
committerGitHub <noreply@github.com>
Wed, 3 Apr 2024 10:18:05 +0000 (12:18 +0200)
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().

Lib/test/test_weakref.py
Objects/weakrefobject.c

index 4cdd66d3769e0ca48beba9452098cd11d58b50b4..d6470fb6919cfd22750dda9e5e8d02e32dc93541 100644 (file)
@@ -116,6 +116,33 @@ class ReferencesTestCase(TestBase):
         del o
         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):
         class MyConfig(dict):
             def __getattr__(self, x):
@@ -195,6 +222,20 @@ class ReferencesTestCase(TestBase):
         self.assertRaises(ReferenceError, bool, ref3)
         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):
         o = factory()
         ref = weakref.ref(o)
index b7b29064151609f4c1536db783771046c2e4a1ac..d8dd6aea3aff022b94faff5e1231dd6bc6b0571a 100644 (file)
@@ -177,13 +177,13 @@ weakref_repr(PyObject *self)
     PyObject *repr;
     if (name == NULL || !PyUnicode_Check(name)) {
         repr = PyUnicode_FromFormat(
-            "<weakref at %p; to '%s' at %p>",
-            self, Py_TYPE(obj)->tp_name, obj);
+            "<weakref at %p; to '%T' at %p>",
+            self, obj, obj);
     }
     else {
         repr = PyUnicode_FromFormat(
-            "<weakref at %p; to '%s' at %p (%U)>",
-            self, Py_TYPE(obj)->tp_name, obj, name);
+            "<weakref at %p; to '%T' at %p (%U)>",
+            self, obj, obj, name);
     }
     Py_DECREF(obj);
     Py_XDECREF(name);
@@ -471,10 +471,18 @@ static PyObject *
 proxy_repr(PyObject *proxy)
 {
     PyObject *obj = _PyWeakref_GET_REF(proxy);
-    PyObject *repr = PyUnicode_FromFormat(
-        "<weakproxy at %p to %s at %p>",
-        proxy, Py_TYPE(obj)->tp_name, obj);
-    Py_DECREF(obj);
+    PyObject *repr;
+    if (obj != NULL) {
+        repr = PyUnicode_FromFormat(
+            "<weakproxy at %p; to '%T' at %p>",
+            proxy, obj, obj);
+        Py_DECREF(obj);
+    }
+    else {
+        repr = PyUnicode_FromFormat(
+            "<weakproxy at %p; dead>",
+            proxy);
+    }
     return repr;
 }