View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0015661CMakeModulespublic2015-07-23 14:072016-06-10 14:31
ReporterPaul "TBBle" Hampson 
Assigned ToKitware Robot 
PrioritynormalSeveritymajorReproducibilityalways
StatusclosedResolutionmoved 
PlatformOSWindowsOS Version7 SP1
Product VersionCMake 3.2.2 
Target VersionFixed in Version 
Summary0015661: FindPythonInterp will accept "python" in the path, even though it is the wrong version
DescriptionThe 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 ReproduceCall

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 InformationI 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.
TagsNo tags attached.
Attached Files

 Relationships

  Notes
(0039167)
Rolf Eike Beer (developer)
2015-07-23 14:38

Since 3.4.3 is newer than 2.6 this is a valid result.
(0039169)
Paul "TBBle" Hampson (reporter)
2015-07-23 17:14

Python 3 is not a valid interpreter for Python 2 scripts, see https://docs.python.org/3/whatsnew/3.0.html [^]

The FindPythonInterp module attempts to enforce this if a major version or major.minor version is provided, but is then undermined by the above-mentioned find_program call accepting a python.exe found in the path that does not match the specific version it is currently searching for.

Looking again, the issue might be slightly wider, as the first part (that handles a versioned request) only works for executables named pythonMAJ or pythonMAJ.MIN, but probably _should_ equally discovery [regkey/MAJ/MIN]/Python.exe.

I suspect involvement of things like cygwin probably make this even more complicated. It might be best if the script was able to _reject_ python executables discovered that did not meet the version requirements.
(0039207)
Greg Jung (reporter)
2015-07-30 15:54

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

WIN32 is too general a designation because some will have a win32 system, with a win32 python that is incompatible with their build intentions. I.e. a Mingw/msys or a cygwin or any other that would like to bypass and ignore any registry entries. (Actually CYGWIN will purge the WIN32 designation so this is not an issue).

In fact since python3 is so incompatible with python2 there should probably be separate python3, python2 cmake scripts also. My mingw installation has python2.exe as well as python.exe, the same file/ one can be a link.

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

Be sure at least that you use (WIN32 AND NOT (MINGW OR MSYS))
(0039213)
Paul "TBBle" Hampson (reporter)
2015-07-31 19:35

If python2.exe is in the path, that'll be preferred. The core issue is that it accepts any python.exe in the path, without validating that it's the requested version of the Python language.

Since right now you can't find both a python3 _and_ python2 interpreter (as they use the same variables and will cache whichever one is searched for first), the best solution would indeed appear to be to split the script into FindPython2Interp and FindPython3Interp, with FindPythonInterp maintaining the current behaviour.

This also addresses the issue that "FindPythonInterp" without a major version only makes sense if you're going to support whichever one is actually found, by checking the resulting version number. That seems unusual at best.
(0039254)
Paul "TBBle" Hampson (reporter)
2015-08-09 02:26

Looks like there's no module maintainer for Python (either Interp or Libs), according to http://www.cmake.org/Wiki/CMake:Module_Maintainers [^]
(0042811)
Kitware Robot (administrator)
2016-06-10 14:29

Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.

 Issue History
Date Modified Username Field Change
2015-07-23 14:07 Paul "TBBle" Hampson New Issue
2015-07-23 14:38 Rolf Eike Beer Note Added: 0039167
2015-07-23 17:14 Paul "TBBle" Hampson Note Added: 0039169
2015-07-30 15:54 Greg Jung Note Added: 0039207
2015-07-31 19:35 Paul "TBBle" Hampson Note Added: 0039213
2015-08-09 02:26 Paul "TBBle" Hampson Note Added: 0039254
2016-06-10 14:29 Kitware Robot Note Added: 0042811
2016-06-10 14:29 Kitware Robot Status new => resolved
2016-06-10 14:29 Kitware Robot Resolution open => moved
2016-06-10 14:29 Kitware Robot Assigned To => Kitware Robot
2016-06-10 14:31 Kitware Robot Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team