From 3b97a4b243c1f80c62270126335b5fe2daf9a76c Mon Sep 17 00:00:00 2001 From: yehsin <102135888+Yehsin0815@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:07:02 +0000 Subject: [PATCH 1/5] Fix error messages missing the f-string prefix Several error messages contained `{...}` placeholders without the `f` prefix, so users saw the literal placeholder text instead of the value: - monai/data/synthetic.py: `create_test_image_3d` rad_min check (the `f` was inside the quotes) - monai/apps/pathology/transforms/post/dictionary.py: two "output key already exists" errors - monai/inferers/inferer.py: SPADE label_nc mismatch error (also adds the missing space between "semantic" and "labels") - monai/networks/blocks/pos_embed_utils.py: unsupported spatial_dims Add tests asserting the rendered messages. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_0179phxTW4cZ7jW2yxennmvF Signed-off-by: yehsin <102135888+Yehsin0815@users.noreply.github.com> --- .../pathology/transforms/post/dictionary.py | 4 +-- monai/data/synthetic.py | 2 +- monai/inferers/inferer.py | 4 +-- monai/networks/blocks/pos_embed_utils.py | 2 +- ..._hovernet_instance_map_post_processingd.py | 5 ++++ tests/data/test_synthetic.py | 2 ++ tests/networks/blocks/test_pos_embed_utils.py | 26 +++++++++++++++++++ 7 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 tests/networks/blocks/test_pos_embed_utils.py diff --git a/monai/apps/pathology/transforms/post/dictionary.py b/monai/apps/pathology/transforms/post/dictionary.py index b1dde44ec1f..44f9279b544 100644 --- a/monai/apps/pathology/transforms/post/dictionary.py +++ b/monai/apps/pathology/transforms/post/dictionary.py @@ -536,7 +536,7 @@ def __call__(self, data): for k in [self.instance_info_key, self.instance_map_key]: if k in d: - raise ValueError("The output key ['{k}'] already exists in the input dictionary!") + raise ValueError(f"The output key ['{k}'] already exists in the input dictionary!") d[self.instance_info_key], d[self.instance_map_key] = self.instance_map_post_process( d[self.nuclear_prediction_key], d[self.hover_map_key] @@ -590,7 +590,7 @@ def __call__(self, data): ) if self.return_type_map: if self.type_map_key in d: - raise ValueError("The output key ['{self.type_map_key}'] already exists in the input dictionary!") + raise ValueError(f"The output key ['{self.type_map_key}'] already exists in the input dictionary!") d[self.type_map_key] = type_map return d diff --git a/monai/data/synthetic.py b/monai/data/synthetic.py index 97ed57ba7c3..d0879aa0619 100644 --- a/monai/data/synthetic.py +++ b/monai/data/synthetic.py @@ -133,7 +133,7 @@ def create_test_image_3d( if rad_max <= rad_min: raise ValueError(f"`rad_min` {rad_min} should be less than `rad_max` {rad_max}.") if rad_min < 1: - raise ValueError("f`rad_min` {rad_min} should be no less than 1.") + raise ValueError(f"`rad_min` {rad_min} should be no less than 1.") min_size = min(height, width, depth) if min_size <= 2 * rad_max: raise ValueError(f"the minimal size {min_size} of the image should be larger than `2 * rad_max` 2x{rad_max}.") diff --git a/monai/inferers/inferer.py b/monai/inferers/inferer.py index 32bfc163a2f..1f8ac1bc6d1 100644 --- a/monai/inferers/inferer.py +++ b/monai/inferers/inferer.py @@ -1987,8 +1987,8 @@ def sample( # type: ignore[override] and autoencoder_model.decoder.label_nc != diffusion_model.label_nc ): raise ValueError( - "If both autoencoder_model and diffusion_model implement SPADE, the number of semantic" - "labels for each must be compatible. Got {autoencoder_model.decoder.label_nc} and {diffusion_model.label_nc}" + "If both autoencoder_model and diffusion_model implement SPADE, the number of semantic " + f"labels for each must be compatible. Got {autoencoder_model.decoder.label_nc} and {diffusion_model.label_nc}" ) if cn_cond.shape[2:] != input_noise.shape[2:]: diff --git a/monai/networks/blocks/pos_embed_utils.py b/monai/networks/blocks/pos_embed_utils.py index 0612a02c28b..0b6307ececb 100644 --- a/monai/networks/blocks/pos_embed_utils.py +++ b/monai/networks/blocks/pos_embed_utils.py @@ -150,7 +150,7 @@ def build_sincos_position_embedding( dim=1, )[None, :, :] else: - raise NotImplementedError("Spatial Dimension Size {spatial_dims} Not Implemented!") + raise NotImplementedError(f"Spatial Dimension Size {spatial_dims} Not Implemented!") pos_embed = nn.Parameter(pos_emb) pos_embed.requires_grad = False diff --git a/tests/apps/pathology/transforms/post/test_hovernet_instance_map_post_processingd.py b/tests/apps/pathology/transforms/post/test_hovernet_instance_map_post_processingd.py index 216c13476c1..b8a21bc8a43 100644 --- a/tests/apps/pathology/transforms/post/test_hovernet_instance_map_post_processingd.py +++ b/tests/apps/pathology/transforms/post/test_hovernet_instance_map_post_processingd.py @@ -61,6 +61,11 @@ def test_value(self, in_type, test_data, kwargs, expected_info, expected_map): # instance map assert_allclose(outputs[inst_map_key], expected_map, type_test=False) + def test_existing_output_key(self): + input = {HoVerNetBranch.NP.value: image.astype(float), "instance_map": image} + with self.assertRaisesRegex(ValueError, r"\['instance_map'\] already exists"): + HoVerNetInstanceMapPostProcessingd()(input) + if __name__ == "__main__": unittest.main() diff --git a/tests/data/test_synthetic.py b/tests/data/test_synthetic.py index 4ab21445680..6846a7147aa 100644 --- a/tests/data/test_synthetic.py +++ b/tests/data/test_synthetic.py @@ -61,6 +61,8 @@ def test_ill_radius(self): img, seg = create_test_image_3d(32, 32, 32, rad_max=10, rad_min=11) with self.assertRaisesRegex(ValueError, ""): img, seg = create_test_image_2d(32, 32, rad_max=10, rad_min=0) + with self.assertRaisesRegex(ValueError, "`rad_min` 0 should be no less than 1"): + img, seg = create_test_image_3d(32, 32, 32, rad_max=10, rad_min=0) if __name__ == "__main__": diff --git a/tests/networks/blocks/test_pos_embed_utils.py b/tests/networks/blocks/test_pos_embed_utils.py new file mode 100644 index 00000000000..2476a355d3a --- /dev/null +++ b/tests/networks/blocks/test_pos_embed_utils.py @@ -0,0 +1,26 @@ +# Copyright (c) MONAI Consortium +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations + +import unittest + +from monai.networks.blocks.pos_embed_utils import build_sincos_position_embedding + + +class TestBuildSincosPositionEmbedding(unittest.TestCase): + def test_unsupported_spatial_dims(self): + with self.assertRaisesRegex(NotImplementedError, "Spatial Dimension Size 4 Not Implemented"): + build_sincos_position_embedding(grid_size=[2, 2, 2, 2], embed_dim=8, spatial_dims=4) + + +if __name__ == "__main__": + unittest.main() From cd6ceffd25479b55739b19f3f052e68d710962f5 Mon Sep 17 00:00:00 2001 From: yehsin <102135888+Yehsin0815@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:30:20 +0000 Subject: [PATCH 2/5] Add tests for SPADE label_nc and type_map_key error messages Address review feedback: cover the SPADE label_nc mismatch message in ControlNetLatentDiffusionInferer.sample and the existing type_map_key error in HoVerNetNuclearTypePostProcessingd. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_0179phxTW4cZ7jW2yxennmvF Signed-off-by: yehsin <102135888+Yehsin0815@users.noreply.github.com> --- tests/inferers/test_controlnet_inferers.py | 50 +++++++++++++++++++ ..._hovernet_nuclear_type_post_processingd.py | 12 +++++ 2 files changed, 62 insertions(+) diff --git a/tests/inferers/test_controlnet_inferers.py b/tests/inferers/test_controlnet_inferers.py index 1799fec5422..f1dd65f73a6 100644 --- a/tests/inferers/test_controlnet_inferers.py +++ b/tests/inferers/test_controlnet_inferers.py @@ -1501,6 +1501,56 @@ def test_incompatible_spade_setup(self): seg=input_seg, ) + @skipUnless(has_einops, "Requires einops") + def test_sample_spade_label_nc_mismatch(self): + """Check that mismatched SPADE ``label_nc`` values raise an error reporting both values.""" + stage_1 = SPADEAutoencoderKL( + spatial_dims=2, + in_channels=1, + out_channels=1, + channels=(4, 4), + latent_channels=3, + attention_levels=[False, False], + num_res_blocks=1, + norm_num_groups=4, + label_nc=5, + ) + stage_2 = SPADEDiffusionModelUNet( + spatial_dims=2, + in_channels=3, + out_channels=3, + channels=[4, 4], + norm_num_groups=4, + attention_levels=[False, False], + num_res_blocks=1, + num_head_channels=4, + label_nc=3, + ) + controlnet = ControlNet( + spatial_dims=2, + in_channels=3, + channels=[4, 4], + attention_levels=[False, False], + num_res_blocks=1, + norm_num_groups=4, + num_head_channels=4, + conditioning_embedding_num_channels=[16], + conditioning_embedding_in_channels=1, + ) + scheduler = DDPMScheduler(num_train_timesteps=10) + inferer = ControlNetLatentDiffusionInferer(scheduler=scheduler, scale_factor=1.0) + scheduler.set_timesteps(num_inference_steps=10) + with self.assertRaisesRegex(ValueError, "number of semantic labels .* Got 5 and 3"): + inferer.sample( + input_noise=torch.randn(1, 3, 4, 4), + autoencoder_model=stage_1, + diffusion_model=stage_2, + scheduler=scheduler, + seg=torch.randn(1, 5, 8, 8), + controlnet=controlnet, + cn_cond=torch.randn(1, 1, 8, 8), + ) + if __name__ == "__main__": unittest.main() diff --git a/tests/integration/test_hovernet_nuclear_type_post_processingd.py b/tests/integration/test_hovernet_nuclear_type_post_processingd.py index f2117dc15ef..b8b41923c15 100644 --- a/tests/integration/test_hovernet_nuclear_type_post_processingd.py +++ b/tests/integration/test_hovernet_nuclear_type_post_processingd.py @@ -66,6 +66,18 @@ def test_value(self, in_type, test_data, kwargs, expected): else: assert_allclose(outputs["type_map"], expected[2], type_test=False) + def test_existing_type_map_key(self): + """Check that an existing ``type_map_key`` raises an error naming that key.""" + input = { + HoVerNetBranch.NP.value: image.astype(float), + HoVerNetBranch.HV.value: ComputeHoVerMaps()(image.astype(int)), + HoVerNetBranch.NC.value: image, + } + outputs = HoVerNetInstanceMapPostProcessingd()(input) + outputs["custom_type_map"] = image + with self.assertRaisesRegex(ValueError, r"\['custom_type_map'\] already exists"): + HoVerNetNuclearTypePostProcessingd(type_map_key="custom_type_map")(outputs) + if __name__ == "__main__": unittest.main() From 2527ecd2ebd56d42016a0612e56f48903adb1c70 Mon Sep 17 00:00:00 2001 From: yehsin <102135888+Yehsin0815@users.noreply.github.com> Date: Mon, 28 Sep 2026 23:35:35 +0800 Subject: [PATCH 3/5] Add docstring to test_existing_output_key Signed-off-by: yehsin <102135888+Yehsin0815@users.noreply.github.com> Signed-off-by: yehsin <102135888+Yehsin0815@users.noreply.github.com> --- .../post/test_hovernet_instance_map_post_processingd.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/apps/pathology/transforms/post/test_hovernet_instance_map_post_processingd.py b/tests/apps/pathology/transforms/post/test_hovernet_instance_map_post_processingd.py index b8a21bc8a43..3e3695af64f 100644 --- a/tests/apps/pathology/transforms/post/test_hovernet_instance_map_post_processingd.py +++ b/tests/apps/pathology/transforms/post/test_hovernet_instance_map_post_processingd.py @@ -62,6 +62,7 @@ def test_value(self, in_type, test_data, kwargs, expected_info, expected_map): assert_allclose(outputs[inst_map_key], expected_map, type_test=False) def test_existing_output_key(self): + """Check that an existing output key raises an error naming that key.""" input = {HoVerNetBranch.NP.value: image.astype(float), "instance_map": image} with self.assertRaisesRegex(ValueError, r"\['instance_map'\] already exists"): HoVerNetInstanceMapPostProcessingd()(input) From 4c5d77a24bf78aadbb876590431267f3bc001099 Mon Sep 17 00:00:00 2001 From: yehsin <102135888+Yehsin0815@users.noreply.github.com> Date: Mon, 28 Sep 2026 23:37:59 +0800 Subject: [PATCH 4/5] Add docstrings to pos embed tests Signed-off-by: yehsin <102135888+Yehsin0815@users.noreply.github.com> Signed-off-by: yehsin <102135888+Yehsin0815@users.noreply.github.com> --- tests/networks/blocks/test_pos_embed_utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/networks/blocks/test_pos_embed_utils.py b/tests/networks/blocks/test_pos_embed_utils.py index 2476a355d3a..d79ff268d65 100644 --- a/tests/networks/blocks/test_pos_embed_utils.py +++ b/tests/networks/blocks/test_pos_embed_utils.py @@ -17,7 +17,9 @@ class TestBuildSincosPositionEmbedding(unittest.TestCase): + """Tests for build_sincos_position_embedding.""" def test_unsupported_spatial_dims(self): + """Check that an unsupported spatial_dims raises an error reporting the value.""" with self.assertRaisesRegex(NotImplementedError, "Spatial Dimension Size 4 Not Implemented"): build_sincos_position_embedding(grid_size=[2, 2, 2, 2], embed_dim=8, spatial_dims=4) From 2cf9129965fc7c52fecf53042ef1a7b52e6741ae Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:38:55 +0000 Subject: [PATCH 5/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/networks/blocks/test_pos_embed_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/networks/blocks/test_pos_embed_utils.py b/tests/networks/blocks/test_pos_embed_utils.py index d79ff268d65..5692fc84bac 100644 --- a/tests/networks/blocks/test_pos_embed_utils.py +++ b/tests/networks/blocks/test_pos_embed_utils.py @@ -18,6 +18,7 @@ class TestBuildSincosPositionEmbedding(unittest.TestCase): """Tests for build_sincos_position_embedding.""" + def test_unsupported_spatial_dims(self): """Check that an unsupported spatial_dims raises an error reporting the value.""" with self.assertRaisesRegex(NotImplementedError, "Spatial Dimension Size 4 Not Implemented"):