Skip to content

spatial_resample raises TypeError when spatial_size is None and spatial_rank is 1 #9068

Description

@hjmjohnson

Describe the bug

spatial_resample passes lambda x: x >= 0 to fall_back_tuple, but that helper's default predicate is lambda x: x and x > 0, whose x and short-circuits on None. The override does not, so a None element raises TypeError instead of falling back to the default — which is the documented behaviour of fall_back_tuple, and its own docstring says so:

>>> fall_back_tuple((-1, None), (32, 32))
(32, 32)

monai/transforms/spatial/functional.py:159:

spatial_size = torch.tensor(
    fall_back_tuple(ensure_tuple(spatial_size)[:spatial_rank], in_spatial_size, lambda x: x >= 0)
)

spatial_size reaches that line as None whenever the caller did not supply one and spatial_rank <= 1: the branch above it, elif spatial_size is None and spatial_rank > 1, is the only thing that replaces None, so with a rank of 1 the None survives into ensure_tuple(None)(None,)None >= 0.

To Reproduce

import numpy as np
from monai.data.image_writer import NibabelWriter

w = NibabelWriter()
w.set_data_array(np.random.rand(3, 5), channel_dim=None)
w.set_metadata({"affine": np.diag([1, 1, 1]), "original_affine": np.diag([1.4, 1, 1])})
File "monai/data/image_writer.py", line 604, in set_metadata
File "monai/data/image_writer.py", line 273, in resample_if_needed
File "monai/transforms/spatial/array.py", line 229, in __call__
File "monai/transforms/spatial/functional.py", line 159, in <lambda>
    fall_back_tuple(ensure_tuple(spatial_size)[:spatial_rank], in_spatial_size, lambda x: x >= 0)
TypeError: '>=' not supported between instances of 'NoneType' and 'int'

Instrumenting spatial_resample confirms it is entered with spatial_size=None and img.shape=(1, 3, 5).

Expected behavior

None means "no size given for this axis" and should fall back to the corresponding in_spatial_size entry, exactly as fall_back_tuple's docstring describes.

Screenshots / test impact

This is not a corner case reachable only by hand — it fails 8 tests on current dev:

  • tests/data/test_nifti_rw.pytest_write_2d, test_write_3d
  • tests/data/test_image_rw.py — 4 failures + 4 errors across TestRegRes / writer round-trips

Reproduced on unmodified dev (c1240a2d4) in two independent environments:

Python 3.12 / torch 2.13.0 / numpy 2.x fails
Python 3.10 / torch 2.11.0 (highest version CI tests) / numpy 2.2.6 fails identically

So it is not a new-dependency artifact. git log -L159,159 dates that line to #6068 (Feb 2023).

Environment

Ensuring you use the relevant python executable, please paste the output of:
MONAI version: 1.6.0rc1+58.gc1240a2d4
Python: 3.10 and 3.12 (both affected)
PyTorch: 2.11.0 and 2.13.0 (both affected)
numpy: 2.2.6
nibabel: 5.4.2

Additional context

The narrowest fix is to make the predicate None-safe at the call site, matching the helper's default:

lambda x: x is not None and x >= 0

Worth checking the other fall_back_tuple callers that pass an explicit func for the same hazard — any predicate that does not short-circuit on None inherits it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions