Package: src:rdkit
Version: 202603.4-2.2
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 rdkit only builds against the default Python
version.

This is a problem because it doesn't build the module for Python 3.15,
making packages that depend on it also unable to build for Python 3.15
(for example, mdanse).

To fix this, I've made a change that makes rdkit build against all
supported Python versions. I'm attaching a debdiff with this and the
changes made for #1146588.

I've applied the fix in the sandbox [1] to verify that both rdkit and
the packages that depend on it build 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/

--
"Can you imagine what I would do if I could do all I can?" -- Sun Tzu
Saludos /\/\ /\ >< `/
diff --git a/debian/changelog b/debian/changelog
index ea95655e9..d3a27215b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+rdkit (202603.4-2.1) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload.
+  * Avoid catch2 thread safety issues
+  * Build the extensions for every supported python version.
+
+ -- Maximiliano Curia <[email protected]>  Thu, 17 Sep 2026 09:08:16 +0200
+
 rdkit (202603.4-2) unstable; urgency=medium
 
   * Backport modified upstream commit to fix FTBFS with eigen3 >= 5.0.0
@@ -22,8 +30,8 @@ rdkit (202603.2-1) unstable; urgency=medium
 
   * New upstream version 202603.2.
   * debian/patches/NoDownloads.patch: Removed GraphMol/MolInterchange hunk,
-    functionality removed upstream. 
-  * debian/patches/sphinx_compile_fixes.patch: Refreshed. 
+    functionality removed upstream.
+  * debian/patches/sphinx_compile_fixes.patch: Refreshed.
   * debian/patches/fix_inchi_linking.patch: Likewise.
   * debian/patches/better_enums.patch: Likewise.
   * debian/control, debian/control.in (python3-rdkit/Depends): Added
@@ -100,7 +108,7 @@ rdkit (202503.1-1) unstable; urgency=medium
 
   * New upstream release.
   * debian/patches/disable_riscv64_timeout_tests.patch: Refreshed.
-  * debian/patches/better_enums.patch: Vendorize better_enums header. 
+  * debian/patches/better_enums.patch: Vendorize better_enums header.
 
  -- Michael Banck <[email protected]>  Sun, 06 Apr 2025 00:16:38 +0200
 
@@ -114,9 +122,9 @@ rdkit (202409.6-2) unstable; urgency=medium
 rdkit (202409.6-1) unstable; urgency=medium
 
   * New upstream point release.
-  * debian/patches/disable_pgsql_test.patch: Refreshed. 
+  * debian/patches/disable_pgsql_test.patch: Refreshed.
   * debian/control.in, debian/control (Build-Depends): Add architecture-is-
-    little-endian (Closes: #1093086). 
+    little-endian (Closes: #1093086).
 
  -- Michael Banck <[email protected]>  Tue, 04 Mar 2025 01:24:41 +0100
 
@@ -296,7 +304,7 @@ rdkit (202209.3-1) unstable; urgency=medium
 
   * New upstream point release.
   * debian/patches/postgres_Makefile_fixes.patch: Updated, removed one hunnk
-    that got applied upstream. 
+    that got applied upstream.
 
  -- Michael Banck <[email protected]>  Sat, 14 Jan 2023 13:24:33 +0100
 
@@ -311,7 +319,7 @@ rdkit (202209.1-1) unstable; urgency=medium
   * debian/patches/postgres_Makefile_fixes.patch: Compile clang bytecode with
     -std=c++17.
   * debian/patches/postgres_Makefile_fixes.patch: Update RDKit version number.
-  * debian/gbp.conf: Set import-orig filter for upstream .gitattributes. 
+  * debian/gbp.conf: Set import-orig filter for upstream .gitattributes.
 
  -- Michael Banck <[email protected]>  Sat, 05 Nov 2022 10:43:38 +0100
 
@@ -360,7 +368,7 @@ rdkit (202109.2-1) unstable; urgency=medium
 
   * New upstream release.
     + Includes updated PostgreSQL regression outputs (Closes: #1000579).
-  * debian/patches/postgres_compile_fixes.patch: Refreshed. 
+  * debian/patches/postgres_compile_fixes.patch: Refreshed.
   * debian/patches/postgres_Makefile_fixes.patch: Add RDK_TOOLKIT_VERSION
     definition, hardcoded to current release for now.
   * debian/rules (DH_AUTO_CONFIGURE_OPTS): Added -DRDK_INSTALL_COMIC_FONTS=OFF
@@ -373,7 +381,7 @@ rdkit (202109.2-1) unstable; urgency=medium
 rdkit (202103.5-1) unstable; urgency=medium
 
   * New upstream release.
-  * debian/patches/sphinx_compile_fixes.patch: Refreshed. 
+  * debian/patches/sphinx_compile_fixes.patch: Refreshed.
   * debian/control (postgresql-PGVERSION-rdkit): Bump PostgreSQL version to 14
     (Closes: #997745).
 
@@ -392,7 +400,7 @@ rdkit (202009.5-1) unstable; urgency=medium
   * debian/watch: Updated.
   * debian/patches/sphinx_compile_fixes.patch: Drop hunk that got applied
     upstream.
-  * debian/patches/postgres_compile_fixes.patch: Refreshed. 
+  * debian/patches/postgres_compile_fixes.patch: Refreshed.
 
  -- Michael Banck <[email protected]>  Fri, 14 May 2021 23:46:40 +0200
 
@@ -517,7 +525,7 @@ rdkit (201903.1-2) unstable; urgency=medium
 rdkit (201903.1-1) unstable; urgency=medium
 
   * New upstream release.
-  * debian/copyright: Removed Files-Excluded, no longer needed. 
+  * debian/copyright: Removed Files-Excluded, no longer needed.
   * debian/patches/NoDownloads.patch: Remove CoordGen-specific hunks and add
     another CoordGen-specific hunk that drops the template.mae template
     support.
@@ -556,7 +564,7 @@ rdkit (201809.1+dfsg-7) unstable; urgency=medium
 rdkit (201809.1+dfsg-6) unstable; urgency=medium
 
   * debian/patches/fix_coordgen_include_path.patch: New patch, fixes the
-    include path for system-installed coordgen headers. 
+    include path for system-installed coordgen headers.
 
  -- Michael Banck <[email protected]>  Thu, 31 Jan 2019 14:20:27 +0100
 
diff --git a/debian/control b/debian/control
index 76033e518..752dbe785 100644
--- a/debian/control
+++ b/debian/control
@@ -33,7 +33,7 @@ Build-Depends: architecture-is-64-bit,
                libsqlite3-dev,
                pandoc,
                postgresql-server-dev-all,
-               python3-dev,
+               python3-all-dev,
                python3-myst-parser,
                python3-numpy-dev,
                python3-pandas,
diff --git a/debian/control.in b/debian/control.in
index f7b49b998..baa24dde6 100644
--- a/debian/control.in
+++ b/debian/control.in
@@ -33,7 +33,7 @@ Build-Depends: architecture-is-64-bit,
                libsqlite3-dev,
                pandoc,
                postgresql-server-dev-all,
-               python3-dev,
+               python3-all-dev,
                python3-myst-parser,
                python3-numpy-dev,
                python3-pandas,
diff --git a/debian/patches/fix_distgeom_threadsafety.patch b/debian/patches/fix_distgeom_threadsafety.patch
new file mode 100644
index 000000000..e5cd3f56a
--- /dev/null
+++ b/debian/patches/fix_distgeom_threadsafety.patch
@@ -0,0 +1,29 @@
+Description: Avoid Catch2 assertions in multithreaded test helper
+ Catch2 assertion macros are not thread-safe (prior catch2 3.12) and cause
+ assertion failures in OutputRedirect when invoked concurrently across worker
+ threads.
+Author: Maximiliano Curia <[email protected]>
+Forwarded: no
+--- a/Code/GraphMol/DistGeomHelpers/testDgeomHelpers.cpp
++++ b/Code/GraphMol/DistGeomHelpers/testDgeomHelpers.cpp
+@@ -943,17 +943,17 @@ void runblock(const std::vector<std::sha
+           .useLegacyImplementation = legacyETKDG};
+       std::vector<int> cids =
+           DGeomHelpers::EmbedMultipleConfs(*mol, 10, params);
+-      REQUIRE(cids.size() == 10);
++      TEST_ASSERT(cids.size() == 10);
+       std::unique_ptr<ForceFields::ForceField> field(
+           UFF::constructForceField(*mol, 100, cids[0]));
+-      REQUIRE(field);
++      TEST_ASSERT(field);
+       field->initialize();
+       double eng = field->calcEnergy();
+       if (!feq(eng, energies[i])) {
+         std::cerr << i << " iter " << j << " " << energies[i] << " != " << eng
+                   << std::endl;
+       }
+-      CHECK(feq(eng, energies[i]));
++      TEST_ASSERT(feq(eng, energies[i]));
+     }
+   }
+ }
diff --git a/debian/patches/fix_substruct_threadsafety.patch b/debian/patches/fix_substruct_threadsafety.patch
new file mode 100644
index 000000000..8fe8c2cad
--- /dev/null
+++ b/debian/patches/fix_substruct_threadsafety.patch
@@ -0,0 +1,16 @@
+Description: Avoid Catch2 assertions in substruct multithreaded test helper
+ Catch2 assertion macros are not thread-safe and cause assertion failures in
+ OutputRedirect when invoked concurrently across worker threads.
+Author: Maximiliano Curia <[email protected]>
+Forwarded: no
+--- a/Code/GraphMol/Substruct/testSubstructMatch.cpp
++++ b/Code/GraphMol/Substruct/testSubstructMatch.cpp
+@@ -541,7 +541,7 @@ void runblock(const std::vector<std::uni
+       MatchVectType matchV;
+       bool found = SubstructMatch(*mol, *query, matchV);
+ 
+-      CHECK(found == hits[i]);
++      TEST_ASSERT(found == hits[i]);
+     }
+   }
+ }
diff --git a/debian/patches/python_with_soabi.patch b/debian/patches/python_with_soabi.patch
new file mode 100644
index 000000000..efa60a7cd
--- /dev/null
+++ b/debian/patches/python_with_soabi.patch
@@ -0,0 +1,14 @@
+Description: Build Python extension modules with SOABI suffix for multi-Python support
+Author: Maximiliano Curia <[email protected]>
+
+--- a/Code/cmake/Modules/RDKitUtils.cmake
++++ b/Code/cmake/Modules/RDKitUtils.cmake
+@@ -190,7 +190,7 @@ macro(rdkit_python_extension)
+   CAR(RDKPY_NAME ${RDKPY_DEFAULT_ARGS})
+   CDR(RDKPY_SOURCES ${RDKPY_DEFAULT_ARGS})
+   if(RDK_BUILD_PYTHON_WRAPPERS)
+-    Python3_add_library(${RDKPY_NAME} MODULE ${RDKPY_SOURCES})
++    Python3_add_library(${RDKPY_NAME} MODULE WITH_SOABI ${RDKPY_SOURCES})
+     set_target_properties(${RDKPY_NAME} PROPERTIES PREFIX "")
+ 
+     if(WIN32)
diff --git a/debian/patches/series b/debian/patches/series
index f307b3ba9..7209e96a5 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -14,3 +14,6 @@ fix-shebangs.patch
 remove-badges.patch
 d8ce92b61ce356bc2764e13f0d4b9a5df48094c5.patch
 fab08afd7000ac6000358a7c79e95cc1940e1c39.patch
+fix_distgeom_threadsafety.patch
+fix_substruct_threadsafety.patch
+python_with_soabi.patch
diff --git a/debian/rules b/debian/rules
index 773ec51b9..7b4848f00 100755
--- a/debian/rules
+++ b/debian/rules
@@ -20,8 +20,8 @@ export DOCDIR       := $(CURDIR)/debian/rdkit-doc/usr/share/doc/rdkit/
 
 export RDBASE       := $(CURDIR)
 
-PY3VERS = $(shell py3versions -v -d)
-PY3 = $(shell which python$(PY3VERS))
+PY3VERS = $(shell py3versions -s)
+PY3DEF = $(shell py3versions -d)
 export DEBTMP := $(CURDIR)/debian/tmp
 
 DH_AUTO_CONFIGURE_OPTS := -DCMAKE_BUILD_TYPE=None -DCMAKE_SKIP_RPATH=ON \
@@ -91,18 +91,23 @@ override_dh_auto_clean:
 	rdkit/ML/Data/test_data/testquant.qdat.pkl
 	$(RM) Code/RDGeneral/versions.h rdkit/sping/tests/testallps.ps
 	dh_auto_clean
+	$(RM) -rf $(CURDIR)/build-*
 	$(RM) -rf $(CURDIR)/Code/PgSQL/rdkit/build-*
 
 override_dh_auto_configure:
-	dh_auto_configure -- $(DH_AUTO_CONFIGURE_OPTS) -DPYTHON_EXECUTABLE=$(PY3) ../
+	for py in $(PY3VERS); do \
+		dh_auto_configure --builddirectory=build-$$py -- $(DH_AUTO_CONFIGURE_OPTS) -DPython3_EXECUTABLE=/usr/bin/$$py -DPYTHON_EXECUTABLE=/usr/bin/$$py; \
+	done
 	for v in $$(pg_buildext supported-versions); do \
 		(mkdir -p Code/PgSQL/rdkit/build-$$v && cd Code/PgSQL/rdkit/build-$$v && cmake -DPostgreSQL_CONFIG=/usr/lib/postgresql/$$v/bin/pg_config -DRDK_PGSQL_STATIC=OFF -DPostgreSQL_TYPE_INCLUDE_DIR="/usr/include/postgresql/$$v/server" -DCMAKE_VERBOSE_MAKEFILE=1 -DRDKit_CodeDir=../../../Code ../); \
 	done
 
 override_dh_auto_build:
-	dh_auto_build
+	for py in $(PY3VERS); do \
+		dh_auto_build --builddirectory=build-$$py; \
+	done
 	for v in $$(pg_buildext supported-versions); do \
-		(cd Code/PgSQL/rdkit/build-$$v && make || $$(cat ../../../../obj-*/Code/PgSQL/rdkit/CMakeFiles/rdkit.dir/link.txt | sed -e 's#\.\./\.\./#../../../../obj-*/Code/#g')); \
+		(cd Code/PgSQL/rdkit/build-$$v && make || $$(cat ../../../../build-$(PY3DEF)/Code/PgSQL/rdkit/CMakeFiles/rdkit.dir/link.txt | sed -e 's#\.\./\.\./#../../../../build-$(PY3DEF)/Code/#g')); \
 	done
 	(cd $(CURDIR)/Code; doxygen doxygen/doxygen.config)
 	(cd $(CURDIR)/Docs/Book; RDBASE=$(CURDIR) $(MAKE) html)
@@ -110,18 +115,25 @@ override_dh_auto_build:
 	# (cd $(CURDIR)/Docs/Book; RDBASE=$(CURDIR) $(MAKE) latexpdf)
 
 override_dh_auto_install:
-	dh_auto_install
+	for py in $(filter-out $(PY3DEF),$(PY3VERS)) $(PY3DEF); do \
+		dh_auto_install --builddirectory=build-$$py; \
+	done
 
 override_dh_install:
-	mkdir -p $(DEBTMP)/usr/lib/python3
-	mv $(DEBTMP)/usr/lib/python$(PY3VERS)/site-packages $(DEBTMP)/usr/lib/python3/dist-packages
-	$(RM) -rf $(DEBTMP)/usr/lib/python$(PY3VERS)
+	mkdir -p $(DEBTMP)/usr/lib/python3/dist-packages
+	for py in $(PY3VERS); do \
+		for dir in site-packages dist-packages; do \
+			if [ -d $(DEBTMP)/usr/lib/$$py/$$dir ]; then \
+				cp -a $(DEBTMP)/usr/lib/$$py/$$dir/* $(DEBTMP)/usr/lib/python3/dist-packages/; \
+			fi; \
+		done; \
+		$(RM) -rf $(DEBTMP)/usr/lib/$$py; \
+	done
 	ln -sf /usr/share/fonts/truetype/freefont/FreeSans.ttf $(DEBTMP)/usr/lib/python3/dist-packages/rdkit/Chem/Draw/FreeSans.ttf
 	dh_install -ppython3-rdkit /usr/lib/python3
 	$(RM) -rf $(DEBTMP)/usr/lib/python3/dist-packages/rdkit/docs/
 	$(RM) -rf $(DEBTMP)/usr/share/RDKit/Projects/__pycache__
 	$(RM) -rf $(DEBTMP)/usr/share/RDKit/Projects/DbCLI/__pycache__
-	dh_numpy3
 	dh_install
 	for v in $$(pg_buildext supported-versions); do \
 		mkdir -p debian/postgresql-$$v-rdkit/usr/lib/postgresql/$$v/lib/ debian/postgresql-$$v-rdkit/usr/share/postgresql/$$v/extension/; \
@@ -149,7 +161,9 @@ override_dh_python3:
 
 ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
 override_dh_auto_test:
-	cp -r rdkit obj-*/
-	find $(CURDIR) -name rdchem.so
-	PYTHONPATH=$(wildcard $(CURDIR)/obj-*/):$(wildcard $(CURDIR)/obj-*/)/rdkit/Chem/ LD_LIBRARY_PATH="$(wildcard $(CURDIR)/obj-*/)/lib:$(LD_LIBRARY_PATH)" dh_auto_test
+	for py in $(PY3VERS); do \
+		cp -r rdkit build-$$py/; \
+		PYTHONPATH=$(CURDIR)/build-$$py:$(CURDIR)/build-$$py/rdkit/Chem LD_LIBRARY_PATH="$(CURDIR)/build-$$py/lib:$(LD_LIBRARY_PATH)" dh_auto_test --builddirectory=build-$$py; \
+	done
 endif
+
diff --git a/debian/tests/control b/debian/tests/control
index a1b36e426..1927706f2 100644
--- a/debian/tests/control
+++ b/debian/tests/control
@@ -10,6 +10,7 @@ Restrictions:
 
 Depends:
  @,
+ python3-all,
 Tests:
  importcheck,
 Restrictions:
diff --git a/debian/tests/importcheck b/debian/tests/importcheck
index 83b4d26e0..8faf05750 100644
--- a/debian/tests/importcheck
+++ b/debian/tests/importcheck
@@ -1,4 +1,10 @@
-#!/usr/bin/env python3
+#!/bin/sh
+set -e
+
+cd "${AUTOPKGTEST_TMP:-/tmp}"
+
+for py in $(py3versions -s); do
+    echo "=== Testing $py ==="
+    $py -c "import rdkit; from rdkit import Chem"
+done
 
-import rdkit
-from rdkit import Chem

Reply via email to