Skip to content

COMP: Fail early when wrapped Python is older than the 3.11 minimum#6659

Merged
hjmjohnson merged 2 commits into
InsightSoftwareConsortium:mainfrom
hjmjohnson:python-wrap-min-version-fail-early
Jul 20, 2026
Merged

COMP: Fail early when wrapped Python is older than the 3.11 minimum#6659
hjmjohnson merged 2 commits into
InsightSoftwareConsortium:mainfrom
hjmjohnson:python-wrap-min-version-fail-early

Conversation

@hjmjohnson

@hjmjohnson hjmjohnson commented Jul 17, 2026

Copy link
Copy Markdown
Member

Abort configuration when ITK_WRAP_PYTHON=ON and the resolved Python is older than the 3.11 minimum raised in #6490, instead of failing at import itk after a full build + test cycle.

A second commit names the missing Python3 component and the command that installs it, so a numpy-less interpreter reports Missing required Python3 COMPONENT(s): NumPy plus a copy-pasteable pip install line instead of a wall of Python3_*_FOUND variables.

@dzenanz — this targets your Ubuntu-22.04-gcc11.4-Rel-Python nightly (RogueResearch/Kitware dashboard), which currently submits with Python 3.10 and produces ~194 import itk failures every night. That dashboard's submission needs its interpreter updated to Python ≥ 3.11 (or ITK_WRAP_PYTHON=OFF). Once this merges, that config will fail fast at configure with an actionable message rather than after ~3 hours of building and testing.

Why the 3.11 floor is currently bypassed

CMake/ITKSetPython3Vars.cmake sets PYTHON_VERSION_MIN 3.11, but when a dashboard passes an explicit Python3_EXECUTABLE, this block narrows the range to that interpreter's exact version:

set(PYTHON_VERSION_MIN ${_specified_Python3_VERSION_MM})   # e.g. 3.10
set(PYTHON_VERSION_MAX ${_specified_Python3_VERSION_MM})

So find_package(Python3 3.11...3.999) never rejects the older interpreter. Wrapping configures and builds normally, then every wrapped test fails identically at runtime:

from typing import Self, TypeAlias, Union, TYPE_CHECKING   # itk/support/types.py
ImportError: cannot import name 'Self' from 'typing'  (python3.10)

typing.Self (PEP 673) is Python 3.11+, consistent with #6490 raising the wrapped-Python minimum to 3.11.

Fix and local verification

Adds a canonical ITK_WRAP_PYTHON_MINIMUM_VERSION floor and asserts the resolved Python3_VERSION against it immediately after find_package, before any wrapping/SWIG work.

Verified locally against upstream/main:

  • -DITK_WRAP_PYTHON=ON -DPython3_EXECUTABLE=python3.10 → configure aborts (exit 1) after ~75 lines with ITK Python wrapping (ITK_WRAP_PYTHON=ON) requires Python >= 3.11 …, before SWIG/wrapping.
  • -DITK_WRAP_PYTHON=ON -DPython3_EXECUTABLE=python3.11 → guard silent, full configure succeeds (exit 0), ITK_WRAP_PYTHON_VERSION=3.11.15.
  • pre-commit run --all-files: clean.
Second commit: name the missing component and its remedy

BUILD_TESTING appends NumPy to the hard-required component list, so an interpreter without numpy aborts configure. The previous error never stated which component was missing or how to supply it. That failure is pre-existing and unrelated to the version guardmain behaves identically, verified below.

Before:

At least 1 required Python3 COMPONENT could not be found from :
Interpreter;Development.Module;Development.SABIModule;NumPy
          in range 3.12.13...3.12.13:
          ... 12 more lines of Python3_*_FOUND variables ...

After:

Missing required Python3 COMPONENT(s): NumPy

          NumPy: /usr/bin/python3.11 -m pip install numpy

          Or set ITK_WRAP_PYTHON=OFF to build without Python wrapping.

A missing Development.Module / Development.SABIModule gets its own line pointing at the matching -dev package. The original variable dump is retained below the summary. Behavior is unchanged; only the diagnostic text differs.

Failure tracks numpy, not the Python version (Ubuntu 24.04, cmake 3.28.3, ITK_WRAP_PYTHON=ON, BUILD_TESTING=ON):

ref interpreter numpy result
main python3.11 no COMPONENT could not be found
main python3.12 yes configures
main python3.13 no COMPONENT could not be found
this PR python3.11 no Missing … NumPy + remedy
this PR python3.12 yes configures
this PR python3.13 no Missing … NumPy + remedy

Full ITK configures (not a harness):

  • -DITK_WRAP_PYTHON=ON with a numpy-less interpreter → aborts with the new message.
  • -DITK_WRAP_PYTHON=ON with numpy present → Configuring done (79.4s) / Generating done, exit 0.
  • All four missing-component combinations (NumPy, Development.Module, both, Development.SABIModule) exercised directly.
  • pre-commit run --all-files: clean.

@github-actions github-actions Bot added type:Compiler Compiler support or related warnings type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots labels Jul 17, 2026
@hjmjohnson
hjmjohnson marked this pull request as ready for review July 17, 2026 18:40
@hjmjohnson
hjmjohnson requested a review from dzenanz July 17, 2026 18:42
@dzenanz

dzenanz commented Jul 17, 2026

Copy link
Copy Markdown
Member

Using this branch, doing an incremental configure succeeds:
Screenshot from 2026-07-17 14-41-41

@greptile-apps

greptile-apps Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes Python wrapping fail during CMake configure when the selected interpreter is below the supported minimum. The main changes are:

  • Adds ITK_WRAP_PYTHON_MINIMUM_VERSION as the canonical Python wrapping floor.
  • Keeps the existing narrowed find_package(Python3) range for explicit Python3_EXECUTABLE values.
  • Adds a configure-time FATAL_ERROR when resolved Python3_VERSION is older than 3.11.

Confidence Score: 5/5

Safe to merge with minimal risk.

The change is localized to Python wrapping configuration and preserves the existing interpreter selection behavior while adding an explicit version guard.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • Verified Python availability and PATH, confirming Python 3.11.6 is used and Python 3.10 is not on PATH.
  • Executed and validated CMake configure and generate for Python 3.11.6, with ITK_WRAP_PYTHON_VERSION=3.11.6 and EXIT_CODE: 0.
  • Validated the CMake cache shows Python3_EXECUTABLE is /usr/local/bin/python3 and ITK wrapping is enabled (ITK_WRAP_PYTHON:BOOL=ON).
  • Reviewed the collection of five log artifacts to corroborate interpreter, configuration, and cache state.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
CMake/ITKSetPython3Vars.cmake Introduces a separate Python wrapping minimum version and fails configure early when the resolved wrapping interpreter is older than Python 3.11; no issues found.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant User as CMake configure
participant Vars as ITKSetPython3Vars.cmake
participant Find as find_package(Python3)
participant Wrap as Python wrapping setup

User->>Vars: "ITK_WRAP_PYTHON=ON / Python3_EXECUTABLE optional"
Vars->>Vars: "Set ITK_WRAP_PYTHON_MINIMUM_VERSION = 3.11"
alt Python3_EXECUTABLE specified
    Vars->>Vars: Narrow search range to executable version
end
Vars->>Find: Resolve Python3 interpreter and components
Find-->>Vars: Python3_VERSION
alt "Python3_VERSION < 3.11"
    Vars-->>User: FATAL_ERROR with upgrade/disable guidance
else "Python3_VERSION >= 3.11"
    Vars->>Wrap: Continue wrapping configuration
end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant User as CMake configure
participant Vars as ITKSetPython3Vars.cmake
participant Find as find_package(Python3)
participant Wrap as Python wrapping setup

User->>Vars: "ITK_WRAP_PYTHON=ON / Python3_EXECUTABLE optional"
Vars->>Vars: "Set ITK_WRAP_PYTHON_MINIMUM_VERSION = 3.11"
alt Python3_EXECUTABLE specified
    Vars->>Vars: Narrow search range to executable version
end
Vars->>Find: Resolve Python3 interpreter and components
Find-->>Vars: Python3_VERSION
alt "Python3_VERSION < 3.11"
    Vars-->>User: FATAL_ERROR with upgrade/disable guidance
else "Python3_VERSION >= 3.11"
    Vars->>Wrap: Continue wrapping configuration
end
Loading

Reviews (1): Last reviewed commit: "COMP: Fail early when wrapped Python is ..." | Re-trigger Greptile

@dzenanz dzenanz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good. Let me try a clean build.

@dzenanz

dzenanz commented Jul 17, 2026

Copy link
Copy Markdown
Member

Doing a configure using CMake-GUI, then turning on ITK_WRAP_PYTHON and re-configuring succeeds:
Screenshot from 2026-07-17 14-53-45

@dzenanz

dzenanz commented Jul 17, 2026

Copy link
Copy Markdown
Member

When ITK_WRAP_PYTHON is turned on during the initial configure, it correctly complains about version:

dzenan.zukic@krs-7714:~/ITK/ITK-py-direct$ cmake -DITK_WRAP_PYTHON=ON ../ITK-git/
-- Setting build type to 'Release' as none was specified.
-- The CXX compiler identification is GNU 11.4.0
-- The C compiler identification is GNU 11.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/lib/ccache/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/lib/ccache/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Found Git: /usr/bin/git (found version "2.34.1")
-- Performing Test C_HAS_WARNING-Wno-unused-parameter
-- Performing Test C_HAS_WARNING-Wno-unused-parameter - Success
-- Performing Test C_HAS_WARNING-Wall
-- Performing Test C_HAS_WARNING-Wall - Success
-- Performing Test C_HAS_WARNING-Wcast-align
-- Performing Test C_HAS_WARNING-Wcast-align - Success
-- Performing Test C_HAS_WARNING-Wdisabled-optimization
-- Performing Test C_HAS_WARNING-Wdisabled-optimization - Success
-- Performing Test C_HAS_WARNING-Wextra
-- Performing Test C_HAS_WARNING-Wextra - Success
-- Performing Test C_HAS_WARNING-Wformat_2
-- Performing Test C_HAS_WARNING-Wformat_2 - Success
-- Performing Test C_HAS_WARNING-Winvalid-pch
-- Performing Test C_HAS_WARNING-Winvalid-pch - Success
-- Performing Test C_HAS_WARNING-Wpointer-arith
-- Performing Test C_HAS_WARNING-Wpointer-arith - Success
-- Performing Test C_HAS_WARNING-Wshadow
-- Performing Test C_HAS_WARNING-Wshadow - Success
-- Performing Test C_HAS_WARNING-Wunused
-- Performing Test C_HAS_WARNING-Wunused - Success
-- Performing Test C_HAS_WARNING-Wwrite-strings
-- Performing Test C_HAS_WARNING-Wwrite-strings - Success
-- Performing Test CXX_HAS_WARNING-Wall
-- Performing Test CXX_HAS_WARNING-Wall - Success
-- Performing Test CXX_HAS_WARNING-Wcast-align
-- Performing Test CXX_HAS_WARNING-Wcast-align - Success
-- Performing Test CXX_HAS_WARNING-Wdisabled-optimization
-- Performing Test CXX_HAS_WARNING-Wdisabled-optimization - Success
-- Performing Test CXX_HAS_WARNING-Wextra
-- Performing Test CXX_HAS_WARNING-Wextra - Success
-- Performing Test CXX_HAS_WARNING-Wformat_2
-- Performing Test CXX_HAS_WARNING-Wformat_2 - Success
-- Performing Test CXX_HAS_WARNING-Winvalid-pch
-- Performing Test CXX_HAS_WARNING-Winvalid-pch - Success
-- Performing Test CXX_HAS_WARNING-Wpointer-arith
-- Performing Test CXX_HAS_WARNING-Wpointer-arith - Success
-- Performing Test CXX_HAS_WARNING-Wshadow
-- Performing Test CXX_HAS_WARNING-Wshadow - Success
-- Performing Test CXX_HAS_WARNING-Wunused
-- Performing Test CXX_HAS_WARNING-Wunused - Success
-- Performing Test CXX_HAS_WARNING-Wwrite-strings
-- Performing Test CXX_HAS_WARNING-Wwrite-strings - Success
-- Performing Test CXX_HAS_WARNING-Wno-undefined-var-template
-- Performing Test CXX_HAS_WARNING-Wno-undefined-var-template - Failed
-- Performing Test CXX_HAS_WARNING-Woverloaded-virtual
-- Performing Test CXX_HAS_WARNING-Woverloaded-virtual - Success
-- Performing Test CXX_HAS_WARNING-Wctad-maybe-unsupported
-- Performing Test CXX_HAS_WARNING-Wctad-maybe-unsupported - Success
-- Performing Test CXX_HAS_WARNING-Wstrict-null-sentinel
-- Performing Test CXX_HAS_WARNING-Wstrict-null-sentinel - Success
-- Performing Test CXX_HAS_DISABLE_OPTIMIZATION_FLAG
-- Performing Test CXX_HAS_DISABLE_OPTIMIZATION_FLAG - Failed
-- Could NOT find Python3 (missing: Python3_NumPy_INCLUDE_DIRS NumPy) (found suitable version "3.13.2", required range is "3.11...3.999")
-- Could NOT find Python3 (missing: Python3_NumPy_INCLUDE_DIRS NumPy) (found suitable version "3.13.2", minimum required is "3.13.2")
-- Python3_FOUND=FALSE
--  o Python3 Found COMPONENT: Python3_Interpreter_FOUND: TRUE
--  o Python3 Found COMPONENT: Python3_Development.Module_FOUND: TRUE
--  o Python3 Found COMPONENT: Python3_Development.SABIModule_FOUND: TRUE
--  o Python3 Missing COMPONENT: Python3_NumPy_FOUND: FALSE
CMake Error at CMake/ITKSetPython3Vars.cmake:178 (message):
  At least 1 required Python3 COMPONENT could not be found from :
  Interpreter;Development.Module;Development.SABIModule;NumPy

            in range 3.11...3.999:
            Python3_EXECUTABLE=:/home/local/KHQ/dzenan.zukic/miniconda3/bin/python3.13:
            ITK_WRAP_PYTHON_VERSION=:3.13.2:
            Python3_ROOT_DIR=::
            ---
            Python3_FOUND=FALSE
            Python3_Interpreter_FOUND=TRUE
            Python3_Compiler_FOUND=FALSE
            Python3_Development_FOUND=FALSE
            Python3_Development.Module_FOUND=TRUE
            Python3_Development.SABIModule_FOUND=TRUE
            Python3_Development.Embed_FOUND=FALSE
            Python3_NumPy_FOUND=FALSE
      
Call Stack (most recent call first):
  CMakeLists.txt:758 (include)


-- Configuring incomplete, errors occurred!

@hjmjohnson
hjmjohnson force-pushed the python-wrap-min-version-fail-early branch from a08929e to 0f1a9ae Compare July 17, 2026 19:03
@hjmjohnson

Copy link
Copy Markdown
Member Author

Good catch, @dzenanz — thanks for testing the incremental case. Fixed and pushed.

The original check ran after find_package(Python3) and read Python3_VERSION; on an incremental reconfigure of a cached below-floor tree that path wasn't reliably re-triggering the abort. The check now runs off the execute_process result inside the if(DEFINED Python3_EXECUTABLE) block, which re-runs on every configure — so it fires before find_package and before any wrapping work.

Reproduced your scenario locally: a complete Python 3.10 wrapping configure, then an incremental reconfigure on this branch. Before, the incremental completed; now it aborts at configure:

CMake Error at CMake/ITKSetPython3Vars.cmake:37 (message):
  ITK Python wrapping (ITK_WRAP_PYTHON=ON) requires Python >= 3.11, but the
  specified Python3_EXECUTABLE=/opt/homebrew/bin/python3.10 is Python 3.10.20.
  Provide a Python >= 3.11 interpreter, or set ITK_WRAP_PYTHON=OFF.

Clean and incremental configures with Python 3.11 still succeed. Your Ubuntu-22.04-gcc11.4-Rel-Python dashboard will need its interpreter moved to ≥ 3.11 either way — this just makes it fail fast with an actionable message instead of after the build+test cycle.

@dzenanz dzenanz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now works.

An explicit Python3_EXECUTABLE narrows PYTHON_VERSION_MIN/MAX to that
interpreter's exact version, so find_package(Python3 3.11...) no longer
rejects a below-floor interpreter. Wrapping then configures, builds, and
tests for hours before every wrapped test fails at "import itk" because
itk/support/types.py imports PEP 673 typing.Self, which requires Python
3.11.

Check the interpreter version against the 3.11 floor in three places so
no configure path slips through:

- From the execute_process result inside the explicit-executable block,
  which re-runs every configure, so an incremental reconfigure of a
  cached below-floor tree also aborts.
- After the first find_package, treating an empty Python3_VERSION as a
  failure. Otherwise the second find_package runs unversioned and
  silently accepts a below-floor interpreter (e.g. auto-detected system
  Python 3.10 after the 3.11 range rejects it).
@hjmjohnson
hjmjohnson force-pushed the python-wrap-min-version-fail-early branch from 0f1a9ae to 56cdfa7 Compare July 17, 2026 19:24
@hjmjohnson

Copy link
Copy Markdown
Member Author

Your second case (GUI: configure, then turn on ITK_WRAP_PYTHON and re-configure, ending at ITK_WRAP_PYTHON_VERSION=3.10.12) was a distinct hole — now fixed and pushed.

Root cause: with no explicit Python3_EXECUTABLE, the first find_package(Python3 3.11...3.999) correctly rejects system 3.10 and leaves Python3_VERSION empty. The old guard was if(Python3_VERSION AND …), so it silently skipped on empty — and the second find_package(Python3 ${ITK_WRAP_PYTHON_VERSION} …) then ran with an empty (unversioned) constraint and happily accepted /usr/bin/python3.10.

The guard now fails on an empty Python3_VERSION too, before that second find_package runs:

if(NOT Python3_VERSION OR Python3_VERSION VERSION_LESS ${ITK_WRAP_PYTHON_MINIMUM_VERSION})
  message(FATAL_ERROR "… requires Python >= 3.11, but no such interpreter was found in range …")
endif()

There are now three checkpoints covering the paths you found: the execute_process version check (explicit executable / incremental reconfigure), and this empty-or-below-floor check after the first find_package (auto-detected system Python).

Verified locally:

  • Clean and incremental configures with Python 3.11 → succeed.
  • Explicit -DPython3_EXECUTABLE=…/python3.10 and toggling ITK_WRAP_PYTHON=ON on a cached 3.10 tree → abort at configure.
  • The empty-Python3_VERSION → unversioned-second-find path (your itkMaskFeaturePointSelectionFilter and itkBlockMatchingImageFilter #2) reproduced in a minimal model: it falsely succeeded before, and now aborts.

Your #3 (conda 3.13, missing NumPy) is already correct behavior — 3.13 passes the version floor and it fails on the NumPy component, as intended.

@dzenanz

dzenanz commented Jul 17, 2026

Copy link
Copy Markdown
Member

There is something wrong with this. If I do CMake-GUI configure, then turn on wrapping, then specify Python3_EXECUTABLE=/home/local/KHQ/dzenan.zukic/miniconda3/bin/python3.13, I run into:

Could NOT find Python3 (missing: Python3_NumPy_INCLUDE_DIRS NumPy) (found suitable version "3.13.2", required range is "3.13.2...3.13.2")
Could NOT find Python3 (missing: Python3_NumPy_INCLUDE_DIRS NumPy) (found suitable version "3.13.2", minimum required is "3.13.2")
Python3_FOUND=FALSE
 o Python3 Found COMPONENT: Python3_Interpreter_FOUND: TRUE
 o Python3 Found COMPONENT: Python3_Development.Module_FOUND: TRUE
 o Python3 Found COMPONENT: Python3_Development.SABIModule_FOUND: TRUE
 o Python3 Missing COMPONENT: Python3_NumPy_FOUND: FALSE
CMake Error at CMake/ITKSetPython3Vars.cmake:195 (message):
  At least 1 required Python3 COMPONENT could not be found from :
  Interpreter;Development.Module;Development.SABIModule;NumPy

            in range 3.13.2...3.13.2:
            Python3_EXECUTABLE=:/home/local/KHQ/dzenan.zukic/miniconda3/bin/python3.13:
            ITK_WRAP_PYTHON_VERSION=:3.13.2:
            Python3_ROOT_DIR=::
            ---
            Python3_FOUND=FALSE
            Python3_Interpreter_FOUND=TRUE
            Python3_Compiler_FOUND=FALSE
            Python3_Development_FOUND=FALSE
            Python3_Development.Module_FOUND=TRUE
            Python3_Development.SABIModule_FOUND=TRUE
            Python3_Development.Embed_FOUND=FALSE
            Python3_NumPy_FOUND=FALSE
      
Call Stack (most recent call first):
  CMakeLists.txt:758 (include)


Configuring incomplete, errors occurred!

@hjmjohnson

Copy link
Copy Markdown
Member Author

@dzenanz FYI: I have other obligations tonight and tomorrow. I don't know if I'll get around to this again for a few days. This "fail quick" is getting to be a bigger scope than I can tackle today.

@dzenanz

dzenanz commented Jul 17, 2026

Copy link
Copy Markdown
Member

I am not in a hurry. I will try to switch the nightly to 3.13 today.

@dzenanz

dzenanz commented Jul 17, 2026

Copy link
Copy Markdown
Member

This patch is overly restrictive:

dzenan.zukic@krs-7714:~/ITK/ITK-git$ sudo apt install python3.12 python3.12-venv python3.12-dev -y
...OK
dzenan.zukic@krs-7714:~/ITK/ITK-git$ which python3.12
/usr/bin/python3.12
dzenan.zukic@krs-7714:~/ITK/ITK-git$ python3.12 --version
Python 3.12.13
dzenan.zukic@krs-7714:~/ITK/ITK-git$ cd ..
dzenan.zukic@krs-7714:~/ITK$ mkdir ITK-py-direct
dzenan.zukic@krs-7714:~/ITK$ cd ITK-py-direct/
dzenan.zukic@krs-7714:~/ITK/ITK-py-direct$ cmake -DPython3_EXECUTABLE=/usr/bin/python3.12 -DITK_WRAP_PYTHON=ON ../ITK-git/
-- Setting build type to 'Release' as none was specified.
-- The CXX compiler identification is GNU 11.4.0
-- The C compiler identification is GNU 11.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/lib/ccache/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/lib/ccache/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Found Git: /usr/bin/git (found version "2.34.1")
-- Performing Test C_HAS_WARNING-Wno-unused-parameter
...
-- Performing Test CXX_HAS_DISABLE_OPTIMIZATION_FLAG
-- Performing Test CXX_HAS_DISABLE_OPTIMIZATION_FLAG - Failed
-- Could NOT find Python3 (missing: Python3_NumPy_INCLUDE_DIRS NumPy) (found suitable version "3.12.13", required range is "3.12.13...3.12.13")
-- Could NOT find Python3 (missing: Python3_NumPy_INCLUDE_DIRS NumPy) (found suitable version "3.12.13", minimum required is "3.12.13")
-- Python3_FOUND=FALSE
--  o Python3 Found COMPONENT: Python3_Interpreter_FOUND: TRUE
--  o Python3 Found COMPONENT: Python3_Development.Module_FOUND: TRUE
--  o Python3 Found COMPONENT: Python3_Development.SABIModule_FOUND: TRUE
--  o Python3 Missing COMPONENT: Python3_NumPy_FOUND: FALSE
CMake Error at CMake/ITKSetPython3Vars.cmake:195 (message):
  At least 1 required Python3 COMPONENT could not be found from :
  Interpreter;Development.Module;Development.SABIModule;NumPy

            in range 3.12.13...3.12.13:
            Python3_EXECUTABLE=:/usr/bin/python3.12:
            ITK_WRAP_PYTHON_VERSION=:3.12.13:
            Python3_ROOT_DIR=::
            ---
            Python3_FOUND=FALSE
            Python3_Interpreter_FOUND=TRUE
            Python3_Compiler_FOUND=FALSE
            Python3_Development_FOUND=FALSE
            Python3_Development.Module_FOUND=TRUE
            Python3_Development.SABIModule_FOUND=TRUE
            Python3_Development.Embed_FOUND=FALSE
            Python3_NumPy_FOUND=FALSE
      
Call Stack (most recent call first):
  CMakeLists.txt:758 (include)


-- Configuring incomplete, errors occurred!

@dzenanz

dzenanz commented Jul 17, 2026

Copy link
Copy Markdown
Member

Hmh, even main fails to configure with dzenan.zukic@krs-7714:~/ITK/ITK-py-direct$ cmake -DPython3_EXECUTABLE=/usr/bin/python3.12 -DITK_WRAP_PYTHON=ON ../ITK-git/:

dzenan.zukic@krs-7714:~/ITK/ITK-py-direct$ cmake -DPython3_EXECUTABLE=/usr/bin/python3.12 -DITK_WRAP_PYTHON=ON ../ITK-git/
-- Setting build type to 'Release' as none was specified.
-- The CXX compiler identification is GNU 11.4.0
-- The C compiler identification is GNU 11.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/lib/ccache/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/lib/ccache/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Found Git: /usr/bin/git (found version "2.34.1")
-- Performing Test C_HAS_WARNING-Wno-unused-parameter
-- Performing Test C_HAS_WARNING-Wno-unused-parameter - Success
-- Performing Test C_HAS_WARNING-Wall
-- Performing Test C_HAS_WARNING-Wall - Success
-- Performing Test C_HAS_WARNING-Wcast-align
-- Performing Test C_HAS_WARNING-Wcast-align - Success
-- Performing Test C_HAS_WARNING-Wdisabled-optimization
-- Performing Test C_HAS_WARNING-Wdisabled-optimization - Success
-- Performing Test C_HAS_WARNING-Wextra
-- Performing Test C_HAS_WARNING-Wextra - Success
-- Performing Test C_HAS_WARNING-Wformat_2
-- Performing Test C_HAS_WARNING-Wformat_2 - Success
-- Performing Test C_HAS_WARNING-Winvalid-pch
-- Performing Test C_HAS_WARNING-Winvalid-pch - Success
-- Performing Test C_HAS_WARNING-Wpointer-arith
-- Performing Test C_HAS_WARNING-Wpointer-arith - Success
-- Performing Test C_HAS_WARNING-Wshadow
-- Performing Test C_HAS_WARNING-Wshadow - Success
-- Performing Test C_HAS_WARNING-Wunused
-- Performing Test C_HAS_WARNING-Wunused - Success
-- Performing Test C_HAS_WARNING-Wwrite-strings
-- Performing Test C_HAS_WARNING-Wwrite-strings - Success
-- Performing Test CXX_HAS_WARNING-Wall
-- Performing Test CXX_HAS_WARNING-Wall - Success
-- Performing Test CXX_HAS_WARNING-Wcast-align
-- Performing Test CXX_HAS_WARNING-Wcast-align - Success
-- Performing Test CXX_HAS_WARNING-Wdisabled-optimization
-- Performing Test CXX_HAS_WARNING-Wdisabled-optimization - Success
-- Performing Test CXX_HAS_WARNING-Wextra
-- Performing Test CXX_HAS_WARNING-Wextra - Success
-- Performing Test CXX_HAS_WARNING-Wformat_2
-- Performing Test CXX_HAS_WARNING-Wformat_2 - Success
-- Performing Test CXX_HAS_WARNING-Winvalid-pch
-- Performing Test CXX_HAS_WARNING-Winvalid-pch - Success
-- Performing Test CXX_HAS_WARNING-Wpointer-arith
-- Performing Test CXX_HAS_WARNING-Wpointer-arith - Success
-- Performing Test CXX_HAS_WARNING-Wshadow
-- Performing Test CXX_HAS_WARNING-Wshadow - Success
-- Performing Test CXX_HAS_WARNING-Wunused
-- Performing Test CXX_HAS_WARNING-Wunused - Success
-- Performing Test CXX_HAS_WARNING-Wwrite-strings
-- Performing Test CXX_HAS_WARNING-Wwrite-strings - Success
-- Performing Test CXX_HAS_WARNING-Wno-undefined-var-template
-- Performing Test CXX_HAS_WARNING-Wno-undefined-var-template - Failed
-- Performing Test CXX_HAS_WARNING-Woverloaded-virtual
-- Performing Test CXX_HAS_WARNING-Woverloaded-virtual - Success
-- Performing Test CXX_HAS_WARNING-Wctad-maybe-unsupported
-- Performing Test CXX_HAS_WARNING-Wctad-maybe-unsupported - Success
-- Performing Test CXX_HAS_WARNING-Wstrict-null-sentinel
-- Performing Test CXX_HAS_WARNING-Wstrict-null-sentinel - Success
-- Performing Test CXX_HAS_DISABLE_OPTIMIZATION_FLAG
-- Performing Test CXX_HAS_DISABLE_OPTIMIZATION_FLAG - Failed
-- Could NOT find Python3 (missing: Python3_NumPy_INCLUDE_DIRS NumPy) (found suitable version "3.12.13", required range is "3.12.13...3.12.13")
-- Could NOT find Python3 (missing: Python3_NumPy_INCLUDE_DIRS NumPy) (found suitable version "3.12.13", minimum required is "3.12.13")
-- Python3_FOUND=FALSE
--  o Python3 Found COMPONENT: Python3_Interpreter_FOUND: TRUE
--  o Python3 Found COMPONENT: Python3_Development.Module_FOUND: TRUE
--  o Python3 Found COMPONENT: Python3_Development.SABIModule_FOUND: TRUE
--  o Python3 Missing COMPONENT: Python3_NumPy_FOUND: FALSE
CMake Error at CMake/ITKSetPython3Vars.cmake:158 (message):
  At least 1 required Python3 COMPONENT could not be found from :
  Interpreter;Development.Module;Development.SABIModule;NumPy

            in range 3.12.13...3.12.13:
            Python3_EXECUTABLE=:/usr/bin/python3.12:
            ITK_WRAP_PYTHON_VERSION=:3.12.13:
            Python3_ROOT_DIR=::
            ---
            Python3_FOUND=FALSE
            Python3_Interpreter_FOUND=TRUE
            Python3_Compiler_FOUND=FALSE
            Python3_Development_FOUND=FALSE
            Python3_Development.Module_FOUND=TRUE
            Python3_Development.SABIModule_FOUND=TRUE
            Python3_Development.Embed_FOUND=FALSE
            Python3_NumPy_FOUND=FALSE
      
Call Stack (most recent call first):
  CMakeLists.txt:758 (include)


-- Configuring incomplete, errors occurred!

@dzenanz

dzenanz commented Jul 17, 2026

Copy link
Copy Markdown
Member

How to point to non-system Python installed via DeadSnakes PPA (sudo add-apt-repository ppa:deadsnakes/ppa)?

@dzenanz

dzenanz commented Jul 17, 2026

Copy link
Copy Markdown
Member

Or even the one installed by MiniConda:

(base) dzenan.zukic@krs-7714:~/ITK/ITK-git$ which python3.13
/home/local/KHQ/dzenan.zukic/miniconda3/bin/python3.13

A Python interpreter without numpy fails the required-component check
with a wall of Python3_*_FOUND variables that never states which
component is missing or how to supply it. Lead the error with the
missing component list and the command that installs it.

Behavior is unchanged; only the diagnostic text differs.
@hjmjohnson

Copy link
Copy Markdown
Member Author

@dzenanz — heads-up before you finish switching the nightly: the failures you hit at 3.12 and 3.13 are numpy missing for that interpreter, not the version guard. main fails identically, so switching the nightly to 3.13 alone won't fix it — that interpreter will also need numpy.

I've pushed one more commit here that makes this obvious at configure time instead of making you read the variable dump.

Evidence: the failure tracks numpy, not the Python version

Ubuntu 24.04, cmake 3.28.3, ITK_WRAP_PYTHON=ON, BUILD_TESTING=ON, comparing main (21253ca) against this PR's head (56cdfa7):

ref interpreter numpy installed result
main python3.11 no COMPONENT could not be found
main python3.12 yes configures
main python3.13 no COMPONENT could not be found
this PR python3.11 no COMPONENT could not be found
this PR python3.12 yes configures
this PR python3.13 no COMPONENT could not be found

All three interpreters clear the 3.11 floor, so the new guard never fires in any of those rows. The only variable that changes the outcome is whether numpy is importable — which matches your own observation that main fails the same way.

Same venv, same CMake code, only pip install numpy in between:

before -> Missing required Python3 COMPONENT(s): NumPy
after  -> configures

Where the requirement comes from: CMake/ITKSetPython3Vars.cmake appends NumPy to the hard-required component list whenever BUILD_TESTING is on.

Answers to your DeadSnakes / MiniConda questions

Python3_EXECUTABLE is the right knob and it is working — your logs show it resolving 3.12.13 and 3.13.2 correctly. The interpreter it points at just has to carry numpy and the development headers:

  • DeadSnakes: apt install python3.12-dev and python3.12 -m pip install numpy
  • MiniConda: conda install numpy (a bare base env doesn't ship it)

For the nightly, whichever interpreter you settle on needs both.

What the new commit changes

Behavior is unchanged; only the diagnostic differs. Previously:

At least 1 required Python3 COMPONENT could not be found from :
Interpreter;Development.Module;Development.SABIModule;NumPy
          in range 3.12.13...3.12.13:
          ... 12 more lines of Python3_*_FOUND variables ...

Now:

Missing required Python3 COMPONENT(s): NumPy

          NumPy: /usr/bin/python3.11 -m pip install numpy

          Or set ITK_WRAP_PYTHON=OFF to build without Python wrapping.

The interpreter path is interpolated so the command is copy-pasteable. A missing Development.Module / Development.SABIModule gets its own line pointing at the matching -dev package. The original variable dump is retained below the summary.

Verified on macOS and Ubuntu 24.04 across python3.10 / 3.11 / 3.12 / 3.13, with and without numpy: every outcome matches this PR's previous head except the message text.

Sorry for the runaround on the earlier rounds — your GUI and incremental-reconfigure cases were real holes and the fixes for them stand. This last one was pre-existing and I sent you chasing it.

@dzenanz dzenanz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New commit looks reasonable. I will try this when I get back to the office.

@dzenanz

dzenanz commented Jul 20, 2026

Copy link
Copy Markdown
Member

I didn't have luck with deadsnakes Python:

dzenan.zukic@krs-7714:~/ITK/ITK-py-direct$ /usr/bin/python3.12 -m pip install numpy
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/usr/lib/python3/dist-packages/pip/__main__.py", line 29, in <module>
    from pip._internal.cli.main import main as _main
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/main.py", line 9, in <module>
    from pip._internal.cli.autocompletion import autocomplete
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/autocompletion.py", line 10, in <module>
    from pip._internal.cli.main_parser import create_main_parser
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/main_parser.py", line 8, in <module>
    from pip._internal.cli import cmdoptions
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/cmdoptions.py", line 23, in <module>
    from pip._internal.cli.parser import ConfigOptionParser
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/parser.py", line 12, in <module>
    from pip._internal.configuration import Configuration, ConfigurationError
  File "/usr/lib/python3/dist-packages/pip/_internal/configuration.py", line 26, in <module>
    from pip._internal.utils.logging import getLogger
  File "/usr/lib/python3/dist-packages/pip/_internal/utils/logging.py", line 27, in <module>
    from pip._internal.utils.misc import ensure_dir
  File "/usr/lib/python3/dist-packages/pip/_internal/utils/misc.py", line 39, in <module>
    from pip._internal.locations import get_major_minor_version
  File "/usr/lib/python3/dist-packages/pip/_internal/locations/__init__.py", line 14, in <module>
    from . import _distutils, _sysconfig
  File "/usr/lib/python3/dist-packages/pip/_internal/locations/_distutils.py", line 9, in <module>
    from distutils.cmd import Command as DistutilsCommand
ModuleNotFoundError: No module named 'distutils'

This command works properly for the system-bundled Python (3.10). So I ended up using the one from Miniconda. I updated my nightly build script.

@dzenanz

dzenanz commented Jul 20, 2026

Copy link
Copy Markdown
Member

Thank you for the fix, Hans!

@hjmjohnson
hjmjohnson merged commit 0ae23ea into InsightSoftwareConsortium:main Jul 20, 2026
23 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:Compiler Compiler support or related warnings type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants