Package: src:dbus-python Version: 1.4.0-1 User: [email protected] Usertags: python3.15
Hi!
While rebuilding packages against Python 3.15 we found that dbus-python
failed to build from source due to failing tests. All the tests were
saying something like:
test: dbus-python:standalone
start time: 10:20:31
duration: 0.05s
result: exit status 1
command:
DBUS_TEST_TMPDIR=/build/reproducible-path/dbus-python-1.4.0/build-3.15/test
DBUS_TOP_SRCDIR=/build/reproducible-path/dbus-python-1.4.0
DBUS_PYTHON_VERSION=1.4.0 MALLOC_PERTURB_=171
UBSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1
PYTHONPATH=/build/reproducible-path/dbus-python-1.4.0:/build/reproducible-path/dbus-python-1.4.0/test:/build/reproducible-path/dbus-python-1.4.0/build-3.15:/build/reproducible-path/dbus-python-1.4.0/build-3.15/test
MSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1
ASAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1
DBUS_TEST_UNINSTALLED=1 DBUS_FATAL_WARNINGS=1 MESON_TEST_ITERATION=1
DBUS_TOP_BUILDDIR=/build/reproducible-path/dbus-python-1.4.0/build-3.15
/usr/bin/dbus-run-session --config-file
/build/reproducible-path/dbus-python-1.4.0/build-3.15/test/tmp-session-bus.conf
-- /usr/bin/python3.15
/build/reproducible-path/dbus-python-1.4.0/build-3.15/../test/test-standalone.py
----------------------------------- stderr -----------------------------------
Traceback (most recent call last):
File
"/build/reproducible-path/dbus-python-1.4.0/build-3.15/../test/test-standalone.py",
line 39, in <module>
import _dbus_bindings
SystemError: type _dbus_bindings.Connection has the Py_TPFLAGS_MANAGED_WEAKREF
flag but not Py_TPFLAGS_HAVE_GC flag
The problem seems to be caused by the fact that the Connection is a
GenericAlloc that's missing the PyGC_Head header header, this is now detected in
Python 3.15 (see: https://github.com/python/cpython/issues/134786).
The weakref was introduced by ebecd174 but the previous mechanism still
works, so I'm reverting ebecd174 and adding a regression test that
should fail in python 3.12 to 3.14.
Happy hacking,
--
"Backtracking algorithms are nondeterministic, not in the sense of being
random, but in the sense of having free will."
-- Robert W. Floyd Saludos /\/\ /\ >< `/
From: Maximiliano Curia <[email protected]> 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",
signature.asc
Description: PGP signature

