From cc7f116cb409236697c4a17e5ad012e7c2790ce5 Mon Sep 17 00:00:00 2001
From: Marc Chevrier <marc.chevrier@gmail.com>
Date: Tue, 17 Mar 2020 14:50:43 +0100
Subject: FindPython: fix regression on version validation

In commit 3dab4682f6 (FindPython: reduces consumption of resources,
2020-02-10, v3.17.0-rc1~11^2) we accidentally broke the python
executable version validation when the "LOCATION" strategy is used
with the plain `FindPython` module.  Fix the logic and add test
cases covering those combinations.

Fixes: #20465
---
 Modules/FindPython/Support.cmake       |  8 ++---
 Tests/FindPython/CMakeLists.txt        | 56 ++++++++++++++++++++++++++++++++--
 Tests/FindPython/Python/CMakeLists.txt | 26 ++++++++--------
 3 files changed, 71 insertions(+), 19 deletions(-)

diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 32c5283..ce06458 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -316,7 +316,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
         list (REMOVE_DUPLICATES _values)
       elseif (NAME STREQUAL "SOABI")
         # clean-up: remove prefix character and suffix
-        string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\.(so|pyd))$" "\\1" _values "${_values}")
+        string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
       endif()
     endif()
   endif()
@@ -357,7 +357,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
           list (GET _soabi 1 _values)
           if (_values)
             # clean-up: remove prefix character and suffix
-            string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\.(so|pyd))$" "\\1" _values "${_values}")
+            string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
           endif()
         endif()
       endif()
@@ -527,8 +527,8 @@ function (_PYTHON_VALIDATE_INTERPRETER)
         set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
       else()
         # check that version is OK
-        string(REGEX REPLACE "^([0-9]+)\." "\\1" major_version "${version}")
-        string(REGEX REPLACE "^([0-9]+)\." "\\1" expected_major_version "${expected_version}")
+        string(REGEX REPLACE "^([0-9]+)\\..*$" "\\1" major_version "${version}")
+        string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" expected_major_version "${expected_version}")
         if (NOT major_version VERSION_EQUAL expected_major_version
             OR NOT version VERSION_GREATER_EQUAL expected_version)
           set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt
index bfec986..01fa6c3 100644
--- a/Tests/FindPython/CMakeLists.txt
+++ b/Tests/FindPython/CMakeLists.txt
@@ -67,14 +67,64 @@ if(CMake_TEST_FindPython)
   set_tests_properties(FindPython.Python3Fail PROPERTIES
     PASS_REGULAR_EXPRESSION "Could NOT find Python3 \\(missing: foobar\\)")
 
-  add_test(NAME FindPython.Python COMMAND
+  add_test(NAME FindPython.Python.LOCATION COMMAND
     ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
-    "${CMake_BINARY_DIR}/Tests/FindPython/Python"
+    "${CMake_BINARY_DIR}/Tests/FindPython/Python.LOCATION"
     ${build_generator_args}
     --build-project TestPython
-    --build-options ${build_options}
+    --build-options ${build_options} -DPython_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.Python.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+    "${CMake_BINARY_DIR}/Tests/FindPython/Python.VERSION"
+    ${build_generator_args}
+    --build-project TestPython
+    --build-options ${build_options} -DPython_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.Python.V2.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+    "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.LOCATION"
+    ${build_generator_args}
+    --build-project TestPython
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.Python.V2.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+    "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.VERSION"
+    ${build_generator_args}
+    --build-project TestPython
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.Python.V3.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+    "${CMake_BINARY_DIR}/Tests/FindPython/Python.V3.LOCATION"
+    ${build_generator_args}
+    --build-project TestPython
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.Python.V3.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+    "${CMake_BINARY_DIR}/Tests/FindPython/Python.V3.VERSION"
+    ${build_generator_args}
+    --build-project TestPython
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=VERSION
     --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
     )
 
diff --git a/Tests/FindPython/Python/CMakeLists.txt b/Tests/FindPython/Python/CMakeLists.txt
index 62c805e..3ee38e3 100644
--- a/Tests/FindPython/Python/CMakeLists.txt
+++ b/Tests/FindPython/Python/CMakeLists.txt
@@ -4,9 +4,9 @@ project(TestPython C)
 
 include(CTest)
 
-find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
+find_package(Python ${Python_REQUESTED_VERSION} REQUIRED COMPONENTS Interpreter Development)
 if (NOT Python_FOUND)
-  message (FATAL_ERROR "Fail to found Python 3")
+  message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}")
 endif()
 
 if(NOT TARGET Python::Interpreter)
@@ -20,13 +20,15 @@ if(NOT TARGET Python::Module)
   message(SEND_ERROR "Python::Module not found")
 endif()
 
-Python_add_library (spam3 MODULE ../spam.c)
-target_compile_definitions (spam3 PRIVATE PYTHON3)
-
-add_test (NAME python_spam3
-          COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam3>"
-          "${Python_EXECUTABLE}" -c "import spam3; spam3.system(\"cd\")")
-
-add_test(NAME findpython_script
-         COMMAND "${CMAKE_COMMAND}" -DPYTHON_PACKAGE_NAME=Python
-         -P "${CMAKE_CURRENT_LIST_DIR}/../FindPythonScript.cmake")
+if (Python_REQUESTED_VERSION)
+  Python_add_library (spam${Python_REQUESTED_VERSION} MODULE ../spam.c)
+  target_compile_definitions (spam${Python_REQUESTED_VERSION} PRIVATE PYTHON${Python_REQUESTED_VERSION})
+
+  add_test (NAME python_spam${Python_REQUESTED_VERSION}
+            COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam${Python_REQUESTED_VERSION}>"
+            "${Python_EXECUTABLE}" -c "import spam${Python_REQUESTED_VERSION}; spam${Python_REQUESTED_VERSION}.system(\"cd\")")
+else()
+  add_test(NAME findpython_script
+           COMMAND "${CMAKE_COMMAND}" -DPYTHON_PACKAGE_NAME=Python
+           -P "${CMAKE_CURRENT_LIST_DIR}/../FindPythonScript.cmake")
+endif()
-- 
cgit v0.12