From 5167f9874ac9e8bb006b5d8e594fa2414e7c5031 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Feb 2026 21:46:50 +0000 Subject: [PATCH 1/2] BUG: Fix image_from_array to handle non-contiguous arrays The issue was that GetImageViewFromArray always reversed the shape for non-vector images, regardless of whether the array was C-contiguous or F-contiguous. However, the C++ code reverses the shape again for F-contiguous arrays, resulting in a double reversal. The fix: Only reverse the shape in Python for C-contiguous arrays. For F-contiguous arrays, pass the shape as-is to C++, which will handle the reversal there. Added comprehensive test cases for both image_from_array and image_view_from_array with transposed arrays. Co-authored-by: Matthew McCormick --- Modules/Bridge/NumPy/wrapping/PyBuffer.i.in | 5 ++++- Wrapping/Generators/Python/Tests/extras.py | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Modules/Bridge/NumPy/wrapping/PyBuffer.i.in b/Modules/Bridge/NumPy/wrapping/PyBuffer.i.in index 22a95428726..61e725179c4 100644 --- a/Modules/Bridge/NumPy/wrapping/PyBuffer.i.in +++ b/Modules/Bridge/NumPy/wrapping/PyBuffer.i.in @@ -103,7 +103,10 @@ else: imgview = itkPyBuffer@PyBufferTypes@._get_image_view_from_contiguous_array(ndarr, ndarr.shape[-1:0:-1], ndarr.shape[0]) else: - imgview = itkPyBuffer@PyBufferTypes@._get_image_view_from_contiguous_array(ndarr, ndarr.shape[::-1], 1) + if ndarr.flags['C_CONTIGUOUS']: + imgview = itkPyBuffer@PyBufferTypes@._get_image_view_from_contiguous_array(ndarr, ndarr.shape[::-1], 1) + else: + imgview = itkPyBuffer@PyBufferTypes@._get_image_view_from_contiguous_array(ndarr, ndarr.shape, 1) # Keep a reference imgview._SetBase(ndarr) diff --git a/Wrapping/Generators/Python/Tests/extras.py b/Wrapping/Generators/Python/Tests/extras.py index c0601e5ef2d..0f4b4d8f6e3 100644 --- a/Wrapping/Generators/Python/Tests/extras.py +++ b/Wrapping/Generators/Python/Tests/extras.py @@ -418,6 +418,24 @@ def custom_callback(name, progress): arr_fortran = arr.copy(order="F") image = itk.GetImageViewFromArray(arr_fortran) assert np.array_equal(arr_fortran.shape, image.shape) +# Test that image_from_array handles array.T correctly (F-contiguous arrays) +test_arr = np.empty((1, 2, 3)) +image_from_arr = itk.image_from_array(test_arr) +image_from_transpose = itk.image_from_array(test_arr.T) +image_from_transpose_copy = itk.image_from_array(test_arr.T.copy()) +assert np.array_equal(image_from_arr.shape, test_arr.shape), \ + f"Expected shape {test_arr.shape}, got {image_from_arr.shape}" +assert np.array_equal(image_from_transpose.shape, test_arr.T.shape), \ + f"Expected shape {test_arr.T.shape}, got {image_from_transpose.shape}" +assert np.array_equal(image_from_transpose_copy.shape, test_arr.T.shape), \ + f"Expected shape {test_arr.T.shape}, got {image_from_transpose_copy.shape}" +# Also verify with image_view_from_array for consistency +image_view_from_arr = itk.image_view_from_array(test_arr) +image_view_from_transpose = itk.image_view_from_array(test_arr.T) +assert np.array_equal(image_view_from_arr.shape, test_arr.shape), \ + f"Expected shape {test_arr.shape}, got {image_view_from_arr.shape}" +assert np.array_equal(image_view_from_transpose.shape, test_arr.T.shape), \ + f"Expected shape {test_arr.T.shape}, got {image_view_from_transpose.shape}" image = itk.image_from_array(arr, is_vector=True) assert image.GetImageDimension() == 2 image = itk.GetImageViewFromArray(arr, is_vector=True) From 7c49c8a65b4dff1b1d0d5e7b9564886bf7884ca0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:53:39 +0000 Subject: [PATCH 2/2] Fix black formatting for test assertions Apply black code formatter's preferred style for multi-line assertions with continuation. This addresses the pre-commit CI failure. Co-authored-by: thewtex <25432+thewtex@users.noreply.github.com> --- Wrapping/Generators/Python/Tests/extras.py | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Wrapping/Generators/Python/Tests/extras.py b/Wrapping/Generators/Python/Tests/extras.py index 0f4b4d8f6e3..0638f862233 100644 --- a/Wrapping/Generators/Python/Tests/extras.py +++ b/Wrapping/Generators/Python/Tests/extras.py @@ -423,19 +423,24 @@ def custom_callback(name, progress): image_from_arr = itk.image_from_array(test_arr) image_from_transpose = itk.image_from_array(test_arr.T) image_from_transpose_copy = itk.image_from_array(test_arr.T.copy()) -assert np.array_equal(image_from_arr.shape, test_arr.shape), \ - f"Expected shape {test_arr.shape}, got {image_from_arr.shape}" -assert np.array_equal(image_from_transpose.shape, test_arr.T.shape), \ - f"Expected shape {test_arr.T.shape}, got {image_from_transpose.shape}" -assert np.array_equal(image_from_transpose_copy.shape, test_arr.T.shape), \ - f"Expected shape {test_arr.T.shape}, got {image_from_transpose_copy.shape}" +assert np.array_equal( + image_from_arr.shape, test_arr.shape +), f"Expected shape {test_arr.shape}, got {image_from_arr.shape}" +assert np.array_equal( + image_from_transpose.shape, test_arr.T.shape +), f"Expected shape {test_arr.T.shape}, got {image_from_transpose.shape}" +assert np.array_equal( + image_from_transpose_copy.shape, test_arr.T.shape +), f"Expected shape {test_arr.T.shape}, got {image_from_transpose_copy.shape}" # Also verify with image_view_from_array for consistency image_view_from_arr = itk.image_view_from_array(test_arr) image_view_from_transpose = itk.image_view_from_array(test_arr.T) -assert np.array_equal(image_view_from_arr.shape, test_arr.shape), \ - f"Expected shape {test_arr.shape}, got {image_view_from_arr.shape}" -assert np.array_equal(image_view_from_transpose.shape, test_arr.T.shape), \ - f"Expected shape {test_arr.T.shape}, got {image_view_from_transpose.shape}" +assert np.array_equal( + image_view_from_arr.shape, test_arr.shape +), f"Expected shape {test_arr.shape}, got {image_view_from_arr.shape}" +assert np.array_equal( + image_view_from_transpose.shape, test_arr.T.shape +), f"Expected shape {test_arr.T.shape}, got {image_view_from_transpose.shape}" image = itk.image_from_array(arr, is_vector=True) assert image.GetImageDimension() == 2 image = itk.GetImageViewFromArray(arr, is_vector=True)