[cmake-developers] [CMake 0015661]: FindPythonInterp will accept "python" in the path, even though it is the wrong version

Mantis Bug Tracker mantis at public.kitware.com
Thu Jul 23 14:07:46 EDT 2015


The following issue has been SUBMITTED. 
====================================================================== 
http://public.kitware.com/Bug/view.php?id=15661 
====================================================================== 
Reported By:                Paul "TBBle" Hampson
Assigned To:                
====================================================================== 
Project:                    CMake
Issue ID:                   15661
Category:                   Modules
Reproducibility:            always
Severity:                   major
Priority:                   normal
Status:                     new
====================================================================== 
Date Submitted:             2015-07-24 04:07 AEST
Last Modified:              2015-07-24 04:07 AEST
====================================================================== 
Summary:                    FindPythonInterp will accept "python" in the path,
even though it is the wrong version
Description: 
The command

FIND_PACKAGE(PythonInterp 2.6 REQUIRED)

will discover a Python 3 installation if that is 'python' in the path, in
preference to a Python 2 installation.

Steps to Reproduce: 
Call 

FIND_PACKAGE(PythonInterp 2.6 REQUIRED)

in a CMake script, when your PATH contains C:\Python34 but both Python 3.4 and
Python 2.7 are installed locally.

Expected result:

-- Found PythonInterp: C:/Python27/python.exe (found suitable version "2.7.9",
minimum required is "2.6")

Actual result:

-- Found PythonInterp: C:/Python34/python.exe (found suitable version "3.4.3",
minimum required is "2.6")

Additional Information: 
I haven't diagnosed this yet, but the problem appears to be the following blocks
in FindPythonInterp.cmake:

=====
# Search for the current active python version first
list(APPEND _Python_VERSIONS ";")
list(APPEND _Python_VERSIONS ${_PYTHON_FIND_OTHER_VERSIONS})
....
# Search for newest python version if python executable isn't found
if(NOT PYTHON_EXECUTABLE)
    foreach(_CURRENT_VERSION IN LISTS _Python_VERSIONS)
      set(_Python_NAMES python${_CURRENT_VERSION})
      if(WIN32)
        list(APPEND _Python_NAMES python)
      endif()
      find_program(PYTHON_EXECUTABLE
        NAMES ${_Python_NAMES}
        PATHS
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]
        )
    endforeach()
endif()
=====

If I'm reading this correctly, it's possible for _Python_VERSIONS to be empty
before this if neither ADDTIONAL_VERSIONS nor PYTHONLIBS_VERSION_STRING (from
FindPythonLibs.cmake) are set.

This means that when the given loop is hit, the first value of _CURRENT_VERSION
is "", so 'python' is searched for by find_program. There's also the
WIN32-specific block that explicitly searches for the executable name 'python',
as that's the name of the executable on Windows installations.

If python.exe is in the Path (a non-default but common installer option) then
the first search attempt will discover it and use it.

It might be simplest to split this search, and on Win32 not search the system
path until the registry walk has completed.

I think there's also a couple of other issues here: A per-user install of Python
sets a different registry key, and we don't fail if Python 2 was requested but
Python 3 is found, or vice-versa.

We also don't support py.exe, which as of Python 3.3 supports running python
scripts with arbitrary versions by processing the #! initial line the same way
an executable .py file is handled on POSIX systems.
====================================================================== 

Issue History 
Date Modified    Username       Field                    Change               
====================================================================== 
2015-07-24 04:07 Paul "TBBle" HampsonNew Issue                                  
 
======================================================================



More information about the cmake-developers mailing list