Index: adios2/bindings/CMakeLists.txt
===================================================================
--- adios2.orig/bindings/CMakeLists.txt	2024-12-06 14:32:44.826716293 +0100
+++ adios2/bindings/CMakeLists.txt	2024-12-06 14:32:44.814716210 +0100
@@ -3,8 +3,19 @@
 # accompanying file Copyright.txt for details.
 #------------------------------------------------------------------------------#
 
-if(ADIOS2_HAVE_Python)
-  add_subdirectory(Python)
+if(ADIOS2_USE_Python)
+  if(ADIOS2_Python_Version)
+    # specific Python versions specified, e.g. -DADIOS2_Python_Version=3.12;3.11
+    foreach(pyver IN LISTS ADIOS2_Python_Version)
+      file(REMOVE_RECURSE Python${pyver})
+      file(COPY Python DESTINATION ${CMAKE_BINARY_DIR}/build_source/bindings/Python${pyver})
+      file(WRITE ${CMAKE_BINARY_DIR}/build_source/bindings/Python${pyver}/Python/ADIOS2_Python_Version.txt ${pyver})
+      add_subdirectory(${CMAKE_BINARY_DIR}/build_source/bindings/Python${pyver}/Python ${CMAKE_BINARY_DIR}/bindings/Python${pyver}/Python)
+    endforeach()
+  else()
+    # build for the default Python version only
+    add_subdirectory(Python)
+  endif()
 endif()
 
 if(ADIOS2_HAVE_Fortran)
Index: adios2/bindings/Python/CMakeLists.txt
===================================================================
--- adios2.orig/bindings/Python/CMakeLists.txt	2024-12-06 14:32:44.826716293 +0100
+++ adios2/bindings/Python/CMakeLists.txt	2024-12-06 14:34:43.059535709 +0100
@@ -1,4 +1,12 @@
-Python_add_library(adios2_py MODULE
+# If a specific Python version should be used, it will be defined in ADIOS2_Python_Version.txt
+if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/ADIOS2_Python_Version.txt)
+  file(READ ${CMAKE_CURRENT_LIST_DIR}/ADIOS2_Python_Version.txt PYVER)
+  include(${PROJECT_SOURCE_DIR}/cmake/DetectPythonOptions.cmake)
+endif()
+
+include(${PROJECT_SOURCE_DIR}/cmake/ADIOSFunctions.cmake)
+
+Python_add_library(adios2_py${PYVER} MODULE
   WITH_SOABI
   py11ADIOS.cpp
   py11IO.cpp
@@ -9,9 +17,9 @@
   py11Query.cpp
   py11glue.cpp
 )
-target_compile_definitions(adios2_py PRIVATE "ADIOS2_PYTHON_MODULE_NAME=adios2_bindings${ADIOS2_LIBRARY_SUFFIX}")
+target_compile_definitions(adios2_py${PYVER} PRIVATE "ADIOS2_PYTHON_MODULE_NAME=adios2_bindings${ADIOS2_LIBRARY_SUFFIX}")
 if(ADIOS2_HAVE_MPI)
-  target_sources(adios2_py PRIVATE
+    target_sources(adios2_py${PYVER} PRIVATE
     py11ADIOSMPI.cpp
     py11IOMPI.cpp
   )
@@ -23,7 +31,7 @@
   set(maybe_adios2_core_mpi)
   set(maybe_mpi4py)
 endif()
-target_link_libraries(adios2_py PRIVATE
+target_link_libraries(adios2_py${PYVER} PRIVATE
   ${maybe_adios2_cxx11_mpi} adios2_cxx11
   ${maybe_adios2_core_mpi} adios2_core
   adios2::thirdparty::pybind11
@@ -46,7 +54,7 @@
 )
 
 # We need the $<0:> for the Windows python unittests to work
-set_target_properties(adios2_py PROPERTIES
+set_target_properties(adios2_py${PYVER} PROPERTIES
   CXX_VISIBILITY_PRESET hidden
   OUTPUT_NAME adios2_bindings${ADIOS2_LIBRARY_SUFFIX}
   ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_PYTHON_OUTPUT_DIRECTORY}/adios2/bindings$<0:>
@@ -63,14 +71,14 @@
 
 string(REGEX REPLACE "[^/]+" ".." relative_base "${install_location}/bindings")
 if(CMAKE_SYSTEM_NAME MATCHES "Linux")
-  set_property(TARGET adios2_py APPEND PROPERTY
+    set_property(TARGET adios2_py${PYVER} APPEND PROPERTY
     INSTALL_RPATH "$ORIGIN/${relative_base}/${CMAKE_INSTALL_LIBDIR}"
   )
 endif()
 
-install(TARGETS adios2_py
+install(TARGETS adios2_py${PYVER}
   DESTINATION ${install_location}/bindings
-  COMPONENT adios2_python-python
+  COMPONENT adios2_python-python${PYVER}
 )
 install(FILES ${CMAKE_PYTHON_OUTPUT_DIRECTORY}/adios2/bindings/__init__.py
   DESTINATION ${install_location}/bindings
Index: adios2/cmake/DetectPythonOptions.cmake
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ adios2/cmake/DetectPythonOptions.cmake	2024-12-06 14:32:44.818716237 +0100
@@ -0,0 +1,89 @@
+#------------------------------------------------------------------------------#
+# Distributed under the OSI-approved Apache License, Version 2.0.  See
+# accompanying file Copyright.txt for details.
+#------------------------------------------------------------------------------#
+
+# This file contains the option and dependency logic for Python support,
+# moved from DetectOptions.cmake to allow for multiple python versions.
+
+# Python
+
+if(PYVER)
+  set(PY3VER ${PYVER})
+else()
+  set(PY3VER 3)
+endif()
+
+# Not supported on PGI
+if(CMAKE_CXX_COMPILER_ID STREQUAL PGI)
+  if(ADIOS2_USE_Python STREQUAL ON)
+    message(FATAL_ERROR "Python bindings are not supported with the PGI compiler")
+  elseif(ADIOS2_USE_Python STREQUAL AUTO)
+    message(WARNING "Disabling python bindings as they are not supported with the PGI compiler")
+    set(ADIOS2_USE_Python OFF)
+  endif()
+endif()
+
+# Not supported without shared libs
+if(NOT SHARED_LIBS_SUPPORTED)
+  if(ADIOS2_USE_Python STREQUAL ON)
+    message(FATAL_ERROR "Python bindings are not supported without shared library support")
+  elseif(ADIOS2_USE_Python STREQUAL AUTO)
+    message(WARNING "Disabling python bindings since no shared library support was detected.")
+    set(ADIOS2_USE_Python OFF)
+  endif()
+endif()
+
+if(ADIOS2_USE_Python STREQUAL AUTO)
+  if(PYVER)
+  find_package(Python ${PYVER} EXACT COMPONENTS Interpreter Development NumPy)
+  else()
+  find_package(Python 3 COMPONENTS Interpreter Development NumPy)
+  endif()
+  if(Python_FOUND AND ADIOS2_HAVE_MPI)
+    find_package(PythonModule COMPONENTS mpi4py mpi4py/mpi4py.h)
+  endif()
+elseif(ADIOS2_USE_Python)
+  if(PYVER)
+  find_package(Python ${PYVER} EXACT REQUIRED COMPONENTS Interpreter Development NumPy)
+  else()
+  find_package(Python 3 REQUIRED COMPONENTS Interpreter Development NumPy)
+  endif()
+  if(ADIOS2_HAVE_MPI)
+    find_package(PythonModule REQUIRED COMPONENTS mpi4py mpi4py/mpi4py.h)
+  endif()
+endif()
+
+if(Python_FOUND)
+  if(ADIOS2_HAVE_MPI)
+    if(PythonModule_mpi4py_FOUND)
+      set(ADIOS2_HAVE_Python ON)
+    endif()
+  else()
+    set(ADIOS2_HAVE_Python ON)
+  endif()
+endif()
+
+# Even if no python support, we still want the interpreter for tests
+if(BUILD_TESTING AND NOT Python_Interpreter_FOUND)
+  find_package(Python REQUIRED COMPONENTS Interpreter)
+endif()
+
+if(Python_Interpreter_FOUND)
+  # Setup output directories
+  if(Python_Development_FOUND)
+    lists_get_prefix("Python_INCLUDE_DIRS;Python_LIBRARIES;Python_SITEARCH" _Python_DEVPREFIX)
+  else()
+    lists_get_prefix("Python_EXECUTABLE;Python_SITEARCH" _Python_DEVPREFIX)
+  endif()
+  string_strip_prefix(
+    "${_Python_DEVPREFIX}" "${Python_SITEARCH}" CMAKE_INSTALL_PYTHONDIR_DEFAULT
+  )
+  set(CMAKE_INSTALL_PYTHONDIR "${CMAKE_INSTALL_PYTHONDIR_DEFAULT}"
+    CACHE PATH "Install directory for python modules"
+  )
+  mark_as_advanced(CMAKE_INSTALL_PYTHONDIR)
+  set(CMAKE_PYTHON_OUTPUT_DIRECTORY
+    ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_PYTHONDIR}
+  )
+endif()
Index: adios2/cmake/DetectOptions.cmake
===================================================================
--- adios2.orig/cmake/DetectOptions.cmake	2024-12-06 14:32:44.826716293 +0100
+++ adios2/cmake/DetectOptions.cmake	2024-12-06 14:32:44.818716237 +0100
@@ -397,53 +397,53 @@
   endif()
 endif()
 
-if(ADIOS2_USE_PIP)
-  find_package(Python 3.8 REQUIRED COMPONENTS Interpreter Development.Module)
-  set(ADIOS2_HAVE_PIP TRUE)
-elseif(ADIOS2_USE_Python STREQUAL AUTO)
-  find_package(Python 3.8 COMPONENTS Interpreter Development)
-  if(Python_FOUND AND ADIOS2_HAVE_MPI)
-    find_package(PythonModule COMPONENTS mpi4py mpi4py/mpi4py.h)
-  endif()
-elseif(ADIOS2_USE_Python)
-  find_package(Python 3.8 REQUIRED COMPONENTS Interpreter Development)
-  if(ADIOS2_HAVE_MPI)
-    find_package(PythonModule REQUIRED COMPONENTS mpi4py mpi4py/mpi4py.h)
-  endif()
-endif()
-if(Python_FOUND)
-  if(ADIOS2_HAVE_MPI)
-    if(PythonModule_mpi4py_FOUND)
-      set(ADIOS2_HAVE_Python ON)
-    endif()
-  else()
-    set(ADIOS2_HAVE_Python ON)
-  endif()
-endif()
+#if(ADIOS2_USE_PIP)
+#  find_package(Python 3.8 REQUIRED COMPONENTS Interpreter Development.Module)
+#  set(ADIOS2_HAVE_PIP TRUE)
+#elseif(ADIOS2_USE_Python STREQUAL AUTO)
+#  find_package(Python 3.8 COMPONENTS Interpreter Development)
+#  if(Python_FOUND AND ADIOS2_HAVE_MPI)
+#    find_package(PythonModule COMPONENTS mpi4py mpi4py/mpi4py.h)
+#  endif()
+#elseif(ADIOS2_USE_Python)
+#  find_package(Python 3.8 REQUIRED COMPONENTS Interpreter Development)
+#  if(ADIOS2_HAVE_MPI)
+#    find_package(PythonModule REQUIRED COMPONENTS mpi4py mpi4py/mpi4py.h)
+#  endif()
+#endif()
+#if(Python_FOUND)
+#  if(ADIOS2_HAVE_MPI)
+#    if(PythonModule_mpi4py_FOUND)
+#      set(ADIOS2_HAVE_Python ON)
+#    endif()
+#  else()
+#    set(ADIOS2_HAVE_Python ON)
+#  endif()
+#endif()
 
 # Even if no python support, we still want the interpreter for tests
-if(BUILD_TESTING AND NOT Python_Interpreter_FOUND)
-  find_package(Python REQUIRED COMPONENTS Interpreter)
-endif()
-
-if(Python_Interpreter_FOUND)
-  # Setup output directories
-  if(Python_Development_FOUND)
-    lists_get_prefix("Python_INCLUDE_DIRS;Python_LIBRARIES;Python_SITEARCH" _Python_DEVPREFIX)
-  else()
-    lists_get_prefix("Python_EXECUTABLE;Python_SITEARCH" _Python_DEVPREFIX)
-  endif()
-  string_strip_prefix(
-    "${_Python_DEVPREFIX}" "${Python_SITEARCH}" CMAKE_INSTALL_PYTHONDIR_DEFAULT
-  )
-  set(CMAKE_INSTALL_PYTHONDIR "${CMAKE_INSTALL_PYTHONDIR_DEFAULT}"
-    CACHE PATH "Install directory for python modules"
-  )
-  mark_as_advanced(CMAKE_INSTALL_PYTHONDIR)
-  set(CMAKE_PYTHON_OUTPUT_DIRECTORY
-    ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_PYTHONDIR}
-  )
-endif()
+#if(BUILD_TESTING AND NOT Python_Interpreter_FOUND)
+#  find_package(Python REQUIRED COMPONENTS Interpreter)
+#endif()
+#
+#if(Python_Interpreter_FOUND)
+#  # Setup output directories
+#  if(Python_Development_FOUND)
+#    lists_get_prefix("Python_INCLUDE_DIRS;Python_LIBRARIES;Python_SITEARCH" _Python_DEVPREFIX)
+#  else()
+#    lists_get_prefix("Python_EXECUTABLE;Python_SITEARCH" _Python_DEVPREFIX)
+#  endif()
+#  string_strip_prefix(
+#    "${_Python_DEVPREFIX}" "${Python_SITEARCH}" CMAKE_INSTALL_PYTHONDIR_DEFAULT
+#  )
+#  set(CMAKE_INSTALL_PYTHONDIR "${CMAKE_INSTALL_PYTHONDIR_DEFAULT}"
+#    CACHE PATH "Install directory for python modules"
+#  )
+#  mark_as_advanced(CMAKE_INSTALL_PYTHONDIR)
+#  set(CMAKE_PYTHON_OUTPUT_DIRECTORY
+#    ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_PYTHONDIR}
+#  )
+#endif()
 
 # Sst
 if(ADIOS2_USE_SST AND NOT WIN32)
Index: adios2/testing/adios2/engine/CMakeLists.txt
===================================================================
--- adios2.orig/testing/adios2/engine/CMakeLists.txt	2024-12-06 14:32:44.826716293 +0100
+++ adios2/testing/adios2/engine/CMakeLists.txt	2024-12-06 14:32:44.818716237 +0100
@@ -13,7 +13,9 @@
   add_subdirectory(hdf5)
 endif()
 
-if(ADIOS2_HAVE_DataMan)
+# Can only run dataman with a general Python build
+# not with versions specified by ADIOS2_Python_Version
+if(ADIOS2_HAVE_DataMan AND NOT ADIOS2_Python_Version)
   add_subdirectory(dataman)
 endif()
 
Index: adios2/testing/adios2/bindings/CMakeLists.txt
===================================================================
--- adios2.orig/testing/adios2/bindings/CMakeLists.txt	2024-12-06 14:32:44.826716293 +0100
+++ adios2/testing/adios2/bindings/CMakeLists.txt	2024-12-06 14:32:44.818716237 +0100
@@ -3,7 +3,9 @@
 # accompanying file Copyright.txt for details.
 #------------------------------------------------------------------------------#
 
-if(ADIOS2_HAVE_Python)
+# Can only run python binding tests with a general Python build
+# not with versions specified by ADIOS2_Python_Version
+if(ADIOS2_HAVE_Python AND NOT ADIOS2_Python_Version)
   add_subdirectory(python)
 endif()
 
Index: adios2/CMakeLists.txt
===================================================================
--- adios2.orig/CMakeLists.txt	2024-12-06 14:32:44.826716293 +0100
+++ adios2/CMakeLists.txt	2024-12-06 14:32:44.818716237 +0100
@@ -193,6 +193,11 @@
 mark_as_advanced(ADIOS2_USE_PIP)
 include(${PROJECT_SOURCE_DIR}/cmake/DetectOptions.cmake)
 
+if(ADIOS2_Python_Version)
+    # use the last Python version in the list to run tests
+    list(GET ADIOS2_Python_Version -1 ADIOS2_Python_Default_Test)
+endif()
+
 if(ADIOS2_HAVE_CUDA OR ADIOS2_HAVE_Kokkos_CUDA)
     set(CMAKE_CUDA_STANDARD 11)
     set(CMAKE_CUDA_STANDARD_REQUIRED TRUE)
@@ -421,6 +426,8 @@
 message("      cmake: ${CMAKE_INSTALL_CMAKEDIR}")
 if(DEFINED CMAKE_INSTALL_PYTHONDIR)
   message("     python: ${CMAKE_INSTALL_PYTHONDIR}")
+elseif(ADIOS2_Python_Version)
+  message("     python: ${ADIOS2_Python_Version}")
 endif()
 message("")
 message("  Features:")
Index: adios2/thirdparty/CMakeLists.txt
===================================================================
--- adios2.orig/thirdparty/CMakeLists.txt	2024-12-06 14:32:44.826716293 +0100
+++ adios2/thirdparty/CMakeLists.txt	2024-12-06 14:32:44.818716237 +0100
@@ -48,7 +48,7 @@
   endif()
 endif()
 
-if(ADIOS2_HAVE_Python)
+if(ADIOS2_USE_Python)
   if(ADIOS2_USE_EXTERNAL_PYBIND11)
     find_package(pybind11 REQUIRED)
     adios2_add_thirdparty_target(pybind11 pybind11::pybind11)
