From 499c5e6a03b3997f32266815e47b7c71fb48d7b6 Mon Sep 17 00:00:00 2001 From: "Hans J. Johnson" Date: Sat, 20 Jun 2026 12:06:59 -0500 Subject: [PATCH 1/4] COMP: Support SWIG 4.4.1 multi-phase init in Python wrapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ITK packs several SWIG modules per shared library and injects C that calls PyInit__Python() and stores the return directly in sys.modules. SWIG 4.4 (PEP 489 multi-phase init) makes PyInit_* return a raw PyModuleDef rather than a populated module, so the proxy fails at import with 'moduledef' object has no attribute 'delete_SwigPyIterator'. Detect a returned def at runtime and instantiate it via PyModule_FromDefAndSpec + PyModule_ExecDef; the single-phase (<=4.3) path is unchanged. All APIs used are Limited-API-safe (>=3.5). Pin the abi3 floor to a single cached source of truth (_ITK_MINIMUM_SUPPORTED_LIMITED_API_VERSION = 3.11) shared by the Limited-API auto-detect and the USE_SABI setting, so 3.11+ builds are abi3 and load on 3.11. Assisted-by: Claude Code — root-cause analysis and local 3.11/3.13 validation --- CMake/ITKSetPython3Vars.cmake | 12 +++++- Wrapping/Generators/Python/CMakeLists.txt | 37 +++++++++++++++++-- .../macro_files/itk_end_wrap_module.cmake | 2 +- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/CMake/ITKSetPython3Vars.cmake b/CMake/ITKSetPython3Vars.cmake index 061fde1476e..e3a9cd01e6d 100644 --- a/CMake/ITKSetPython3Vars.cmake +++ b/CMake/ITKSetPython3Vars.cmake @@ -58,7 +58,14 @@ else() set(ITK_WRAP_PYTHON_VERSION "${Python3_VERSION}") # start section to define package components based on LIMITED_API support and choices - set(_ITK_MINIMUM_SUPPORTED_LIMITED_API_VERSION 3.11) + # Cached so the abi3 floor is a single source of truth shared with the module + # wrapping macros (itk_end_wrap_module.cmake USE_SABI). + set( + _ITK_MINIMUM_SUPPORTED_LIMITED_API_VERSION + 3.11 + CACHE INTERNAL + "Minimum Python minor version for the abi3 / Limited API floor" + ) # Force ITK_WRAP_PYTHON_VERSION if SKBUILD_SABI_COMPONENT requests it string( @@ -173,7 +180,8 @@ else() endif() unset(_missing_required_component) unset(_python_find_components) - unset(_ITK_MINIMUM_SUPPORTED_LIMITED_API_VERSION) + # _ITK_MINIMUM_SUPPORTED_LIMITED_API_VERSION is cached (INTERNAL) and intentionally + # left set so itk_end_wrap_module.cmake can pin USE_SABI to the same floor. # end section to define package components based on LIMITED_API support and choices if(DEFINED _specified_Python3_EXECUTABLE) set( diff --git a/Wrapping/Generators/Python/CMakeLists.txt b/Wrapping/Generators/Python/CMakeLists.txt index e4fd7bad312..0efaade4d1b 100644 --- a/Wrapping/Generators/Python/CMakeLists.txt +++ b/Wrapping/Generators/Python/CMakeLists.txt @@ -495,10 +495,39 @@ macro(itk_end_wrap_submodule_python group_name) PyObject * ${base_name}AlreadyImported = PyDict_GetItemString(sysModules, \"itk._${base_name}Python\"); if(${base_name}AlreadyImported == NULL) { - PyImport_AddModule(\"itk._${base_name}Python\"); - PyObject * ${base_name}Module = PyInit__${base_name}Python(); - PyDict_SetItemString(sysModules, \"itk._${base_name}Python\", ${base_name}Module); - SWIG_Py_DECREF( ${base_name}Module); + PyObject * ${base_name}Init = PyInit__${base_name}Python(); + PyObject * ${base_name}Module = ${base_name}Init; + if (${base_name}Init != NULL && !PyModule_Check(${base_name}Init)) + { + // SWIG >= 4.4 uses PEP 489 multi-phase init: PyInit_* returns a + // PyModuleDef that must be instantiated against a spec, not used directly. + PyObject * ${base_name}Spec = NULL; + PyObject * ${base_name}Machinery = PyImport_ImportModule(\"importlib.machinery\"); + if (${base_name}Machinery != NULL) + { + PyObject * ${base_name}SpecType = PyObject_GetAttrString(${base_name}Machinery, \"ModuleSpec\"); + if (${base_name}SpecType != NULL) + { + ${base_name}Spec = PyObject_CallFunction(${base_name}SpecType, \"sO\", \"itk._${base_name}Python\", Py_None); + SWIG_Py_DECREF(${base_name}SpecType); + } + SWIG_Py_DECREF(${base_name}Machinery); + } + ${base_name}Module = PyModule_FromDefAndSpec((PyModuleDef *)${base_name}Init, ${base_name}Spec); + if (${base_name}Spec != NULL) + { + SWIG_Py_DECREF(${base_name}Spec); + } + if (${base_name}Module != NULL) + { + PyModule_ExecDef(${base_name}Module, (PyModuleDef *)${base_name}Init); + } + } + if (${base_name}Module != NULL) + { + PyDict_SetItemString(sysModules, \"itk._${base_name}Python\", ${base_name}Module); + SWIG_Py_DECREF(${base_name}Module); + } } " ) diff --git a/Wrapping/macro_files/itk_end_wrap_module.cmake b/Wrapping/macro_files/itk_end_wrap_module.cmake index bfb53dd9796..04bde56dc4b 100644 --- a/Wrapping/macro_files/itk_end_wrap_module.cmake +++ b/Wrapping/macro_files/itk_end_wrap_module.cmake @@ -487,7 +487,7 @@ ${DO_NOT_WAIT_FOR_THREADS_CALLS} set( _Python3_ABI_SETTINGS USE_SABI - ${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR} + ${_ITK_MINIMUM_SUPPORTED_LIMITED_API_VERSION} WITH_SOABI ) else() From 5ac235be0e4a6c5978a7ed40553d206cf07c56ad Mon Sep 17 00:00:00 2001 From: "Hans J. Johnson" Date: Sat, 20 Jun 2026 12:07:03 -0500 Subject: [PATCH 2/4] COMP: Build ITK Python wrapping with pixi-supplied SWIG 4.4.1 and CastXML Add swig (>=4.4.1), castxml, and ccache to the python pixi feature and pass ITK_USE_SYSTEM_SWIG/ITK_USE_SYSTEM_CASTXML in configure-python, so wrapping uses the conda-forge toolchain instead of the internal download/build. --- pixi.lock | 442 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 7 + 2 files changed, 449 insertions(+) diff --git a/pixi.lock b/pixi.lock index b26f798af57..0bea1db9e08 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1591,6 +1591,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/castxml-0.7.0-hde8d07d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.6-hedf47ba_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-4.1.2-hc85cc9f_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-hb991d5c_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda @@ -1600,11 +1602,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-he448592_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-he663afc_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h95f728e_12.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1aa0949_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-38_h4a7cf45_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-38_h0358290_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.8-default_h99862b1_16.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.16.0-h4e3cde8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda @@ -1615,7 +1619,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-38_h47877c9_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.8-hf7376ad_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda @@ -1627,15 +1634,20 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.1-h171cf75_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.4-py313hf6604e3_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.4-h26f9b46_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/swig-4.4.1-h7a96c5f_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda @@ -1661,6 +1673,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_8.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-ares-1.34.5-h86ecc28_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-compiler-1.11.0-hdceaead_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/castxml-0.7.0-ha3e84ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.6-h185addb_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cmake-4.1.2-hc9d863e_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-gcc-specs-14.3.0-h92dcf8a_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cxx-compiler-1.11.0-h7b35c40_0.conda @@ -1670,11 +1684,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx-14.3.0-ha28f942_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_impl_linux-aarch64-14.3.0-h72695c8_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_linux-aarch64-14.3.0-hda493e9_12.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.21.3-h50a48e9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.44-hd32f0e1_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.9.0-38_haddc8a3_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.9.0-38_hd72aa62_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp20.1-20.1.8-default_he95a3c9_16.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcurl-8.16.0-h7bfdcfb_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libev-4.33-h31becfc_2.conda @@ -1685,7 +1701,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h87db57e_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-he277a41_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libhiredis-1.3.0-h5ad3122_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.9.0-38_h88aeb00_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm20-20.1.8-hfd2ba90_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.1-h86ecc28_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-h86ecc28_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnghttp2-1.67.0-ha888d0e_0.conda @@ -1697,15 +1716,20 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hf1166c9_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.2-h3e4203c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuv-1.51.0-he30d5cf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.1-h79dcc73_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.1-h825857f_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.1-hdc560ac_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.3.4-py313h11e5ff7_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.5.4-h8e36d6e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pcre2-10.47-hf841c20_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.13.9-h4c0d347_101_cp313.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.2-h8382b9d_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rhash-1.4.6-h86ecc28_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/swig-4.4.1-h512d76c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h5688188_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xxhash-0.8.3-hd794028_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-hbcf94c1_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda @@ -1740,6 +1764,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.5-hf13058a_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/c-compiler-1.11.0-h7a00415_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/castxml-0.7.0-hb171174_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.6-h894318c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools-1024.3-h67a6458_9.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_osx-64-1024.3-llvm19_1_h3b512aa_9.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/clang-19-19.1.7-default_hc369343_5.conda @@ -1758,6 +1784,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-38_he492b99_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-38_h9b27e0a_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp19.1-19.1.7-default_hc369343_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp20.1-20.1.8-default_h9399c5b_16.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.16.0-h7dd4100_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.4-h3d58e20_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-devel-19.1.7-h7c275be_1.conda @@ -1767,9 +1794,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h306097a_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-h336fb69_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-38_h859234e_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm19-19.1.7-h56e7563_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm20-20.1.8-h56e7563_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda @@ -1787,12 +1816,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.1-h0ba0a54_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.3.4-py313ha99c057_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.5.4-h230baf5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pcre2-10.47-h13923f0_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.9-h17c18a5_101_cp313.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/rhash-1.4.6-h6e16a3a_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/sigtool-0.1.3-h88f4db0_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-64/swig-4.4.1-hdac4ec2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tapi-1300.6.5-h390ca13_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/xxhash-0.8.3-h13e91ac_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h8210216_2.conda osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda @@ -1811,6 +1843,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.5-h5505292_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/castxml-0.7.0-hfc9ce51_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.6-h414bf82_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1024.3-hd01ab73_9.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1024.3-llvm19_1_h8c76c84_9.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_h73dfc95_5.conda @@ -1830,6 +1864,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-38_h51639a9_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-38_hb0561ab_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_h73dfc95_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp20.1-20.1.8-default_hf3020a7_16.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.16.0-hdece5d2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.4-hf598326_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_1.conda @@ -1839,9 +1874,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-hfcf01ff_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-h742603c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.3.0-h286801f_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-38_hd9741b5_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm20-20.1.8-h8e0c9ce_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda @@ -1859,12 +1896,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.1-h4f10f1e_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.3.4-py313h9771d21_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.4-h5503f6c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.47-h30297fc_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.9-hfc2f54d_101_cp313.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-0.1.3-h44b9a77_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/swig-4.4.1-h4366dc5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1300.6.5-h03f4b80_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xxhash-0.8.3-haa4e116_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-h6491c7d_2.conda win-64: - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-h4c7d964_0.conda @@ -1882,6 +1922,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/vswhere-3.1.7-h40126e0_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/castxml-0.7.0-ha22e26b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ccache-4.13.6-h7fd822b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cmake-4.1.2-hdcbee5b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cxx-compiler-1.11.0-h1c1089f_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda @@ -1893,6 +1935,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h1383e82_7.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libgfortran5-15.2.0-hf2bee02_7.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h1383e82_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhiredis-1.3.0-he0c23c2_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.1-default_h64bd3f2_1002.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-38_hf9ab0e9_mkl.conda @@ -1911,7 +1954,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.1-h477610d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.3.4-py313hce7ae62_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.5.4-h725018a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.9-h09917c8_101_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/swig-4.4.1-h9b0202b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-hd094cb3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda @@ -1919,6 +1964,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_32.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xxhash-0.8.3-hbba6f48_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-hbeecb71_2.conda packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -2154,6 +2200,20 @@ packages: license: LGPL-2.1-only or MPL-1.1 size: 978114 timestamp: 1741554591855 +- conda: https://conda.anaconda.org/conda-forge/linux-64/castxml-0.7.0-hde8d07d_0.conda + sha256: f5fa7216baac5b21c13e834e4b176f940621abcf56b9b00f559bdf88644706fa + md5: 710546db9e8bcdc45c5c7221b2d203c4 + depends: + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - libgcc >=14 + - libllvm20 >=20.1.8,<20.2.0a0 + - libclang-cpp20.1 >=20.1.8,<20.2.0a0 + license: Apache-2.0 + license_family: APACHE + run_exports: {} + size: 1020766 + timestamp: 1772089430517 - conda: https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.6-hedf47ba_0.conda sha256: 552639ac2f3d28d93053fa91cd828186730d9ae0a4d7c1dcc40efe8d7cd026ce md5: d66e791d7524770340296e9d34e7f324 @@ -2166,6 +2226,7 @@ packages: - zstd >=1.5.7,<1.6.0a0 license: GPL-3.0-only license_family: GPL + run_exports: {} size: 855698 timestamp: 1777926446042 - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda @@ -2629,6 +2690,9 @@ packages: - libstdcxx >=14 license: MIT license_family: MIT + run_exports: + weak: + - icu >=78.3,<79.0a0 size: 12723451 timestamp: 1773822285671 - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda @@ -2781,6 +2845,21 @@ packages: license_family: BSD size: 17503 timestamp: 1761680091587 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.8-default_h99862b1_16.conda + sha256: 83ef7425c3c5c5b179b6d5accb57acfe1ddf16010727afc642be484b4526044e + md5: ff256a40b66a4b6968075efd741523d5 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libllvm20 >=20.1.8,<20.2.0a0 + - libstdcxx >=14 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libclang-cpp20.1 >=20.1.8,<20.2.0a0 + size: 21300452 + timestamp: 1779374233040 - conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda sha256: 205c4f19550f3647832ec44e35e6d93c8c206782bdd620c1d7cf66237580ff9c md5: 49c553b47ff679a6a1e9fc80b9c5a2d4 @@ -3143,6 +3222,9 @@ packages: - libstdcxx >=13 license: BSD-3-Clause license_family: BSD + run_exports: + weak: + - libhiredis >=1.3.0,<1.4.0a0 size: 140759 timestamp: 1748219397797 - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda @@ -3152,6 +3234,9 @@ packages: - __glibc >=2.17,<3.0.a0 - libgcc >=14 license: LGPL-2.1-only + run_exports: + weak: + - libiconv >=1.18,<2.0a0 size: 790176 timestamp: 1754908768807 - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda @@ -3179,6 +3264,24 @@ packages: license_family: BSD size: 17501 timestamp: 1761680098660 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.8-hf7376ad_1.conda + sha256: bd2981488f63afbc234f6c7759f8363c63faf38dd0f4e64f48ef5a06541c12b4 + md5: eafa8fd1dfc9a107fe62f7f12cabbc9c + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libxml2 + - libxml2-16 >=2.14.5 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libllvm20 >=20.1.8,<20.2.0a0 + size: 43977914 + timestamp: 1757353652788 - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 md5: 1a580f7796c7bf6393fddb8bbbde58dc @@ -3530,6 +3633,23 @@ packages: license_family: MIT size: 556302 timestamp: 1761015637262 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda + sha256: 8331284bf9ae641b70cdc0e5866502dd80055fc3b9350979c74bb1d192e8e09e + md5: 3fdd8d99683da9fe279c2f4cecd1e048 + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=78.1,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - libxml2 2.15.1 + license: MIT + license_family: MIT + run_exports: {} + size: 555747 + timestamp: 1766327145986 - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda sha256: ec0735ae56c3549149eebd7dc22c0bed91fd50c02eaa77ff418613ddda190aa8 md5: e512be7dc1f84966d50959e900ca121f @@ -3545,6 +3665,25 @@ packages: license_family: MIT size: 45283 timestamp: 1761015644057 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda + sha256: 047be059033c394bd32ae5de66ce389824352120b3a7c0eff980195f7ed80357 + md5: 417955234eccd8f252b86a265ccdab7f + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=78.1,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2-16 2.15.1 hca6bf5a_1 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + run_exports: + weak: + - libxml2 + - libxml2-16 >=2.15.1 + size: 45402 + timestamp: 1766327161688 - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 md5: edb0dca6bc32e4f4789199455a1dbeb8 @@ -3725,6 +3864,9 @@ packages: - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD + run_exports: + weak: + - pcre2 >=10.47,<10.48.0a0 size: 1222481 timestamp: 1763655398280 - conda: https://conda.anaconda.org/conda-forge/linux-64/perl-5.32.1-7_hd590300_perl5.conda @@ -3855,6 +3997,21 @@ packages: license_family: MIT size: 193775 timestamp: 1748644872902 +- conda: https://conda.anaconda.org/conda-forge/linux-64/swig-4.4.1-h7a96c5f_0.conda + sha256: 45ec1eedd1de2d7985955290015773a4adc9b8ea95d0f839aaabda2ed075d83c + md5: ce50bd18ea2a92833be8b62881929e23 + depends: + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - pcre2 >=10.47,<10.48.0a0 + constrains: + - swig-abi ==5 + license: GPL-3.0-or-later + license_family: GPL + run_exports: {} + size: 1329174 + timestamp: 1773251886390 - conda: https://conda.anaconda.org/conda-forge/linux-64/texlive-core-20230313-he8f7729_15.conda sha256: c7046cce309c0cec2a4b0e59c4e8530a6f7581903d7b999fc84f9bd07e37472c md5: f1967a2bfb7d45e0739c0e8832d9ffe4 @@ -4145,6 +4302,9 @@ packages: - libgcc >=13 license: BSD-2-Clause license_family: BSD + run_exports: + weak: + - xxhash >=0.8.3,<0.8.4.0a0 size: 108219 timestamp: 1746457673761 - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda @@ -4398,6 +4558,19 @@ packages: license: LGPL-2.1-only or MPL-1.1 size: 966667 timestamp: 1741554768968 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/castxml-0.7.0-ha3e84ed_0.conda + sha256: c3c01516fbd6268ee4151f42798f5fa467e5a3548eef0d47a35c9540cd60b763 + md5: 644b19c2844cb3fb1a7a776dbc24be38 + depends: + - libstdcxx >=14 + - libgcc >=14 + - libllvm20 >=20.1.8,<20.2.0a0 + - libclang-cpp20.1 >=20.1.8,<20.2.0a0 + license: Apache-2.0 + license_family: APACHE + run_exports: {} + size: 1024757 + timestamp: 1772089445719 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.6-h185addb_0.conda sha256: 68ddb4618c6720343e0f4a4de707e3ec09f4c9fdc464070aed91ac4f7bd4bac7 md5: 529eb8e276a92d5d30c924e94c1b8099 @@ -4409,6 +4582,7 @@ packages: - zstd >=1.5.7,<1.6.0a0 license: GPL-3.0-only license_family: GPL + run_exports: {} size: 843745 timestamp: 1777926452238 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cffi-2.0.0-py313h897158f_1.conda @@ -4856,6 +5030,9 @@ packages: - libstdcxx >=14 license: MIT license_family: MIT + run_exports: + weak: + - icu >=78.3,<79.0a0 size: 12837286 timestamp: 1773822650615 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda @@ -4999,6 +5176,20 @@ packages: license_family: BSD size: 17539 timestamp: 1761680168765 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp20.1-20.1.8-default_he95a3c9_16.conda + sha256: 403befc6e10443ba3a48e303ca9fba503f8a98d522c08239e06c37c567fc92d0 + md5: a9b12b5650d566ba204a5725a41986a9 + depends: + - libgcc >=14 + - libllvm20 >=20.1.8,<20.2.0a0 + - libstdcxx >=14 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libclang-cpp20.1 >=20.1.8,<20.2.0a0 + size: 20862034 + timestamp: 1779374601544 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h4f2b762_6.conda sha256: 41b04f995c9f63af8c4065a35931e46cbc2fdd6b9bf7e4c19f90d53cbb2bc8e5 md5: 67828c963b17db7dc989fe5d509ef04a @@ -5331,6 +5522,9 @@ packages: - libstdcxx >=13 license: BSD-3-Clause license_family: BSD + run_exports: + weak: + - libhiredis >=1.3.0,<1.4.0a0 size: 140290 timestamp: 1748220539026 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda @@ -5339,6 +5533,9 @@ packages: depends: - libgcc >=14 license: LGPL-2.1-only + run_exports: + weak: + - libiconv >=1.18,<2.0a0 size: 791226 timestamp: 1754910975665 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d5cf_0.conda @@ -5365,6 +5562,23 @@ packages: license_family: BSD size: 17549 timestamp: 1761680174207 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm20-20.1.8-hfd2ba90_1.conda + sha256: 1a5eb7ebccdc23b0e606f9645cf5b436e01f161c80705bfb34d2793a36846b8f + md5: 36f730da2c88718ea21242a7326292da + depends: + - libgcc >=14 + - libstdcxx >=14 + - libxml2 + - libxml2-16 >=2.14.5 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libllvm20 >=20.1.8,<20.2.0a0 + size: 42749733 + timestamp: 1757353785740 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.1-h86ecc28_2.conda sha256: 498ea4b29155df69d7f20990a7028d75d91dbea24d04b2eb8a3d6ef328806849 md5: 7d362346a479256857ab338588190da0 @@ -5674,6 +5888,22 @@ packages: license_family: MIT size: 875994 timestamp: 1780213408784 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.1-h79dcc73_1.conda + sha256: c76951407554d69dd348151f91cc2dc164efbd679b4f4e77deb2f9aa6eba3c12 + md5: e42758e7b065c34fd1b0e5143752f970 + depends: + - icu >=78.1,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - libxml2 2.15.1 + license: MIT + license_family: MIT + run_exports: {} + size: 599721 + timestamp: 1766327134458 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.1-h8591a01_0.conda sha256: 7a13450bce2eeba8f8fb691868b79bf0891377b707493a527bd930d64d9b98af md5: e7177c6fbbf815da7b215b4cc3e70208 @@ -5703,6 +5933,24 @@ packages: license_family: MIT size: 47192 timestamp: 1761015739999 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.1-h825857f_1.conda + sha256: 9fe997c3e5a8207161d093a5d73f586ae46dc319cb054220086395e150dd1469 + md5: eb4665cdf78fd02d4abc4edf8c15b7b9 + depends: + - icu >=78.1,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2-16 2.15.1 h79dcc73_1 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + run_exports: + weak: + - libxml2 + - libxml2-16 >=2.15.1 + size: 47725 + timestamp: 1766327143205 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda sha256: 5a2c1eeef69342e88a98d1d95bff1603727ab1ff4ee0e421522acd8813439b84 md5: 08aad7cbe9f5a6b460d0976076b6ae64 @@ -5869,6 +6117,9 @@ packages: - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD + run_exports: + weak: + - pcre2 >=10.47,<10.48.0a0 size: 1166552 timestamp: 1763655534263 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/perl-5.32.1-7_h31becfc_perl5.conda @@ -5993,6 +6244,20 @@ packages: license_family: MIT size: 207475 timestamp: 1748644952027 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/swig-4.4.1-h512d76c_0.conda + sha256: ac5e52ae7aededf3aa1489a8b4a47b2210915c2760f25c374dffba2335f014ee + md5: 91c99a0fec455afa9137c1d978445166 + depends: + - libstdcxx >=14 + - libgcc >=14 + - pcre2 >=10.47,<10.48.0a0 + constrains: + - swig-abi ==5 + license: GPL-3.0-or-later + license_family: GPL + run_exports: {} + size: 1399015 + timestamp: 1773251896861 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/texlive-core-20230313-h7479a69_15.conda sha256: df15db9801cdeba1f353add9352896b40d015067121d78326eb37762aac24630 md5: bc4680b033375ee63fe0c808166f463d @@ -6260,6 +6525,9 @@ packages: - libgcc >=13 license: BSD-2-Clause license_family: BSD + run_exports: + weak: + - xxhash >=0.8.3,<0.8.4.0a0 size: 105762 timestamp: 1746457675564 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda @@ -7113,6 +7381,19 @@ packages: license: LGPL-2.1-only or MPL-1.1 size: 896676 timestamp: 1766416262450 +- conda: https://conda.anaconda.org/conda-forge/osx-64/castxml-0.7.0-hb171174_0.conda + sha256: 465108d705ff05850f1ef65ba12edc87d1576922131cd4a1687f89a750330327 + md5: ee04620f071f9b842c1b5b356d48df35 + depends: + - libcxx >=19 + - __osx >=11.0 + - libllvm20 >=20.1.8,<20.2.0a0 + - libclang-cpp20.1 >=20.1.8,<20.2.0a0 + license: Apache-2.0 + license_family: APACHE + run_exports: {} + size: 1017185 + timestamp: 1772089532763 - conda: https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.6-h894318c_0.conda sha256: ff8588dfe87de5e4cc682762997ca8d64e9e3837420bd07411118f34707a762c md5: 8ae9dfcda989b435223605126a97a963 @@ -7124,6 +7405,7 @@ packages: - libhiredis >=1.3.0,<1.4.0a0 license: GPL-3.0-only license_family: GPL + run_exports: {} size: 657026 timestamp: 1777926755291 - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools-1024.3-h67a6458_9.conda @@ -7795,6 +8077,20 @@ packages: license_family: Apache size: 14856234 timestamp: 1759436552121 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp20.1-20.1.8-default_h9399c5b_16.conda + sha256: 6e608b34adcd41a18e8bf8bb1ef3153d6580b9598edc323542e9d8681bf6c04a + md5: c38065ba1fea846f1dd11374fc677f1f + depends: + - __osx >=11.0 + - libcxx >=20.1.8 + - libllvm20 >=20.1.8,<20.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libclang-cpp20.1 >=20.1.8,<20.2.0a0 + size: 14727362 + timestamp: 1779376169143 - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.16.0-h7dd4100_0.conda sha256: faec28271c0c545b6b95b5d01d8f0bbe0a94178edca2f56e93761473077edb78 md5: b905caaffc1753671e1284dcaa283594 @@ -8033,6 +8329,9 @@ packages: - libcxx >=18 license: BSD-3-Clause license_family: BSD + run_exports: + weak: + - libhiredis >=1.3.0,<1.4.0a0 size: 59830 timestamp: 1748219625377 - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda @@ -8090,6 +8389,23 @@ packages: license_family: Apache size: 28801374 timestamp: 1757354631264 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm20-20.1.8-h56e7563_1.conda + sha256: d61976b0938af6025de5907486f6c4686c6192e9842d9fc9873eb7f50815e17d + md5: 862eed3ed84906f3387d15ac20075a0d + depends: + - __osx >=10.13 + - libcxx >=19 + - libxml2 + - libxml2-16 >=2.14.5 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libllvm20 >=20.1.8,<20.2.0a0 + size: 30758108 + timestamp: 1757354844443 - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda sha256: 7e22fd1bdb8bf4c2be93de2d4e718db5c548aa082af47a7430eb23192de6bb36 md5: 8468beea04b9065b9807fc8b9cdc5894 @@ -8562,6 +8878,9 @@ packages: - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD + run_exports: + weak: + - pcre2 >=10.47,<10.48.0a0 size: 1106584 timestamp: 1763655837207 - conda: https://conda.anaconda.org/conda-forge/osx-64/perl-5.32.1-7_h10d778d_perl5.conda @@ -8687,6 +9006,20 @@ packages: license_family: MIT size: 123083 timestamp: 1767045007433 +- conda: https://conda.anaconda.org/conda-forge/osx-64/swig-4.4.1-hdac4ec2_0.conda + sha256: 5f89ae3ec8f2ac47f355838e5071708440807c78afbe68bf5d5719e0d9483197 + md5: 4f5f602a207a0b56d48ada419014b26e + depends: + - libcxx >=19 + - __osx >=11.0 + - pcre2 >=10.47,<10.48.0a0 + constrains: + - swig-abi ==5 + license: GPL-3.0-or-later + license_family: GPL + run_exports: {} + size: 1234602 + timestamp: 1773252006725 - conda: https://conda.anaconda.org/conda-forge/osx-64/tapi-1300.6.5-h390ca13_0.conda sha256: f97372a1c75b749298cb990405a690527e8004ff97e452ed2c59e4bc6a35d132 md5: c6ee25eb54accb3f1c8fc39203acfaf1 @@ -8748,6 +9081,9 @@ packages: - __osx >=10.13 license: BSD-2-Clause license_family: BSD + run_exports: + weak: + - xxhash >=0.8.3,<0.8.4.0a0 size: 108449 timestamp: 1746457796808 - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda @@ -8886,6 +9222,19 @@ packages: license: LGPL-2.1-only or MPL-1.1 size: 900035 timestamp: 1766416416791 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/castxml-0.7.0-hfc9ce51_0.conda + sha256: 5c7885b980e3a55acee9500ed696341cdfd337911d635ce69e88bde42cb0ed4a + md5: 20e240fa69e39c2af78ae9138a1f0e66 + depends: + - __osx >=11.0 + - libcxx >=19 + - libllvm20 >=20.1.8,<20.2.0a0 + - libclang-cpp20.1 >=20.1.8,<20.2.0a0 + license: Apache-2.0 + license_family: APACHE + run_exports: {} + size: 1013942 + timestamp: 1772089510243 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.6-h414bf82_0.conda sha256: ea63ad4cba40ec76439f69d9d396db20c016d5b595c8815efff4497436fb575c md5: 1628795893a799313a719264fd7f2227 @@ -8897,6 +9246,7 @@ packages: - libhiredis >=1.3.0,<1.4.0a0 license: GPL-3.0-only license_family: GPL + run_exports: {} size: 601285 timestamp: 1777926636412 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1024.3-hd01ab73_9.conda @@ -9578,6 +9928,20 @@ packages: license_family: Apache size: 14064699 timestamp: 1776988581784 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp20.1-20.1.8-default_hf3020a7_16.conda + sha256: 67f1e3fb6a44047bc4d1c7d53c883ceb117c579defa88ab76b0ddc3416052bbf + md5: c046cb62d7149b09340c782eb2be3d3a + depends: + - __osx >=11.0 + - libcxx >=20.1.8 + - libllvm20 >=20.1.8,<20.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libclang-cpp20.1 >=20.1.8,<20.2.0a0 + size: 13963413 + timestamp: 1779377618958 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.16.0-hdece5d2_0.conda sha256: f20ce8db8c62f1cdf4d7a9f92cabcc730b1212a7165f4b085e45941cc747edac md5: 0537c38a90d179dcb3e46727ccc5bcc1 @@ -9816,6 +10180,9 @@ packages: - libcxx >=18 license: BSD-3-Clause license_family: BSD + run_exports: + weak: + - libhiredis >=1.3.0,<1.4.0a0 size: 56746 timestamp: 1748219528586 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda @@ -9873,6 +10240,23 @@ packages: license_family: Apache size: 26914852 timestamp: 1757353228286 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm20-20.1.8-h8e0c9ce_1.conda + sha256: 6639cbbde4143b14b666db9dc33beddbf6772317a42d317c8c5162b9524bd24a + md5: 717f1efdf0a0240255c7c34d55889d58 + depends: + - __osx >=11.0 + - libcxx >=19 + - libxml2 + - libxml2-16 >=2.14.5 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libllvm20 >=20.1.8,<20.2.0a0 + size: 28800783 + timestamp: 1757354439972 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda sha256: 0cb92a9e026e7bd4842f410a5c5c665c89b2eb97794ffddba519a626b8ce7285 md5: d6df911d4564d77c4374b02552cb17d1 @@ -10344,6 +10728,9 @@ packages: - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD + run_exports: + weak: + - pcre2 >=10.47,<10.48.0a0 size: 850231 timestamp: 1763655726735 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/perl-5.32.1-7_h4614cfb_perl5.conda @@ -10470,6 +10857,20 @@ packages: license_family: MIT size: 114331 timestamp: 1767045086274 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/swig-4.4.1-h4366dc5_0.conda + sha256: 6491edeb3df94578b016015f78dd80bddc0f85e2624ed9cea79ad9f9f4b240ca + md5: f9a4ce9ad596a0feac7cc7aba8517389 + depends: + - libcxx >=19 + - __osx >=11.0 + - pcre2 >=10.47,<10.48.0a0 + constrains: + - swig-abi ==5 + license: GPL-3.0-or-later + license_family: GPL + run_exports: {} + size: 1189583 + timestamp: 1773252068990 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1300.6.5-h03f4b80_0.conda sha256: 37cd4f62ec023df8a6c6f9f6ffddde3d6620a83cbcab170a8fff31ef944402e5 md5: b703bc3e6cba5943acf0e5f987b5d0e2 @@ -10532,6 +10933,9 @@ packages: - __osx >=11.0 license: BSD-2-Clause license_family: BSD + run_exports: + weak: + - xxhash >=0.8.3,<0.8.4.0a0 size: 98913 timestamp: 1746457827085 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda @@ -10661,6 +11065,19 @@ packages: license: LGPL-2.1-only or MPL-1.1 size: 1537783 timestamp: 1766416059188 +- conda: https://conda.anaconda.org/conda-forge/win-64/castxml-0.7.0-ha22e26b_0.conda + sha256: 18602218a9a045c2798c449fa3afa1625960abdc7091a8680eba086e59d5375c + md5: 444b03cc1fd97f111454a99f92a23e01 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.1,<2.0a0 + license: Apache-2.0 + license_family: APACHE + run_exports: {} + size: 32530472 + timestamp: 1772089442701 - conda: https://conda.anaconda.org/conda-forge/win-64/ccache-4.13.6-h7fd822b_0.conda sha256: e3363b5ee179a2b369421f69e8879203a958d4efb5cb8c1c52f6b462c1197df7 md5: d9a4b1ce7d3d948ebe662ea7adf79219 @@ -10674,6 +11091,7 @@ packages: - xxhash >=0.8.3,<0.8.4.0a0 license: GPL-3.0-only license_family: GPL + run_exports: {} size: 692199 timestamp: 1777926529520 - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda @@ -11156,6 +11574,9 @@ packages: - vc14_runtime >=14.29.30139 license: BSD-3-Clause license_family: BSD + run_exports: + weak: + - libhiredis >=1.3.0,<1.4.0a0 size: 64205 timestamp: 1748219812303 - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.1-default_h64bd3f2_1002.conda @@ -11616,6 +12037,9 @@ packages: - vc14_runtime >=14.44.35208 license: BSD-3-Clause license_family: BSD + run_exports: + weak: + - pcre2 >=10.47,<10.48.0a0 size: 995992 timestamp: 1763655708300 - conda: https://conda.anaconda.org/conda-forge/win-64/perl-5.32.1.1-7_h57928b3_strawberry.conda @@ -11710,6 +12134,21 @@ packages: license_family: MIT size: 182043 timestamp: 1758892011955 +- conda: https://conda.anaconda.org/conda-forge/win-64/swig-4.4.1-h9b0202b_0.conda + sha256: f05e256f8edd14786c7832288e842f313b244a506975c2830ea9bbe7d4abc205 + md5: 0341bd38d90eae2041629f9084bb143a + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - pcre2 >=10.47,<10.48.0a0 + constrains: + - swig-abi ==5 + license: GPL-3.0-or-later + license_family: GPL + run_exports: {} + size: 1154778 + timestamp: 1773251909868 - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-hd094cb3_0.conda sha256: 290b1ae188d614d7e1fb98dc04b8afd9762dd82d3a0e2de2a8616c750de7cfab md5: d21952ac3d528fa8ca2f268f262f9ec6 @@ -12002,6 +12441,9 @@ packages: - vc14_runtime >=14.29.30139 license: BSD-2-Clause license_family: BSD + run_exports: + weak: + - xxhash >=0.8.3,<0.8.4.0a0 size: 105768 timestamp: 1746458183583 - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda diff --git a/pyproject.toml b/pyproject.toml index a15907900d5..eed4ffac26a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,9 @@ pytest = ">=8.4.1,<9" numpy = ">=2.3.4,<3" libopenblas = ">=0.3.30,<0.4" libgfortran5 = ">=15.2.0,<16" +swig = ">=4.4.1" +castxml = ">=0.7.0,<0.8" +ccache = ">=4.13.6,<5" [tool.pixi.feature.cxx.tasks.configure] cmd = '''cmake \ @@ -230,6 +233,8 @@ cmd = '''cmake \ -S. \ -GNinja \ -DITK_WRAP_PYTHON:BOOL=ON \ + -DITK_USE_SYSTEM_SWIG:BOOL=ON \ + -DITK_USE_SYSTEM_CASTXML:BOOL=ON \ -DCMAKE_BUILD_TYPE:STRING=Release \ -DBUILD_TESTING:BOOL=ON''' description = "Configure ITK Python" @@ -258,6 +263,8 @@ cmd = '''cmake \ -S. \ -GNinja \ -DITK_WRAP_PYTHON:BOOL=ON \ + -DITK_USE_SYSTEM_SWIG:BOOL=ON \ + -DITK_USE_SYSTEM_CASTXML:BOOL=ON \ -DCMAKE_BUILD_TYPE:STRING=Debug \ -DBUILD_TESTING:BOOL=ON''' description = "Configure ITK Python - Debug" From 0353d7e3d3be5972eda85432c32df91cbb10676b Mon Sep 17 00:00:00 2001 From: "Hans J. Johnson" Date: Sat, 20 Jun 2026 12:07:06 -0500 Subject: [PATCH 3/4] COMP: Add ITK.Pixi.Python CI exercising SWIG 4.4.1 Python wrapping New workflow builds the Python wrapping with system SWIG 4.4.1 + CastXML on ubuntu/windows/macos, runs an import + filter + std::vector smoke test, and a scoped set of Python regression tests. --- .github/workflows/pixi-python.yml | 139 ++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 .github/workflows/pixi-python.yml diff --git a/.github/workflows/pixi-python.yml b/.github/workflows/pixi-python.yml new file mode 100644 index 00000000000..f50c4e4b83c --- /dev/null +++ b/.github/workflows/pixi-python.yml @@ -0,0 +1,139 @@ +name: ITK.Pixi.Python + +on: + workflow_dispatch: + push: + branches: + - main + - 'release*' + paths-ignore: + - '*.md' + - LICENSE + - NOTICE + - 'Documentation/**' + - 'Utilities/Debugger/**' + - 'Utilities/ITKv5Preparation/**' + - 'Utilities/Maintenance/**' + - 'Modules/Remote/*.remote.cmake' + pull_request: + paths-ignore: + - '*.md' + - LICENSE + - NOTICE + - 'Documentation/**' + - 'Utilities/Debugger/**' + - 'Utilities/ITKv5Preparation/**' + - 'Utilities/Maintenance/**' + - 'Modules/Remote/*.remote.cmake' + +concurrency: + group: '${{ github.workflow }}@${{ github.head_ref || github.ref }}' + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + Pixi-Python: + runs-on: ${{ matrix.os }} + timeout-minutes: 0 + strategy: + fail-fast: false + matrix: + os: [ubuntu-22.04, windows-2022, macos-15] + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 5 + clean: true + + - name: Configure ccache environment + shell: bash + run: | + echo "CCACHE_BASEDIR=${GITHUB_WORKSPACE}" >> "$GITHUB_ENV" + echo "CCACHE_COMPILERCHECK=content" >> "$GITHUB_ENV" + echo "CCACHE_NOHASHDIR=true" >> "$GITHUB_ENV" + echo "CCACHE_SLOPPINESS=pch_defines,time_macros" >> "$GITHUB_ENV" + echo "CCACHE_DIR=${{ runner.temp }}/ccache" >> "$GITHUB_ENV" + echo "CCACHE_MAXSIZE=5G" >> "$GITHUB_ENV" + # configure-python has no ccache launcher of its own; CMake initializes + # CMAKE__COMPILER_LAUNCHER from these environment variables. + echo "CMAKE_C_COMPILER_LAUNCHER=ccache" >> "$GITHUB_ENV" + echo "CMAKE_CXX_COMPILER_LAUNCHER=ccache" >> "$GITHUB_ENV" + if [ "$RUNNER_OS" == "Linux" ]; then + sudo apt-get update -qq && sudo apt-get install -y locales + sudo locale-gen de_DE.UTF-8 + fi + + - name: Restore compiler cache + uses: actions/cache/restore@v5 + with: + path: ${{ runner.temp }}/ccache + key: ccache-v4-${{ runner.os }}-pixi-python-${{ github.sha }} + restore-keys: | + ccache-v4-${{ runner.os }}-pixi-python- + + - name: Disk space reporting BEFORE + shell: bash + run: df -h / + + - name: Free Disk Space (Ubuntu) + if: matrix.os == 'ubuntu-22.04' + uses: BRAINSia/free-disk-space@v2 + with: + removalmode: "rmz" + swap-storage: "true" + haskell: "true" + dotnet: "true" + docker-images: "false" + tool-cache: "true" + android: "false" + large-packages: "true" + mandb: "true" + + - name: Set up Pixi + uses: prefix-dev/setup-pixi@v0.9.5 + + - name: ccache stats (zero) + shell: bash + run: pixi run -e python ccache --zero-stats + + - name: Build Python wrapping (system SWIG 4.4.1 + CastXML) + shell: bash + run: | + df -h / + pixi run build-python + df -h / + + - name: Import smoke test + shell: bash + run: | + # The build tree's itk package is on the path via WrapITK.pth; expose its + # directory on PYTHONPATH (pixi run preserves the exported variable). + export PYTHONPATH="${GITHUB_WORKSPACE}/build-python/Wrapping/Generators/Python" + pixi run -e python python -c " + import itk, numpy as np + print('ITK', itk.Version.GetITKVersion()) + img = itk.image_from_array(np.zeros((16, 16), dtype=np.float32)) + out = itk.median_image_filter(img, radius=2) + assert list(itk.size(out)) == [16, 16] + v = itk.vector[itk.D]([1.0, 2.0, 3.0]) # std::vector / SwigPyIterator path + assert len(v) == 3 and v[0] == 1.0 + print('SWIG 4.4.1 Python wrapping import + filter + vector OK') + " + + - name: Scoped Python regression tests + shell: bash + run: | + pixi run -e python ctest --test-dir build-python --output-on-failure \ + -R "PythonSimplePipeline|PythonTemplatedPipeline|PythonLazyLoading|NonBlockingPythonFilterCoverage|PythonExtrasTest" + + - name: ccache stats + if: always() + shell: bash + run: pixi run -e python ccache --show-stats + + - name: Save compiler cache + if: ${{ !cancelled() }} + uses: actions/cache/save@v5 + with: + path: ${{ runner.temp }}/ccache + key: ccache-v4-${{ runner.os }}-pixi-python-${{ github.sha }} From f3a0ca1568f123fb8ebb24a673ddb7d1a9ddb06e Mon Sep 17 00:00:00 2001 From: "Hans J. Johnson" Date: Sat, 20 Jun 2026 12:07:09 -0500 Subject: [PATCH 4/4] COMP: WIP co-opt ITK.Pixi CI for SWIG 4.4.1 Python wrapping TEMPORARY scaffolding to iterate on the SWIG 4.4.1 Python wrapping: - Co-opts the reliably-triggering ITK.Pixi workflow (pixi.yml) to run the Python wrapping via configure-python-ci / build-python-ci / test-python-ci (system SWIG/CastXML + ccache in the python env) instead of the cxx env. - Neuters the PR triggers of the remaining build/check CI (arm, doxygen, perf-benchmark, pre-commit GHA set to workflow_dispatch; Azure Linux/LinuxPython/MacOSPython/WindowsPython set pr: none). REVERT THIS COMMIT before merge to restore the normal cxx ITK.Pixi CI and re-enable all other CI. --- .github/workflows/arm.yml | 26 ++------------ .github/workflows/doxygen.yml | 17 ++------- .github/workflows/perf-benchmark.yml | 11 +----- .github/workflows/pixi.yml | 35 ++++++++++--------- .github/workflows/pre-commit.yml | 4 +-- .../AzurePipelinesLinux.yml | 15 ++------ .../AzurePipelinesLinuxPython.yml | 15 ++------ .../AzurePipelinesMacOSPython.yml | 15 ++------ .../AzurePipelinesWindowsPython.yml | 15 ++------ pyproject.toml | 28 +++++++++++++++ 10 files changed, 62 insertions(+), 119 deletions(-) diff --git a/.github/workflows/arm.yml b/.github/workflows/arm.yml index 5fa97d3b5e3..a0076b16e78 100644 --- a/.github/workflows/arm.yml +++ b/.github/workflows/arm.yml @@ -1,30 +1,8 @@ name: ITK.Arm64 +# WIP(SWIG-4.4.1 pixi-python): disabled so only ITK.Pixi.Python runs; revert this commit to re-enable on: - push: - branches: - - main - - 'release*' - paths-ignore: - - '*.md' - - LICENSE - - NOTICE - - 'Documentation/**' - - 'Utilities/Debugger/**' - - 'Utilities/ITKv5Preparation/**' - - 'Utilities/Maintenance/**' - - 'Modules/Remote/*.remote.cmake' - pull_request: - paths-ignore: - - '*.md' - - LICENSE - - NOTICE - - 'Documentation/**' - - 'Utilities/Debugger/**' - - 'Utilities/ITKv5Preparation/**' - - 'Utilities/Maintenance/**' - - 'Modules/Remote/*.remote.cmake' - + workflow_dispatch: concurrency: group: '${{ github.workflow }}@${{ github.head_ref || github.ref }}' cancel-in-progress: ${{ github.event_name == 'pull_request' }} diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml index 9fbcdacd0b4..7e8e23b4db7 100644 --- a/.github/workflows/doxygen.yml +++ b/.github/workflows/doxygen.yml @@ -2,22 +2,9 @@ name: ITK.Doxygen.Warnings # pull_request intentionally has no paths-ignore: the check always runs, so it # can safely be made a required status without stranding filtered PRs. +# WIP(SWIG-4.4.1 pixi-python): disabled so only ITK.Pixi.Python runs; revert this commit to re-enable on: - push: - branches: - - main - - 'release*' - tags: - - 'v*' - paths-ignore: - - '*.md' - - LICENSE - - NOTICE - - 'Utilities/Debugger/**' - - 'Utilities/ITKv5Preparation/**' - - 'Utilities/Maintenance/**' - pull_request: - + workflow_dispatch: concurrency: group: '${{ github.workflow }}@${{ github.head_ref || github.ref }}' cancel-in-progress: ${{ github.event_name == 'pull_request' }} diff --git a/.github/workflows/perf-benchmark.yml b/.github/workflows/perf-benchmark.yml index 6ecd1e745d6..f49e5ce434e 100644 --- a/.github/workflows/perf-benchmark.yml +++ b/.github/workflows/perf-benchmark.yml @@ -1,17 +1,8 @@ name: ITK.Performance +# WIP(SWIG-4.4.1 pixi-python): disabled so only ITK.Pixi.Python runs; revert this commit to re-enable on: - pull_request: - paths-ignore: - - '*.md' - - LICENSE - - NOTICE - - 'Documentation/**' - - 'Utilities/Debugger/**' - - 'Utilities/ITKv5Preparation/**' - - 'Utilities/Maintenance/**' workflow_dispatch: - concurrency: group: '${{ github.workflow }}@${{ github.head_ref || github.ref }}' cancel-in-progress: ${{ github.event_name == 'pull_request' }} diff --git a/.github/workflows/pixi.yml b/.github/workflows/pixi.yml index 7e9798e10ff..0a906b64833 100644 --- a/.github/workflows/pixi.yml +++ b/.github/workflows/pixi.yml @@ -1,6 +1,10 @@ name: ITK.Pixi +# WIP(SWIG-4.4.1 pixi-python): temporarily co-opted to build/test the Python +# wrapping (configure/build/test-python-ci) instead of the cxx env. Revert this +# commit to restore the normal cxx CI. on: + workflow_dispatch: push: branches: - main @@ -24,7 +28,6 @@ on: - 'Utilities/ITKv5Preparation/**' - 'Utilities/Maintenance/**' - 'Modules/Remote/*.remote.cmake' - concurrency: group: '${{ github.workflow }}@${{ github.head_ref || github.ref }}' cancel-in-progress: ${{ github.event_name == 'pull_request' }} @@ -64,9 +67,9 @@ jobs: uses: actions/cache/restore@v5 with: path: ${{ runner.temp }}/ccache - key: ccache-v4-${{ runner.os }}-pixi-cxx-${{ github.sha }} + key: ccache-v4-${{ runner.os }}-pixi-python-${{ github.sha }} restore-keys: | - ccache-v4-${{ runner.os }}-pixi-cxx- + ccache-v4-${{ runner.os }}-pixi-python- - name: Restore ExternalData object store id: restore-externaldata @@ -127,21 +130,21 @@ jobs: - name: Show ccache configuration, stats and maintenance shell: bash run: | - pixi run -e cxx ccache --zero-stats - pixi run -e cxx ccache --evict-older-than 7d - pixi run -e cxx ccache --show-config + pixi run -e python ccache --zero-stats + pixi run -e python ccache --evict-older-than 7d + pixi run -e python ccache --show-config - name: Configure - run: pixi run configure-ci + run: pixi run configure-python-ci - name: Fetch ExternalData - run: pixi run --skip-deps build-external-data-ci + run: pixi run -e python cmake --build build-python --target ITKData - name: Build run: | echo "****** df -h / -- pre build" df -h / - pixi run --skip-deps build-ci + pixi run --skip-deps build-python-ci echo "****** df -h / -- post build" df -h / @@ -152,16 +155,16 @@ jobs: # .obj/.lib also name Wavefront-mesh and Makefile test data, so match # only compiled objects in intermediate dirs (CMakeFiles/ for Ninja, # *.dir/ for Visual Studio) and archives under lib/. - find build -type f \( -path '*/CMakeFiles/*' -o -path '*.dir/*' \) \( -name "*.o" -o -name "*.obj" \) -delete - find build/lib -type f \( -name "*.a" -o -name "*.lib" \) -delete 2>/dev/null || true + find build-python -type f \( -path '*/CMakeFiles/*' -o -path '*.dir/*' \) \( -name "*.o" -o -name "*.obj" \) -delete + find build-python/lib -type f \( -name "*.a" -o -name "*.lib" \) -delete 2>/dev/null || true # Trim ccache to stay within CCACHE_MAXSIZE and remove orphaned entries - pixi run -e cxx ccache --evict-older-than 1d 2>/dev/null || true - pixi run -e cxx ccache --cleanup 2>/dev/null || true + pixi run -e python ccache --evict-older-than 1d 2>/dev/null || true + pixi run -e python ccache --cleanup 2>/dev/null || true echo "****** df -h / -- post cleanup" df -h / - name: Test - run: pixi run --skip-deps test-ci + run: pixi run --skip-deps test-python-ci - name: Disk space reporting AFTER (optimize free-disk-space) run: | @@ -176,7 +179,7 @@ jobs: uses: actions/cache/save@v5 with: path: ${{ runner.temp }}/ccache - key: ccache-v4-${{ runner.os }}-pixi-cxx-${{ github.sha }} + key: ccache-v4-${{ runner.os }}-pixi-python-${{ github.sha }} # ExternalData object store is populated by # .github/workflows/populate-externaldata-cache.yml — a dedicated @@ -188,7 +191,7 @@ jobs: - name: ccache stats if: always() - run: pixi run -e cxx ccache --show-stats + run: pixi run -e python ccache --show-stats prune-superseded-caches: # Background housekeeping: removes ccache entries whose SHA-suffixed diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index dabebc4a162..903862d802d 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -1,8 +1,8 @@ name: pre-commit +# WIP(SWIG-4.4.1 pixi-python): disabled so only ITK.Pixi.Python runs; revert this commit to re-enable on: - pull_request: - + workflow_dispatch: jobs: pre-commit: runs-on: ubuntu-24.04 diff --git a/Testing/ContinuousIntegration/AzurePipelinesLinux.yml b/Testing/ContinuousIntegration/AzurePipelinesLinux.yml index 90a1419ae9a..8f3c7ec3aea 100644 --- a/Testing/ContinuousIntegration/AzurePipelinesLinux.yml +++ b/Testing/ContinuousIntegration/AzurePipelinesLinux.yml @@ -15,19 +15,8 @@ trigger: - Utilities/ITKv5Preparation/* - Utilities/Maintenance/* - Modules/Remote/*.remote.cmake -pr: - # Validate draft PRs (Azure default) so contributors see all gating results while iterating. - drafts: true - paths: - exclude: - - '*.md' - - LICENSE - - NOTICE - - Documentation/* - - Utilities/Debugger/* - - Utilities/ITKv5Preparation/* - - Utilities/Maintenance/* - - Modules/Remote/*.remote.cmake +# WIP(SWIG-4.4.1 pixi-python): co-opting ITK.Pixi for the Python build; revert this commit to re-enable. +pr: none variables: ExternalData_OBJECT_STORES: $(Pipeline.Workspace)/ExternalData CCACHE_DIR: $(Pipeline.Workspace)/.ccache diff --git a/Testing/ContinuousIntegration/AzurePipelinesLinuxPython.yml b/Testing/ContinuousIntegration/AzurePipelinesLinuxPython.yml index b1c42b92c77..f527a45bb5f 100644 --- a/Testing/ContinuousIntegration/AzurePipelinesLinuxPython.yml +++ b/Testing/ContinuousIntegration/AzurePipelinesLinuxPython.yml @@ -15,19 +15,8 @@ trigger: - Utilities/ITKv5Preparation/* - Utilities/Maintenance/* - Modules/Remote/*.remote.cmake -pr: - # Validate draft PRs (Azure default) so contributors see all gating results while iterating. - drafts: true - paths: - exclude: - - '*.md' - - LICENSE - - NOTICE - - Documentation/* - - Utilities/Debugger/* - - Utilities/ITKv5Preparation/* - - Utilities/Maintenance/* - - Modules/Remote/*.remote.cmake +# WIP(SWIG-4.4.1 pixi-python): co-opting ITK.Pixi for the Python build; revert this commit to re-enable. +pr: none variables: ExternalData_OBJECT_STORES: $(Pipeline.Workspace)/ExternalData CCACHE_DIR: $(Pipeline.Workspace)/.ccache diff --git a/Testing/ContinuousIntegration/AzurePipelinesMacOSPython.yml b/Testing/ContinuousIntegration/AzurePipelinesMacOSPython.yml index 898ba9743cf..15094373f1b 100644 --- a/Testing/ContinuousIntegration/AzurePipelinesMacOSPython.yml +++ b/Testing/ContinuousIntegration/AzurePipelinesMacOSPython.yml @@ -15,19 +15,8 @@ trigger: - Utilities/ITKv5Preparation/* - Utilities/Maintenance/* - Modules/Remote/*.remote.cmake -pr: - # Validate draft PRs (Azure default) so contributors see all gating results while iterating. - drafts: true - paths: - exclude: - - '*.md' - - LICENSE - - NOTICE - - Documentation/* - - Utilities/Debugger/* - - Utilities/ITKv5Preparation/* - - Utilities/Maintenance/* - - Modules/Remote/*.remote.cmake +# WIP(SWIG-4.4.1 pixi-python): co-opting ITK.Pixi for the Python build; revert this commit to re-enable. +pr: none variables: ExternalData_OBJECT_STORES: $(Pipeline.Workspace)/ExternalData CCACHE_DIR: $(Pipeline.Workspace)/.ccache diff --git a/Testing/ContinuousIntegration/AzurePipelinesWindowsPython.yml b/Testing/ContinuousIntegration/AzurePipelinesWindowsPython.yml index 3e834a7dfda..7bd448a2dd5 100644 --- a/Testing/ContinuousIntegration/AzurePipelinesWindowsPython.yml +++ b/Testing/ContinuousIntegration/AzurePipelinesWindowsPython.yml @@ -15,19 +15,8 @@ trigger: - Utilities/ITKv5Preparation/* - Utilities/Maintenance/* - Modules/Remote/*.remote.cmake -pr: - # Validate draft PRs (Azure default) so contributors see all gating results while iterating. - drafts: true - paths: - exclude: - - '*.md' - - LICENSE - - NOTICE - - Documentation/* - - Utilities/Debugger/* - - Utilities/ITKv5Preparation/* - - Utilities/Maintenance/* - - Modules/Remote/*.remote.cmake +# WIP(SWIG-4.4.1 pixi-python): co-opting ITK.Pixi for the Python build; revert this commit to re-enable. +pr: none variables: ExternalData_OBJECT_STORES: $(Pipeline.Workspace)/ExternalData CCACHE_DIR: $(Pipeline.Workspace)/.ccache diff --git a/pyproject.toml b/pyproject.toml index eed4ffac26a..77533bc28ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -240,6 +240,34 @@ cmd = '''cmake \ description = "Configure ITK Python" outputs = ["build-python/CMakeFiles/"] +[tool.pixi.feature.python.tasks.configure-python-ci] +cmd = '''cmake \ + -Bbuild-python \ + -S. \ + -GNinja \ + -DITK_WRAP_PYTHON:BOOL=ON \ + -DITK_USE_SYSTEM_SWIG:BOOL=ON \ + -DITK_USE_SYSTEM_CASTXML:BOOL=ON \ + -DCMAKE_BUILD_TYPE:STRING=Release \ + -DBUILD_TESTING:BOOL=ON \ + -DITK_USE_CCACHE:BOOL=ON \ + -DCMAKE_C_COMPILER_LAUNCHER:STRING=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER:STRING=ccache \ + -DITK_COMPUTER_MEMORY_SIZE:STRING=5''' +description = "Configure ITK Python wrapping for CI (system SWIG/CastXML + ccache)" +outputs = ["build-python/CMakeFiles/"] + +[tool.pixi.feature.python.tasks.build-python-ci] +cmd = "cmake --build build-python" +description = "Build ITK Python wrapping for CI" +outputs = ["build-python/lib/**"] +depends-on = ["configure-python-ci"] + +[tool.pixi.feature.python.tasks.test-python-ci] +cmd = "ctest -j3 --test-dir build-python --output-on-failure -R Python" +description = "Test ITK Python wrapping for CI" +depends-on = ["build-python-ci"] + [tool.pixi.feature.python.tasks.build-python] cmd = "cmake --build build-python" description = "Build ITK Python"