Describe the bug
Whether the unit-test suite passes depends on which Python version the environment was built with, because [project.optional-dependencies].all has no upper bounds. Several dependencies have moved to requires-python >= 3.11 or >= 3.12, so a Python 3.10 environment simply cannot reach the releases that break MONAI, while a 3.12 environment installs them by default.
CI pins PYTHON_VER1: '3.10' and uses it for static-checks and full-dep, so CI never resolves the versions that fail. A contributor following CONTRIBUTING.md on a current interpreter does.
To Reproduce
uv venv --python 3.12 /tmp/env312 && VIRTUAL_ENV=/tmp/env312 uv pip install -e ".[all,testing]"
uv venv --python 3.10 /tmp/env310 && VIRTUAL_ENV=/tmp/env310 uv pip install -e ".[all,testing]"
./runtests.sh -u --net --coverage
What each interpreter resolves, from the same unbounded specifiers:
| dependency |
Python 3.12 |
Python 3.10 |
why 3.10 cannot reach it |
zarr |
3.3.0 |
2.18.3 |
requires-python >= 3.12 |
scipy |
1.18.1 |
1.15.3 |
requires-python >= 3.12 |
matplotlib |
3.11.1 |
3.10.9 |
requires-python >= 3.11 |
Full suite, unmodified dev (c1240a2d4), Python 3.12: 18196 tests, 15 failures, 26 errors. Rebuilding the same tree on Python 3.10 clears five of the seven affected modules.
Which modules fail on 3.12 and why
| module |
cause |
3.10 |
tests.inferers.test_zarr_avg_merger (20 errors) |
zarr 3.3.0: ValueError: True is not a valid chunk input. Use chunks=None or chunks="auto" ... from zarr/core/chunk_grids.py:781 |
passes |
tests.metrics.test_compute_fid_metric |
scipy 1.18 removed disp from scipy.linalg.sqrtm; monai/metrics/fid.py:85 calls sqrtm(..., disp=False) and unpacks two return values |
passes |
tests.data.test_threadcontainer |
matplotlib baseline-image comparison, RMS 23.6 vs tolerance 0.05 (the baseline PNG dates from 2021) |
passes |
tests.visualize.utils.test_matshow3d |
same |
passes |
tests.transforms.test_orientation |
'LIP' != 'LPS', 'RSP' != 'RAS' |
passes |
tests.data.test_nifti_rw, tests.data.test_image_rw |
unrelated — a genuine bug, filed separately as #9068 |
still fails |
Note the zarr failure here is not the one in #8476 (compressor cannot be used for arrays with zarr_format 3); zarr 3.3.0 also rejects chunks=True. Related: #8380, #8459, #8476.
QUICKTEST=True, which full-dep sets, does not skip any of these — I checked. CI avoids them purely through the Python pin.
torch has the same shape of gap: torch>=2.8.0 is unbounded, while CI tests 2.8.0–2.11.0 (PYTORCH_VER1..PYTORCH_VER4). A fresh environment installs 2.13.0, two minor versions past anything exercised.
Expected behavior
A contributor who follows CONTRIBUTING.md should get an environment where the suite passes, or a clear failure at install time — not green-or-red depending on the interpreter they happened to use.
Additional context
Two directions, not mutually exclusive:
- Bound what is known to break. Upper caps for
zarr, scipy and matplotlib state the supported range explicitly instead of leaving it to interpreter-driven resolution. This is bookkeeping and it goes stale, but it makes the constraint visible.
- Test a modern Python. The
min-dep matrix covers 3.10–3.13 with pinned torch, but full-dep — the job that installs [all] — runs only PYTHON_VER1 (3.10). A full-dep leg on PYTHON_VER3/PYTHON_VER4 would surface these at the same time contributors hit them, rather than after the fact.
The matplotlib case may want handling on its own terms: a 2021 baseline PNG compared at 0.05 tolerance will drift with any renderer change, independent of pinning policy.
Describe the bug
Whether the unit-test suite passes depends on which Python version the environment was built with, because
[project.optional-dependencies].allhas no upper bounds. Several dependencies have moved torequires-python >= 3.11or>= 3.12, so a Python 3.10 environment simply cannot reach the releases that break MONAI, while a 3.12 environment installs them by default.CI pins
PYTHON_VER1: '3.10'and uses it forstatic-checksandfull-dep, so CI never resolves the versions that fail. A contributor followingCONTRIBUTING.mdon a current interpreter does.To Reproduce
What each interpreter resolves, from the same unbounded specifiers:
zarrrequires-python >= 3.12scipyrequires-python >= 3.12matplotlibrequires-python >= 3.11Full suite, unmodified
dev(c1240a2d4), Python 3.12: 18196 tests, 15 failures, 26 errors. Rebuilding the same tree on Python 3.10 clears five of the seven affected modules.Which modules fail on 3.12 and why
tests.inferers.test_zarr_avg_merger(20 errors)ValueError: True is not a valid chunk input. Use chunks=None or chunks="auto" ...fromzarr/core/chunk_grids.py:781tests.metrics.test_compute_fid_metricdispfromscipy.linalg.sqrtm;monai/metrics/fid.py:85callssqrtm(..., disp=False)and unpacks two return valuestests.data.test_threadcontainertests.visualize.utils.test_matshow3dtests.transforms.test_orientation'LIP' != 'LPS','RSP' != 'RAS'tests.data.test_nifti_rw,tests.data.test_image_rwNote the zarr failure here is not the one in #8476 (
compressor cannot be used for arrays with zarr_format 3); zarr 3.3.0 also rejectschunks=True. Related: #8380, #8459, #8476.QUICKTEST=True, whichfull-depsets, does not skip any of these — I checked. CI avoids them purely through the Python pin.torchhas the same shape of gap:torch>=2.8.0is unbounded, while CI tests 2.8.0–2.11.0 (PYTORCH_VER1..PYTORCH_VER4). A fresh environment installs 2.13.0, two minor versions past anything exercised.Expected behavior
A contributor who follows
CONTRIBUTING.mdshould get an environment where the suite passes, or a clear failure at install time — not green-or-red depending on the interpreter they happened to use.Additional context
Two directions, not mutually exclusive:
zarr,scipyandmatplotlibstate the supported range explicitly instead of leaving it to interpreter-driven resolution. This is bookkeeping and it goes stale, but it makes the constraint visible.min-depmatrix covers 3.10–3.13 with pinned torch, butfull-dep— the job that installs[all]— runs onlyPYTHON_VER1(3.10). Afull-depleg onPYTHON_VER3/PYTHON_VER4would surface these at the same time contributors hit them, rather than after the fact.The matplotlib case may want handling on its own terms: a 2021 baseline PNG compared at 0.05 tolerance will drift with any renderer change, independent of pinning policy.