Skip to content

Commit f6325e2

Browse files
committed
adding premerge tests for py3.10 (#5370)
### Description adding tests for python 3.10 ### 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: Wenqi Li <wenqil@nvidia.com>
1 parent 4609206 commit f6325e2

11 files changed

+74
-34
lines changed

.github/workflows/pythonapp-min.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ jobs:
7474
strategy:
7575
fail-fast: false
7676
matrix:
77-
python-version: [3.7, 3.8, 3.9]
77+
python-version: [3.7, 3.8, 3.9, '3.10']
7878
timeout-minutes: 40
7979
steps:
8080
- uses: actions/checkout@v3

.github/workflows/setupapp.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
runs-on: ubuntu-latest
7979
strategy:
8080
matrix:
81-
python-version: [3.7, 3.8, 3.9]
81+
python-version: [3.7, 3.8, 3.9, '3.10']
8282
steps:
8383
- uses: actions/checkout@v3
8484
with:

requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
pytorch-ignite==0.4.10
44
gdown>=4.4.0
55
scipy
6-
itk>=5.2
6+
itk>=5.2; python_version < "3.10"
77
nibabel
88
pillow!=8.3.0 # https://github.com/python-pillow/Pillow/issues/5571
99
tensorboard

tests/test_ensure_channel_first.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,39 @@
1313
import tempfile
1414
import unittest
1515

16-
import itk
1716
import nibabel as nib
1817
import numpy as np
1918
import torch
2019
from parameterized import parameterized
2120
from PIL import Image
2221

23-
from monai.data import ITKReader
2422
from monai.data.meta_tensor import MetaTensor
2523
from monai.transforms import EnsureChannelFirst, LoadImage
24+
from monai.utils import optional_import
25+
26+
itk, has_itk = optional_import("itk", allow_namespace_pkg=True)
27+
ITKReader, _ = optional_import("monai.data", name="ITKReader", as_type="decorator")
2628

2729
TEST_CASE_1 = [{}, ["test_image.nii.gz"], None]
2830

2931
TEST_CASE_2 = [{}, ["test_image.nii.gz"], -1]
3032

3133
TEST_CASE_3 = [{}, ["test_image.nii.gz", "test_image2.nii.gz", "test_image3.nii.gz"], None]
3234

33-
TEST_CASE_4 = [{"reader": ITKReader()}, ["test_image.nii.gz"], None]
34-
35-
TEST_CASE_5 = [{"reader": ITKReader()}, ["test_image.nii.gz"], -1]
36-
37-
TEST_CASE_6 = [{"reader": ITKReader()}, ["test_image.nii.gz", "test_image2.nii.gz", "test_image3.nii.gz"], None]
35+
TEST_CASE_4 = [{"reader": ITKReader() if has_itk else "itkreader"}, ["test_image.nii.gz"], None]
3836

39-
TEST_CASE_7 = [{"reader": ITKReader(pixel_type=itk.UC)}, "tests/testing_data/CT_DICOM", None]
37+
TEST_CASE_5 = [{"reader": ITKReader() if has_itk else "itkreader"}, ["test_image.nii.gz"], -1]
4038

41-
itk.ProcessObject.SetGlobalWarningDisplay(False)
39+
TEST_CASE_6 = [
40+
{"reader": ITKReader() if has_itk else "itkreader"},
41+
["test_image.nii.gz", "test_image2.nii.gz", "test_image3.nii.gz"],
42+
None,
43+
]
4244

4345

4446
class TestEnsureChannelFirst(unittest.TestCase):
4547
@parameterized.expand([TEST_CASE_1, TEST_CASE_2, TEST_CASE_3, TEST_CASE_4, TEST_CASE_5, TEST_CASE_6])
48+
@unittest.skipUnless(has_itk, "itk not installed")
4649
def test_load_nifti(self, input_param, filenames, original_channel_dim):
4750
if original_channel_dim is None:
4851
test_image = np.random.rand(8, 8, 8)
@@ -58,9 +61,11 @@ def test_load_nifti(self, input_param, filenames, original_channel_dim):
5861
result = EnsureChannelFirst()(result)
5962
self.assertEqual(result.shape[0], len(filenames))
6063

61-
@parameterized.expand([TEST_CASE_7])
62-
def test_itk_dicom_series_reader(self, input_param, filenames, _):
63-
result = LoadImage(image_only=True, **input_param)(filenames)
64+
@unittest.skipUnless(has_itk, "itk not installed")
65+
def test_itk_dicom_series_reader(self):
66+
filenames = "tests/testing_data/CT_DICOM"
67+
itk.ProcessObject.SetGlobalWarningDisplay(False)
68+
result = LoadImage(image_only=True, reader=ITKReader(pixel_type=itk.UC))(filenames)
6469
result = EnsureChannelFirst()(result)
6570
self.assertEqual(result.shape[0], 1)
6671

tests/test_image_rw.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@
2323
from monai.data.image_writer import ITKWriter, NibabelWriter, PILWriter, register_writer, resolve_writer
2424
from monai.data.meta_tensor import MetaTensor
2525
from monai.transforms import LoadImage, SaveImage, moveaxis
26-
from monai.utils import MetaKeys, OptionalImportError
26+
from monai.utils import MetaKeys, OptionalImportError, optional_import
2727
from tests.utils import TEST_NDARRAYS, assert_allclose
2828

29+
_, has_itk = optional_import("itk", allow_namespace_pkg=True)
2930

31+
32+
@unittest.skipUnless(has_itk, "itk not installed")
3033
class TestLoadSaveNifti(unittest.TestCase):
3134
def setUp(self):
3235
self.test_dir = tempfile.mkdtemp()
@@ -82,6 +85,7 @@ def test_4d(self, reader, writer):
8285
self.nifti_rw(test_data, reader, writer, np.float16)
8386

8487

88+
@unittest.skipUnless(has_itk, "itk not installed")
8589
class TestLoadSavePNG(unittest.TestCase):
8690
def setUp(self):
8791
self.test_dir = tempfile.mkdtemp()
@@ -137,6 +141,7 @@ def test_1_new(self):
137141
self.assertEqual(resolve_writer("new")[0](0), 1)
138142

139143

144+
@unittest.skipUnless(has_itk, "itk not installed")
140145
class TestLoadSaveNrrd(unittest.TestCase):
141146
def setUp(self):
142147
self.test_dir = tempfile.mkdtemp()

tests/test_load_image.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,23 @@
1515
import unittest
1616
from pathlib import Path
1717

18-
import itk
1918
import nibabel as nib
2019
import numpy as np
2120
import torch
2221
from parameterized import parameterized
2322
from PIL import Image
2423

25-
from monai.data import ITKReader, NibabelReader, PydicomReader
24+
from monai.data import NibabelReader, PydicomReader
2625
from monai.data.meta_obj import set_track_meta
2726
from monai.data.meta_tensor import MetaTensor
2827
from monai.transforms import LoadImage
28+
from monai.utils import optional_import
2929
from tests.utils import assert_allclose
3030

31+
itk, has_itk = optional_import("itk", allow_namespace_pkg=True)
32+
ITKReader, _ = optional_import("monai.data", name="ITKReader", as_type="decorator")
33+
itk_uc, _ = optional_import("itk", name="UC", allow_namespace_pkg=True)
34+
3135

3236
class _MiniReader:
3337
"""a test case customised reader"""
@@ -67,34 +71,39 @@ def get_data(self, _obj):
6771

6872
TEST_CASE_5 = [{"reader": NibabelReader(mmap=False)}, ["test_image.nii.gz"], (128, 128, 128)]
6973

70-
TEST_CASE_6 = [{"reader": ITKReader()}, ["test_image.nii.gz"], (128, 128, 128)]
74+
TEST_CASE_6 = [{"reader": ITKReader() if has_itk else "itkreader"}, ["test_image.nii.gz"], (128, 128, 128)]
7175

72-
TEST_CASE_7 = [{"reader": ITKReader()}, ["test_image.nii.gz"], (128, 128, 128)]
76+
TEST_CASE_7 = [{"reader": ITKReader() if has_itk else "itkreader"}, ["test_image.nii.gz"], (128, 128, 128)]
7377

7478
TEST_CASE_8 = [
75-
{"reader": ITKReader()},
79+
{"reader": ITKReader() if has_itk else "itkreader"},
7680
["test_image.nii.gz", "test_image2.nii.gz", "test_image3.nii.gz"],
7781
(3, 128, 128, 128),
7882
]
7983

8084
TEST_CASE_8_1 = [
81-
{"reader": ITKReader(channel_dim=0)},
85+
{"reader": ITKReader(channel_dim=0) if has_itk else "itkreader"},
8286
["test_image.nii.gz", "test_image2.nii.gz", "test_image3.nii.gz"],
8387
(384, 128, 128),
8488
]
8589

8690
TEST_CASE_9 = [
87-
{"reader": ITKReader()},
91+
{"reader": ITKReader() if has_itk else "itkreader"},
8892
["test_image.nii.gz", "test_image2.nii.gz", "test_image3.nii.gz"],
8993
(3, 128, 128, 128),
9094
]
9195

92-
TEST_CASE_10 = [{"reader": ITKReader(pixel_type=itk.UC)}, "tests/testing_data/CT_DICOM", (16, 16, 4), (16, 16, 4)]
96+
TEST_CASE_10 = [
97+
{"reader": ITKReader(pixel_type=itk_uc) if has_itk else "itkreader"},
98+
"tests/testing_data/CT_DICOM",
99+
(16, 16, 4),
100+
(16, 16, 4),
101+
]
93102

94-
TEST_CASE_11 = [{"reader": "ITKReader", "pixel_type": itk.UC}, "tests/testing_data/CT_DICOM", (16, 16, 4), (16, 16, 4)]
103+
TEST_CASE_11 = [{"reader": "ITKReader", "pixel_type": itk_uc}, "tests/testing_data/CT_DICOM", (16, 16, 4), (16, 16, 4)]
95104

96105
TEST_CASE_12 = [
97-
{"reader": "ITKReader", "pixel_type": itk.UC, "reverse_indexing": True},
106+
{"reader": "ITKReader", "pixel_type": itk_uc, "reverse_indexing": True},
98107
"tests/testing_data/CT_DICOM",
99108
(16, 16, 4),
100109
(4, 16, 16),
@@ -124,14 +133,14 @@ def get_data(self, _obj):
124133
TEST_CASE_19 = [{"reader": PydicomReader()}, "tests/testing_data/CT_DICOM", (16, 16, 4), (16, 16, 4)]
125134

126135
TEST_CASE_20 = [
127-
{"reader": "PydicomReader", "ensure_channel_first": True},
136+
{"reader": "PydicomReader", "ensure_channel_first": True, "force": True},
128137
"tests/testing_data/CT_DICOM",
129138
(16, 16, 4),
130139
(1, 16, 16, 4),
131140
]
132141

133142
TEST_CASE_21 = [
134-
{"reader": "PydicomReader", "affine_lps_to_ras": True, "defer_size": "2 MB"},
143+
{"reader": "PydicomReader", "affine_lps_to_ras": True, "defer_size": "2 MB", "force": True},
135144
"tests/testing_data/CT_DICOM",
136145
(16, 16, 4),
137146
(16, 16, 4),
@@ -146,6 +155,7 @@ def get_data(self, _obj):
146155
TESTS_META.append([{"reader": "ITKReader", "fallback_only": False}, (128, 128, 128), track_meta])
147156

148157

158+
@unittest.skipUnless(has_itk, "itk not installed")
149159
class TestLoadImage(unittest.TestCase):
150160
@parameterized.expand(
151161
[TEST_CASE_1, TEST_CASE_2, TEST_CASE_3, TEST_CASE_3_1, TEST_CASE_4, TEST_CASE_4_1, TEST_CASE_5]
@@ -290,7 +300,7 @@ def test_my_reader(self):
290300

291301
def test_itk_meta(self):
292302
"""test metadata from a directory"""
293-
out = LoadImage(image_only=True, reader="ITKReader", pixel_type=itk.UC, series_meta=True)(
303+
out = LoadImage(image_only=True, reader="ITKReader", pixel_type=itk_uc, series_meta=True)(
294304
"tests/testing_data/CT_DICOM"
295305
)
296306
idx = "0008|103e"
@@ -313,6 +323,7 @@ def test_channel_dim(self, input_param, filename, expected_shape):
313323
self.assertEqual(result.meta["original_channel_dim"], input_param["channel_dim"])
314324

315325

326+
@unittest.skipUnless(has_itk, "itk not installed")
316327
class TestLoadImageMeta(unittest.TestCase):
317328
@classmethod
318329
def setUpClass(cls):

tests/test_load_imaged.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import unittest
1616
from pathlib import Path
1717

18-
import itk
1918
import nibabel as nib
2019
import numpy as np
2120
import torch
@@ -26,8 +25,11 @@
2625
from monai.data.meta_tensor import MetaTensor
2726
from monai.transforms import Compose, EnsureChannelFirstD, FromMetaTensord, LoadImaged, SaveImageD
2827
from monai.transforms.meta_utility.dictionary import ToMetaTensord
28+
from monai.utils import optional_import
2929
from tests.utils import assert_allclose
3030

31+
itk, has_itk = optional_import("itk", allow_namespace_pkg=True)
32+
3133
KEYS = ["image", "label", "extra"]
3234

3335
TEST_CASE_1 = [{"keys": KEYS}, (128, 128, 128)]
@@ -40,6 +42,7 @@
4042
TESTS_META.append([{"keys": KEYS, "reader": "ITKReader", "fallback_only": False}, (128, 128, 128), track_meta])
4143

4244

45+
@unittest.skipUnless(has_itk, "itk not installed")
4346
class TestLoadImaged(unittest.TestCase):
4447
@parameterized.expand([TEST_CASE_1, TEST_CASE_2])
4548
def test_shape(self, input_param, expected_shape):
@@ -87,6 +90,7 @@ def test_no_file(self):
8790
LoadImaged(keys="img", reader="nibabelreader", image_only=True)({"img": "unknown"})
8891

8992

93+
@unittest.skipUnless(has_itk, "itk not installed")
9094
class TestConsistency(unittest.TestCase):
9195
def _cmp(self, filename, ch_shape, reader_1, reader_2, outname, ext):
9296
data_dict = {"img": filename}
@@ -147,6 +151,7 @@ def test_png(self):
147151
self._cmp(filename, (3, 224, 256), "itkreader", "nibabelreader", output_name, ".png")
148152

149153

154+
@unittest.skipUnless(has_itk, "itk not installed")
150155
class TestLoadImagedMeta(unittest.TestCase):
151156
@classmethod
152157
def setUpClass(cls):

tests/test_meta_tensor.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ def test_construct_with_pre_applied_transforms(self):
499499
def test_multiprocessing(self, device=None, dtype=None):
500500
"""multiprocessing sharing with 'device' and 'dtype'"""
501501
buf = io.BytesIO()
502-
t = MetaTensor([0.0, 0.0], device=device, dtype=dtype)
502+
t = MetaTensor([0, 0] if dtype in (torch.int32, torch.int64) else [0.0, 0.0], device=device, dtype=dtype)
503503
t.is_batch = True
504504
if t.is_cuda:
505505
with self.assertRaises(NotImplementedError):
@@ -518,7 +518,9 @@ def test_array_function(self, device="cpu", dtype=float):
518518
assert_allclose(np.sum(a), np.sum(b))
519519
assert_allclose(np.sum(a, axis=1), np.sum(b, axis=1))
520520
assert_allclose(np.linalg.qr(a), np.linalg.qr(b))
521-
c = MetaTensor([1.0, 2.0, 3.0], device=device, dtype=dtype)
521+
c = MetaTensor(
522+
[1, 2, 3] if dtype in (torch.int32, torch.int64) else [1.0, 2.0, 3.0], device=device, dtype=dtype
523+
)
522524
assert_allclose(np.argwhere(c == 1.0).astype(int).tolist(), [[0]])
523525
assert_allclose(np.concatenate([c, c]), np.asarray([1.0, 2.0, 3.0, 1.0, 2.0, 3.0]))
524526
if pytorch_after(1, 8, 1):
@@ -530,7 +532,7 @@ def test_array_function(self, device="cpu", dtype=float):
530532
@parameterized.expand(TESTS)
531533
def test_numpy(self, device=None, dtype=None):
532534
"""device, dtype"""
533-
t = MetaTensor([0.0], device=device, dtype=dtype)
535+
t = MetaTensor([0 if dtype in (torch.int32, torch.int64) else 0.0], device=device, dtype=dtype)
534536
self.assertIsInstance(t, MetaTensor)
535537
assert_allclose(t.array, np.asarray([0.0]))
536538
t.array = np.asarray([1.0])
@@ -540,7 +542,7 @@ def test_numpy(self, device=None, dtype=None):
540542
self.check_meta(t, MetaTensor([2.0]))
541543
assert_allclose(t.as_tensor(), torch.as_tensor([2.0]))
542544
if not t.is_cuda:
543-
t.array[0] = torch.as_tensor(3.0, device=device, dtype=dtype)
545+
t.array[0] = torch.as_tensor(3 if dtype in (torch.int32, torch.int64) else 3.0, device=device, dtype=dtype)
544546
self.check_meta(t, MetaTensor([3.0]))
545547
assert_allclose(t.as_tensor(), torch.as_tensor([3.0]))
546548

tests/test_resample_to_match.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@
2424
from monai.data.image_reader import ITKReader, NibabelReader
2525
from monai.data.image_writer import ITKWriter
2626
from monai.transforms import Compose, EnsureChannelFirstd, LoadImaged, ResampleToMatch, SaveImaged
27+
from monai.utils import optional_import
2728
from tests.utils import assert_allclose, download_url_or_skip_test, testing_data_config
2829

30+
_, has_itk = optional_import("itk", allow_namespace_pkg=True)
31+
2932
TEST_CASES = ["itkreader", "nibabelreader"]
3033

3134

@@ -36,6 +39,7 @@ def get_rand_fname(len=10, suffix=".nii.gz"):
3639
return out
3740

3841

42+
@unittest.skipUnless(has_itk, "itk not installed")
3943
class TestResampleToMatch(unittest.TestCase):
4044
@classmethod
4145
def setUpClass(cls):

tests/test_save_image.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
from monai.data.meta_tensor import MetaTensor
2020
from monai.transforms import SaveImage
21+
from monai.utils import optional_import
22+
23+
_, has_itk = optional_import("itk", allow_namespace_pkg=True)
2124

2225
TEST_CASE_1 = [torch.randint(0, 255, (1, 2, 3, 4)), {"filename_or_obj": "testfile0.nii.gz"}, ".nii.gz", False]
2326

@@ -33,6 +36,7 @@
3336
]
3437

3538

39+
@unittest.skipUnless(has_itk, "itk not installed")
3640
class TestSaveImage(unittest.TestCase):
3741
@parameterized.expand([TEST_CASE_1, TEST_CASE_2, TEST_CASE_3, TEST_CASE_4])
3842
def test_saved_content(self, test_data, meta_data, output_ext, resample):

0 commit comments

Comments
 (0)