Skip to content

Commit 77b5ce0

Browse files
committed
fix(transforms): make _to_int_list ROI coercion correct and type-safe
The prior _to_int_list used issequenceiterable, which broke in three ways once the missing import was restored and the code actually ran: - str/bytes were no longer rejected (issequenceiterable("10") is False, so "10" coerced to the scalar [10] instead of raising, silently building wrong slices); - mypy could not narrow the union through issequenceiterable, so the iterate/scalar branches failed type checking. Rewrite the helper to reject str/bytes explicitly, then coerce via the existing ensure_tuple helper, which handles scalars, sequences, tensors and ndarrays uniformly and is mypy-clean. Likewise return the crop slices via ensure_tuple so compute_slices matches its declared tuple[slice] return type. Behaviour is covered by test_compute_slices_broadcast. Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk>
1 parent 8e975a1 commit 77b5ce0

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

monai/transforms/croppad/array.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,9 @@ def compute_pad_width(self, spatial_shape: Sequence[int]) -> tuple[tuple[int, in
344344

345345
def _to_int_list(data: Sequence[int] | int | NdarrayOrTensor) -> list[int]:
346346
"""Coerce an ROI spec (scalar, sequence, tensor or ndarray) to a list of Python ints."""
347-
if issequenceiterable(data):
348-
return [int(i) for i in data]
349-
return [int(data)]
347+
if isinstance(data, (str, bytes)):
348+
raise TypeError("ROI specs must be integers or sequences of integers, not strings.")
349+
return [int(i) for i in ensure_tuple(data)]
350350

351351

352352
def _broadcast_int_pair(
@@ -412,7 +412,7 @@ def compute_slices(
412412
starts, ends = _broadcast_int_pair(roi_start, roi_end)
413413
starts = [max(s, 0) for s in starts]
414414
# clamp each end to its own start so no slice has negative width
415-
return tuple(slice(s, max(e, s)) for s, e in zip(starts, ends))
415+
return ensure_tuple(slice(s, max(e, s)) for s, e in zip(starts, ends))
416416

417417
def __call__( # type: ignore[override]
418418
self, img: torch.Tensor, slices: tuple[slice, ...], lazy: bool | None = None

0 commit comments

Comments
 (0)