From: Maximiliano Curia <maxy@debian.org>
Date: Sat, 16 Aug 2026 12:00:00 +0200
Subject: Don't use Py_TPFLAGS_MANAGED_WEAKREF on types without
 Py_TPFLAGS_HAVE_GC

Revert ebecd174 plus regression test.

Forwarded: no
Last-Update: 2026-08-16
---
Index: dbus-python/dbus_bindings/conn-internal.h
===================================================================
--- dbus-python.orig/dbus_bindings/conn-internal.h
+++ dbus-python/dbus_bindings/conn-internal.h
@@ -42,10 +42,8 @@ typedef struct {
      */
     PyObject *object_paths;
 
-#if !DBUSPY_PY_VERSION_AT_LEAST(3, 12, 0, 0)
     /* Weak-references list to make Connections weakly referenceable */
     PyObject *weaklist;
-#endif
 
     dbus_bool_t has_mainloop;
 } Connection;
Index: dbus-python/dbus_bindings/conn.c
===================================================================
--- dbus-python.orig/dbus_bindings/conn.c
+++ dbus-python/dbus_bindings/conn.c
@@ -238,9 +238,7 @@ DBusPyConnection_NewConsumingDBusConnect
     self->has_mainloop = (mainloop != Py_None);
     self->conn = NULL;
     self->filters = PyList_New(0);
-#if !DBUSPY_PY_VERSION_AT_LEAST(3, 12, 0, 0)
     self->weaklist = NULL;
-#endif
     if (!self->filters) goto err;
     self->object_paths = PyDict_New();
     if (!self->object_paths) goto err;
@@ -394,10 +392,7 @@ static void Connection_tp_dealloc(Connec
     /* avoid clobbering any pending exception */
     PyErr_Fetch(&et, &ev, &etb);
 
-#if !DBUSPY_PY_VERSION_AT_LEAST(3, 12, 0, 0)
-    if (self->weaklist)
-#endif
-    {
+    if (self->weaklist) {
         PyObject_ClearWeakRefs((PyObject *)self);
     }
 
@@ -460,19 +455,12 @@ PyTypeObject DBusPyConnection_Type = {
     0,                      /*tp_getattro*/
     0,                      /*tp_setattro*/
     0,                      /*tp_as_buffer*/
-#if DBUSPY_PY_VERSION_AT_LEAST(3, 12, 0, 0)
-    Py_TPFLAGS_MANAGED_WEAKREF |
-#endif
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     Connection_tp_doc,      /*tp_doc*/
     0,                      /*tp_traverse*/
     0,                      /*tp_clear*/
     0,                      /*tp_richcompare*/
-#if DBUSPY_PY_VERSION_AT_LEAST(3, 12, 0, 0)
-    0,                      /*tp_weaklistoffset*/
-#else
     offsetof(Connection, weaklist),   /*tp_weaklistoffset*/
-#endif
     0,                      /*tp_iter*/
     0,                      /*tp_iternext*/
     DBusPyConnection_tp_methods,  /*tp_methods*/
Index: dbus-python/dbus_bindings/server.c
===================================================================
--- dbus-python.orig/dbus_bindings/server.c
+++ dbus-python/dbus_bindings/server.c
@@ -38,10 +38,8 @@ typedef struct {
     /* The Connection subtype for which this Server is a factory */
     PyObject *conn_class;
 
-#if !DBUSPY_PY_VERSION_AT_LEAST(3, 12, 0, 0)
     /* Weak-references list to make server weakly referenceable */
     PyObject *weaklist;
-#endif
 
     PyObject *mainloop;
 } Server;
@@ -425,9 +423,7 @@ Server_tp_new(PyTypeObject *cls, PyObjec
         return NULL;
     }
 
-#if !DBUSPY_PY_VERSION_AT_LEAST(3, 12, 0, 0)
     ((Server *)self)->weaklist = NULL;
-#endif
     TRACE(self);
 
     return self;
@@ -442,10 +438,7 @@ static void Server_tp_dealloc(Server *se
     /* avoid clobbering any pending exception */
     PyErr_Fetch(&et, &ev, &etb);
 
-#if !DBUSPY_PY_VERSION_AT_LEAST(3, 12, 0, 0)
-    if (self->weaklist)
-#endif
-    {
+    if (self->weaklist) {
         PyObject_ClearWeakRefs((PyObject *)self);
     }
 
@@ -577,19 +570,12 @@ PyTypeObject DBusPyServer_Type = {
     0,                      /*tp_getattro*/
     0,                      /*tp_setattro*/
     0,                      /*tp_as_buffer*/
-#if DBUSPY_PY_VERSION_AT_LEAST(3, 12, 0, 0)
-    Py_TPFLAGS_MANAGED_WEAKREF |
-#endif
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     Server_tp_doc,          /*tp_doc*/
     0,                      /*tp_traverse*/
     0,                      /*tp_clear*/
     0,                      /*tp_richcompare*/
-#if DBUSPY_PY_VERSION_AT_LEAST(3, 12, 0, 0)
-    0,                      /*tp_weaklistoffset*/
-#else
     offsetof(Server, weaklist),   /*tp_weaklistoffset*/
-#endif
     0,                      /*tp_iter*/
     0,                      /*tp_iternext*/
     DBusPyServer_tp_methods,/*tp_methods*/
Index: dbus-python/test/test-client.py
===================================================================
--- dbus-python.orig/test/test-client.py
+++ dbus-python/test/test-client.py
@@ -110,6 +110,22 @@ class TestDBusBindings(unittest.TestCase
         del bus
         self.assertTrue(ref() is None)
 
+    def testWeakRefsToBaseConnection(self):
+        # dbus.SessionBus() is a Python subclass, which always has
+        # Py_TPFLAGS_HAVE_GC; the C types do not, so they need their own
+        # coverage. Marking a non-GC type Py_TPFLAGS_MANAGED_WEAKREF makes
+        # CPython look for the weakref slot in the PyGC_Head that was never
+        # allocated, which reads and writes off the front of the object.
+        address = os.environ['DBUS_SESSION_BUS_ADDRESS']
+        conn = _dbus_bindings.Connection(address)
+        try:
+            ref = weakref.ref(conn)
+            self.assertTrue(ref() is conn)
+        finally:
+            conn.close()
+        del conn
+        self.assertTrue(ref() is None)
+
     def testInterfaceKeyword(self):
         #test dbus_interface parameter
         print(self.remote_object.Echo("dbus_interface on Proxy test Passed", 
