Skip to content

Modernising Build Process#9010

Draft
ericspod wants to merge 12 commits into
Project-MONAI:devfrom
ericspod:build_update
Draft

Modernising Build Process#9010
ericspod wants to merge 12 commits into
Project-MONAI:devfrom
ericspod:build_update

Conversation

@ericspod

Copy link
Copy Markdown
Member

Fixes #8980.

Description

This updates the way MONAI is built to be more modern, relying on pip for everything with all information consolidated into the pyproject.toml file. This is still in progress and requires more testing, and needs to be double checked that the optional dependencies are correct. Highlights:

  • Move everything build related into pyproject.toml.
  • Remove the requirements file and the setup.cfg file.
  • Add a script to recreate the requirements files if needed.
  • Update the version of Versioneer used.
  • Update actions to use the new installation process in a uniform manner.
  • Update the Docker files to use the process.
  • Update installation docs to reflect these changes and clarify some parts.

Types of changes

  • Non-breaking change (fix or new feature that would not break existing functionality).
  • Breaking change (fix or new feature that would cause existing functionality to change).
  • New tests added to cover the changes.
  • Integration tests passed locally by running ./runtests.sh -f -u --net --coverage.
  • Quick tests passed locally by running ./runtests.sh --quick --unittests --disttests.
  • In-line docstrings updated.
  • Documentation updated, tested make html command in the docs/ folder.

ericspod added 10 commits July 17, 2026 14:40
Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…requirements

Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 356fce0d-cd4e-48a1-b155-7bfd5837139e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (3)
monai/_version.py (1)

47-640: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Make generated definitions conform durably.

These modified definitions lack the required Google-style argument/return/exception documentation. Update the Versioneer template or exempt generated monai/_version.py; hand edits will be overwritten. As per path instructions, definitions require Google-style variable, return, and exception documentation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@monai/_version.py` around lines 47 - 640, The generated Versioneer
definitions lack the required Google-style variable, return, and exception
documentation. Update the Versioneer template that generates symbols such as
get_config, run_command, git_pieces_from_vcs, render, and get_versions, or add
the generated monai/_version.py path to the documentation exemption; do not
hand-edit the generated file because regeneration will overwrite it.

Source: Path instructions

runtests.sh (1)

139-146: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Quote $REQ and clean up the temp file.

Unquoted $REQ (Lines 145-146) is unsafe if TMPDIR contains spaces/glob chars, and the temp requirements file is never removed after use.

🧹 Proposed fix
     REQ=$(mktemp --tmpdir XXX.txt)
-    ${cmdPrefix}"${PY_EXE}" monai/config/print_dependencies.py all testing > $REQ
-    ${cmdPrefix}"${PY_EXE}" -m pip install -r $REQ
+    ${cmdPrefix}"${PY_EXE}" monai/config/print_dependencies.py all testing > "$REQ"
+    ${cmdPrefix}"${PY_EXE}" -m pip install -r "$REQ"
+    rm -f "$REQ"
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@runtests.sh` around lines 139 - 146, Update install_deps to quote "$REQ"
wherever the temporary requirements file is passed to pip, and remove the
temporary file after installation completes. Keep the existing
dependency-generation and installation flow unchanged.

Source: Linters/SAST tools

docs/source/installation.md (1)

54-56: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add a language to the fenced code block.

Markdownlint flags this block for missing a fence language (MD040).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/source/installation.md` around lines 54 - 56, Add a language identifier
to the fenced code block containing the dependency list in the installation
documentation, using an appropriate plain-text language such as text; leave the
dependency contents unchanged.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/cicd_tests.yml:
- Around line 277-282: Update the dependency installation steps in the workflow
to install only `.[all,testing]`, then explicitly install `omegaconf` and
`nvsubquadratic>=0.1.1` with `--no-deps`. Remove the separate `python -m pip
install -e .[hyena]` step and keep the existing isolation strategy.

In @.github/workflows/cron.yml:
- Line 189: Update the artifact-install step in the workflow to install the
built package by its package name variable, using the extras all and testing,
instead of installing the current directory. Remove the python -m pip install
.[all,testing] command and the obsolete requirements*.txt copy from this step.
- Line 242: Update the dependency installation steps in the workflow to complete
the pip-only migration: replace both the existing pip install and BUILD_MONAI
setup.py develop commands with BUILD_MONAI=1 python -m pip install -e
.[all,testing].

In @.github/workflows/integration.yml:
- Line 40: Update the container image used by both integration jobs in
.github/workflows/integration.yml at lines 40-40 and 115-115 to the same image
providing Python 3.10 or newer, before the python -m pip install steps; no other
workflow behavior needs to change.

In `@Dockerfile.slim`:
- Around line 49-56: Update the editable install command after the BUILD_MONAI
and FORCE_CUDA environment settings to include pip’s --no-build-isolation
option, matching the established Dockerfile installation pattern and ensuring
extensions build against the preinstalled runtime dependencies.

In `@docs/source/installation.md`:
- Around line 52-58: Update the corresponding packages list in the installation
documentation by adding cucim-cu12 and cucim-cu13 immediately after clearml and
before cupy, preserving the extras list order so cucim has a 1:1 mapping with
its Pip dependencies.

In `@monai/__init__.py`:
- Around line 65-66: Update the __revision_id__ assignment to preserve an absent
full-revisionid as an empty string instead of converting None to "None", while
leaving the existing version fallback unchanged.

In `@monai/config/print_dependencies.py`:
- Around line 29-57: The parse_dependencies function mutates the caller-owned
sections collection via sections.remove and uses a mutable default. Change
sections to default to None, create a local set from the provided sections, and
perform BUILD_SYSTEM_KEY removal and subsequent membership/iteration operations
on that local copy.

In `@pyproject.toml`:
- Around line 72-73: Update the MetricsReloaded dependency entries for both the
all and metrics_reloaded extras to use the same immutable commit reference
instead of the differing mutable branches. Remove the branch-based URLs and
ensure both entries resolve to that identical pinned commit.

---

Nitpick comments:
In `@docs/source/installation.md`:
- Around line 54-56: Add a language identifier to the fenced code block
containing the dependency list in the installation documentation, using an
appropriate plain-text language such as text; leave the dependency contents
unchanged.

In `@monai/_version.py`:
- Around line 47-640: The generated Versioneer definitions lack the required
Google-style variable, return, and exception documentation. Update the
Versioneer template that generates symbols such as get_config, run_command,
git_pieces_from_vcs, render, and get_versions, or add the generated
monai/_version.py path to the documentation exemption; do not hand-edit the
generated file because regeneration will overwrite it.

In `@runtests.sh`:
- Around line 139-146: Update install_deps to quote "$REQ" wherever the
temporary requirements file is passed to pip, and remove the temporary file
after installation completes. Keep the existing dependency-generation and
installation flow unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 27887d1b-aeae-4dea-b5b2-726433564b42

📥 Commits

Reviewing files that changed from the base of the PR and between a3d5160 and bbdb0bc.

📒 Files selected for processing (27)
  • .github/workflows/build_docs.yml
  • .github/workflows/cicd_tests.yml
  • .github/workflows/codeql-analysis.yml
  • .github/workflows/cron-ngc-bundle.yml
  • .github/workflows/cron.yml
  • .github/workflows/docker.yml
  • .github/workflows/integration.yml
  • .github/workflows/pythonapp-gpu.yml
  • .github/workflows/pythonapp-hyena-gpu.yml
  • .github/workflows/release.yml
  • .github/workflows/weekly-preview.yml
  • Dockerfile
  • Dockerfile.slim
  • docs/requirements.txt
  • docs/source/installation.md
  • environment-dev.yml
  • monai/__init__.py
  • monai/_version.py
  • monai/config/print_dependencies.py
  • pyproject.toml
  • requirements-dev.txt
  • requirements-min.txt
  • requirements.txt
  • runtests.sh
  • setup.cfg
  • setup.py
  • versioneer.py
💤 Files with no reviewable changes (6)
  • requirements-dev.txt
  • setup.cfg
  • .github/workflows/docker.yml
  • requirements-min.txt
  • requirements.txt
  • .github/workflows/release.yml

Comment on lines +277 to +282
python -m pip install -e .[all,hyena,testing]
# # nvsubquadratic runtime imports need only torch + einops + omegaconf; install
# # the package itself without its core dependency tree (see job comment above).
# python -m pip install omegaconf
# python -m pip install --no-deps 'nvsubquadratic>=0.1.1'
python -m pip install -e .[hyena]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Keep the Hyena dependency install --no-deps.

.[hyena] resolves nvsubquadratic and its Torch constraint, contradicting the job’s stated isolation strategy. Install .[all,testing], then explicitly install omegaconf and nvsubquadratic with --no-deps; remove the second editable install.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/cicd_tests.yml around lines 277 - 282, Update the
dependency installation steps in the workflow to install only `.[all,testing]`,
then explicitly install `omegaconf` and `nvsubquadratic>=0.1.1` with
`--no-deps`. Remove the separate `python -m pip install -e .[hyena]` step and
keep the existing isolation strategy.

python -c "import torch; print(torch.__version__); print('{} of GPUs available'.format(torch.cuda.device_count()))"

python -m pip install -r requirements-dev.txt
python -m pip install .[all,testing]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not install . from the artifact directory.

At this point $tmp_dir contains the sdist and tests, not pyproject.toml or setup.py, so this fails. Install "${name}[all,testing]" at the artifact-install step and remove this command and the obsolete requirements*.txt copy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/cron.yml at line 189, Update the artifact-install step in
the workflow to install the built package by its package name variable, using
the extras all and testing, instead of installing the current directory. Remove
the python -m pip install .[all,testing] command and the obsolete
requirements*.txt copy from this step.

which python
python -m pip install --upgrade pip wheel
python -m pip install -r requirements-dev.txt
python -m pip install .[all,testing]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow matching files =="
fd -a 'cron\.yml$|cron\.yaml$' .github/workflows 2>/dev/null || true

echo "== target lines =="
if [ -f .github/workflows/cron.yml ]; then
  nl -ba .github/workflows/cron.yml | sed -n '228,250p'
fi

echo "== pip install / setup.py occurrences =="
rg -n "pip install|setup\.py develop|\[all,testing\]|BUILD_MONAI" .github/workflows/cron.yml .github/workflows 2>/dev/null || true

echo "== repository references to install commands =="
rg -n "pip install.*\[all,testing\]|setup\.py develop|BUILD_MONAI|editable|develop" .github workflows setup.py pyproject.toml 2>/dev/null | head -120 || true

Repository: Project-MONAI/MONAI

Length of output: 292


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== target lines =="
awk 'NR>=228 && NR<=252 { printf "%s\t%s\n", NR, $0 }' .github/workflows/cron.yml

echo "== install-related occurrences in cron workflow =="
awk '
  /pip install|setup\.py develop|\[all,testing\]|BUILD_MONAI|develop|editable|editable_install/ {
    printf "%s\t%s\n", NR, $0
  }
' .github/workflows/cron.yml

echo "== repository installs mentioning all/testing/build_monai/develop =="
git grep -n "pip install.*\[all,testing\]\|setup\.py develop\|BUILD_MONAI\|\[all,testing\]\|\[testing\]" .github setup.py pyproject.toml README.md 2>/dev/null | head -200 || true

Repository: Project-MONAI/MONAI

Length of output: 7270


Finish the pip-only migration.

Line 243 still runs BUILD_MONAI=1 python setup.py develop. Replace both install commands with BUILD_MONAI=1 python -m pip install -e .[all,testing].

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/cron.yml at line 242, Update the dependency installation
steps in the workflow to complete the pip-only migration: replace both the
existing pip install and BUILD_MONAI setup.py develop commands with
BUILD_MONAI=1 python -m pip install -e .[all,testing].

pip uninstall -y monai-weekly
python -m pip install --upgrade torch torchvision torchaudio torchtext
python -m pip install -r requirements-dev.txt
python -m pip install .[all,testing]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Use a Python 3.10+ integration image. Both jobs run nvcr.io/nvidia/pytorch:22.04-py3 (Python 3.8), while pyproject.toml requires Python >=3.10; pip will reject these installs.

  • .github/workflows/integration.yml#L40-L40: update the container to a Python 3.10+ image before installing extras.
  • .github/workflows/integration.yml#L115-L115: update the container to the same compatible Python version.
📍 Affects 1 file
  • .github/workflows/integration.yml#L40-L40 (this comment)
  • .github/workflows/integration.yml#L115-L115
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/integration.yml at line 40, Update the container image
used by both integration jobs in .github/workflows/integration.yml at lines
40-40 and 115-115 to the same image providing Python 3.10 or newer, before the
python -m pip install steps; no other workflow behavior needs to change.

Comment thread Dockerfile.slim
Comment on lines +49 to +56
# TODO: remark for issue [revise the dockerfile #1276](https://github.com/Project-MONAI/MONAI/issues/1276)
# please specify exact files and folders to be copied -- else, basically always, the Docker build process cannot cache
# this or anything below it and always will build from at most here; one file change leads to no caching from here on...
COPY LICENSE CHANGELOG.md CODE_OF_CONDUCT.md CONTRIBUTING.md README.md versioneer.py setup.py pyproject.toml runtests.sh MANIFEST.in ./
COPY tests ./tests
COPY monai ./monai

# install full deps
RUN python -m pip install --no-cache-dir --no-build-isolation -U wheel wheel-stub
RUN python -m pip install --no-cache-dir --no-build-isolation "torch>=2.8.0,<2.11" -r requirements-dev.txt

# compile ext
RUN CUDA_HOME=/usr/local/cuda FORCE_CUDA=1 USE_COMPILED=1 BUILD_MONAI=1 python setup.py develop
RUN BUILD_MONAI=1 FORCE_CUDA=1 pip install --no-cache-dir -e .[all,testing]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Missing --no-build-isolation risks ABI-mismatched compiled extensions.

Unlike Dockerfile (which pre-installs build-system deps and uses --no-build-isolation), this editable install with BUILD_MONAI=1 uses pip's default build isolation. Per this PR's own new warning in docs/source/installation.md, build isolation may resolve a different PyTorch than the one that ends up installed at runtime, producing a compiled extension that's ABI-incompatible and won't load. Apply the same pattern as Dockerfile.

🔧 Proposed fix mirroring Dockerfile's approach
-RUN BUILD_MONAI=1 FORCE_CUDA=1 pip install --no-cache-dir -e .[all,testing]
+RUN python monai/config/print_dependencies.py build-system | xargs pip install --no-cache-dir --no-build-isolation \
+  && BUILD_MONAI=1 FORCE_CUDA=1 pip install --no-cache-dir --no-build-isolation -e .[all,testing]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# TODO: remark for issue [revise the dockerfile #1276](https://github.com/Project-MONAI/MONAI/issues/1276)
# please specify exact files and folders to be copied -- else, basically always, the Docker build process cannot cache
# this or anything below it and always will build from at most here; one file change leads to no caching from here on...
COPY LICENSE CHANGELOG.md CODE_OF_CONDUCT.md CONTRIBUTING.md README.md versioneer.py setup.py pyproject.toml runtests.sh MANIFEST.in ./
COPY tests ./tests
COPY monai ./monai
# install full deps
RUN python -m pip install --no-cache-dir --no-build-isolation -U wheel wheel-stub
RUN python -m pip install --no-cache-dir --no-build-isolation "torch>=2.8.0,<2.11" -r requirements-dev.txt
# compile ext
RUN CUDA_HOME=/usr/local/cuda FORCE_CUDA=1 USE_COMPILED=1 BUILD_MONAI=1 python setup.py develop
RUN BUILD_MONAI=1 FORCE_CUDA=1 pip install --no-cache-dir -e .[all,testing]
# TODO: remark for issue [revise the dockerfile `#1276`](https://github.com/Project-MONAI/MONAI/issues/1276)
# please specify exact files and folders to be copied -- else, basically always, the Docker build process cannot cache
# this or anything below it and always will build from at most here; one file change leads to no caching from here on...
COPY LICENSE CHANGELOG.md CODE_OF_CONDUCT.md CONTRIBUTING.md README.md versioneer.py setup.py pyproject.toml runtests.sh MANIFEST.in ./
COPY tests ./tests
COPY monai ./monai
RUN python monai/config/print_dependencies.py build-system | xargs pip install --no-cache-dir --no-build-isolation \
&& BUILD_MONAI=1 FORCE_CUDA=1 pip install --no-cache-dir --no-build-isolation -e .[all,testing]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Dockerfile.slim` around lines 49 - 56, Update the editable install command
after the BUILD_MONAI and FORCE_CUDA environment settings to include pip’s
--no-build-isolation option, matching the established Dockerfile installation
pattern and ensuring extensions build against the preinstalled runtime
dependencies.

Comment on lines +52 to +58
MONAI supports the extras syntax such as `pip install 'monai[nibabel]'`. The options are

```
clearml, cucim, cupy, einops, fire, gdown, h5py, huggingface_hub, hyena, ignite, imagecodecs, itk, jsonschema, lmdb, lpips, matplotlib, mccabe, metrics_reloaded, mlflow, mypy, nibabel, nni, onnx, openslide, optuna, pandas, pillow, polygraphy, psutil, pyamg, pybind11, pydicom, pynrrd, pytest, pynvml, pyyaml, requests, segment_anything, scipy, skimage, tensorboard, tensorboardX, tifffile, torchio, torchvision, tqdm, transformers, zarr
```

which correspond to the packages: `clearml`, `cupy`, `einops`, `fire`, `gdown`, `h5py`, `huggingface_hub`, `nvsubquadratic`, `omegaconf`, `pytorch-ignite`, `imagecodecs`, `itk`, `jsonschema`, `lmdb`, `lpips`, `matplotlib`, `mccabe`, `MetricsReloaded`, `mlflow`, `mypy`, `nibabel`, `nni`, `filelock`, `onnx`, `onnxruntime`, `onnx_graphsurgeon`, `onnxscript`, `openslide-python`, `openslide-bin`, `optuna`, `pandas`, `pillow`, `polygraphy`, `psutil`, `pyamg`, `pybind11`, `pydicom`, `pynrrd`, `pytest`, `nvidia-ml-py`, `pyyaml`, `requests`, `segment_anything`, `scipy`, `scikit-image`, `tensorboard`, `tensorboardX`, `tifffile`, `torchio`, `torchvision`, `tqdm`, `transformers`, `zarr`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file exists and relevant section =="
if [ -f docs/source/installation.md ]; then
  sed -n '45,65p' docs/source/installation.md | cat -n -v
else
  echo "docs/source/installation.md not found"
 fi

echo
echo "== search for cucim in repo =="
rg -n "\bcucim\b|clearml|cupy|openslide-python|pip install" docs/source/installation.md setup.py setup.cfg pyproject.toml 2>/dev/null || true

echo
echo "== deterministic list comparison for sections around lines 54-58 =="
python3 - <<'PY'
from pathlib import Path
import re

p = Path("docs/source/installation.md")
if not p.exists():
    print("source missing")
    raise SystemExit(0)

text = p.read_text()
m = re.search(r"```(?P<l>\w*)\n(?P<body>.*?)\n```", text)
if not m:
    print("no fenced block found")
    raise SystemExit(0)
print("fence language:", repr(m.group("l")))
block = m.group("body").strip().splitlines()
print("extras block lines:", len(block))
matches = [re.sub(r"[,\s]+", " ", line).split() for line in block if line.strip()]
extras = [x for entry in matches for x in entry]
next_sentence = []
for line in text[m.end():].splitlines():
    if line.strip():
        next_sentence.append(line)
        break
print("next sentence:", next_sentence)

all_text = "\n".join(matches[-6:])
# take comma-separated package names while preserving dashes/underscores, and strip package names from quotes if any.
pkgs = re.findall(r"(?:^|,\s*|:\s*|)`?([A-Za-z0-9_\-\.]+)`?", "\n".join(matches))
pkgs_normalized = []
for pkg in pkgs:
    # Strip quote-surrounded entries if any
    pkg = pkg.strip("'`").strip()
    if pkg:
        pkgs_normalized.append(pkg)

print("extras:", "\n".join(f"{i}: {e}" for i,e in enumerate(extras)))
print("packages:", "\n".join(f"{i}: {pe}" for i,pe in enumerate(pkgs_normalized)))
print("counts:", len(extras), len(pkgs_normalized))
print("same extras==packages?", extras == pkgs_normalized)
for i, (e, pe) in enumerate(zip(extras, pkgs_normalized)):
    if e != pe:
        print("first mismatch:", i, repr(e), repr(pe))
PY

Repository: Project-MONAI/MONAI

Length of output: 6440


🌐 Web query:

MONAI installation documentation cucumber cucim extras pip install cucim correspondence list

💡 Result:

In the MONAI ecosystem, the cucim extra is a dependency option that facilitates GPU-accelerated image processing [1][2]. ### Installation and Correspondence When installing MONAI via pip, you can include cucim as an optional dependency using the extras syntax [1][3]. For example: pip install 'monai[cucim]' This command specifically triggers the installation of the corresponding cucim packages [2]. According to the project's configuration, the cucim extra maps to cucim-cu12 (for Python versions 3.9–3.10) or cucim-cu13 (for Python 3.11 and newer) on Linux platforms [2]. ### Important Compatibility Notes * Platform Limitation: The cucim packages currently provided through MONAI's extras are primarily intended for Linux environments [2]. Users on Windows may encounter errors if they attempt to install the all extras bundle—which includes cucim—because cucim does not currently provide native Windows wheels [4]. * Scope: Including cucim via pip install 'monai[cucim]' provides the necessary libraries to enable specific GPU-accelerated features within MONAI, such as those found in cucim.skimage [5][6]. * Full Installation: If you wish to install all optional dependencies, including cucim, you can use pip install 'monai[all]' [1][7]. However, users on unsupported platforms (like Windows) should install dependencies selectively to avoid dependency resolution or wheel availability issues [4].

Citations:


Align the extras and corresponding packages list for the cucim entry.

docs/source/installation.md:55 lists cucim, but line 58 jumps from clearml to cupy, so packages after cupy no longer match their extras. For cucim, the corresponding Pip dependencies are cucim-cu12 and cucim-cu13; add those to the package list before cupy to keep the 1:1 mapping accurate.

🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 54-54: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/source/installation.md` around lines 52 - 58, Update the corresponding
packages list in the installation documentation by adding cucim-cu12 and
cucim-cu13 immediately after clearml and before cupy, preserving the extras list
order so cucim has a 1:1 mapping with its Pip dependencies.

Source: Path instructions

Comment thread monai/__init__.py
Comment on lines +29 to +57
def parse_dependencies(filename=TOML_FILE, sections=[]):
# these imports should be here to avoid attempting to import when MONAI is imported and both packages are missing
if sys.version_info.minor >= 11:
import tomllib

load_func = tomllib.loads
else:
import tomli

load_func = tomli.loads

with open(filename) as o:
data = load_func(o.read())

proj = data[PROJ_KEY]
opts = proj[OPTS_KEY]
dependencies = list(proj[DEP_KEY])

if BUILD_SYSTEM_KEY in sections:
sections.remove(BUILD_SYSTEM_KEY)
dependencies += data[BUILD_SYSTEM_KEY][REQ_KEY]

if "*" in sections:
dependencies += sum(opts.values(), [])
else:
for s in sections:
dependencies += opts[s]

return sorted(set(dependencies))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Do not mutate a default/caller-owned collection.

sections.remove() changes the passed collection. Default to None and copy into a local set.

🧰 Tools
🪛 ast-grep (0.44.1)

[warning] 39-39: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(filename)
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(open-filename-from-request)

🪛 Ruff (0.15.21)

[warning] 29-29: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


[warning] 52-52: Avoid quadratic list summation

Replace with functools.reduce

(RUF017)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@monai/config/print_dependencies.py` around lines 29 - 57, The
parse_dependencies function mutates the caller-owned sections collection via
sections.remove and uses a mutable default. Change sections to default to None,
create a local set from the provided sections, and perform BUILD_SYSTEM_KEY
removal and subsequent membership/iteration operations on that local copy.

Source: Linters/SAST tools

Comment thread pyproject.toml
Comment on lines +72 to +73
# TODO: change URL to https://github.com/Project-MONAI/MetricsReloaded@monai-support before finalising
"MetricsReloaded @ git+https://github.com/ericspod/MetricsReloaded@monai-support-fix",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Pin and unify MetricsReloaded.

all uses monai-support-fix, while metrics_reloaded uses monai-support; both are mutable branches. Use one immutable commit reference in both extras.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pyproject.toml` around lines 72 - 73, Update the MetricsReloaded dependency
entries for both the all and metrics_reloaded extras to use the same immutable
commit reference instead of the differing mutable branches. Remove the
branch-based URLs and ensure both entries resolve to that identical pinned
commit.

@ericspod
ericspod requested a review from garciadias July 23, 2026 22:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Modernise Building Process

1 participant