Skip to content

Commit 255db19

Browse files
committed
Raise exception when user-specified reader package is not installed
When a user explicitly specifies a reader (e.g., reader="ITKReader") but the required package is not installed, LoadImage now raises an OptionalImportError instead of silently falling back to another reader with only a warning. This makes the behavior explicit: if the user specifically requested a reader, they should be informed immediately that it cannot be used, rather than having the system silently use a different reader which may produce unexpected results. Default behavior (reader=None) remains unchanged — missing optional packages are still handled gracefully with debug logging. Fixes #7437 Signed-off-by: haoyu-haoyu <haoyu-haoyu@users.noreply.github.com> Signed-off-by: SexyERIC0723 <haoyuwang144@gmail.com>
1 parent daaedaa commit 255db19

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

monai/transforms/io/array.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,11 @@ def __init__(
209209
the_reader = look_up_option(_r.lower(), SUPPORTED_READERS)
210210
try:
211211
self.register(the_reader(*args, **kwargs))
212-
except OptionalImportError:
213-
warnings.warn(
214-
f"required package for reader {_r} is not installed, or the version doesn't match requirement."
215-
)
212+
except OptionalImportError as e:
213+
raise OptionalImportError(
214+
f"Required package for reader {_r} is not installed, or the version doesn't match requirement. "
215+
f"Please install the required package to use {_r}."
216+
) from e
216217
except TypeError: # the reader doesn't have the corresponding args/kwargs
217218
warnings.warn(f"{_r} is not supported with the given parameters {args} {kwargs}.")
218219
self.register(the_reader())

tests/transforms/test_load_image.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,5 +498,45 @@ def test_correct(self, input_param, expected_shape, track_meta):
498498
self.assertFalse(hasattr(r, "affine"))
499499

500500

501+
class TestLoadImageReaderNotInstalled(unittest.TestCase):
502+
"""Test that specifying a reader whose required package is not installed raises an error.
503+
504+
Addresses https://github.com/Project-MONAI/MONAI/issues/7437
505+
"""
506+
507+
@unittest.skipIf(has_itk, "test requires itk to NOT be installed")
508+
def test_specified_reader_not_installed_raises(self):
509+
"""When a user explicitly specifies a reader that is not installed, LoadImage should raise
510+
an OptionalImportError instead of silently falling back to another reader."""
511+
from monai.utils import OptionalImportError
512+
513+
with self.assertRaises(OptionalImportError):
514+
LoadImage(reader="ITKReader")
515+
516+
def test_specified_reader_not_installed_raises_mocked(self):
517+
"""Mock test to verify OptionalImportError is raised (not just warned) when a user-specified
518+
reader's required package is not installed."""
519+
from unittest.mock import patch
520+
521+
from monai.utils import OptionalImportError
522+
523+
_original = __import__("monai.transforms.io.array", fromlist=["optional_import"]).optional_import
524+
525+
def _mock_optional_import(module, name="", *args, **kwargs):
526+
if name == "MockMissingReader":
527+
# Return a class that raises OptionalImportError on instantiation,
528+
# simulating a reader whose backend package is not installed
529+
class _Unavailable:
530+
def __init__(self, *a, **kw):
531+
raise OptionalImportError("mock package is not installed")
532+
533+
return _Unavailable, True
534+
return _original(module, *args, name=name, **kwargs)
535+
536+
with patch("monai.transforms.io.array.optional_import", side_effect=_mock_optional_import):
537+
with self.assertRaises(OptionalImportError):
538+
LoadImage(reader="MockMissingReader")
539+
540+
501541
if __name__ == "__main__":
502542
unittest.main()

0 commit comments

Comments
 (0)