Skip to content

Commit 0940296

Browse files
committed
fix: raise exception when LoadImage reader is specified but not installed
Previously, when a user explicitly specified a reader (e.g. LoadImage(reader='ITKReader')) but the required optional package was not installed, MONAI would silently warn and fall back to the next available reader. This silent fallback is surprising and hard to debug. This change raises a RuntimeError instead, giving the user a clear actionable message that explains what happened and how to fix it (install the package or omit the reader argument to use automatic fallback). Backward compatibility is preserved: if no reader is specified, the existing warn-and- skip behavior for missing optional packages is unchanged. Fixes #7437 Signed-off-by: Alan Bishop <alanbishop@users.noreply.github.com>
1 parent daaedaa commit 0940296

2 files changed

Lines changed: 37 additions & 4 deletions

File tree

monai/transforms/io/array.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,12 @@ 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 RuntimeError(
214+
f"The required package for reader '{_r}' is not installed, or the version doesn't match "
215+
f"the requirement. If you want to use '{_r}', please install the required package. "
216+
f"If you want to use an alternative reader, do not specify the `reader` argument."
217+
) from e
216218
except TypeError: # the reader doesn't have the corresponding args/kwargs
217219
warnings.warn(f"{_r} is not supported with the given parameters {args} {kwargs}.")
218220
self.register(the_reader())

tests/transforms/test_load_image.py

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

500500

501+
502+
503+
class TestLoadImageMissingReader(unittest.TestCase):
504+
"""Test that LoadImage raises RuntimeError when a user-specified reader is not installed."""
505+
506+
def test_explicit_reader_not_installed_raises_runtime_error(self):
507+
"""When the user explicitly names a reader whose package is missing, a RuntimeError must be raised."""
508+
from unittest.mock import patch
509+
from monai.utils import OptionalImportError
510+
511+
# Patch the reader class so that instantiation raises OptionalImportError,
512+
# simulating a missing optional dependency (e.g. itk not installed).
513+
with patch("monai.data.ITKReader.__init__", side_effect=OptionalImportError("itk")):
514+
with self.assertRaises(RuntimeError) as ctx:
515+
LoadImage(reader="ITKReader")
516+
self.assertIn("ITKReader", str(ctx.exception))
517+
self.assertIn("not installed", str(ctx.exception))
518+
519+
def test_unspecified_reader_falls_back_silently(self):
520+
"""When no reader is specified, missing optional readers should be silently skipped (no exception)."""
521+
# This should not raise even if some optional readers are unavailable.
522+
loader = LoadImage()
523+
self.assertIsInstance(loader, LoadImage)
524+
525+
def test_explicit_reader_available_succeeds(self):
526+
"""When the user explicitly names a reader whose package IS installed, no exception is raised."""
527+
# NibabelReader is always available (nibabel is a core dep)
528+
loader = LoadImage(reader="NibabelReader")
529+
self.assertIsInstance(loader, LoadImage)
530+
531+
501532
if __name__ == "__main__":
502533
unittest.main()

0 commit comments

Comments
 (0)