diff --git a/Wrapping/Generators/Python/Tests/CMakeLists.txt b/Wrapping/Generators/Python/Tests/CMakeLists.txt index c7a19b26b35..47bebab03d0 100644 --- a/Wrapping/Generators/Python/Tests/CMakeLists.txt +++ b/Wrapping/Generators/Python/Tests/CMakeLists.txt @@ -281,3 +281,9 @@ itk_python_add_test( COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/test_gil_release_safety.py ) + +itk_python_add_test( + NAME CTypeTest + COMMAND + ${CMAKE_CURRENT_SOURCE_DIR}/test_ctype.py +) diff --git a/Wrapping/Generators/Python/Tests/test_ctype.py b/Wrapping/Generators/Python/Tests/test_ctype.py new file mode 100644 index 00000000000..71d300bb04e --- /dev/null +++ b/Wrapping/Generators/Python/Tests/test_ctype.py @@ -0,0 +1,75 @@ +# ========================================================================== +# +# Copyright NumFOCUS +# +# 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 +# +# https://www.apache.org/licenses/LICENSE-2.0.txt +# +# 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. +# +# ========================================================================== + +import itk +import unittest +import numpy as np +import os + + +class CTypeTestCase(unittest.TestCase): + """Tests itkCType""" + + def test_dtype_of_ctype_aliases_for_specific_sizes(self) -> None: + """Tests that each `CType` alias for a specific size has the corresponding `dtype`""" + + # Check uint8 to uint64 and int8 to int64: + for number_of_bits in (8, 16, 32, 64): + self.assertEqual( + getattr(itk, f"int{number_of_bits}_t").dtype, + getattr(np, f"int{number_of_bits}"), + ) + self.assertEqual( + getattr(itk, f"uint{number_of_bits}_t").dtype, + getattr(np, f"uint{number_of_bits}"), + ) + + # Check float32 and float64: + for number_of_bits in (32, 64): + self.assertEqual( + getattr(itk, f"float{number_of_bits}_t").dtype, + getattr(np, f"float{number_of_bits}"), + ) + + def test_ctype_aliases_for_64_bit_integers(self) -> None: + """Tests `int64_t` and `uint64_t`, for both Windows and non-Windows""" + + if os.name == "nt": + # On Windows, only `long long` integer types (SLL and ULL) are 64-bit. + self.assertEqual( + itk.int64_t, + itk.SLL, + ) + self.assertEqual( + itk.uint64_t, + itk.ULL, + ) + else: + # On Linux and MacOS, `long` integer types (SL and UL) are already 64-bit. + self.assertEqual( + itk.int64_t, + itk.SL, + ) + self.assertEqual( + itk.uint64_t, + itk.UL, + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/Wrapping/Generators/Python/itk/__init__.py b/Wrapping/Generators/Python/itk/__init__.py index f591e5fa49f..b1e20609546 100644 --- a/Wrapping/Generators/Python/itk/__init__.py +++ b/Wrapping/Generators/Python/itk/__init__.py @@ -48,6 +48,16 @@ SI, SLL, B, + float32_t, + float64_t, + uint8_t, + uint16_t, + uint32_t, + uint64_t, + int8_t, + int16_t, + int32_t, + int64_t, ST, IT, OT, diff --git a/Wrapping/Generators/Python/itk/support/types.py b/Wrapping/Generators/Python/itk/support/types.py index 4ed6ae8b8c7..759c3a2571a 100644 --- a/Wrapping/Generators/Python/itk/support/types.py +++ b/Wrapping/Generators/Python/itk/support/types.py @@ -145,6 +145,18 @@ def initialize_c_types_once(cls) -> tuple[Self, ...]: B, ) = itkCType.initialize_c_types_once() +# Aliases for numeric types of specific sizes (specified by their number of bits) +float32_t = F +float64_t = D +uint8_t = UC +uint16_t = US +uint32_t = UI +uint64_t = UL if UL.dtype.itemsize == 8 else ULL +int8_t = SC +int16_t = SS +int32_t = SI +int64_t = SL if SL.dtype.itemsize == 8 else SLL + # Aliases for SizeValueType, IdentifierType, OffsetType ST = UL IT = UL