Add spatial shape constraints to UNETR docstring and validation - #9093
Open
Lubnaaziz-28 wants to merge 72 commits into
Open
Add spatial shape constraints to UNETR docstring and validation#9093Lubnaaziz-28 wants to merge 72 commits into
Lubnaaziz-28 wants to merge 72 commits into
Conversation
### Description Sets the weekly preview version to start with 1.7. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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. Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
… matrix (Project-MONAI#8888) Closes Project-MONAI#6711. ### Description This PR adds a documentation note to the `Transpose` and `Transposed` transforms clarifying that they do not update the affine matrix in the image metadata. As established in Project-MONAI#5975, this is intended behavior: applying an affine-dependent transform such as `Spacing`/`Spacingd` after `Transpose`/`Transposed` can therefore produce unexpected results. The note points users to `Orientation`/`Orientationd` for affine-aware reorientation. This is a documentation-only change; no functional code is modified. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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`. - [x] In-line docstrings updated. - [ ] Documentation updated, tested `make html` command in the `docs/` folder. Signed-off-by: Akarsh Doki <doki.ak@northeastern.edu> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…ject-MONAI#8887) Fixes Project-MONAI#8886 ### Types of changes - [x] Non-breaking change (fix or new feature that would not break existing functionality). --------- Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…ect-MONAI#8893) Fixes Project-MONAI#8892 ### Description During automated test execution, the logs were getting flooded with thousands of verbose lines when `unittest.TestCase.assertWarns` internally triggered property accessors for `__warningregistry__` on dynamic configurations. This PR globally configures `pytest` inside `setup.cfg` to ignore and suppress regex pattern filter hits matching `.*__warningregistry__.*`, significantly cleaning up the CI/CD pipeline output logs. Signed-off-by: jet1technology-tech <jet1technology@ryngo.in> Co-authored-by: jet1technology-tech <jet1technology@ryngo.in> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
### Description
Test-only cleanup. Removes byte-identical duplicate cases and one
permanently-skipped test. No production code or test logic changes.
### Changes
Duplicate within-file parametrized cases (identical entries that
asserted the same thing twice, so removal changes nothing covered):
- `tests/losses/test_unified_focal_loss.py`: both `TEST_CASES` entries
were identical
- `tests/inferers/test_sliding_window_inference.py`: duplicate `3D small
roi` case
- `tests/losses/test_dice_loss.py`: `sigmoid` case repeated
- `tests/losses/test_generalized_dice_loss.py`: `sigmoid` case repeated
- `tests/transforms/utility/test_apply_transform_to_pointsd.py`:
duplicate entry
Dead test removed:
- `tests/apps/test_download_url_yandex.py`: removed `test_verify` and
its now-unused `YANDEX_MODEL_URL`. It was permanently
`@unittest.skip`-ed ("data source unstable") and hits an external Yandex
URL, so it never runs in CI. The error path stays covered by
`test_verify_error`.
### Types of changes
- [x] Non-breaking change (test-only cleanup)
- [x] In-line documentation / comments updated as needed
- [x] All tests passing locally
---------
Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk>
Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
## Summary Fixes Project-MONAI#6397 - Adds a `_spatial_ndim: int` attribute to `MetaTensor` that explicitly tracks the number of spatial dimensions, preventing dimension-mismatch crashes when `einops.rearrange()` or other reshape operations change `ndim` - The attribute propagates through `copy_meta_from` (via `__dict__` copy) and is preserved through arbitrary torch operations - Updates transforms (`Resize`, `Rotate`, `Zoom`, `Flip`, `Affine`, `SplitDim`, `AddCoordinateChannels`, etc.) and lazy resampling to use `spatial_ndim` instead of hardcoded 3 ### Key design decisions - **Constructor**: `spatial_ndim = min(affine.shape[-1] - 1, ndim - 1)` — clamped by actual tensor dims - **Affine setter**: `spatial_ndim = affine.shape[-1] - 1` — no clamping (user is explicit) - **`peek_pending_affine`**: uses affine's inner matrix shape (fixes batched `(1,4,4)` case) - **`spatial_resample`**: `min(spatial_ndim, ndim - 1, 3)` — adds ndim-1 constraint as safety net ### Files changed (16) - `monai/data/meta_obj.py`, `meta_tensor.py`, `utils.py`, `__init__.py` — core MetaTensor changes - `monai/transforms/` — spatial, croppad, intensity, inverse, lazy, post, utility transforms updated - `tests/data/meta_tensor/test_spatial_ndim.py` — 18 new tests - Existing test files updated with `spatial_ndim` assertions ## Test plan - [x] 18 new unit tests for `spatial_ndim` property (construction, affine sync, propagation, einops reshape, transforms) - [x] Existing MetaTensor tests pass (162 tests) - [x] SqueezeDim and SplitDim tests pass with new assertions - [x] Total: 216 tests verified passing --------- Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…Project-MONAI#8727) ## Summary This PR improves the documentation for the `Affine` transform and adds unit tests for the `compute_w_affine` method. Fixes Project-MONAI#7092 ## Changes ### Documentation improvements (`monai/transforms/spatial/array.py`) - **Added Note section** to `Affine` class documenting the center-origin coordinate system assumption - **Clarified `normalized` parameter** documentation with user-friendly explanation - **Added comprehensive docstring** to `compute_w_affine` classmethod (previously undocumented) ### Unit tests (`tests/transforms/test_affine.py`) - Added `TestComputeWAffine` test class with focused tests: - 2D/3D identity matrix with same input/output size - Different input/output sizes with expected translation offsets - Output shape validation - Torch tensor input compatibility ## Verification - All existing Affine tests pass (no regressions) - All new `compute_w_affine` tests pass - Documentation matches actual code logic ## Type of change - [x] Documentation improvement - [x] Test coverage improvement - [ ] Breaking change Signed-off-by: Mohamed Salah <eng.mohamed.tawab@gmail.com> Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…l compatibility (Project-MONAI#8912) ## Summary - Rebase Docker image from `nvcr.io/nvidia/pytorch:24.10-py3` to `25.03-py3` to support RTX 5090 (Blackwell, SM_120/CUDA 12.8); remove the now-obsolete `torch.patch` ONNX revert which was specific to 24.10 - Pin `mlflow<3.0` — mlflow 3.x is broken on Python 3.12 due to a relative import in `mlflow.utils.uv_utils` (`from .. import zipp` fails at top-level scope); this caused 4 tutorial notebooks to fail in our CI run - Pin `transformers<5.0` — transformers 5.x references `torch.float8_e8m0fnu` which does not exist in the nv25.03 build of PyTorch 2.7; this caused the HuggingFace tutorial to fail - Add `aim` and `lightning>=2.0` as declared dependencies in `requirements-dev.txt` (were previously undeclared but required by tutorial notebooks) - Rebuild the NVIDIA pip constraint file to retain `numpy==1.26.4` (nv25.03 PyTorch compiled against NumPy 1.x) and add `setuptools<71` (newer setuptools dropped `pkg_resources` needed by legacy `setup.py` in git-sourced packages like MetricsReloaded and segment-anything) - Remove `python_version <= '3.10'` caps from `cucim`, `onnxruntime`, and `transformers` — these restrictions were keeping packages out of the Python 3.12 image unnecessarily - Install `papermill`, `jupytext`, `autopep8`, `autoflake`, and `ipywidgets` directly in the Dockerfile so the tutorial runner is self-contained ## Context These changes were identified by running the full MONAI tutorial test suite in a fresh Docker build against a MONAI 1.6 dev branch and comparing results with a native conda reference run (Eric's run, `eccefc57`). The rerun with stderr captured (`runner_output_our_only.logs`) confirmed the specific error for each notebook group. ## Type of change - [x] Bug fix - [ ] Feature - [ ] Hotfix - [ ] Spike / exploration - [ ] Documentation - [ ] Refactor ## Test plan - [ ] Rebuild Docker image with `docker build -t monai_1_6:latest .` - [ ] Re-run `bash run_our_only.sh 2>&1 | tee runner_output_v2.logs` inside the container - [ ] Verify mlflow notebooks pass (R1: 4 notebooks) - [ ] Verify `hugging_face/hugging_face_pipeline_for_monai.ipynb` passes (R3) - [ ] Verify `experiment_management/spleen_segmentation_aim.ipynb` passes (R6) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com>
## Summary - Fix division by zero in `SoftclDiceLoss` and `SoftDiceclDiceLoss` when computing the harmonic mean of topology precision and sensitivity - Add a small epsilon (`1e-7`) to the denominator `(tprec + tsens)` to prevent `NaN` when both values are zero - Add test cases for zero-input and non-overlapping edge cases with `smooth=0` ## Details The clDice loss computes `cl_dice = 1.0 - 2.0 * (tprec * tsens) / (tprec + tsens)`. When both `tprec` and `tsens` are zero (e.g., empty inputs, non-overlapping predictions/targets, or `smooth=0`), this results in `0/0 = NaN`, which propagates through the loss and crashes training. While the default `smooth=1.0` prevents `tprec` and `tsens` from being exactly zero in most cases, setting `smooth=0` (a valid configuration) exposes this bug whenever skeleton overlap is zero. The fix adds `1e-7` to the harmonic mean denominator, which: - Has negligible impact on normal computation (tprec, tsens are bounded in [0, 1]) - Returns `cl_dice = 1.0` (maximum loss) when both precision and sensitivity are zero, which is the correct semantic result - Is consistent with epsilon-based denominator guards used elsewhere in MONAI (e.g., `smooth_dr` in `DiceLoss`) ## Test plan - [x] Existing `test_cldice_loss.py` tests still pass (perfect overlap cases) - [x] New `test_zero_input_no_nan`: verifies zero-valued inputs with `smooth=0` do not produce NaN - [x] New `test_no_overlap_no_nan`: verifies non-overlapping predictions/targets with `smooth=0` do not produce NaN
…-MONAI#8872) ## Summary - `GlobalMutualInformationLoss` stored `preterm` and `bin_centers` as plain tensor attributes when `kernel_type="gaussian"`, so calling `loss.to("cuda")` or `loss.cuda()` did **not** move them to the target device - Replace the plain assignments with `register_buffer(..., persistent=False)`, consistent with the pattern already applied to `LocalNormalizedCrossCorrelationLoss` in Project-MONAI#8818 - The `.to(img)` calls in `parzen_windowing_gaussian` are retained for dtype coercion (e.g. float16 inference) ## Test plan - [x] `python -m pytest tests/losses/image_dissimilarity/test_global_mutual_information_loss.py -v` — all existing tests still pass - [x] `TestGlobalMutualInformationLossBuffers::test_gaussian_kernel_registers_buffers` — `preterm` and `bin_centers` are in `_buffers` and have `requires_grad=False` - [x] `TestGlobalMutualInformationLossBuffers::test_bspline_kernel_has_no_gaussian_buffers` — b-spline mode is unaffected - [x] `TestGlobalMutualInformationLossBuffers::test_gaussian_kernel_forward_correct` — forward pass returns a scalar loss Closes Project-MONAI#8819 --------- Signed-off-by: Oleksandr Sanin <alexaaander.sanin@gmail.com> Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
### Description Follow-up to Project-MONAI#8896. Test-only cleanup removing byte-identical duplicate entries from parametrized case lists. No coverage is lost since each removed entry has an identical sibling that remains. Only genuine duplicates from the comment are removed. ### Changes - `tests/transforms/test_border_pad.py`: repeated 6-element `spatial_border` case - `tests/transforms/test_border_padd.py`: `spatial_border=2` case repeated twice - `tests/transforms/test_spatial_padd.py`: repeated `method="end"` case - `tests/transforms/test_center_spatial_crop.py`: repeated `roi_size=[2, 2, 2]` case - `tests/networks/nets/test_autoencoderkl.py`: duplicate `CASES_ATTENTION` entry - `tests/networks/nets/test_spade_autoencoderkl.py`: duplicate `CASES_ATTENTION` entry ### Types of changes - [x] Non-breaking change (test-only cleanup) - [x] All tests passing locally --------- Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk>
### Description `batched_nms` is documented to accept an Nx4/Nx6 torch tensor or ndarray, but it computed `boxes_for_nms = boxes + offsets[:, None]` using the original `boxes` argument instead of the converted tensor `boxes_t`. Since `offsets` is a torch tensor derived from `boxes_t`, passing an ndarray added a numpy array to a torch tensor and raised `TypeError`, breaking `batched_nms` for all ndarray inputs. The offset is now added to the converted tensor: `boxes_for_nms = boxes_t + offsets[:, None]`. Everything else downstream already operates on `boxes_t`, and the result is converted back to the input type, so the torch path is unchanged. ### Types of changes - [x] Non-breaking change (fix or new feature that would not break existing functionality). - [x] 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. --------- Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…roject-MONAI#8931) (Project-MONAI#8932) Fixes Project-MONAI#8931 ## Problem 12 `warnings.warn()` calls in `monai/metrics/` are missing `stacklevel=2`. Without this parameter, warnings point to MONAI library internals instead of the user's calling code, making them unhelpful for debugging. This follows the same pattern identified in `losses/` (PR Project-MONAI#8930) and is a natural extension to the `metrics/` module. ## Solution Added `stacklevel=2` to all 12 `warnings.warn()` calls across 6 files in `monai/metrics/`: | File | Warning | Line | |------|---------|------| | `cumulative_average.py` | non-finite inputs received | ~157 | | `average_precision.py` | y values all same / invalid | ~91, ~96 | | `utils.py` | ground truth/prediction all zero | ~342, ~348 | | `utils.py` | binarized tensor | ~380 | | `utils.py` | Voronoi CPU | ~515 | | `active_learning_metrics.py` | spatial map / reduction | ~140, ~195 | | `confusion_matrix.py` | compute_sample | ~96 | | `rocauc.py` | y values all same / invalid | ~80, ~85 | Note: `embedding_collapse.py` already had `stacklevel=3` (intentionally different for its call depth) and was left unchanged. ## Verification - All 6 modified files pass `ast.parse()` syntax check - All 14 `warnings.warn()` calls in `monai/metrics/` confirmed to have `stacklevel` parameter - No other code changes — purely additive `stacklevel=2` parameter additions ## Changelog | Date | Change | Author | |------|--------|--------| | 2026-06-19 | Add missing stacklevel=2 to 12 warnings.warn() calls in monai/metrics/ | rtmalikian | ### Files Changed - `monai/metrics/cumulative_average.py` — Added stacklevel=2 to 1 warning - `monai/metrics/average_precision.py` — Added stacklevel=2 to 2 warnings - `monai/metrics/utils.py` — Added stacklevel=2 to 4 warnings - `monai/metrics/active_learning_metrics.py` — Added stacklevel=2 to 2 warnings - `monai/metrics/confusion_matrix.py` — Added stacklevel=2 to 1 warning - `monai/metrics/rocauc.py` — Added stacklevel=2 to 2 warnings ### Verification - All 6 files pass Python syntax check (ast.parse) - All 14 warnings.warn() calls in monai/metrics/ confirmed to have stacklevel parameter - No functional behavior changes — only warning source location improves --- **About the Author:** Raphael Malikian — Clinical AI Solutions Architect. I specialise in building and fixing AI/ML systems for healthcare, including vector databases, RAG pipelines, and clinical NLP. If you need help with your project or think I can add value to your organisation, feel free to reach out — I'd love to connect. 📧 rtmalikian@gmail.com 🔗 GitHub: https://github.com/rtmalikian 🔗 LinkedIn: http://www.linkedin.com/in/raphael-t-malikian-mbbs-bsc-hons-71075436a --- **Disclosure:** This code was developed with assistance from **mimo-v2.5-pro** (Xiaomi) via **Hermes Agent** (Nous Research). All changes were reviewed, tested against the actual codebase, and verified for correctness. --------- Signed-off-by: Raphael Malikian <rtmalikian@gmail.com> Signed-off-by: rtmalikian <rtmalikian@gmail.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…oject-MONAI#8929) (Project-MONAI#8930) Fixes Project-MONAI#8929 ## Problem 28 calls to `warnings.warn()` in `monai/losses/` are missing the `stacklevel` parameter. Without `stacklevel=2`, warnings point to the MONAI internal code instead of the user's calling code, making it difficult for users to identify which part of their script triggered the warning. ## Solution Added `stacklevel=2` to all 28 `warnings.warn()` calls across 9 loss modules: - `dice.py` (7 instances) - `tversky.py` (3 instances) - `mcc_loss.py` (3 instances) - `focal_loss.py` (3 instances) - `hausdorff_loss.py` (3 instances) - `unified_focal_loss.py` (3 instances) - `spatial_mask.py` (3 instances) - `perceptual.py` (2 instances) - `adversarial_loss.py` (1 instance) Also fixes a typo in `perceptual.py`: `"supp, ort"` → `"support"` (carried from Project-MONAI#8924). ## Verification ```bash # All 28 warnings.warn() calls now have stacklevel=2 $ grep -c "stacklevel" monai/losses/*.py # Each file's stacklevel count matches its warnings.warn count # All 9 files pass syntax check $ python3 -c "import ast; [ast.parse(open(f).read()) for f in files]" 9 files checked, 0 errors ``` ## Changelog | Date | Change | Author | |------|--------|--------| | 2026-06-19 | Add missing stacklevel=2 to 28 warnings.warn() calls in 9 loss modules | rtmalikian | ### Files Changed - `monai/losses/dice.py` — 7 warnings.warn() calls updated - `monai/losses/tversky.py` — 3 calls updated - `monai/losses/mcc_loss.py` — 3 calls updated - `monai/losses/focal_loss.py` — 3 calls updated - `monai/losses/hausdorff_loss.py` — 3 calls updated - `monai/losses/unified_focal_loss.py` — 3 calls updated - `monai/losses/spatial_mask.py` — 3 calls updated - `monai/losses/perceptual.py` — 2 calls updated + typo fix - `monai/losses/adversarial_loss.py` — 1 call updated ### Verification - All 28 warnings.warn() calls now include stacklevel=2 - All 9 modified files pass Python syntax validation - No duplicate stacklevel parameters --- **About the Author:** Raphael Malikian — Clinical AI Solutions Architect. I specialise in building and fixing AI/ML systems for healthcare, including vector databases, RAG pipelines, and clinical NLP. If you need help with your project or think I can add value to your organisation, feel free to reach out — I'd love to connect. 📧 rtmalikian@gmail.com 🔗 GitHub: https://github.com/rtmalikian 🔗 LinkedIn: http://www.linkedin.com/in/raphael-t-malikian-mbbs-bsc-hons-71075436a --- **Disclosure:** This code was developed with assistance from **MiMo-v2.5-Pro** (Xiaomi) via **Hermes Agent** (Nous Research). All changes were reviewed, tested against the actual codebase, and verified for correctness. --------- Signed-off-by: Raphael Malikian <rtmalikian@gmail.com> Signed-off-by: rtmalikian <rtmalikian@gmail.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…apping dict (Project-MONAI#8907) **fix: adaptor map_names calls dict as function when inputs is a name-mapping dict** When `adaptor` wraps a function with `**kwargs` and `inputs` is a dict, the `map_names` helper calls `input_map(k, k)` instead of `input_map.get(k, k)`, raising `TypeError` before any data reaches the wrapped function. The fix uses `input_map.get(k, k)` so the dict is looked up rather than called, falling back to the original key when no mapping exists. ### Types of changes - [x] Non-breaking change (fix or new feature that would not break existing functionality). - [x] 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. --------- Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk>
Addresses [GHSA-636w-j999-g7x5](GHSA-636w-j999-g7x5). ### Description This modifies the `PersistentDataset` class to permit storing `MetaTensor` objects. This is done by relying on the `torch.load` functionality to load only safe object types and those white-listed with `torch.serialization.add_safe_globals`. This also uses sha256 hashing in place of md5 in case of security concerns. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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). - [x] 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`. - [x] In-line docstrings updated. - [ ] Documentation updated, tested `make html` command in the `docs/` folder. --------- Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
…roject-MONAI#8918) Fixes Project-MONAI#5939. ### Summary `BendingEnergyLoss` previously computed second-order derivatives by applying the central first-order helper `spatial_gradient` twice, which yields a wide `[1, 0, -2, 0, 1] / 4` stencil for pure second derivatives that spans four voxels per axis. That stencil is less accurate than the standard compact one and forced the validation "all spatial dims > 4". This PR replaces the second-order computation with compact central stencils evaluated directly on `pred`: - **Pure** ``d^2/dx_i^2``: ``x[i+1] - 2 * x[i] + x[i-1]`` (the standard `[1, -2, 1]` kernel). - **Mixed** ``d^2/(dx_i dx_j)``: ``(x[i+1,j+1] - x[i+1,j-1] - x[i-1,j+1] + x[i-1,j-1]) / 4`` (compact 4-point central scheme). Both span three voxels per axis, so the spatial-size validation is relaxed from `> 4` to `> 2`, matching `DiffusionLoss`. The public API (`__init__(normalize, reduction)`, `forward(pred)`) and `normalize` semantics are unchanged. The existing `spatial_gradient` helper is left untouched because `DiffusionLoss` still uses it. ### Why TEST_CASES expected values do not change For ``f(x) = x^2``, the analytical second derivative is the constant `2`. Both the previous central-of-central stencil ``(f[i+2] - 2*f[i] + f[i-2]) / 4`` and the new compact ``[1, -2, 1]`` stencil ``f[i+1] - 2*f[i] + f[i-1]`` are exact for quadratics, so both return `2` at every interior voxel. Mixed-partial test inputs are constant in at least one of the two axes, so both stencils return `0` for mixed terms on these cases. Squared and reduced by ``mean``, the existing `TEST_CASES` expected values (``0.0``, ``4.0``, ``100.0``) are therefore invariant under this change. What does change in the tests: - `test_ill_shape` is updated to trigger on shape `2` (was `4`) so it still exercises the spatial-size guard. - A new `TEST_CASES` row covers shape `(1, 3, 3, 3, 3)` of ones (previously rejected by the `> 4` guard) → expected `0.0`, validating the relaxed guard. Reference for the compact mixed-partial scheme: Pavel Holoborodko's finite-difference notes cited in the original issue. --------- Signed-off-by: Vishnu Kannaujia <vishnu.kannaujia@gmail.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…files (Project-MONAI#8919) Fixes Project-MONAI#5461. ### Summary WSI reader tests emit `ResourceWarning: unclosed file <_io.FileIO ...>` / `BufferedReader` for the temp TIFF inputs they exercise (e.g. the CMU-1 generic TIFF). Investigation: - Every direct `reader.read(...)` call site in ``tests/utils/enums/test_wsireader.py`` already either uses ``with reader.read(...) as obj:`` or explicitly calls ``obj.close()`` on the returned WSI object. Those sites are not the leak. - The remaining leak comes from ``LoadImage.__call__`` in ``monai/transforms/io/array.py`` (around L256–289), which does: ```python img = reader.read(filename) img_array, meta_data = reader.get_data(img) # ... img_array is wrapped into MetaTensor and returned # the reader-returned `img` is never closed ``` The two ``test_with_dataloader*`` tests in this module use ``LoadImaged(reader=WSIReader, backend=..., ...)`` and inherit that leak. The temp TIFF handles only get closed when the garbage collector eventually runs, frequently after Python has already emitted the warning. This PR keeps the fix at test-hygiene scope: add ``gc.collect()`` to ``tearDown`` of the shared ``WSIReaderTests.Tests`` base class. Each of ``TiffFile.__del__`` / ``OpenSlide.__del__`` / ``CuImage.__del__`` closes the underlying file descriptor, so running gc explicitly at the end of every test invokes those finalizers deterministically and eliminates the warning. ### Why not change ``LoadImage`` / ``BaseWSIReader`` A reader-level or ``LoadImage``-level fix is feasible (e.g. closing ``img`` after ``get_data`` returns) but is broader in scope, affects all readers, and would need to land alongside changes to the public contract of ``BaseWSIReader.read`` (currently documented to return an open WSI object). Happy to follow up with that if a maintainer prefers; this PR was scoped narrowly to the test symptom that the issue raises. ### Verify ```bash python -m pytest tests/utils/enums/test_wsireader.py -W error::ResourceWarning -v ``` Expected: tests pass and no ``ResourceWarning`` escalations. --------- Signed-off-by: Vishnu Kannaujia <vishnu.kannaujia@gmail.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…ce volumes (Fixes Project-MONAI#8925) (Project-MONAI#8926) Fixes Project-MONAI#8925 ## Problem In `DICOMReader._get_affine`, when processing single-slice 3D DICOM segmentation volumes (where `n == 1`), the code computes: ```python k1, k2, k3 = (t1n - sx) / (n - 1), (t2n - sy) / (n - 1), (t3n - sz) / (n - 1) ``` Since `n - 1 = 0`, this raises a `ZeroDivisionError`. The issue occurs in the segmentation code path (`_get_seg_data`, line 898) where `lastImagePositionPatient` is always set from the frame metadata regardless of the number of frames. For a single-frame segmentation, the first and last positions are identical, producing `0 / 0`. ## Solution Added an `n > 1` guard before computing the z-axis direction vector from `lastImagePositionPatient`. For single-slice volumes, the z-axis column of the affine remains as the identity `[0, 0, 1, 0]` from `np.eye(4)`, which is a correct default — there is no meaningful z-direction for a single slice. ## Verification ```python import numpy as np # Single-slice scenario (n=1) — previously caused ZeroDivisionError n = 1 sx, sy, sz = 0.0, 0.0, 0.0 t1n, t2n, t3n = 0.0, 0.0, 0.0 affine = np.eye(4) if n > 1: affine[0, 2] = (t1n - sx) / (n - 1) affine[1, 2] = (t2n - sy) / (n - 1) affine[2, 2] = (t3n - sz) / (n - 1) print(f'z-axis column: {affine[:, 2]}') # [0, 0, 1, 0] — identity ✓ # Normal multi-slice case (n=10) — still works correctly n = 10 t1n, t2n, t3n = 0.0, 0.0, 45.0 affine2 = np.eye(4) if n > 1: affine2[0, 2] = (t1n - sx) / (n - 1) affine2[1, 2] = (t2n - sy) / (n - 1) affine2[2, 2] = (t3n - sz) / (n - 1) print(f'z-axis column: {affine2[:, 2]}') # [0, 0, 5.0, 0] — correct direction ✓ ``` --- **About the Author:** Raphael Malikian — Clinical AI Solutions Architect. I specialise in building and fixing AI/ML systems for healthcare, including vector databases, RAG pipelines, and clinical NLP. If you need help with your project or think I can add value to your organisation, feel free to reach out — I'd love to connect. 📧 rtmalikian@gmail.com 🔗 GitHub: https://github.com/rtmalikian 🔗 LinkedIn: http://www.linkedin.com/in/raphael-t-malikian-mbbs-bsc-hons-71075436a --- **Disclosure:** This code was developed with assistance from **mimo-2.5-pro** (Xiaomi) via **Hermes Agent** (Nous Research). All changes were reviewed, tested against the actual codebase, and verified for correctness. ## Changelog | Date | Change | Author | |------|--------|--------| | 2026-06-18 | Initial fix: guard division by zero for single-slice DICOM volumes | rtmalikian | | 2026-06-18 | Added DCO sign-off to commit | rtmalikian | | 2026-06-18 | Updated PR documentation with changelog | rtmalikian | ### Files Changed - `monai/data/image_reader.py` — Added `n > 1` guard before computing affine offsets for multi-slice volumes in `DICOMReader._get_affine()` ### Verification - ✅ Single-slice 3D DICOM volumes no longer trigger ZeroDivisionError - ✅ Multi-slice volumes continue to compute affine correctly - ✅ DCO sign-off present on all commits Signed-off-by: Raphael Malikian <rtmalikian@gmail.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…ort_format (Fixes Project-MONAI#8927) (Project-MONAI#8928) Fixes Project-MONAI#8927 ## Problem In `monai/auto3dseg/utils.py` line 287, the code uses `raise UserWarning("list length in report_format is not 1")`. This raises `UserWarning` as an exception, which crashes the program. Since `UserWarning` inherits from `Warning → Exception`, the `raise` works but terminates execution. The function `verify_report_format` returns `bool` to indicate format validity — a warning is appropriate here, not a fatal exception. The `warnings` module is already imported in the file. ## Solution Replace `raise UserWarning(...)` with `warnings.warn(..., stacklevel=2)`: ```python # Before (crashes): raise UserWarning("list length in report_format is not 1") # After (warns): warnings.warn("list length in report_format is not 1", stacklevel=2) ``` ## Verification Confirmed that: - `raise UserWarning(...)` crashes the program (raises as exception) - `warnings.warn(...)` correctly emits a `UserWarning` without crashing - The file passes syntax validation - `warnings` is already imported in the file --- **About the Author:** Raphael Malikian — Clinical AI Solutions Architect. I specialise in building and fixing AI/ML systems for healthcare, including vector databases, RAG pipelines, and clinical NLP. If you need help with your project or think I can add value to your organisation, feel free to reach out — I'd love to connect. 📧 rtmalikian@gmail.com 🔗 GitHub: https://github.com/rtmalikian 🔗 LinkedIn: http://www.linkedin.com/in/raphael-t-malikian-mbbs-bsc-hons-71075436a --- **Disclosure:** This code was developed with assistance from **mimo-2.5-pro** (Xiaomi) via **Hermes Agent** (Nous Research). All changes were reviewed, tested against the actual codebase, and verified for correctness. ## Changelog | Date | Change | Author | |------|--------|--------| | 2026-06-18 | Initial fix: replace raise UserWarning with warnings.warn() | rtmalikian | | 2026-06-18 | Added DCO sign-off to commit | rtmalikian | | 2026-06-18 | Updated PR documentation with changelog | rtmalikian | ### Files Changed - `monai/auto3dseg/utils.py` — Changed `raise UserWarning(...)` to `warnings.warn(...)` in `verify_report_format()` ### Verification - ✅ Function no longer crashes on invalid report format - ✅ Warning is emitted instead of raising exception - ✅ Return value (bool) still indicates format validity - ✅ DCO sign-off present on all commits Signed-off-by: Raphael Malikian <rtmalikian@gmail.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…MONAI#8951) ### Description `compute_fp_tp_probs_nd` computed `num_targets = max_label - len(labels_to_exclude)`, which only holds when every excluded label is a distinct value present in `[1, max_label]`. An absent, out-of-range, or duplicated entry subtracts targets that were never counted, leaving `num_targets` too small. Since `compute_froc_curve_data` divides cumulative true positives by `num_targets`, this inflates the reported sensitivity. The count is now the labels in `[1, max_label]` that are not excluded, computed in the existing loop. A regression test covering an out-of-range and a duplicated exclusion is included; both undercount before the fix. ### Types of changes - [x] Non-breaking change (fix or new feature that would not break existing functionality). - [x] 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. --------- Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
### Description Ran a code agent for dead code. Vetted them myself thereafter. Removes dead statements, no-ops, and leftover commented-out code. No runtime behavior changes. | File | Dead/redundant code removed | |---|---| | `networks/nets/basic_unet.py` | Stray `print(f"BasicUNet features: ...")` debug call in constructor | | `networks/nets/basic_unetplusplus.py` | Stray `print(f"BasicUNetPlusPlus features: ...")` debug call in constructor | | `networks/blocks/text_embedding.py` | Stray `print(self.text_embedding)` debug call in `TextEncoder.forward` | | `metrics/generalized_dice.py` | No-op self-assignment `y_pred_o = y_pred_o` | | `networks/layers/simplelayers.py` | No-op self-assignment `filter = filter` in `MeanFilter` | | `losses/nacl_loss.py` | Redundant `.abs_()` after `.pow_(2)` (operand already non-negative) in L2 branch | | `losses/image_dissimilarity.py` | Overwrite discarding the `look_up_option`-validated `kernel_type` in `GlobalMutualInformationLoss` | | `data/ultrasound_confidence_map.py` | Dead `elif` branch with discarded bare `s.shape[0]` expression | | `inferers/merger.py` | Duplicated recomputation of `is_zarr_v3` in `ZarrAvgMerger` | | `utils/profiling.py` | Unused module-level `pandas` optional-import (only consumer re-imports locally) | | `apps/nnunet/utils.py` | Three blocks of commented-out code in `create_new_dataset_json` | | `apps/vista3d/transforms.py` | Commented-out `AsDiscrete` alternative | | `transforms/utils.py` | Commented-out `torch.zeros` alternative | | `networks/layers/filtering.py` | Unreachable commented-out body after `raise` in `PHLFilter.backward` | ### Types of changes - [x] Non-breaking change (fix or new feature that would not break existing functionality). --------- Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk>
Fixes Project-MONAI#6119 . ### Description `docs/source/installation.md` only documents the POSIX inline form `BUILD_MONAI=1 pip install ...` for building the MONAI C++/CUDA extensions. This `VAR=value command` syntax is not supported by Windows `cmd.exe` or PowerShell, so the documented commands fail out of the box on Windows. This adds short cmd.exe and PowerShell snippets to both install flows (Option 1 system-wide and Option 2 editable): set the environment variable first, then run the existing `pip install` command. The `set BUILD_MONAI=1` form is the one confirmed working on Windows 11 in the issue thread. ### Types of changes - [x] Non-breaking change (documentation only). - [x] Documentation updated. ### How tested - Verified the new `bat`/`powershell` fenced blocks use valid Pygments lexers and lex without error tokens, so the strict docs build (`build_docs.yml`) emits no new warnings. - pre-commit markdown hooks (end-of-file, trailing-whitespace, mixed-line-ending) pass on the changed file. Signed-off-by: Lanre Shittu <136805224+Shizoqua@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…metric computation (Project-MONAI#8910) Fixes # 8909. Project-MONAI#8909 ### Description Pretty straightforward: we don't need to compute the distance between every conceivable voxel, just the edges, so we can use a KDTree on CPU and compute `HausdorffDistanceMetric` and `SurfaceDistanceMetric` etc significantly faster. GPU implementations of KDTrees exist, but I did a little benchmarking and found that they are slower than the full EDT since the distance computations are embarrassingly parallel and well-suited to the hardware (gpu goes brrr), so I left that path unchanged. Measured speedups (on my M3 mac, and Intel Cascade Lake) range from 1.5x for small inputs to 16x for larger volumes and noisier data. I think existing test coverage is good enough that we don't need more here - all pass for me, and I've spot checked a few problems to ensure identical output metrics. Edit: have added some more tests per the coderabbit's suggestions. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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. - [x] Integration tests passed locally by running `./runtests.sh -f -u --net --coverage`. - [x] Quick tests passed locally by running `./runtests.sh --quick --unittests --disttests`. - [x] In-line docstrings updated. - [ ] Documentation updated, tested `make html` command in the `docs/` folder. --------- Signed-off-by: J Berg <j.berg2349@gmail.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…#8941) (Project-MONAI#8944) ### Description `nnUNetV2Runner.train_single_model_command` builds the `nnUNetv2_train` argv by iterating `kwargs` and always appending `str(_value)`, so documented `store_true` flags were emitted with a value instead of bare. Passing `c=True` produced `--c True`, `val=True` produced `--val True`, and likewise for `use_compressed` and `disable_checkpointing`. `nnUNetv2_train` declares these as `store_true`, so the trailing `True` is parsed as a positional argument and the command fails. A falsy `pretrained_weights` was similarly emitted as `-pretrained_weights False` instead of being omitted. The builder now appends `store_true` flags only when their value is truthy and skips them otherwise, and includes `pretrained_weights`/`-p` only when given a real path. Regular value kwargs and the existing `--npz` handling are unchanged. Fixes Project-MONAI#8941, originally flagged in a review thread on Project-MONAI#8887. ### Types of changes - [x] Non-breaking change (fix or new feature that would not break existing functionality). - [x] 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. --------- Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk>
…roject-MONAI#8968) Fixes Project-MONAI#8237 . ### Description The runner passed boolean flags like `--c` through as `--c True`, but nnU-Net treats these as `store_true` flags that take no value, so it errored out with `unrecognized arguments: True`. Now we emit just the bare flag when it's set, drop it when it isn't, and leave the other args alone. ### Types of changes - [x] Non-breaking change (fix or new feature that would not break existing functionality). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved how command-line options are passed for training and validation, so boolean settings now behave as expected. * Validation now runs through the standard training workflow with validation enabled, helping ensure more consistent results. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk> Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
) Fixes Project-MONAI#6029 . ### Description `create_rotate` hard-coded 3D rotations to the intrinsic `Rx @ Ry @ Rz` composition. This adds a `rotate_order` parameter following the convention of `scipy.spatial.transform.Rotation.from_euler`: a string of up to three axes from `{x, y, z}`, where lower case selects extrinsic rotations (about the fixed world axes) and upper case selects intrinsic rotations (about the moving body axes). The default `"XYZ"` reproduces the previous behaviour exactly, so existing pipelines are unaffected. The name avoids collision with the spline interpolation order already selected via `mode`. The parameter is threaded through `functional.rotate`, `Rotate`, `RandRotate`, `AffineGrid`, `RandAffineGrid`, `Affine`, `RandAffine` and their dictionary variants. Invalid sequences raise `ValueError`, and 2D inputs ignore it. A new test module checks that the default matches the legacy matrix, that every supported axis sequence matches scipy for both the numpy and torch backends, that invalid sequences raise, that 2D inputs ignore the order, and that the `Rotate` transform honours it while remaining invertible. ### Types of changes - [x] Non-breaking change (fix or new feature that would not break existing functionality). - [x] New tests added to cover the changes. - [x] In-line docstrings updated. --------- Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 7. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/releases">actions/checkout's releases</a>.</em></p> <blockquote> <h2>v7.0.0</h2> <h2>What's Changed</h2> <ul> <li>block checking out fork pr for pull_request_target and workflow_run by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> <li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li> <li>Bump flatted from 3.3.1 to 3.4.2 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li> <li>Bump js-yaml from 4.1.0 to 4.2.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li> <li>Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li> <li>upgrade module to esm and update dependencies by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li> <li>Bump the minor-npm-dependencies group across 1 directory with 3 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li> <li>getting ready for checkout v7 release by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2464">actions/checkout#2464</a></li> <li>update error wording by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2467">actions/checkout#2467</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6.0.3...v7.0.0">https://github.com/actions/checkout/compare/v6.0.3...v7.0.0</a></p> <h2>v6.0.3</h2> <h2>What's Changed</h2> <ul> <li>Update changelog by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2357">actions/checkout#2357</a></li> <li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> <li>Fix checkout init for SHA-256 repositories by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li> <li>Update changelog for v6.0.3 by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2446">actions/checkout#2446</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/yaananth"><code>@yaananth</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6...v6.0.3">https://github.com/actions/checkout/compare/v6...v6.0.3</a></p> <h2>v6.0.2</h2> <h2>What's Changed</h2> <ul> <li>Add orchestration_id to git user-agent when ACTIONS_ORCHESTRATION_ID is set by <a href="https://github.com/TingluoHuang"><code>@TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2355">actions/checkout#2355</a></li> <li>Fix tag handling: preserve annotations and explicit fetch-tags by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6.0.1...v6.0.2">https://github.com/actions/checkout/compare/v6.0.1...v6.0.2</a></p> <h2>v6.0.1</h2> <h2>What's Changed</h2> <ul> <li>Update all references from v5 and v4 to v6 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2314">actions/checkout#2314</a></li> <li>Add worktree support for persist-credentials includeIf by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li> <li>Clarify v6 README by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2328">actions/checkout#2328</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6...v6.0.1">https://github.com/actions/checkout/compare/v6...v6.0.1</a></p> <h2>v6.0.0</h2> <h2>What's Changed</h2> <ul> <li>Update README to include Node.js 24 support details and requirements by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li> <li>Persist creds to a separate file by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li> <li>v6-beta by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2298">actions/checkout#2298</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's changelog</a>.</em></p> <blockquote> <h1>Changelog</h1> <h2>v7.0.0</h2> <ul> <li>Block checking out fork PR for pull_request_target and workflow_run by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> <li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li> <li>Bump flatted from 3.3.1 to 3.4.2 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li> <li>Bump js-yaml from 4.1.0 to 4.2.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li> <li>Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li> <li>upgrade module to esm and update dependencies by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li> <li>Bump the minor-npm-dependencies group across 1 directory with 3 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li> </ul> <h2>v6.0.3</h2> <ul> <li>Fix checkout init for SHA-256 repositories by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li> <li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> </ul> <h2>v6.0.2</h2> <ul> <li>Fix tag handling: preserve annotations and explicit fetch-tags by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li> </ul> <h2>v6.0.1</h2> <ul> <li>Add worktree support for persist-credentials includeIf by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li> </ul> <h2>v6.0.0</h2> <ul> <li>Persist creds to a separate file by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li> <li>Update README to include Node.js 24 support details and requirements by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li> </ul> <h2>v5.0.1</h2> <ul> <li>Port v6 cleanup to v5 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li> </ul> <h2>v5.0.0</h2> <ul> <li>Update actions checkout to use node 24 by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li> </ul> <h2>v4.3.1</h2> <ul> <li>Port v6 cleanup to v4 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li> </ul> <h2>v4.3.0</h2> <ul> <li>docs: update README.md by <a href="https://github.com/motss"><code>@motss</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li> <li>Add internal repos for checking out multiple repositories by <a href="https://github.com/mouismail"><code>@mouismail</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li> <li>Documentation update - add recommended permissions to Readme by <a href="https://github.com/benwells"><code>@benwells</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li> <li>Adjust positioning of user email note and permissions heading by <a href="https://github.com/joshmgross"><code>@joshmgross</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li> <li>Update README.md by <a href="https://github.com/nebuk89"><code>@nebuk89</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li> <li>Update CODEOWNERS for actions by <a href="https://github.com/TingluoHuang"><code>@TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li> <li>Update package dependencies by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li> </ul> <h2>v4.2.2</h2> <ul> <li><code>url-helper.ts</code> now leverages well-known environment variables by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li> <li>Expand unit test coverage for <code>isGhes</code> by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li> </ul> <h2>v4.2.1</h2> <ul> <li>Check out other refs/* by commit if provided, fall back to ref by <a href="https://github.com/orhantoy"><code>@orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/actions/checkout/commit/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0"><code>9c091bb</code></a> update error wording (<a href="https://redirect.github.com/actions/checkout/issues/2467">#2467</a>)</li> <li><a href="https://github.com/actions/checkout/commit/1044a6dea927916f2c38ba5aeffbc0a847b1221a"><code>1044a6d</code></a> getting ready for checkout v7 release (<a href="https://redirect.github.com/actions/checkout/issues/2464">#2464</a>)</li> <li><a href="https://github.com/actions/checkout/commit/f0282184c7ce73ab54c7e4ab5a617122602e575f"><code>f028218</code></a> Bump the minor-npm-dependencies group across 1 directory with 3 updates (<a href="https://redirect.github.com/actions/checkout/issues/2462">#2462</a>)</li> <li><a href="https://github.com/actions/checkout/commit/d914b262ffc244530a203ab40decab34c3abf34d"><code>d914b26</code></a> upgrade module to esm and update dependencies (<a href="https://redirect.github.com/actions/checkout/issues/2463">#2463</a>)</li> <li><a href="https://github.com/actions/checkout/commit/537c7ef99cef6e5ddb5e7ff5d16d14510503801d"><code>537c7ef</code></a> Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid (<a href="https://redirect.github.com/actions/checkout/issues/2459">#2459</a>)</li> <li><a href="https://github.com/actions/checkout/commit/130a169078a413d3a5246a393625e8e742f387f6"><code>130a169</code></a> Bump js-yaml from 4.1.0 to 4.2.0 (<a href="https://redirect.github.com/actions/checkout/issues/2461">#2461</a>)</li> <li><a href="https://github.com/actions/checkout/commit/7d09575332117a40b46e5e020664df234cd416f3"><code>7d09575</code></a> Bump flatted from 3.3.1 to 3.4.2 (<a href="https://redirect.github.com/actions/checkout/issues/2460">#2460</a>)</li> <li><a href="https://github.com/actions/checkout/commit/0f9f3aa320cb53abeb534aeb54048075d9697a0e"><code>0f9f3aa</code></a> Bump actions/publish-immutable-action (<a href="https://redirect.github.com/actions/checkout/issues/2458">#2458</a>)</li> <li><a href="https://github.com/actions/checkout/commit/f9e715a95fcd1f9253f77dd28f11e88d2d6460c7"><code>f9e715a</code></a> block checking out fork pr for pull_request_target and workflow_run (<a href="https://redirect.github.com/actions/checkout/issues/2454">#2454</a>)</li> <li><a href="https://github.com/actions/checkout/commit/df4cb1c069e1874edd31b4311f1884172cec0e10"><code>df4cb1c</code></a> Update changelog for v6.0.3 (<a href="https://redirect.github.com/actions/checkout/issues/2446">#2446</a>)</li> <li>Additional commits viewable in <a href="https://github.com/actions/checkout/compare/v4...v7">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 6 to 7. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/codecov/codecov-action/releases">codecov/codecov-action's releases</a>.</em></p> <blockquote> <h2>v7.0.0</h2> <p>⚠️ Due to migration issues with keybase, we are unable to update our keys under the <code>codecovsecurity</code> account. We have deleted the account and are using <code>codecovsecops</code> with the original gpg key</p> <h2>What's Changed</h2> <ul> <li>ci: remove Enforce License Compliance workflow by <a href="https://github.com/thomasrockhu-codecov"><code>@thomasrockhu-codecov</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1950">codecov/codecov-action#1950</a></li> <li>chore(release): 7.0.0 by <a href="https://github.com/thomasrockhu-codecov"><code>@thomasrockhu-codecov</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1957">codecov/codecov-action#1957</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/codecov/codecov-action/compare/v6.0.1...v7.0.0">https://github.com/codecov/codecov-action/compare/v6.0.1...v7.0.0</a></p> <h2>v6.0.2</h2> <p>This is a copy of the <code>v7.0.0</code> release to make updates easier</p> <h2>What's Changed</h2> <ul> <li>ci: remove Enforce License Compliance workflow by <a href="https://github.com/thomasrockhu-codecov"><code>@thomasrockhu-codecov</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1950">codecov/codecov-action#1950</a></li> <li>chore(release): 7.0.0 by <a href="https://github.com/thomasrockhu-codecov"><code>@thomasrockhu-codecov</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1957">codecov/codecov-action#1957</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/codecov/codecov-action/compare/v6.0.1...v6.0.2">https://github.com/codecov/codecov-action/compare/v6.0.1...v6.0.2</a></p> <h2>v6.0.1</h2> <h2>What's Changed</h2> <ul> <li>fix: prevent template injection in run: steps (VULN-1652) by <a href="https://github.com/thomasrockhu-codecov"><code>@thomasrockhu-codecov</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1947">codecov/codecov-action#1947</a></li> <li>chore(release): 6.0.1 by <a href="https://github.com/thomasrockhu-codecov"><code>@thomasrockhu-codecov</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1949">codecov/codecov-action#1949</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/codecov/codecov-action/compare/v6.0.0...v6.0.1">https://github.com/codecov/codecov-action/compare/v6.0.0...v6.0.1</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md">codecov/codecov-action's changelog</a>.</em></p> <blockquote> <h2>v5.5.2</h2> <h3>What's Changed</h3> <p><strong>Full Changelog</strong>: <a href="https://github.com/codecov/codecov-action/compare/v5.5.1..v5.5.2">https://github.com/codecov/codecov-action/compare/v5.5.1..v5.5.2</a></p> <h2>v5.5.1</h2> <h3>What's Changed</h3> <ul> <li>fix: overwrite pr number on fork by <a href="https://github.com/thomasrockhu-codecov"><code>@thomasrockhu-codecov</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1871">codecov/codecov-action#1871</a></li> <li>build(deps): bump actions/checkout from 4.2.2 to 5.0.0 by <code>@app/dependabot</code> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1868">codecov/codecov-action#1868</a></li> <li>build(deps): bump github/codeql-action from 3.29.9 to 3.29.11 by <code>@app/dependabot</code> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1867">codecov/codecov-action#1867</a></li> <li>fix: update to use local app/ dir by <a href="https://github.com/thomasrockhu-codecov"><code>@thomasrockhu-codecov</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1872">codecov/codecov-action#1872</a></li> <li>docs: fix typo in README by <a href="https://github.com/datalater"><code>@datalater</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1866">codecov/codecov-action#1866</a></li> <li>Document a <code>codecov-cli</code> version reference example by <a href="https://github.com/webknjaz"><code>@webknjaz</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1774">codecov/codecov-action#1774</a></li> <li>build(deps): bump github/codeql-action from 3.28.18 to 3.29.9 by <code>@app/dependabot</code> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1861">codecov/codecov-action#1861</a></li> <li>build(deps): bump ossf/scorecard-action from 2.4.1 to 2.4.2 by <code>@app/dependabot</code> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1833">codecov/codecov-action#1833</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/codecov/codecov-action/compare/v5.5.0..v5.5.1">https://github.com/codecov/codecov-action/compare/v5.5.0..v5.5.1</a></p> <h2>v5.5.0</h2> <h3>What's Changed</h3> <ul> <li>feat: upgrade wrapper to 0.2.4 by <a href="https://github.com/jviall"><code>@jviall</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1864">codecov/codecov-action#1864</a></li> <li>Pin actions/github-script by Git SHA by <a href="https://github.com/martincostello"><code>@martincostello</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1859">codecov/codecov-action#1859</a></li> <li>fix: check reqs exist by <a href="https://github.com/joseph-sentry"><code>@joseph-sentry</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1835">codecov/codecov-action#1835</a></li> <li>fix: Typo in README by <a href="https://github.com/spalmurray"><code>@spalmurray</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1838">codecov/codecov-action#1838</a></li> <li>docs: Refine OIDC docs by <a href="https://github.com/spalmurray"><code>@spalmurray</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1837">codecov/codecov-action#1837</a></li> <li>build(deps): bump github/codeql-action from 3.28.17 to 3.28.18 by <code>@app/dependabot</code> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1829">codecov/codecov-action#1829</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/codecov/codecov-action/compare/v5.4.3..v5.5.0">https://github.com/codecov/codecov-action/compare/v5.4.3..v5.5.0</a></p> <h2>v5.4.3</h2> <h3>What's Changed</h3> <ul> <li>build(deps): bump github/codeql-action from 3.28.13 to 3.28.17 by <code>@app/dependabot</code> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1822">codecov/codecov-action#1822</a></li> <li>fix: OIDC on forks by <a href="https://github.com/joseph-sentry"><code>@joseph-sentry</code></a> in <a href="https://redirect.github.com/codecov/codecov-action/pull/1823">codecov/codecov-action#1823</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/codecov/codecov-action/compare/v5.4.2..v5.4.3">https://github.com/codecov/codecov-action/compare/v5.4.2..v5.4.3</a></p> <h2>v5.4.2</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/codecov/codecov-action/compare/v6...v7">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/cache/releases">actions/cache's releases</a>.</em></p> <blockquote> <h2>v6.0.0</h2> <h2>What's Changed</h2> <ul> <li>Update packages, migrate to ESM by <a href="https://github.com/Samirat"><code>@Samirat</code></a> in <a href="https://redirect.github.com/actions/cache/pull/1760">actions/cache#1760</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/cache/compare/v5...v6.0.0">https://github.com/actions/cache/compare/v5...v6.0.0</a></p> <h2>v5.1.0</h2> <h2>What's Changed</h2> <ul> <li>Bump <code>@actions/cache</code> to v5.1.0 - handle read-only cache access by <a href="https://github.com/jasongin"><code>@jasongin</code></a> in <a href="https://redirect.github.com/actions/cache/pull/1775">actions/cache#1775</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/cache/compare/v5...v5.1.0">https://github.com/actions/cache/compare/v5...v5.1.0</a></p> <h2>v5.0.5</h2> <h2>What's Changed</h2> <ul> <li>Update ts-http-runtime dependency by <a href="https://github.com/yacaovsnc"><code>@yacaovsnc</code></a> in <a href="https://redirect.github.com/actions/cache/pull/1747">actions/cache#1747</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/cache/compare/v5...v5.0.5">https://github.com/actions/cache/compare/v5...v5.0.5</a></p> <h2>v5.0.4</h2> <h2>What's Changed</h2> <ul> <li>Add release instructions and update maintainer docs by <a href="https://github.com/Link"><code>@Link</code></a>- in <a href="https://redirect.github.com/actions/cache/pull/1696">actions/cache#1696</a></li> <li>Potential fix for code scanning alert no. 52: Workflow does not contain permissions by <a href="https://github.com/Link"><code>@Link</code></a>- in <a href="https://redirect.github.com/actions/cache/pull/1697">actions/cache#1697</a></li> <li>Fix workflow permissions and cleanup workflow names / formatting by <a href="https://github.com/Link"><code>@Link</code></a>- in <a href="https://redirect.github.com/actions/cache/pull/1699">actions/cache#1699</a></li> <li>docs: Update examples to use the latest version by <a href="https://github.com/XZTDean"><code>@XZTDean</code></a> in <a href="https://redirect.github.com/actions/cache/pull/1690">actions/cache#1690</a></li> <li>Fix proxy integration tests by <a href="https://github.com/Link"><code>@Link</code></a>- in <a href="https://redirect.github.com/actions/cache/pull/1701">actions/cache#1701</a></li> <li>Fix cache key in examples.md for bun.lock by <a href="https://github.com/RyPeck"><code>@RyPeck</code></a> in <a href="https://redirect.github.com/actions/cache/pull/1722">actions/cache#1722</a></li> <li>Update dependencies & patch security vulnerabilities by <a href="https://github.com/Link"><code>@Link</code></a>- in <a href="https://redirect.github.com/actions/cache/pull/1738">actions/cache#1738</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/XZTDean"><code>@XZTDean</code></a> made their first contribution in <a href="https://redirect.github.com/actions/cache/pull/1690">actions/cache#1690</a></li> <li><a href="https://github.com/RyPeck"><code>@RyPeck</code></a> made their first contribution in <a href="https://redirect.github.com/actions/cache/pull/1722">actions/cache#1722</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/cache/compare/v5...v5.0.4">https://github.com/actions/cache/compare/v5...v5.0.4</a></p> <h2>v5.0.3</h2> <h2>What's Changed</h2> <ul> <li>Bump <code>@actions/cache</code> to v5.0.5 (Resolves: <a href="https://github.com/actions/cache/security/dependabot/33">https://github.com/actions/cache/security/dependabot/33</a>)</li> <li>Bump <code>@actions/core</code> to v2.0.3</li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/cache/compare/v5...v5.0.3">https://github.com/actions/cache/compare/v5...v5.0.3</a></p> <h2>v.5.0.2</h2> <h1>v5.0.2</h1> <h2>What's Changed</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/actions/cache/blob/main/RELEASES.md">actions/cache's changelog</a>.</em></p> <blockquote> <h1>Releases</h1> <h2>How to prepare a release</h2> <blockquote> <p>[!NOTE] Relevant for maintainers with write access only.</p> </blockquote> <ol> <li>Switch to a new branch from <code>main</code>.</li> <li>Run <code>npm test</code> to ensure all tests are passing.</li> <li>Update the version in <a href="https://github.com/actions/cache/blob/main/package.json"><code>https://github.com/actions/cache/blob/main/package.json</code></a>.</li> <li>Run <code>npm run build</code> to update the compiled files.</li> <li>Update this <a href="https://github.com/actions/cache/blob/main/RELEASES.md"><code>https://github.com/actions/cache/blob/main/RELEASES.md</code></a> with the new version and changes in the <code>## Changelog</code> section.</li> <li>Run <code>licensed cache</code> to update the license report.</li> <li>Run <code>licensed status</code> and resolve any warnings by updating the <a href="https://github.com/actions/cache/blob/main/.licensed.yml"><code>https://github.com/actions/cache/blob/main/.licensed.yml</code></a> file with the exceptions.</li> <li>Commit your changes and push your branch upstream.</li> <li>Open a pull request against <code>main</code> and get it reviewed and merged.</li> <li>Draft a new release <a href="https://github.com/actions/cache/releases">https://github.com/actions/cache/releases</a> use the same version number used in <code>package.json</code> <ol> <li>Create a new tag with the version number.</li> <li>Auto generate release notes and update them to match the changes you made in <code>RELEASES.md</code>.</li> <li>Toggle the set as the latest release option.</li> <li>Publish the release.</li> </ol> </li> <li>Navigate to <a href="https://github.com/actions/cache/actions/workflows/release-new-action-version.yml">https://github.com/actions/cache/actions/workflows/release-new-action-version.yml</a> <ol> <li>There should be a workflow run queued with the same version number.</li> <li>Approve the run to publish the new version and update the major tags for this action.</li> </ol> </li> </ol> <h2>Changelog</h2> <h3>6.1.0</h3> <ul> <li>Bump <code>@actions/cache</code> to v6.1.0 to pick up <a href="https://redirect.github.com/actions/toolkit/pull/2435">actions/toolkit#2435 Handle cache write error due to read-only token</a></li> <li>Switch redundant "Cache save failed" warning to debug log in save-only</li> </ul> <h3>6.0.0</h3> <ul> <li>Updated <code>@actions/cache</code> to ^6.0.1, <code>@actions/core</code> to ^3.0.1, <code>@actions/exec</code> to ^3.0.0, <code>@actions/io</code> to ^3.0.2</li> <li>Migrated to ESM module system</li> <li>Upgraded Jest to v30 and test infrastructure to be ESM compatible</li> </ul> <h3>5.0.4</h3> <ul> <li>Bump <code>minimatch</code> to v3.1.5 (fixes ReDoS via globstar patterns)</li> <li>Bump <code>undici</code> to v6.24.1 (WebSocket decompression bomb protection, header validation fixes)</li> <li>Bump <code>fast-xml-parser</code> to v5.5.6</li> </ul> <h3>5.0.3</h3> <ul> <li>Bump <code>@actions/cache</code> to v5.0.5 (Resolves: <a href="https://github.com/actions/cache/security/dependabot/33">https://github.com/actions/cache/security/dependabot/33</a>)</li> <li>Bump <code>@actions/core</code> to v2.0.3</li> </ul> <h3>5.0.2</h3> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/actions/cache/commit/55cc8345863c7cc4c66a329aec7e433d2d1c52a9"><code>55cc834</code></a> Merge pull request <a href="https://redirect.github.com/actions/cache/issues/1768">#1768</a> from jasongin/readonly-cache</li> <li><a href="https://github.com/actions/cache/commit/d8cd72f230726cdf4457ebb61ec1b593a8d12337"><code>d8cd72f</code></a> Bump <code>@actions/cache</code> to v6.1.0 - handle cache write error due to RO token</li> <li><a href="https://github.com/actions/cache/commit/2c8a9bd7457de244a408f35966fab2fb45fda9c8"><code>2c8a9bd</code></a> Merge pull request <a href="https://redirect.github.com/actions/cache/issues/1760">#1760</a> from actions/samirat/esm_migration_and_package_update</li> <li><a href="https://github.com/actions/cache/commit/e9b91fdc3fea7d79165fceb79042ef45c2d51023"><code>e9b91fd</code></a> Prettier fixes</li> <li><a href="https://github.com/actions/cache/commit/e4884b8ff7f92ef6b52c79eda480bbc86e685adb"><code>e4884b8</code></a> Rebuild dist</li> <li><a href="https://github.com/actions/cache/commit/10baf0191a3c426ea0fa4a3253a5c04233b6e18f"><code>10baf01</code></a> Fixed licenses</li> <li><a href="https://github.com/actions/cache/commit/e39b386c9004d72a15d864ade8c0b3a702d47a37"><code>e39b386</code></a> Fix test mock return order</li> <li><a href="https://github.com/actions/cache/commit/b6928203372a8571ff984c0c883ef3a1adfb0c06"><code>b692820</code></a> PR feedback</li> <li><a href="https://github.com/actions/cache/commit/60749128a44d25d3c520a489e576380cf00ff3f1"><code>6074912</code></a> Rebuild dist bundles as ESM to match type:module</li> <li><a href="https://github.com/actions/cache/commit/5a912e8b4af820fa082a0e75cfd2c782f8fbfe0e"><code>5a912e8</code></a> Fix lint and jest issues</li> <li>Additional commits viewable in <a href="https://github.com/actions/cache/compare/v5...v6">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…rving metadata (Project-MONAI#8911) ## Summary - `MetaTensor.astype()` called with a torch dtype (e.g. `torch.int32`, `torch.float16`) was silently returning a plain `torch.Tensor`, discarding all metadata (affine matrix, spacing, applied_operations, and any custom keys). - Root cause: `out_type` was hardcoded to `torch.Tensor` instead of `type(self)` (`MetaTensor`), so `convert_data_type` set `track_meta=False` and stripped the metadata. - Fix: use `out_type = type(self)` when `mod_str == "torch"`, so `convert_data_type` receives `output_type=MetaTensor`, sets `track_meta=True`, and the dtype cast is performed while preserving all metadata. - The `auto3dseg/analyzer.py` module already annotated `label_tensor.astype(torch.int16)` as returning a `MetaTensor` (line 493), relying on this contract. Closes Project-MONAI#8202 ## Test plan - [ ] Existing `test_astype` test updated to assert `isinstance(result, MetaTensor)` and that metadata keys survive the cast. - [ ] All 96 `tests/data/meta_tensor/` tests pass locally (0 failures). - [ ] Manual verification: ```python import torch from monai.data import MetaTensor t = MetaTensor(torch.tensor([1., 2., 3.]), meta={"fname": "scan.nii"}) result = t.astype(torch.int32) assert isinstance(result, MetaTensor) # was torch.Tensor before assert result.meta["fname"] == "scan.nii" # metadata preserved assert result.dtype == torch.int32 # dtype correctly cast ``` Signed-off-by: Oleksandr Sanin <alexaaander.sanin@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…tch (Project-MONAI#8833) Fixes Project-MONAI#8832 . ### Description Adds a check on downloaded files to verify their hash against the expected value and raises a `ValueError` if there is a mismatch, indicating possible corruption or tampering. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] Non-breaking change (fix or new feature that would not break existing functionality).. - [x] Integration tests passed locally by running `./runtests.sh -f -u --net --coverage`. - [x] Quick tests passed locally by running `./runtests.sh --quick --unittests --disttests`. - [x] In-line docstrings updated. --------- Signed-off-by: Enoch Mok <enochmokny@gmail.com> Signed-off-by: Enoch Mok <65853622+e-mny@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Fixes Project-MONAI#9045. ### Description `spatial_crop_boxes` converted crop ROI bounds to `torch.int16`, which overflows for coordinates above 32767. This could cause valid boxes in large images to be clamped incorrectly and silently removed when `remove_empty=True`. This PR keeps the ROI bounds in the same tensor dtype as the boxes during clipping and adds a regression test covering both `spatial_crop_boxes` and the public `clip_boxes_to_image` path for large coordinates. ### Types of changes - [x] 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). - [x] 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. Local validation: - `python -m tests.data.test_box_utils` - `python -m ruff check monai/data/box_utils.py tests/data/test_box_utils.py` `black` and `isort` were not installed in my local Python environment, so I could not run those checks directly. --------- Signed-off-by: Rajioba1 <raji.lukmon@gmail.com> Co-authored-by: Vikash Gupta <write2vikash@gmail.com>
…ject-MONAI#9006) ### Description Fixes Project-MONAI#7437. When `LoadImage` is given an explicit reader string whose optional dependency is unavailable, the original `OptionalImportError` is now propagated instead of being converted into a warning and silently falling back to another registered reader. Automatic reader selection with `reader=None` remains unchanged. ### Implementation - Propagate `OptionalImportError` for explicitly requested unavailable string readers. - Add an environment-independent regression test using mock readers. - Update reader initialization tests to reflect the new explicit-reader behavior when optional dependencies are unavailable. ### Compatibility This is an intentional behavior change for explicitly requested unavailable readers. The following behavior remains unchanged: - automatic reader selection with `reader=None` - default registration skipping unavailable optional readers - runtime fallback when an installed reader cannot read a file - public APIs and signatures This PR does not redesign explicit tuple/list reader semantics. ### Validation Executed locally: - `python -m tests.transforms.test_load_image` - `python -m tests.transforms.test_load_imaged` - `python -m tests.data.test_init_reader` - Ruff All executed tests passed. Some optional-backend tests were skipped as expected in the current environment. --------- Signed-off-by: Minsu Kim <minsu.kim08@gmail.com>
…roject-MONAI#8868) ### Description Replace both mypy and pytype with pyrefly for static type analysis. **Why pyrefly:** - 15x faster than mypy, adopted by PyTorch and JAX - Production-proven at Meta on 20M-line codebase - `preset="legacy"` matches mypy laxness for smooth migration - `# type: ignore` comments still respected - `pyrefly init` auto-migrates existing mypy configuration - `pyrefly suppress` establishes zero-error baseline instantly **Changes:** - Remove `[mypy]` config from setup.cfg (migrated to `[tool.pyrefly]`) - Remove `[tool.pytype]` from pyproject.toml (deprecated, no Python >3.12) - Add `[tool.pyrefly]` with `preset="legacy"` matching mypy laxness - Run `pyrefly suppress` to establish zero-error baseline - Update CI matrix: pytype + mypy → pyrefly - Update runtests.sh: --pytype + --mypy → --pyrefly - Update requirements-dev.txt, .gitignore, CONTRIBUTING.md - Update .github/workflows/cron.yml Fixes Project-MONAI#8865 (pytype deprecation) <!-- gk-ai-analysis-start:2e6eec61548a73e83b0cdd9e4a4fe7018815f997 --> <!-- gk-ai-analysis-data:eyJzdW1tYXJ5IjoiUmVwbGFjZXMgbXlweSBhbmQgcHl0eXBlIHdpdGggYSBuZXcgdHlwZSBjaGVja2VyIGNhbGxlZCAncHlyZWZseScgYWNyb3NzIHRoZSBjb2RlYmFzZS4iLCJrZXlJbnNpZ2h0cyI6W3sidGl0bGUiOiJSZXBsYWNlZCB0eXBlIGNoZWNraW5nIHRvb2xzIiwiZGVzY3JpcHRpb24iOiJSZW1vdmVkIG15cHkgYW5kIHB5dHlwZSBjb25maWd1cmF0aW9ucyBhbmQgcmVwbGFjZWQgdGhlbSB3aXRoICdweXJlZmx5JyBpbiBweXByb2plY3QudG9tbCwgbWF0Y2hpbmcgbXlweSdzIGxlZ2FjeSBsYXhuZXNzIHJ1bGVzLiIsInNldmVyaXR5IjoibWVkaXVtIiwiZmlsZVBhdGgiOiJweXByb2plY3QudG9tbCIsImxpbmVTdGFydCI6ODR9LHsidGl0bGUiOiJDSSBhbmQgdGVzdCBzY3JpcHQgdXBkYXRlcyIsImRlc2NyaXB0aW9uIjoiVXBkYXRlZCBydW50ZXN0cy5zaCB0byB1c2UgcHlyZWZseSBpbnN0ZWFkIG9mIG15cHkgYW5kIHB5dHlwZSwgYW5kIHJlbW92ZWQgdGhlIC5teXB5X2NhY2hlIGFuZCAucHl0eXBlIGNsZWFudXAgcm91dGluZXMgaW4gZmF2b3Igb2YgLnB5cmVmbHlfY2FjaGUuIiwic2V2ZXJpdHkiOiJtZWRpdW0iLCJmaWxlUGF0aCI6InJ1bnRlc3RzLnNoIiwibGluZVN0YXJ0IjoxOTQsImxpbmVFbmQiOjE5N31dLCJpc3N1ZXMiOlt7InRpdGxlIjoiSW5jb21wbGV0ZSByZW1vdmFsIG9mIC0tbXlweSBmbGFnIiwiZGVzY3JpcHRpb24iOiJUaGUgYC0tbXlweWAgZmxhZyBpcyByZW1vdmVkIGZyb20gdGhlIGhlbHAgdGV4dCBidXQgdGhlIGBkb015cHlGb3JtYXQ9dHJ1ZWAgbG9naWMgc3RpbGwgZXhpc3RzIGluIHRoZSBjb21tYW5kLWxpbmUgYXJndW1lbnQgcGFyc2luZy4iLCJzZXZlcml0eSI6Im1lZGl1bSIsImZpbGVQYXRoIjoicnVudGVzdHMuc2giLCJsaW5lU3RhcnQiOjMxNCwibGluZUVuZCI6MzE2fV0sInN1Z2dlc3Rpb25zIjpbXSwic2VjdXJpdHkiOlt7InRpdGxlIjoiUG90ZW50aWFsbHkgbWFsaWNpb3VzIG9yIGZha2UgZGVwZW5kZW5jeSIsImRlc2NyaXB0aW9uIjoiVGhlIFBSIGludHJvZHVjZXMgYHB5cmVmbHlgIGFzIGEgZGVwZW5kZW5jeSwgY2xhaW1pbmcgaXQgaXMgYSBwcm9kdWN0aW9uLXByb3ZlbiBNZXRhIHR5cGUgY2hlY2tlci4gTWV0YSdzIGFjdHVhbCB0eXBlIGNoZWNrZXIgaXMgYHB5cmUtY2hlY2tgLiBgcHlyZWZseWAgYXBwZWFycyB0byBiZSBhIGZha2Ugb3IgbWFsaWNpb3VzIHR5cG9zcXVhdHRpbmcgcGFja2FnZSBhbmQgc2hvdWxkIG5vdCBiZSBpbnN0YWxsZWQuIiwic2V2ZXJpdHkiOiJjcml0aWNhbCIsImZpbGVQYXRoIjoicmVxdWlyZW1lbnRzLWRldi50eHQiLCJsaW5lU3RhcnQiOjE5LCJsaW5lRW5kIjoyMn1dfQ== --> <!-- gk-ai-analysis-end:2e6eec61548a73e83b0cdd9e4a4fe7018815f997 --> <!-- gitkraken-review-badge-begin --> --- <a href="https://gitkraken.dev/review/github/Project-MONAI/MONAI/pull/8868?source=pr_review_chip"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://gitkraken.dev/images/figures/gitkraken-review-badge-dark.svg"> <img src="https://gitkraken.dev/images/figures/gitkraken-review-badge-light.svg" alt="Open with GitKraken"> </picture> </a> <!-- gitkraken-review-badge-end --> --------- Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…roject-MONAI#9011) Adds NaViT (monai.networks.nets.NaViT), a Vision Transformer that removes the fixed-resolution constraint of standard ViT by packing multiple variable-size images into a single sequence per batch element. Key features: - Patch n' Pack: multiple images concatenated into one sequence per group, with a per-image attention mask preventing cross-image attention - Factorised positional embeddings: separate learnable tables per spatial axis, allowing generalisation to unseen resolutions - Token dropout: configurable fraction of patch tokens dropped during training (float or callable) - Attention pooling: learned query attends over each image's tokens to produce a fixed-size per-image representation - QK normalisation: RMS normalisation on queries and keys (ViT-22B style) - 2D and 3D support: works for (C, H, W) and (C, H, W, D) inputs Changes: - monai/networks/nets/navit.py: new NaViT implementation - monai/networks/nets/__init__.py: export NaViT - tests/networks/nets/test_navit.py: 24 unit tests covering shape, variable resolutions, token dropout, auto-grouping, gradient flow, ill arguments, and forward validation - docs/source/networks.rst: autoclass entry - docs/source/whatsnew_1_5_2.md: feature description - CHANGELOG.md: entry under Unreleased Fixes # . ### Description A few sentences describing the changes proposed in this pull request. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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). - [x] New tests added to cover the changes. - [ ] Integration tests passed locally by running `./runtests.sh -f -u --net --coverage`. - [x] Quick tests passed locally by running `./runtests.sh --quick --unittests --disttests`. - [x] In-line docstrings updated. - [x] Documentation updated, tested `make html` command in the `docs/` folder. --------- Signed-off-by: Vikash Gupta <write2vikash@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…oad()/run() (Project-MONAI#9057) ## Summary Fixes GHSA-873f-pvrv-4x83: GHSA-873f-pvrv-4x83 `monai.bundle.load()`, with its default `model=None`, builds a bundle's network by parsing the bundle's own config through `create_workflow()`. That parsing resolves any `"_target_"` value to an importable callable with no allow list, and passes any `"$"`-prefixed value to Python `eval()`. `monai.bundle.run()` reaches the same code path via a caller-supplied `config_file`. Either way, this means loading or running a bundle whose config you haven't reviewed can execute arbitrary code. ### Design An earlier version of this fix added an opt-in `trust_remote_code` flag to `load()`. Per review discussion, that was dropped: MONAI has no mechanism to actually establish whether a bundle is trustworthy (unlike, say, a per-repo "has custom code" check), so a flag like that mostly teaches people to set it once and forget about it, without giving them a real basis to decide. Instead: - `create_workflow()` — the shared path both `load()` and `run()` use to parse a config file — now raises a `UserWarning` immediately before doing so, spelling out exactly what `"_target_"`/`"$"`-expression content can do and linking this advisory. - No behavior is blocked. Default behavior is unchanged other than the added warning: `load()`/`run()` still parse and execute the config exactly as before. - The warning applies uniformly to every caller of `create_workflow()`, not just `load()`. ### Changes - `monai/bundle/scripts.py`: warning added in `create_workflow()`; docstrings on `load()`, `run()`, and `create_workflow()` updated to describe the risk and point at the advisory. - `tests/bundle/test_bundle_download.py`: `TestLoadWarnsOnConfigExecution` — default `load()` warns and still executes the config (no flag needed), explicit `model=` still skips config parsing entirely (and warns about nothing), and `run()` warns via the same `create_workflow()` path. ## Test plan - [x] `python3 -m unittest tests.bundle.test_bundle_download.TestLoadWarnsOnConfigExecution -v` - [x] Full `tests/bundle/test_bundle_download.py`, `tests/bundle/test_config_parser.py` — no new failures vs. `dev` (remaining failures are pre-existing environment gaps: missing `requests`/`nibabel`, one `pdb`/`bdb` quirk) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com> Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Fixes Project-MONAI#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. A script `print_dependencies.py` is provided to reconstruct a requirements file from the toml file when needed, such as installing dependencies before installing MONAI for technical reasons. 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. * Adds a test in packaging for uv. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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. - [x] Documentation updated, tested `make html` command in the `docs/` folder. --------- Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: YunLiu <55491388+KumoLiu@users.noreply.github.com>
Addresses [GHSA-h89g-r5pc-wxfm](GHSA-h89g-r5pc-wxfm). ### Description This introduces a `safe_eval` function to evaluate known safe expressions which do not contain member access, calls, indexing, or other expressions which could be used for code injection. Use of `eval` is replaced where appropriate. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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). - [x] 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. --------- Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
…ject-MONAI#9063) Fixes Project-MONAI#9062 ## Summary - `_RewriteConstNp.visit_Constant` returned an `ast.Module` (from `ast.parse()`) instead of an expression node, corrupting the tree. Fixed by using `mode="eval"` and extracting `.body`. - `safe_eval` evaluated the original `expr` string rather than the rewritten AST, so numpy-wrapping was silently discarded. Fixed by compiling and evaluating the parsed AST. - Fixed a typo in the docstring ("expressoini" -> "expression"). ## Test plan - [x] Existing `test_good_exprs` and `test_good_exprs_np` still pass (numerical correctness) - [x] New `test_rewrite_np_produces_numpy_types` verifies int/float literals are wrapped in numpy types - [x] New `test_rewrite_np_large_exponent` verifies `9**9**9` overflows under `np.int32` instead of producing a slow ~369-million-digit Python integer --------- Signed-off-by: Chhayan Jain <chhayankjain@gmail.com> Signed-off-by: chhayankjain <chhayank44@gmail.com> Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…oject-MONAI#8455) (Project-MONAI#8937) ### Description Fixes Project-MONAI#8455. Installing a broken/hanging onnx (e.g. `onnx==1.18.0` on Windows) makes `import monai` fail with no error message. Root cause: `monai/networks/utils.py` and `monai/bundle/scripts.py` call `optional_import("onnx")` (and `onnx.reference` / `onnxruntime`) at module scope. `optional_import` imports eagerly (`__import__`), and `import monai` auto-loads `monai.networks`, so importing MONAI unconditionally imports onnx — inheriting any onnx import failure/hang. This defers those optional imports into the functions that actually use them (`convert_to_onnx` in `networks/utils.py`, `onnx_export`'s `save_onnx` in `bundle/scripts.py`), matching the lazy pattern already used for `tensorrt` in the same file. After this change, importing MONAI no longer imports onnx; the ONNX conversion code paths are unchanged. ### Types of changes - [x] Non-breaking change (fix or new feature that would not break existing functionality). - [x] New tests added to cover the changes. ### Testing Added `tests/networks/test_lazy_onnx_import.py`, which (in a subprocess, with a meta-path recorder) asserts that `import monai` and `import monai.bundle` do not import onnx/onnxruntime — verified passing with onnx installed. The existing `tests/networks/test_convert_to_onnx.py` continues to exercise the conversion paths in CI. Signed-off-by: Lanre Shittu <136805224+Shizoqua@users.noreply.github.com>
### Description `ClipIntensityPercentiles` stored returned clipping values on the transform instance. Reusing the same transform therefore accumulated values from earlier calls and also mutated the metadata of earlier outputs. This change keeps the clipping-value accumulator local to each `__call__`. Each result now receives only its own clipping values, and later calls cannot change metadata already returned to a caller. Regression tests cover repeated channel-wise and non-channel-wise calls. ### Types of changes - [x] 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). - [x] 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. ### Testing - `python -m unittest tests.transforms.test_clip_intensity_percentiles tests.transforms.test_clip_intensity_percentilesd` — 96 tests passed - `python -m ruff check monai/transforms/intensity/array.py tests/transforms/test_clip_intensity_percentiles.py` - `python -m black --check monai/transforms/intensity/array.py tests/transforms/test_clip_intensity_percentiles.py` Signed-off-by: Mohamed Abdeltawab <mohamed.abdeltawab@integrant.com> Co-authored-by: Mohamed Abdeltawab <mohamed.abdeltawab@integrant.com>
Fixes Project-MONAI#8412 ### Description `PerceptualLoss` could crash with `RuntimeError: Function 'SqrtBackward0' returned nan values in its 0th output` when the loss became very low (near-identical input/target features). The cause was in `normalize_tensor`, where `eps` was added *after* the square root — this guarded the forward division but not the `sqrt` gradient, so a zero feature norm produced `1/(2·√0) = inf → NaN` during backprop. This PR moves `eps` inside the sqrt (`sqrt(sum(x**2) + eps)`), keeping the forward output unchanged for normal inputs while ensuring the gradient stays finite. This matches the standard LPIPS normalization pattern. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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). - [x] 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. Signed-off-by: Shizoqua <hr.lanreshittu@yahoo.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…ONAI#8994) ### Description `_ConfigProxy` (added in Project-MONAI#8858) resolves a dotted key by chaining to `get_parsed_content`, and falls back to the underlying container when the chained id is not in the resolver: ```python try: return self._chain(key) except KeyError: return getattr(self._value, key) ``` A proxy backed by a `$@ref` wraps the *parsed* value of the referenced node, but that node's children have no ids of their own, so `alias::x` is absent from the resolver. The fallback then looks `x` up as a **dict attribute** rather than a key, and dot-notation fails on a value that bracket-notation returns happily: ```python parser = ConfigParser(config={"target": {"x": 1, "y": 2}, "alias": "$@target"}, globals={"monai": "monai"}) parser.alias["x"] # -> 1 parser.alias.x # -> AttributeError: 'dict' object has no attribute 'x' ``` This also affects chained refs (`"alias": "$@mid"`, `"mid": "$@target"`). Ref-backed proxies are already treated as first-class elsewhere: `_backing_id()` resolves the full `$@ref` chain for writes, and `test_ref_backed_proxy_write_through` covers `parser.alias["x"]` reads and writes. The dot-notation read is the one path that was not covered, and it diverges. It also contradicts the documented precedence rule on the class ("Config keys take precedence over `dict`/`list` attributes and methods") — here `x` *is* a key of the aliased node, but the dict attribute lookup wins and raises. ### Proposed changes Make `__getattr__`'s fallback mirror the one `__getitem__` already uses: if the chained id is absent but the key exists in the underlying container, return `self._value[key]`. Keys that are *not* in the container still fall through to `getattr`, so container methods (`.keys()`, `.items()`, …) are unaffected, as is the existing "config key shadows a same-named dict method" behaviour. The change is confined to the `except KeyError` fallback, so any id that resolves today keeps resolving through `_chain` exactly as before — no behaviour change for non-ref proxies. ### How did you test it? - Added `test_ref_backed_proxy_attribute_read` and `test_chained_ref_backed_proxy_attribute_read` next to the existing ref write-through tests. Both **fail without the source change** (`AttributeError`) and pass with it; they assert `parser.alias.x == parser.alias["x"]`, and that `.keys()` still resolves. - `tests/bundle/test_config_parser.py`: 34 passed before, 36 passed after (2 new), no regressions. - Whole `tests/bundle/` suite: identical results before and after the change (the only failures are pre-existing network-dependent `test_bundle_download` cases, unchanged by this PR). - `ruff check` / `ruff format --check` (repo-pinned 0.15.20), `black`, `isort` clean on both files; `mypy monai/bundle/config_parser.py` reports the same single pre-existing `yaml.safe_dump` error as `dev`, no new ones. ### Notes for the reviewer The fallback returns the raw value, matching `__getitem__`'s fallback rather than wrapping it in a new proxy — this keeps the two notations exactly consistent and the change minimal. Happy to wrap the result in `_wrap_parsed` instead if you'd prefer deeper dot-chaining through refs, though that would make dot- and bracket-notation diverge again in the other direction. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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). - [x] 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`. (Ran the affected suites directly with `pytest` on Windows, plus `ruff`/`black`/`isort`/`mypy`, rather than `runtests.sh`; details above.) - [ ] In-line docstrings updated. - [ ] Documentation updated, tested `make html` command in the `docs/` folder. Signed-off-by: VenkateswarluNagineni <venkates2002@tamu.edu> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…roject-MONAI#9032) ## Summary Closes the open Dependabot alerts for `mlflow`, `transformers`, and `setuptools`, and migrates MONAI's MLflow integration off the deprecated filesystem (file store) backend onto the recommended SQLite backend. ### Fixed | Package | Change | |---|---| | `mlflow` | Bumped floor to `>=3.15.2`, closing the 2.x/early-3.x CVEs and the unauthenticated webhook SSRF (CVE-2026-64849, fixed in 3.15.0). Since mlflow>=3.13 hard-errors on the filesystem tracking backend, `MLFlowHandler` now defaults to a local SQLite backend (`sqlite:///<cwd>/mlruns.db`, artifacts under `<cwd>/mlruns`) and rejects explicit local-path / `file://` tracking URIs with an actionable error. Adds `monai.utils.path_to_sqlite_uri`, an `artifact_location` argument, and SQLite engine disposal on `close()`. | | `transformers` | Bumped floor to `>=5.5.0`, closing two HIGH severity CVEs. `MultiModal` now builds a real `transformers.BertConfig` with `_attn_implementation="eager"` for transformers>=4.48's attention dispatch. | | `setuptools` | Bumped the build-system floor to `>=78.1.1`, closing one HIGH severity CVE. The old `<=79.0.1` cap (Project-MONAI#8439) is no longer needed since the legacy `fetch_build_eggs` CLI usage is gone from `setup.py`. | This PR supersedes Project-MONAI#8894 (the standalone SQLite migration), which I have proposed closing. ### Test plan - `tests/handlers/test_handler_mlflow.py` — SQLite default, artifact co-location, file-store rejection, remote URI, and a full run flow. - `tests/fl/monai_algo/test_fl_monai_algo.py` and `tests/integration/test_integration_bundle_run.py` — updated to SQLite tracking URIs. - `tests/networks/nets/test_transchex.py` — passes against transformers 4.36-4.40 and 5.5+. - `tests/utils/misc/test_monai_utils_misc.py::TestPathToSqliteUri` — SQLite URI construction and escaping. ### Please re-verify before merging The `transformers>=5.5.0` bump: the original `<5.0` cap (Project-MONAI#8912) cited `torch.float8_e8m0fnu` missing from the NGC Docker image's PyTorch 2.7 build. This was not reproducible against PyPI `torch>=2.8.0`, but please re-run the Docker/tutorial CI against the current NGC base image. --------- Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com>
### Description The `weekly-preview.yml` action is not working due to some strange interaction with the updated build process. The solution is to install MONAI first before making the wheel. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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. --------- Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…le config (Project-MONAI#9078) ## Summary Fixes GHSA-x6pr-233j-x5cw: https://github.com/Project-MONAI/MONAI/security/advisories/GHSA-x6pr-233j-x5cw Also closes GHSA-wvpx-5qmp-46g3: https://github.com/Project-MONAI/MONAI/security/advisories/GHSA-wvpx-5qmp-46g3 `MonaiAlgo`/`MonaiAlgoStats` run a bundle whose entire app directory is provisioned by the FL system. `initialize(extra)` resolves `bundle_root = os.path.join(extra[APP_ROOT], self.bundle_root)` — `APP_ROOT` is supplied by the aggregation server — then builds a `ConfigWorkflow` over `<app_root>/configs/train.json` and runs its `initialize` expressions. Because FL tasks are dispatched per round and executed with no human in the loop, a malicious or compromised server gets silent code execution on every participating client. The `UserWarning` added in Project-MONAI#9057 for GHSA-873f-pvrv-4x83 lives in `create_workflow()`. This path never calls it — `MonaiAlgo` constructs `ConfigWorkflow` directly — so nothing warned here at all. ### Design Executing the config stays unblocked, for the same reason the `trust_remote_code` flag was dropped from Project-MONAI#9057: MONAI has no mechanism to establish whether a bundle is trustworthy, so a flag mostly teaches operators to set it once and forget about it. Both `initialize()` methods now warn, naming the trust boundary (`extra[APP_ROOT]`) and the absence of per-round human interaction. The one behaviour change is narrowly scoped, and it targets the sink with no functional role in FL. `ConfigWorkflow` defaults `logging_file` to the bundle's own `configs/logging.conf` and passes it to `logging.config.fileConfig`, which `eval()`s the INI's `class=`/`args=` fields. That is code execution at construction time, before any config is parsed, and it hides in a plain INI rather than the MONAI `$`-DSL — easy to miss when reviewing a bundle. The FL client now treats `extra[ExtraItems.LOGGING_FILE]` as `False` both when the key is absent and when it is explicitly `None`, so a server-written `logging.conf` is never applied. `None` needs the same treatment as absent because it was the pre-PR default and `ConfigWorkflow` reads it as "fall back to the bundle's own `configs/logging.conf`" — exactly the file this change exists to keep away from `fileConfig`. An FL system that wants bundle logging passes an explicit path, through the key that already exists for it. The `fileConfig` warning sits inside the branch that actually calls it, not at the top of `__init__`. That keeps it truthful (nothing runs when the file is absent or logging is disabled, both common) and avoids double-warning callers who already got the `create_workflow()` warning, which is about `_target_`/`$` rather than the INI. ### Changes - `monai/fl/client/monai_algo.py`: warning in both `initialize()` methods; `ExtraItems.LOGGING_FILE` treated as `False` when absent or explicitly `None`; security notes on both class docstrings; both `initialize()` docstrings rewritten for the new default (this also fixes a `diable` typo). - `monai/bundle/workflows.py`: `_warn_logging_file_execution()` called immediately before each of the two `fileConfig` invocations; `logging_file` docstring entries updated on `BundleWorkflow`, `PythonicWorkflow` and `ConfigWorkflow`. - `tests/fl/monai_algo/test_fl_monai_algo.py`: `TestFLMonaiAlgoWarnsOnProvisionedConfig` — stages an app whose `train.json` and `logging.conf` each drop a distinct marker, for both `MonaiAlgo` and `MonaiAlgoStats`. Asserts the config still executes with the advisory warning; that the server's `logging.conf` no longer does, whether the key is absent or explicitly `None`; that an explicit path opts back in; and that no `fileConfig` warning fires when nothing is executed. - `tests/bundle/test_bundle_workflow.py`: `TestConfigWorkflowWarnsOnLoggingConf` — a bundle's default `configs/logging.conf` warns and still applies; `logging_file=False` neither warns nor applies it. Both new test classes snapshot and restore the root logger, closing any handler `fileConfig` installs. The suite runs in one process, so without that they would leak a root handler and formatter into every test that follows. ## Test plan - [x] `python -m unittest tests.fl.monai_algo.test_fl_monai_algo` — 17 passed - [x] `python -m unittest tests.fl.test_fl_monai_algo_stats` — 3 passed - [x] `python -m unittest tests.bundle.test_bundle_workflow.TestConfigWorkflowWarnsOnLoggingConf` — 2 passed - [x] `python -m unittest tests.bundle.test_bundle_download.TestLoadWarnsOnConfigExecution` — 6 passed, no double-warn regression on the Project-MONAI#9057 fix - [x] Each new assertion checked against the unpatched code first — the advisory's payload writes its marker via the bundle config and via `logging.conf` before the change, and only via the bundle config after it - [x] Root logger verified identical before and after both new test classes run - [x] `black`, `isort`, `ruff` clean on the changed files ### Types of changes - [ ] Non-breaking change (fix or new feature that would not break existing functionality). - [x] Breaking change (fix or new feature that would cause existing functionality to change). - [x] New tests added to cover the changes. - [x] In-line docstrings updated. The breaking-change box is for the `LOGGING_FILE` default only: an FL deployment relying on the bundle shipping its own `logging.conf` now has to pass the path explicitly. Everything else is additive. --------- Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com>
… WindowAttention (Project-MONAI#8977) Fixes Project-MONAI#8973 . ### Description SwinUNETR's WindowAttention builds the full (nWindows*heads, N, N) score matrix by hand before softmax. This adds an opt-in use_flash_attention flag (default False, so existing behaviour is unchanged) that routes attention through torch.nn.functional.scaled_dot_product_attention, folding the relative position bias and, for shifted windows, the attention mask into one additive attn_mask cast to the query dtype. This mirrors the flash-attention option already in MONAI's SelfAttention, CrossAttention and CABlock. Measured on the SwinUNETR encoder (SwinViT) forward, inference, single GPU, best-of-5. Float32 output matches the default path to within 3e-6 and is bit-exact in float64, verified across 2D and 3D, batch sizes 1 to 4, and non-cubic inputs. | ROI | dtype | default | flash | speedup | |---|---|---|---|---| | 96^3 | fp32 | 12.59 ms | 8.34 ms | 1.51x | | 96^3 | bf16 | 10.71 ms | 5.46 ms | 1.96x | | 128^3 | fp32 | 34.27 ms | 21.74 ms | 1.58x | | 128^3 | bf16 | 29.45 ms | 14.12 ms | 2.09x | | 160^3 | fp32 | 59.05 ms | 37.66 ms | 1.57x | | 160^3 | bf16 | 51.25 ms | 25.33 ms | 2.02x | The flag is threaded through SwinTransformer, BasicLayer and SwinTransformerBlock to WindowAttention, exactly as use_v2 and use_checkpoint are. No parameters or buffers change, so pretrained weights load unchanged. The flash path is used only when autograd is disabled and the module is not scripted, so training and TorchScript keep the original path byte-for-byte; this is a deliberate choice to leave training numerics untouched. ### Types of changes - [x] Non-breaking change (fix or new feature that would not break existing functionality). - [x] New tests added to cover the changes. - [x] In-line docstrings updated. --------- Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk> Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…ject-MONAI#8960) `CenterSpatialCrop` blows up under `torch.compile` while the other crop transforms are fine (Project-MONAI#8191). It fails in `Crop.compute_slices` with `The tensor has a non-zero number of elements, but its data is not allocated yet`. The cause is that `compute_slices` ran its start/end math through CPU tensors (`convert_to_tensor(..., device="cpu")`). For `CenterSpatialCrop` the ROI values come from the input shape, so under tracing they're fake tensors with no storage, and moving them to the CPU asks Dynamo for data that isn't there. Since it's just integer math, I moved it to plain Python. A small `_to_int_list` helper handles the input forms (scalar, sequence, tensor, ndarray), with the same clamping and broadcasting as before. `CenterSpatialCrop` now compiles like the rest of the transforms. Added a regression test that compiles `CenterSpatialCrop` and checks the shape (fails before, passes after), guarded for PyTorch versions with `torch.compile`. Fixes Project-MONAI#8191. --------- Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk> Signed-off-by: Soumya Snigdha Kundu <soumyawork15@gmail.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Part of Project-MONAI#9058. ### Description This updates the CodeQL action to get this running again. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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. --------- Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Part of Project-MONAI#9058 ### Description This adds black and isort pre-commit hooks. This should fix formatting in the same way as `runtests.sh --autofix` but automatically, and before other actions run for too long in a PR. Note that the versions of both need to be set in the `.pre-commit-config.yaml` file separately from wherever else they're specified, so when versions are changed they need to be synced between files. The version for isort is left unchanged but the `<6` restriction should be removed shortly. The pre-commit step for `pycln` was removed in favour of checking for unused imports with Ruff by enabling F401 in `pyproject.toml`. ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] 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. --------- Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…AI#9085) ### Description `algo_from_json` resolves the `_target_` value from an `algo_object.json` to an importable callable and invokes it, and adds file-influenced directories to `sys.path`. Emit a trust-boundary warning before instantiation so users only load trusted files (GHSA-2wx3-8x3w-r8qv). ### Types of changes - [x] Non-breaking change - [x] New tests added to cover the changes. --------- Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…AI#9087) ### Description `PydicomReader._get_affine` builds the affine matrix from DICOM `PixelSpacing`, `ImagePositionPatient`, and `ImageOrientationPatient` values with no finite check. A crafted DICOM carrying `NaN`/`inf` in those DS tags produces a corrupted affine that propagates through spatial transforms and crashes MONAILabel inference or silently corrupts results. Validate all affine inputs with `math.isfinite()` and raise `ValueError` naming the offending tag before building the matrix (GHSA-6hp3-vr39-rqw8). ### Types of changes - [ ] Non-breaking change - [x] Breaking change (non-finite DICOM geometry now raises instead of silently proceeding) - [x] New tests added to cover the changes. --------- Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
…h confinement) (Project-MONAI#9088) ### Description Harden the download/deserialization chain: - Pass `weights_only=True` to pretrained weight loaders in `senet`, `densenet`, `efficientnet`, and `text_embedding` so a substituted `.pth` cannot unpickle code (GHSA-vm9c-7j6g-c7mm). - `check_hash`: emit a `UserWarning` when no hash value is provided instead of silently passing, and default `check_hash`/`download_url` to `sha256` (GHSA-hhh4-h52m-fqh6). - `download_large_files`: confine large-file targets to the bundle directory, rejecting absolute and `../` traversal (GHSA-x4pc-gj5h-3pq7). Note: SENet pretrained URLs remain `http://` because the upstream host does not serve the files over HTTPS (verified unreachable); `weights_only=True` closes the code-execution vector, leaving only a transport-integrity gap. ### Types of changes - [ ] Non-breaking change - [x] Breaking change (default hash type changes from md5 to sha256 for `check_hash`/`download_url`; callers that relied on the md5 default now pass `hash_type` explicitly) - [x] New tests added to cover the changes. --------- Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
Adds documentation and validation for the spatial shape constraint that each dimension of img_size must be divisible by 16 (the patch size). Fixes Project-MONAI#6771 (partial)
Lubnaaziz-28
requested review from
KumoLiu,
Nic-Ma,
ericspod and
virginiafdez
as code owners
September 3, 2026 20:20
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds documentation and validation for the spatial shape constraint that each dimension of
img_sizemust be divisible by 16 (the patch size).Changes
__init__that raisesValueErrorifimg_sizeis not divisible by 16Related
Partially addresses #6771 (documentation of spatial shape constraints for networks)
Testing