Skip to content

Commit e303b6e

Browse files
authored
Merge branch 'dev' into optimize/vectorize-dice-metric
2 parents ed14964 + 2a7d0cf commit e303b6e

7 files changed

Lines changed: 43 additions & 10 deletions

File tree

.github/workflows/codeql-analysis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ jobs:
6767
rm -rf /opt/hostedtoolcache/{node,go,Ruby,Java*}
6868
ls -al /opt/hostedtoolcache
6969
rm -rf /usr/share/dotnet/
70-
python -m pip install -U pip wheel
71-
python -m pip install -r requirements-dev.txt
70+
python -m pip install -U --no-build-isolation pip wheel wheel-stub
71+
python -m pip install --no-build-isolation -r requirements-dev.txt
7272
BUILD_MONAI=1 ./runtests.sh --build
7373
7474
- name: Perform CodeQL Analysis

.github/workflows/pythonapp-gpu.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
# Jenkinsfile.monai-premerge
22
name: premerge-gpu
33

4-
# on:
4+
on:
55
# # quick tests for pull requests and the releasing branches
66
# push:
77
# branches:
88
# - main
99
# - releasing/*
1010
# pull_request:
1111
# types: [opened, synchronize, closed]
12+
# Allows you to run this workflow manually from the Actions tab
13+
workflow_dispatch:
1214

1315
concurrency:
1416
# automatically cancel the previously triggered workflows when there's a newer version

docs/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ sphinx-autodoc-typehints==1.11.1
2121
pandas
2222
einops
2323
transformers>=4.53.0
24-
mlflow>=2.12.2
24+
mlflow>=2.12.2,<3.13
2525
clearml>=1.10.0rc0
2626
tensorboardX
2727
imagecodecs; platform_system == "Linux" or platform_system == "Darwin"

monai/data/image_reader.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,17 +1231,26 @@ class NumpyReader(ImageReader):
12311231
npz_keys: if loading npz file, only load the specified keys, if None, load all the items.
12321232
stack the loaded items together to construct a new first dimension.
12331233
channel_dim: if not None, explicitly specify the channel dim, otherwise, treat the array as no channel.
1234+
allow_pickle: if True, allows loading pickled contents from NPY/NPZ files. Note that the default value of False
1235+
prevents the risk of remote code execution, set this to True only for loading known trusted data. If this
1236+
argument is False and pickled data is loaded, a ValueError will be raised.
12341237
kwargs: additional args for `numpy.load` API except `allow_pickle`. more details about available args:
12351238
https://numpy.org/doc/stable/reference/generated/numpy.load.html
1236-
12371239
"""
12381240

1239-
def __init__(self, npz_keys: KeysCollection | None = None, channel_dim: str | int | None = None, **kwargs):
1241+
def __init__(
1242+
self,
1243+
npz_keys: KeysCollection | None = None,
1244+
channel_dim: str | int | None = None,
1245+
allow_pickle: bool = False,
1246+
**kwargs,
1247+
):
12401248
super().__init__()
12411249
if npz_keys is not None:
12421250
npz_keys = ensure_tuple(npz_keys)
12431251
self.npz_keys = npz_keys
12441252
self.channel_dim = float("nan") if channel_dim == "no_channel" else channel_dim
1253+
self.allow_pickle = allow_pickle
12451254
self.kwargs = kwargs
12461255

12471256
def verify_suffix(self, filename: Sequence[PathLike] | PathLike) -> bool:
@@ -1267,14 +1276,25 @@ def read(self, data: Sequence[PathLike] | PathLike, **kwargs):
12671276
More details about available args:
12681277
https://numpy.org/doc/stable/reference/generated/numpy.load.html
12691278
1279+
Raises:
1280+
ValueError: when `self.allow_pickle` is False but loaded data contains pickled objects.
12701281
"""
12711282
img_: list[Nifti1Image] = []
12721283

12731284
filenames: Sequence[PathLike] = ensure_tuple(data)
12741285
kwargs_ = self.kwargs.copy()
12751286
kwargs_.update(kwargs)
12761287
for name in filenames:
1277-
img = np.load(name, allow_pickle=True, **kwargs_)
1288+
try:
1289+
img = np.load(name, allow_pickle=self.allow_pickle, **kwargs_)
1290+
except ValueError as e:
1291+
# if a ValueError is raised, this is likely about pickle loading so raise an exception about this
1292+
raise ValueError(
1293+
"MONAI default value for argument `allow_pickle` of `np.load` changed to `False`, "
1294+
"explicitly pass `allow_pickle=True` as a constructor argument to NumpyReader "
1295+
"to enable pickle loading."
1296+
) from e
1297+
12781298
if Path(name).name.endswith(".npz"):
12791299
# load expected items from NPZ file
12801300
npz_keys = list(img.keys()) if self.npz_keys is None else self.npz_keys

requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pandas
3434
requests
3535
einops
3636
transformers>=4.53.0
37-
mlflow>=2.12.2
37+
mlflow>=2.12.2,<3.13
3838
clearml>=1.10.0rc0
3939
matplotlib>=3.6.3
4040
tensorboardX

setup.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ all =
7171
pandas
7272
einops
7373
transformers>=4.53.0
74-
mlflow>=2.12.2
74+
mlflow>=2.12.2,<3.13
7575
clearml>=1.10.0rc0
7676
matplotlib>=3.6.3
7777
tensorboardX
@@ -135,7 +135,7 @@ einops =
135135
transformers =
136136
transformers>=4.36.0, <4.41.0; python_version <= '3.10'
137137
mlflow =
138-
mlflow>=2.12.2
138+
mlflow>=2.12.2,<3.13
139139
matplotlib =
140140
matplotlib>=3.6.3
141141
clearml =

tests/data/test_numpy_reader.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,13 @@ def test_npy_pickle(self):
8181
np.save(filepath, test_data, allow_pickle=True)
8282

8383
reader = NumpyReader()
84+
85+
with self.assertRaises(ValueError):
86+
reader.get_data(reader.read(filepath))
87+
88+
reader = NumpyReader(allow_pickle=True)
8489
result = reader.get_data(reader.read(filepath))[0].item()
90+
8591
np.testing.assert_allclose(result["test"].shape, test_data["test"].shape)
8692
np.testing.assert_allclose(result["test"], test_data["test"])
8793

@@ -92,6 +98,11 @@ def test_kwargs(self):
9298
np.save(filepath, test_data, allow_pickle=True)
9399

94100
reader = NumpyReader(mmap_mode="r")
101+
102+
with self.assertRaises(ValueError):
103+
reader.get_data(reader.read(filepath, mmap_mode=None))
104+
105+
reader = NumpyReader(mmap_mode="r", allow_pickle=True)
95106
result = reader.get_data(reader.read(filepath, mmap_mode=None))[0].item()
96107
np.testing.assert_allclose(result["test"].shape, test_data["test"].shape)
97108

0 commit comments

Comments
 (0)