From 85ed7a94ddd2339d63c1a6c2d2e11fbf2fc8f07f Mon Sep 17 00:00:00 2001 From: skdas20 Date: Sun, 22 Feb 2026 19:32:04 +0000 Subject: [PATCH 1/3] fix: support more dtypes in pad_nd function - Removes hardcoded dtype exclusion list from pad_nd() - Enables torch.nn.functional.pad for bool and integer dtypes - Try-except fallback to numpy still handles unsupported combinations - Fixes #7842 --- monai/transforms/croppad/functional.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/monai/transforms/croppad/functional.py b/monai/transforms/croppad/functional.py index 653db43bc51..572d01ea1dc 100644 --- a/monai/transforms/croppad/functional.py +++ b/monai/transforms/croppad/functional.py @@ -96,12 +96,7 @@ def pad_nd( return _np_pad(img, pad_width=to_pad, mode=mode, **kwargs) try: _pad = _np_pad - if mode in {"constant", "reflect", "edge", "replicate", "wrap", "circular"} and img.dtype not in { - torch.int16, - torch.int64, - torch.bool, - torch.uint8, - }: + if mode in {"constant", "reflect", "edge", "replicate", "wrap", "circular"}: _pad = _pt_pad return _pad(img, pad_width=to_pad, mode=mode, **kwargs) except (ValueError, TypeError, RuntimeError) as err: From 58e774d9ee7436c823aef8f5cdc66aa37fc425f0 Mon Sep 17 00:00:00 2001 From: skdas20 Date: Sun, 22 Feb 2026 19:34:28 +0000 Subject: [PATCH 2/3] improve: add helpful error message for missing tensorboard package - Checks if tensorboard is installed before attempting to create SummaryWriter - Provides installation instructions when tensorboard is missing - Improves user experience for debugging missing dependencies - Addresses issue #7980 Signed-off-by: skdas20 --- monai/handlers/tensorboard_handlers.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/monai/handlers/tensorboard_handlers.py b/monai/handlers/tensorboard_handlers.py index 20e2d74c8c5..0a69ccfabaa 100644 --- a/monai/handlers/tensorboard_handlers.py +++ b/monai/handlers/tensorboard_handlers.py @@ -50,6 +50,11 @@ class TensorBoardHandler: def __init__(self, summary_writer: SummaryWriter | SummaryWriterX | None = None, log_dir: str = "./runs"): if summary_writer is None: + if SummaryWriter is None: + raise RuntimeError( + "TensorBoardHandler requires tensorboard to be installed. " + "Please install it with: pip install tensorboard" + ) self._writer = SummaryWriter(log_dir=log_dir) self.internal_writer = True else: From a5ed44b1b3e543983a92009cc9d914b3ee6467d3 Mon Sep 17 00:00:00 2001 From: Sumit Kumar Das Date: Sat, 25 Jul 2026 19:18:09 +0000 Subject: [PATCH 3/3] fix: capture optional_import availability flag for SummaryWriter optional_import() returns a lazy-raising stub on failure, never None, so the previous 'SummaryWriter is None' guard could never trigger and the RuntimeError was unreachable. Capture and check the availability flag instead, document the exception in the docstring, and add a regression test per CodeRabbit review. --- monai/handlers/tensorboard_handlers.py | 7 +++++-- tests/handlers/test_handler_tb_stats.py | 11 ++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/monai/handlers/tensorboard_handlers.py b/monai/handlers/tensorboard_handlers.py index 0a69ccfabaa..60912d7de74 100644 --- a/monai/handlers/tensorboard_handlers.py +++ b/monai/handlers/tensorboard_handlers.py @@ -31,7 +31,7 @@ Engine, _ = optional_import( "ignite.engine", IgniteInfo.OPT_IMPORT_VERSION, min_version, "Engine", as_type="decorator" ) - SummaryWriter, _ = optional_import("torch.utils.tensorboard", name="SummaryWriter") + SummaryWriter, _tb_available = optional_import("torch.utils.tensorboard", name="SummaryWriter") SummaryWriterX, _ = optional_import("tensorboardX", name="SummaryWriter") DEFAULT_TAG = "Loss" @@ -46,11 +46,14 @@ class TensorBoardHandler: default to create a new TensorBoard writer. log_dir: if using default SummaryWriter, write logs to this directory, default is `./runs`. + Raises: + RuntimeError: When ``summary_writer`` is ``None`` and the ``tensorboard`` package is not installed. + """ def __init__(self, summary_writer: SummaryWriter | SummaryWriterX | None = None, log_dir: str = "./runs"): if summary_writer is None: - if SummaryWriter is None: + if not _tb_available: raise RuntimeError( "TensorBoardHandler requires tensorboard to be installed. " "Please install it with: pip install tensorboard" diff --git a/tests/handlers/test_handler_tb_stats.py b/tests/handlers/test_handler_tb_stats.py index b96bea13a1f..1b25b945f1a 100644 --- a/tests/handlers/test_handler_tb_stats.py +++ b/tests/handlers/test_handler_tb_stats.py @@ -14,12 +14,13 @@ import glob import tempfile import unittest -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch from ignite.engine import Engine, Events from parameterized import parameterized from monai.handlers import TensorBoardStatsHandler +from monai.handlers.tensorboard_handlers import TensorBoardHandler from monai.utils import optional_import SummaryWriter, has_tb = optional_import("torch.utils.tensorboard", name="SummaryWriter") @@ -162,5 +163,13 @@ def _update_metric(engine): ) # 2 = len([1, 3]) from event_filter +class TestTensorBoardHandlerMissingDependency(unittest.TestCase): + + def test_raises_when_tensorboard_unavailable(self): + with patch("monai.handlers.tensorboard_handlers._tb_available", False): + with self.assertRaises(RuntimeError): + TensorBoardHandler() + + if __name__ == "__main__": unittest.main()