From 98fe9d6205f279c29ec9e95bf7ea9ddb61bac26d Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Tue, 24 Nov 2020 12:46:10 -0600 Subject: [PATCH] STYLE: Minimize cmake configured python files All of the cmake configured variables should be contained in the minimal number of files. Move cmake configuration options to the itkConfig.py.in file, and convert itkBuildOptions.py.in to a static python file. The itkBuildOptions.py was previously not used internally, so a simple test has been added to exercise the codebase in itkBuildOptions.py. --- Wrapping/Generators/Python/CMakeLists.txt | 58 +++++++++--------- .../Generators/Python/Tests/CMakeLists.txt | 1 + .../Generators/Python/Tests/build_options.py | 29 +++++++++ .../Python/itk/support/itkBuildOptions.py | 60 +++++++++++++++++++ .../Python/itk/support/itkBuildOptions.py.in | 43 ------------- Wrapping/Generators/Python/itkConfig.py.in | 12 ++++ 6 files changed, 130 insertions(+), 73 deletions(-) create mode 100644 Wrapping/Generators/Python/Tests/build_options.py create mode 100644 Wrapping/Generators/Python/itk/support/itkBuildOptions.py delete mode 100644 Wrapping/Generators/Python/itk/support/itkBuildOptions.py.in diff --git a/Wrapping/Generators/Python/CMakeLists.txt b/Wrapping/Generators/Python/CMakeLists.txt index 525788720a5..c2dad950cf4 100644 --- a/Wrapping/Generators/Python/CMakeLists.txt +++ b/Wrapping/Generators/Python/CMakeLists.txt @@ -72,6 +72,33 @@ endmacro() # bundled up into an install conventiently. Python will take care of turning # the / path separator into \ on windows if needed. if(NOT EXTERNAL_WRAP_ITK_PROJECT) + + # copy the files to expose build options in python + set(ITK_WRAP_PYTHON_VECTOR_REAL ) + foreach(t ${WRAP_ITK_VECTOR_REAL}) + foreach(d ${ITK_WRAP_IMAGE_DIMS}) + list(APPEND ITK_WRAP_PYTHON_VECTOR_REAL ${ITKT_${t}${d}}) + endforeach() + endforeach() + set(ITK_WRAP_PYTHON_COV_VECTOR_REAL ) + foreach(t ${WRAP_ITK_COV_VECTOR_REAL}) + foreach(d ${ITK_WRAP_IMAGE_DIMS}) + list(APPEND ITK_WRAP_PYTHON_COV_VECTOR_REAL ${ITKT_${t}${d}}) + endforeach() + endforeach() + set(ITK_WRAP_PYTHON_RGB ) + foreach(t ${WRAP_ITK_RGB}) + list(APPEND ITK_WRAP_PYTHON_RGB ${ITKT_${t}}) + endforeach() + set(ITK_WRAP_PYTHON_RGBA ) + foreach(t ${WRAP_ITK_RGBA}) + list(APPEND ITK_WRAP_PYTHON_RGBA ${ITKT_${t}}) + endforeach() + set(ITK_WRAP_PYTHON_COMPLEX_REAL ) + foreach(t ${WRAP_ITK_COMPLEX_REAL}) + list(APPEND ITK_WRAP_PYTHON_COMPLEX_REAL ${ITKT_${t}}) + endforeach() + # First setup the InstallOnly directory set(ITK_PYTHON_SWIG_LIBS_DIR "${ITK_WRAP_PYTHON_ROOT_BINARY_DIR}/itk" CACHE INTERNAL "where the swig shared libs are place _ITK*.so files") file(RELATIVE_PATH CONFIG_PYTHON_SWIGPY_DIR ${ITK_PYTHON_PACKAGE_CONFIG_SUPPORT_DIR} ${ITK_PYTHON_SWIG_LIBS_DIR}) @@ -103,36 +130,6 @@ if(NOT EXTERNAL_WRAP_ITK_PROJECT) "${ITK_PYTHON_PACKAGE_CONFIG_SUPPORT_DIR}/${config}/itkConfig.py" @ONLY) endforeach() - - # copy the files to expose build options in python - set(ITK_WRAP_PYTHON_VECTOR_REAL ) - foreach(t ${WRAP_ITK_VECTOR_REAL}) - foreach(d ${ITK_WRAP_IMAGE_DIMS}) - list(APPEND ITK_WRAP_PYTHON_VECTOR_REAL ${ITKT_${t}${d}}) - endforeach() - endforeach() - set(ITK_WRAP_PYTHON_COV_VECTOR_REAL ) - foreach(t ${WRAP_ITK_COV_VECTOR_REAL}) - foreach(d ${ITK_WRAP_IMAGE_DIMS}) - list(APPEND ITK_WRAP_PYTHON_COV_VECTOR_REAL ${ITKT_${t}${d}}) - endforeach() - endforeach() - set(ITK_WRAP_PYTHON_RGB ) - foreach(t ${WRAP_ITK_RGB}) - list(APPEND ITK_WRAP_PYTHON_RGB ${ITKT_${t}}) - endforeach() - set(ITK_WRAP_PYTHON_RGBA ) - foreach(t ${WRAP_ITK_RGBA}) - list(APPEND ITK_WRAP_PYTHON_RGBA ${ITKT_${t}}) - endforeach() - set(ITK_WRAP_PYTHON_COMPLEX_REAL ) - foreach(t ${WRAP_ITK_COMPLEX_REAL}) - list(APPEND ITK_WRAP_PYTHON_COMPLEX_REAL ${ITKT_${t}}) - endforeach() - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/itk/support/itkBuildOptions.py.in" - "${ITK_PYTHON_PACKAGE_CONFIG_SUPPORT_DIR}/itkBuildOptions.py" - @ONLY) - WRAP_ITK_PYTHON_BINDINGS_INSTALL(/ "ITKCommon" "${ITK_PYTHON_PACKAGE_CONFIG_SUPPORT_DIR}/itkBuildOptions.py") endif() @@ -151,6 +148,7 @@ if(NOT EXTERNAL_WRAP_ITK_PROJECT) itk/support/itkLazy itk/support/itkHelpers itk/support/itkInitHelpers + itk/support/itkBuildOptions itk/__init__ itk_generate_pyi # A utility function used to generate the intreface file ) diff --git a/Wrapping/Generators/Python/Tests/CMakeLists.txt b/Wrapping/Generators/Python/Tests/CMakeLists.txt index 05b6b3e2621..3e7e13fd2b2 100644 --- a/Wrapping/Generators/Python/Tests/CMakeLists.txt +++ b/Wrapping/Generators/Python/Tests/CMakeLists.txt @@ -12,6 +12,7 @@ itk_python_add_test(NAME PythonTransformCoverage COMMAND ${CMAKE_CURRENT_SOURCE_ itk_python_add_test(NAME PythonFindEmptyClasses COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/findEmptyClasses.py) itk_python_add_test(NAME PythonGetNameOfClass COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/getNameOfClass.py) itk_python_add_test(NAME PythonTiming COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/timing.py) +itk_python_add_test(NAME PythonBuildOptions COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build_options.py) itk_python_add_test(NAME PythonVerifyGetOutputAPIConsistency COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/verifyGetOutputAPIConsistency.py) itk_python_add_test(NAME PythonVerifyTTypeAPIConsistency COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/verifyTTypeAPIConsistency.py) itk_python_add_test(NAME PythonTypeTest COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/PythonTypeTest.py) diff --git a/Wrapping/Generators/Python/Tests/build_options.py b/Wrapping/Generators/Python/Tests/build_options.py new file mode 100644 index 00000000000..07f352276b4 --- /dev/null +++ b/Wrapping/Generators/Python/Tests/build_options.py @@ -0,0 +1,29 @@ +# ========================================================================== +# +# 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 +# +# http://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. +# +# ==========================================================================*/ + +from itk.support.itkBuildOptions import ALL_TYPES, DIMS + +# Simple exercise of types identified during build +print("-------- PRINTING THE BUILD DIMENSIONS -----------") +for build_dims in DIMS: + print(f"ITK Compliled with support for dimension: {build_dims}") +print("---------------------------------------------") +print("-------- PRINTING THE BUILD TYPES -----------") +for build_types_identified in ALL_TYPES: + print(f"ITK Compliled with support for: {build_types_identified}") +print("---------------------------------------------") diff --git a/Wrapping/Generators/Python/itk/support/itkBuildOptions.py b/Wrapping/Generators/Python/itk/support/itkBuildOptions.py new file mode 100644 index 00000000000..cf19fafc6f4 --- /dev/null +++ b/Wrapping/Generators/Python/itk/support/itkBuildOptions.py @@ -0,0 +1,60 @@ +import itk + +# Finding the named elements in the templates +# requires that they are force loaded before +# before searching +itk.force_load() + +from itk.support import itkTypes +from itk.support.itkTemplate import itkTemplate + +from typing import List, Union +from itkConfig import ITK_GLOBAL_WRAPPING_BUILD_OPTIONS as _itkwrapbo + +DIMS: List[int] = [int(s) for s in _itkwrapbo["ITK_WRAP_IMAGE_DIMS"] if s] +USIGN_INTS: List[itkTypes.itkCType] = [ + getattr(itkTypes, s) for s in _itkwrapbo["WRAP_ITK_USIGN_INT"] if s +] +SIGN_INTS: List[itkTypes.itkCType] = [ + getattr(itkTypes, s) for s in _itkwrapbo["WRAP_ITK_SIGN_INT"] if s +] +REALS: List[itkTypes.itkCType] = [ + getattr(itkTypes, s) for s in _itkwrapbo["WRAP_ITK_REAL"] if s +] + +VECTOR_REALS: List[itkTemplate] = [ + itkTemplate.__templates__[itkTemplate.normalizeName(s)] + for s in _itkwrapbo["ITK_WRAP_PYTHON_VECTOR_REAL"] + if s +] +COV_VECTOR_REALS: List[itkTemplate] = [ + itkTemplate.__templates__[itkTemplate.normalizeName(s)] + for s in _itkwrapbo["ITK_WRAP_PYTHON_COV_VECTOR_REAL"] + if s +] +RGBS: List[itkTemplate] = [ + itkTemplate.__templates__[itkTemplate.normalizeName(s)] + for s in _itkwrapbo["ITK_WRAP_PYTHON_RGB"] + if s +] +RGBAS: List[itkTemplate] = [ + itkTemplate.__templates__[itkTemplate.normalizeName(s)] + for s in _itkwrapbo["ITK_WRAP_PYTHON_RGBA"] + if s +] +COMPLEX_REALS: List[itkTemplate] = [ + itkTemplate.__templates__[itkTemplate.normalizeName(s)] + for s in _itkwrapbo["ITK_WRAP_PYTHON_COMPLEX_REAL"] + if s +] + +INTS: List[itkTypes.itkCType] = SIGN_INTS + USIGN_INTS +SCALARS: List[itkTypes.itkCType] = INTS + REALS +VECTORS: List[itkTemplate] = VECTOR_REALS + COV_VECTOR_REALS +COLORS: List[itkTemplate] = RGBS + RGBAS +ALL_TYPES: List[ + Union[itkTypes.itkCType, itkTemplate] +] = COLORS + VECTORS + SCALARS + COMPLEX_REALS + +del itkTemplate +del itkTypes diff --git a/Wrapping/Generators/Python/itk/support/itkBuildOptions.py.in b/Wrapping/Generators/Python/itk/support/itkBuildOptions.py.in deleted file mode 100644 index d5eaca8682b..00000000000 --- a/Wrapping/Generators/Python/itk/support/itkBuildOptions.py.in +++ /dev/null @@ -1,43 +0,0 @@ -from itk.support import itkTypes -from itk.support.itkTemplate import itkTemplate - -DIMS = [int(s) for s in "@ITK_WRAP_IMAGE_DIMS@".split(";") if s] -USIGN_INTS = [getattr(itkTypes, s) for s in "@WRAP_ITK_USIGN_INT@".split(";") if s] -SIGN_INTS = [getattr(itkTypes, s) for s in "@WRAP_ITK_SIGN_INT@".split(";") if s] -REALS = [getattr(itkTypes, s) for s in "@WRAP_ITK_REAL@".split(";") if s] - -VECTOR_REALS = [ - itkTemplate.__templates__[itkTemplate.normalizeName(s)] - for s in "@ITK_WRAP_PYTHON_VECTOR_REAL@".split(";") - if s -] -COV_VECTOR_REALS = [ - itkTemplate.__templates__[itkTemplate.normalizeName(s)] - for s in "@ITK_WRAP_PYTHON_COV_VECTOR_REAL@".split(";") - if s -] -RGBS = [ - itkTemplate.__templates__[itkTemplate.normalizeName(s)] - for s in "@ITK_WRAP_PYTHON_RGB@".split(";") - if s -] -RGBAS = [ - itkTemplate.__templates__[itkTemplate.normalizeName(s)] - for s in "@ITK_WRAP_PYTHON_RGBA@".split(";") - if s -] -COMPLEX_REALS = [ - itkTemplate.__templates__[itkTemplate.normalizeName(s)] - for s in "@ITK_WRAP_PYTHON_COMPLEX_REAL@".split(";") - if s -] - - -INTS = SIGN_INTS + USIGN_INTS -SCALARS = INTS + REALS -VECTORS = VECTOR_REALS + COV_VECTOR_REALS -COLORS = RGBS + RGBAS -ALL_TYPES = COLORS + VECTORS + SCALARS + COMPLEX_REALS - -del itkTemplate -del itkTypes diff --git a/Wrapping/Generators/Python/itkConfig.py.in b/Wrapping/Generators/Python/itkConfig.py.in index e0620b44688..c4c78f4a08b 100644 --- a/Wrapping/Generators/Python/itkConfig.py.in +++ b/Wrapping/Generators/Python/itkConfig.py.in @@ -34,6 +34,7 @@ Currently-supported options are: LazyLoading: Only load an itk library when needed. Before the library is loaded, the namespace will be inhabited with dummy objects.""" +from typing import Dict, List # User options SILENT: int = 0 @@ -134,6 +135,17 @@ def _initialize(): ITK_GLOBAL_VERSION_STRING: str = "@ITK_VERSION_MAJOR@.@ITK_VERSION_MINOR@.@ITK_VERSION_PATCH@" +ITK_GLOBAL_WRAPPING_BUILD_OPTIONS: Dict[str, List[str]] = { + "ITK_WRAP_IMAGE_DIMS": "@ITK_WRAP_IMAGE_DIMS@".split(";"), + "WRAP_ITK_USIGN_INT": "@WRAP_ITK_USIGN_INT@".split(";"), + "WRAP_ITK_SIGN_INT": "@WRAP_ITK_SIGN_INT@".split(";"), + "WRAP_ITK_REAL": "@WRAP_ITK_REAL@".split(";"), + "ITK_WRAP_PYTHON_VECTOR_REAL": "@ITK_WRAP_PYTHON_VECTOR_REAL@".split(";"), + "ITK_WRAP_PYTHON_COV_VECTOR_REAL": "@ITK_WRAP_PYTHON_COV_VECTOR_REAL@".split(";"), + "ITK_WRAP_PYTHON_RGB": "@ITK_WRAP_PYTHON_RGB@".split(";"), + "ITK_WRAP_PYTHON_RGBA": "@ITK_WRAP_PYTHON_RGBA@".split(";"), + "ITK_WRAP_PYTHON_COMPLEX_REAL": "@ITK_WRAP_PYTHON_COMPLEX_REAL@".split(";"), +} (swig_lib, swig_py, config_py, doxygen_root, path) = _initialize() del _initialize