Package: src:dm-tree Version: 0.1.9-1 User: [email protected] Usertags: python3.15 Tags: patch, ftbfs, forky, sid Severity: important
Hi! While rebuilding the python related packages against the Python 3.15rc2 version we found that dm-tree fails to build from source [1]. The error is: pybind11::handle::dec_ref() is being called while the GIL is either not held or invalid. Please see https://pybind11.readthedocs.io/en/stable/advanced/misc.html#common-sources-of-global-interpreter-lock-errors for debugging advice. If you are convinced there is no bug in your code, you can #define PYBIND11_NO_ASSERT_GIL_HELD_INCREF_DECREF to disable this check. In that case you have to ensure this #define is consistently used for all translation units linked into a given pybind11 extension, otherwise there will be ODR violations. The failing pybind11::handle::dec_ref() call was triggered on a ABCMeta object. terminate called after throwing an instance of 'std::runtime_error' what(): pybind11::handle::dec_ref() PyGILState_Check() failure. Aborted E: pybuild pybuild:485: test: plugin pyproject failed with: exit code=134: cd /build/reproducible-path/dm-tree-0.1.9/.pybuild/cpython3_3.15_dm-tree/build; python3.15 -m pytest To fix the issues I had to apply two fixes: - Backport c9be91f8 Add support for python 3.14 [2]. Which was already included in version 0.1.10. - Add patch to Release static Python objects to avoid dec_ref during finalization. This is because in Python 3.15 this triggers the PyGILState_Check() assertion. I've applied these fixes in the sandbox [3] to verify that it builds successfully, please consider applying the patch to support the upcoming 3.15 version. Setting the severity to important for now. Once Python 3.15 is released, it will be added to python3-defaults and this bug will become release critical. Happy hacking, [1]: https://debusine.debian.net/debian/r-python-python3.15/artifact/4597612/ [2]: https://github.com/google-deepmind/tree/commit/c9be91f8a9b84435da0d1e25b1d4bb4e249bc612 [3]: https://debusine.debian.net/debian/r-python-python3.15/ -- "Can you imagine what I would do if I could do all I can?" -- Sun Tzu Saludos /\/\ /\ >< `/
From: Mathieu Scheltienne <[email protected]> Date: Thu, 26 Mar 2026 20:29:20 +0100 Subject: Add support for python 3.14 Origin: upstream, https://github.com/google-deepmind/tree/commit/c9be91f8a9b84435da0d1e25b1d4bb4e249bc612 --- tree/tree.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) --- a/tree/tree.cc +++ b/tree/tree.cc @@ -15,12 +15,13 @@ #include "tree.h" #include <functional> +#include <atomic> #include <memory> +#include <mutex> #include <string> #include <unordered_map> // logging -#include "absl/memory/memory.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include <pybind11/pybind11.h> @@ -50,7 +51,7 @@ const int kMaxItemsInCache = 1024; -bool WarnedThatSetIsNotSequence = false; +std::atomic<bool> WarnedThatSetIsNotSequence{false}; bool IsString(PyObject* o) { return PyBytes_Check(o) || PyByteArray_Check(o) || PyUnicode_Check(o); @@ -114,6 +115,7 @@ auto* type = Py_TYPE(o); { + std::lock_guard<std::mutex> lock(mutex_); auto it = type_to_sequence_map_.find(type); if (it != type_to_sequence_map_.end()) { return it->second; @@ -133,6 +135,7 @@ // that are eligible for decref. As a precaution, we limit the size of the // map to 1024. { + std::lock_guard<std::mutex> lock(mutex_); if (type_to_sequence_map_.size() < kMaxItemsInCache) { Py_INCREF(type); type_to_sequence_map_.insert({type, check_result}); @@ -145,29 +148,30 @@ private: std::function<int(PyObject*)> ternary_predicate_; std::unordered_map<PyTypeObject*, bool> type_to_sequence_map_; + mutable std::mutex mutex_; }; py::object GetCollectionsSequenceType() { static py::object type = - py::module::import("collections.abc").attr("Sequence"); + py::module_::import("collections.abc").attr("Sequence"); return type; } py::object GetCollectionsMappingType() { static py::object type = - py::module::import("collections.abc").attr("Mapping"); + py::module_::import("collections.abc").attr("Mapping"); return type; } py::object GetCollectionsMappingViewType() { static py::object type = - py::module::import("collections.abc").attr("MappingView"); + py::module_::import("collections.abc").attr("MappingView"); return type; } py::object GetWraptObjectProxyTypeUncached() { try { - return py::module::import("wrapt").attr("ObjectProxy"); + return py::module_::import("wrapt").attr("ObjectProxy"); } catch (const py::error_already_set& e) { if (e.matches(PyExc_ImportError)) return py::none(); throw e; @@ -722,13 +726,13 @@ ValueIteratorPtr GetValueIterator(PyObject* nested) { if (PyDict_Check(nested)) { - return absl::make_unique<DictValueIterator>(nested); + return std::make_unique<DictValueIterator>(nested); } else if (IsMappingHelper(nested)) { - return absl::make_unique<MappingValueIterator>(nested); + return std::make_unique<MappingValueIterator>(nested); } else if (IsAttrsHelper(nested)) { - return absl::make_unique<AttrsValueIterator>(nested); + return std::make_unique<AttrsValueIterator>(nested); } else { - return absl::make_unique<SequenceValueIterator>(nested); + return std::make_unique<SequenceValueIterator>(nested); } } @@ -741,7 +745,7 @@ return py::reinterpret_steal<py::object>(ptr); } -PYBIND11_MODULE(_tree, m) { +PYBIND11_MODULE(_tree, m, py::mod_gil_not_used()) { // Resolve `wrapt.ObjectProxy` at import time to avoid doing // imports during function calls. tree::GetWraptObjectProxyType();
From: Maximiliano Curia <[email protected]> Date: Tue, 8 Sep 2026 10:48:00 +0200 Subject: Release static Python objects to avoid dec_ref during finalization. --- tree/tree.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) Index: python-dm-tree/tree/tree.cc =================================================================== --- python-dm-tree.orig/tree/tree.cc +++ python-dm-tree/tree/tree.cc @@ -151,21 +151,21 @@ class CachedTypeCheck { mutable std::mutex mutex_; }; -py::object GetCollectionsSequenceType() { - static py::object type = - py::module_::import("collections.abc").attr("Sequence"); +py::handle GetCollectionsSequenceType() { + static py::handle type = + py::object(py::module_::import("collections.abc").attr("Sequence")).release(); return type; } -py::object GetCollectionsMappingType() { - static py::object type = - py::module_::import("collections.abc").attr("Mapping"); +py::handle GetCollectionsMappingType() { + static py::handle type = + py::object(py::module_::import("collections.abc").attr("Mapping")).release(); return type; } -py::object GetCollectionsMappingViewType() { - static py::object type = - py::module_::import("collections.abc").attr("MappingView"); +py::handle GetCollectionsMappingViewType() { + static py::handle type = + py::object(py::module_::import("collections.abc").attr("MappingView")).release(); return type; }

