Преглед на файлове

FindPython: Add support for 'PyPy'

Marc Chevrier преди 5 години
родител
ревизия
c1ef70d4d1

+ 5 - 0
Help/release/dev/FindPython-pypy.rst

@@ -0,0 +1,5 @@
+FindPython-pypy
+---------------
+
+* The :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
+  modules gained the capability to handle ``PyPy`` product.

+ 6 - 0
Modules/FindPython.cmake

@@ -85,6 +85,7 @@ This module will set the following variables in your project
     * Anaconda
     * Anaconda
     * Canopy
     * Canopy
     * IronPython
     * IronPython
+    * PyPy
 ``Python_STDLIB``
 ``Python_STDLIB``
   Standard platform independent installation directory.
   Standard platform independent installation directory.
 
 
@@ -147,6 +148,8 @@ This module will set the following variables in your project
   Python minor version.
   Python minor version.
 ``Python_VERSION_PATCH``
 ``Python_VERSION_PATCH``
   Python patch version.
   Python patch version.
+``Python_PyPy_VERSION``
+  Python PyPy version.
 ``Python_NumPy_FOUND``
 ``Python_NumPy_FOUND``
   System has the NumPy.
   System has the NumPy.
 ``Python_NumPy_INCLUDE_DIRS``
 ``Python_NumPy_INCLUDE_DIRS``
@@ -281,6 +284,9 @@ Hints
   * ``IronPython``: This implementation use the ``CSharp`` language for
   * ``IronPython``: This implementation use the ``CSharp`` language for
     ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
     ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
     See `IronPython <http://ironpython.net>`_.
     See `IronPython <http://ironpython.net>`_.
+  * ``PyPy``: This implementation use ``RPython`` language and
+    ``RPython translation toolchain`` to produce the python interpreter.
+    See `PyPy <https://www.pypy.org>`_.
 
 
   The default value is the list: ``CPython``, ``IronPython``.
   The default value is the list: ``CPython``, ``IronPython``.
 
 

+ 91 - 9
Modules/FindPython/Support.cmake

@@ -263,6 +263,14 @@ function (_PYTHON_GET_PATH_SUFFIXES _PYTHON_PGPS_PATH_SUFFIXES)
       if (_PGPS_EXECUTABLE)
       if (_PGPS_EXECUTABLE)
         list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES})
         list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES})
       endif()
       endif()
+    elseif (implementation STREQUAL "PyPy")
+      if (_PGPS_EXECUTABLE)
+        list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_EXECUTABLE_PATH_SUFFIXES})
+      elseif (_PGPS_LIBRARY)
+        list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_LIBRARY_PATH_SUFFIXES})
+      elseif (_PGPS_INCLUDE)
+        list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES})
+      endif()
     endif()
     endif()
   endforeach()
   endforeach()
   list (REMOVE_DUPLICATES path_suffixes)
   list (REMOVE_DUPLICATES path_suffixes)
@@ -333,6 +341,23 @@ function (_PYTHON_GET_NAMES _PYTHON_PGN_NAMES)
       if (_PGN_EXECUTABLE)
       if (_PGN_EXECUTABLE)
         list (APPEND names ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES})
         list (APPEND names ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES})
       endif()
       endif()
+    elseif (implementation STREQUAL "PyPy")
+      if (_PGN_EXECUTABLE)
+        list (APPEND names ${_${_PYTHON_PREFIX}_PYPY_NAMES})
+      elseif (_PGN_LIBRARY)
+        if (_PGN_WIN32)
+          foreach (version IN LISTS _PGN_VERSION)
+            string (REPLACE "." "" version_no_dots ${version})
+
+            set (name "python${version_no_dots}")
+            if (_PGN_DEBUG)
+              string (APPEND name "_d")
+            endif()
+            list (APPEND names "${name}")
+          endforeach()
+        endif()
+        list (APPEND names ${_${_PYTHON_PREFIX}_PYPY_LIB_NAMES})
+      endif()
     endif()
     endif()
   endforeach()
   endforeach()
 
 
@@ -484,8 +509,18 @@ function (_PYTHON_GET_VERSION)
         set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE)
         set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE)
         set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE)
         set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE)
         set (${_PGV_PREFIX}ABI "${CMAKE_MATCH_3}" PARENT_SCOPE)
         set (${_PGV_PREFIX}ABI "${CMAKE_MATCH_3}" PARENT_SCOPE)
+      elseif (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "pypy(3)?")
+        set (version "${CMAKE_MATCH_1}")
+        if (version EQUAL "3")
+          set (${_PGV_PREFIX}VERSION_MAJOR "3" PARENT_SCOPE)
+          set (${_PGV_PREFIX}VERSION "3" PARENT_SCOPE)
+        else()
+          set (${_PGV_PREFIX}VERSION_MAJOR "2" PARENT_SCOPE)
+          set (${_PGV_PREFIX}VERSION "2" PARENT_SCOPE)
         endif()
         endif()
+        set (${_PGV_PREFIX}ABI "" PARENT_SCOPE)
       endif()
       endif()
+    endif()
   else()
   else()
     if (_${_PYTHON_PREFIX}_INCLUDE_DIR)
     if (_${_PYTHON_PREFIX}_INCLUDE_DIR)
       # retrieve version from header file
       # retrieve version from header file
@@ -977,12 +1012,34 @@ else()
 endif()
 endif()
 set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40)
 set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40)
 
 
+# PyPy support
+if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "3")
+  set (_${_PYTHON_PREFIX}_PYPY_NAMES pypy3)
+  set (_${_PYTHON_PREFIX}_PYPY_LIB_NAMES pypy3-c)
+  if (WIN32)
+    # special name for runtime part
+    list (APPEND _${_PYTHON_PREFIX}_PYPY_LIB_NAMES libpypy3-c)
+  endif()
+  set (_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES lib/pypy3)
+else()
+  set (_${_PYTHON_PREFIX}_PYPY_NAMES pypy)
+  set (_${_PYTHON_PREFIX}_PYPY_LIB_NAMES pypy-c)
+  if (WIN32)
+    # special name for runtime part
+    list (APPEND _${_PYTHON_PREFIX}_PYPY_LIB_NAMES libpypy-c)
+  endif()
+  set (_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES lib/pypy)
+endif()
+set (_${_PYTHON_PREFIX}_PYPY_EXECUTABLE_PATH_SUFFIXES bin)
+set (_${_PYTHON_PREFIX}_PYPY_LIBRARY_PATH_SUFFIXES lib libs bin)
+list (APPEND _${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES include)
+
 # Python Implementations handling
 # Python Implementations handling
 unset (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
 unset (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
 if (DEFINED ${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
 if (DEFINED ${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
   foreach (_${_PYTHON_PREFIX}_IMPLEMENTATION IN LISTS ${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
   foreach (_${_PYTHON_PREFIX}_IMPLEMENTATION IN LISTS ${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
-    if (NOT _${_PYTHON_PREFIX}_IMPLEMENTATION MATCHES "^(CPython|IronPython)$")
-      message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${_${_PYTHON_PREFIX}_IMPLEMENTATION}: invalid value for '${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS'. 'CPython' or 'IronPython' expected. Value will be ignored.")
+    if (NOT _${_PYTHON_PREFIX}_IMPLEMENTATION MATCHES "^(CPython|IronPython|PyPy)$")
+      message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${_${_PYTHON_PREFIX}_IMPLEMENTATION}: invalid value for '${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS'. 'CPython', 'IronPython' or 'PyPy' expected. Value will be ignored.")
     else()
     else()
       list (APPEND _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_IMPLEMENTATION})
       list (APPEND _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_IMPLEMENTATION})
     endif()
     endif()
@@ -996,6 +1053,8 @@ unset (_${_PYTHON_PREFIX}_INCLUDE_NAMES)
 foreach (_${_PYTHON_PREFIX}_IMPLEMENTATION IN LISTS _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
 foreach (_${_PYTHON_PREFIX}_IMPLEMENTATION IN LISTS _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
   if (_${_PYTHON_PREFIX}_IMPLEMENTATION STREQUAL "CPython")
   if (_${_PYTHON_PREFIX}_IMPLEMENTATION STREQUAL "CPython")
     list (APPEND _${_PYTHON_PREFIX}_INCLUDE_NAMES "Python.h")
     list (APPEND _${_PYTHON_PREFIX}_INCLUDE_NAMES "Python.h")
+  elseif (_${_PYTHON_PREFIX}_IMPLEMENTATION STREQUAL "PyPy")
+    list (APPEND _${_PYTHON_PREFIX}_INCLUDE_NAMES "PyPy.h")
   endif()
   endif()
 endforeach()
 endforeach()
 
 
@@ -1150,7 +1209,7 @@ unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE)
 # first step, search for the interpreter
 # first step, search for the interpreter
 if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
 if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
   list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_EXECUTABLE
   list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_EXECUTABLE
-               _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES)
+                                              _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES)
   if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter)
   if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter)
     list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE)
     list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE)
   endif()
   endif()
@@ -1526,6 +1585,9 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
             set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda")
             set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda")
           elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought")
           elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought")
             set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy")
             set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy")
+          elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "PyPy ([0-9.]+)")
+            set (${_PYTHON_PREFIX}_INTERPRETER_ID "PyPy")
+            set  (${_PYTHON_PREFIX}_PyPy_VERSION "${CMAKE_MATCH_1}")
           else()
           else()
             string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}")
             string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}")
             if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python")
             if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python")
@@ -1811,11 +1873,19 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
     AND ((${_PYTHON_PREFIX}_Interpreter_FOUND
     AND ((${_PYTHON_PREFIX}_Interpreter_FOUND
         AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
         AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
       OR NOT ${_PYTHON_PREFIX}_Interpreter_FOUND))
       OR NOT ${_PYTHON_PREFIX}_Interpreter_FOUND))
+  if (${_PYTHON_PREFIX}_Interpreter_FOUND)
+    # reduce possible implementations to the interpreter one
+    if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "PyPy")
+      set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS "PyPy")
+    else()
+      set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS "CPython")
+    endif()
+  endif()
   if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
   if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
-    list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_LIBRARY_RELEASE
-                 _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
-                 _${_PYTHON_PREFIX}_LIBRARY_DEBUG
-                 _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+  list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_LIBRARY_RELEASE
+                                              _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
+                                              _${_PYTHON_PREFIX}_LIBRARY_DEBUG
+                                              _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
   endif()
   endif()
   if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
   if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
     list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_INCLUDE_DIR)
     list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_INCLUDE_DIR)
@@ -2265,7 +2335,8 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
       _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
       _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
                                     NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
                                     NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
                                     NAMES_PER_DIR
                                     NAMES_PER_DIR
-                                    HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
+                                    HINTS "${_${_PYTHON_PREFIX}_PATH}"
+                                          "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
                                     PATH_SUFFIXES bin)
                                     PATH_SUFFIXES bin)
     endif()
     endif()
     if (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
     if (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
@@ -2275,7 +2346,8 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
       _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
       _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
                                     NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
                                     NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
                                     NAMES_PER_DIR
                                     NAMES_PER_DIR
-                                    HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
+                                    HINTS "${_${_PYTHON_PREFIX}_PATH}"
+                                          "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
                                     PATH_SUFFIXES bin)
                                     PATH_SUFFIXES bin)
     endif()
     endif()
   endif()
   endif()
@@ -2482,6 +2554,16 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
     set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
     set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
   endif()
   endif()
 
 
+  if ((${_PYTHON_PREFIX}_Development.Module_FOUND
+      OR ${_PYTHON_PREFIX}_Development.Embed_FOUND)
+    AND EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/PyPy.h")
+  # retrieve PyPy version
+  file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" ${_PYTHON_PREFIX}_PyPy_VERSION
+                REGEX "^#define[ \t]+PYPY_VERSION[ \t]+\"[^\"]+\"")
+  string (REGEX REPLACE "^#define[ \t]+PYPY_VERSION[ \t]+\"([^\"]+)\".*" "\\1"
+                ${_PYTHON_PREFIX}_PyPy_VERSION "${${_PYTHON_PREFIX}_PyPy_VERSION}")
+  endif()
+
   if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3"
   if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3"
       AND NOT DEFINED ${_PYTHON_PREFIX}_SOABI)
       AND NOT DEFINED ${_PYTHON_PREFIX}_SOABI)
     _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI)
     _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI)

+ 6 - 0
Modules/FindPython2.cmake

@@ -86,6 +86,7 @@ This module will set the following variables in your project
     * Anaconda
     * Anaconda
     * Canopy
     * Canopy
     * IronPython
     * IronPython
+    * PyPy
 ``Python2_STDLIB``
 ``Python2_STDLIB``
   Standard platform independent installation directory.
   Standard platform independent installation directory.
 
 
@@ -139,6 +140,8 @@ This module will set the following variables in your project
   Python 2 minor version.
   Python 2 minor version.
 ``Python2_VERSION_PATCH``
 ``Python2_VERSION_PATCH``
   Python 2 patch version.
   Python 2 patch version.
+``Python2_PyPy_VERSION``
+  Python 2 PyPy version.
 ``Python2_NumPy_FOUND``
 ``Python2_NumPy_FOUND``
   System has the NumPy.
   System has the NumPy.
 ``Python2_NumPy_INCLUDE_DIRS``
 ``Python2_NumPy_INCLUDE_DIRS``
@@ -228,6 +231,9 @@ Hints
   * ``IronPython``: This implementation use the ``CSharp`` language for
   * ``IronPython``: This implementation use the ``CSharp`` language for
     ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
     ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
     See `IronPython <http://ironpython.net>`_.
     See `IronPython <http://ironpython.net>`_.
+  * ``PyPy``: This implementation use ``RPython`` language and
+    ``RPython translation toolchain`` to produce the python interpreter.
+    See `PyPy <https://www.pypy.org>`_.
 
 
   The default value is the list: ``CPython``, ``IronPython``.
   The default value is the list: ``CPython``, ``IronPython``.
 
 

+ 6 - 0
Modules/FindPython3.cmake

@@ -86,6 +86,7 @@ This module will set the following variables in your project
     * Anaconda
     * Anaconda
     * Canopy
     * Canopy
     * IronPython
     * IronPython
+    * PyPy
 ``Python3_STDLIB``
 ``Python3_STDLIB``
   Standard platform independent installation directory.
   Standard platform independent installation directory.
 
 
@@ -148,6 +149,8 @@ This module will set the following variables in your project
   Python 3 minor version.
   Python 3 minor version.
 ``Python3_VERSION_PATCH``
 ``Python3_VERSION_PATCH``
   Python 3 patch version.
   Python 3 patch version.
+``Python3_PyPy_VERSION``
+  Python 3 PyPy version.
 ``Python3_NumPy_FOUND``
 ``Python3_NumPy_FOUND``
   System has the NumPy.
   System has the NumPy.
 ``Python3_NumPy_INCLUDE_DIRS``
 ``Python3_NumPy_INCLUDE_DIRS``
@@ -278,6 +281,9 @@ Hints
   * ``IronPython``: This implementation use the ``CSharp`` language for
   * ``IronPython``: This implementation use the ``CSharp`` language for
     ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
     ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
     See `IronPython <http://ironpython.net>`_.
     See `IronPython <http://ironpython.net>`_.
+  * ``PyPy``: This implementation use ``RPython`` language and
+    ``RPython translation toolchain`` to produce the python interpreter.
+    See `PyPy <https://www.pypy.org>`_.
 
 
   The default value is the list: ``CPython``, ``IronPython``.
   The default value is the list: ``CPython``, ``IronPython``.
 
 

+ 1 - 1
Tests/CMakeLists.txt

@@ -1477,7 +1477,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
   endif()
   endif()
 
 
   if(CMake_TEST_FindPython OR CMake_TEST_FindPython_NumPy
   if(CMake_TEST_FindPython OR CMake_TEST_FindPython_NumPy
-      OR CMake_TEST_FindPython_Conda OR CMake_TEST_FindPython_IronPython)
+      OR CMake_TEST_FindPython_Conda OR CMake_TEST_FindPython_IronPython OR CMake_TEST_FindPython_PyPy)
     add_subdirectory(FindPython)
     add_subdirectory(FindPython)
   endif()
   endif()
 
 

+ 105 - 0
Tests/FindPython/CMakeLists.txt

@@ -400,3 +400,108 @@ if(CMake_TEST_FindPython_IronPython)
     --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
     --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
     )
     )
 endif()
 endif()
+
+if(CMake_TEST_FindPython_PyPy)
+  add_test(NAME FindPython.PyPy2.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy2"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy2.LOCATION"
+    ${build_generator_args}
+    --build-project TestPyPy2
+    --build-options ${build_options} -DPython2_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy2.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy2"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy2.VERSION"
+    ${build_generator_args}
+    --build-project TestPyPy2
+    --build-options ${build_options} -DPython2_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+
+  add_test(NAME FindPython.PyPy3.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy3"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy3.LOCATION"
+    ${build_generator_args}
+    --build-project TestPyPy3
+    --build-options ${build_options} -DPython3_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy3.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy3"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy3.VERSION"
+    ${build_generator_args}
+    --build-project TestPyPy3
+    --build-options ${build_options} -DPython3_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+
+  add_test(NAME FindPython.PyPy.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.LOCATION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.VERSION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy.V2.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V2.LOCATION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy.V2.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V2.VERSION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy.V3.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V3.LOCATION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy.V3.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V3.VERSION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+endif()

+ 37 - 0
Tests/FindPython/PyPy/CMakeLists.txt

@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPyPy C)
+
+set (Python_FIND_IMPLEMENTATIONS PyPy)
+
+find_package(Python ${Python_REQUESTED_VERSION} COMPONENTS Interpreter Development)
+if (NOT Python_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION}")
+endif()
+
+if (NOT Python_Interpreter_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy Interpreter")
+endif()
+if (NOT Python_INTERPRETER_ID STREQUAL "PyPy")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python_INTERPRETER_ID})")
+endif()
+
+if (NOT Python_Development.Module_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION} Development.Module")
+endif()
+if (NOT Python_Development.Embed_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION} Development.Embed")
+endif()
+if (NOT Python_Development_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION} Development")
+endif()
+
+if(NOT TARGET Python::Interpreter)
+  message(SEND_ERROR "Python::Interpreter not found")
+endif()
+if(NOT TARGET Python::Module)
+  message(SEND_ERROR "Python::Module not found")
+endif()
+if(NOT TARGET Python::Python)
+  message(SEND_ERROR "Python::Python not found")
+endif()

+ 37 - 0
Tests/FindPython/PyPy2/CMakeLists.txt

@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPyPy2 C)
+
+set (Python2_FIND_IMPLEMENTATIONS "PyPy")
+
+find_package(Python2 COMPONENTS Interpreter Development)
+if (NOT Python2_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 2")
+endif()
+
+if (NOT Python2_Interpreter_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 2 Interpreter")
+endif()
+if (NOT Python2_INTERPRETER_ID STREQUAL "PyPy")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python2_INTERPRETER_ID})")
+endif()
+
+if (NOT Python2_Development.Module_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 2 Development.Module")
+endif()
+if (NOT Python2_Development.Embed_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 2 Development.Embed")
+endif()
+if (NOT Python2_Development_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 2 Development")
+endif()
+
+if(NOT TARGET Python2::Interpreter)
+  message(SEND_ERROR "Python2::Interpreter not found")
+endif()
+if(NOT TARGET Python2::Module)
+  message(SEND_ERROR "Python2::Module not found")
+endif()
+if(NOT TARGET Python2::Python)
+  message(SEND_ERROR "Python2::Python not found")
+endif()

+ 37 - 0
Tests/FindPython/PyPy3/CMakeLists.txt

@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPyPy3 C)
+
+set (Python3_FIND_IMPLEMENTATIONS "PyPy")
+
+find_package(Python3 COMPONENTS Interpreter Development)
+if (NOT Python3_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 3")
+endif()
+
+if (NOT Python3_Interpreter_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 3 Interpreter")
+endif()
+if (NOT Python3_INTERPRETER_ID STREQUAL "PyPy")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python3_INTERPRETER_ID})")
+endif()
+
+if (NOT Python3_Development.Module_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 3 Development.Module")
+endif()
+if (NOT Python3_Development.Embed_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 3 Development.Embed")
+endif()
+if (NOT Python3_Development_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 3 Development")
+endif()
+
+if(NOT TARGET Python3::Interpreter)
+  message(SEND_ERROR "Python3::Interpreter not found")
+endif()
+if(NOT TARGET Python3::Module)
+  message(SEND_ERROR "Python3::Module not found")
+endif()
+if(NOT TARGET Python3::Python)
+  message(SEND_ERROR "Python3::Python not found")
+endif()