This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: Calling 'python' via ignoring passed %PATH%
Type: behavior Stage:
Components: Windows Versions: Python 2.7
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: eryksun, paul.moore, phbarnacle, steve.dower, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2015-08-05 09:07 by phbarnacle, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (3)
msg248023 - (view) Author: Gregor (phbarnacle) Date: 2015-08-05 09:07
I just noticed that there is a litte inconvenience when I try to invoke 'python' via passing an environment (%PATH%) from a script. I pass an environment where %PATH% only contains one directory where a python2.7.3-exe is present (I checked with "['where','python'],env=environment)" that python is found there). However when calling "['python'],env=environment)" python 2.7.9 is opened, which is the python version I called the script with. Seems inconvenient to me.

msg248029 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2015-08-05 10:51
This is standard Windows behaviour. Executables are always located first in the directory where your program (in this case the Python executable) is running from - even before searching PATH.

If you want to use a different Python, you should specify the full path  to the executable - "["C:\\Python34\\python.exe"])".
msg248030 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2015-08-05 11:54
Popen calls Windows [CreateProcess][1]. If the Popen "executable" argument isn't used or if the file from the command line doesn't include a directory path, then CreateProcess searches for it in the following directories:

    1. The directory from which the application loaded.
    2. The current directory for the parent process.
       * This step is skipped if the parent defines
    3. The 32-bit Windows system directory.
    4. The 16-bit Windows system directory. 
    5. The Windows directory. 
    6. The directories that are listed in the PATH 
       environment variable. 

Also note that the PATH searched is that of the *parent* process; the "env" parameter doesn't affect this. 

Call the SearchPath function if you need a custom search for the fully qualified path. 

    import ctypes
    from ctypes import wintypes

    kernel32 = ctypes.WinDLL('kernel32')

    kernel32.SearchPathW.argtypes = (
        wintypes.LPCWSTR,                   # _In_opt_  lpPath
        wintypes.LPCWSTR,                   # _In_      lpFileName
        wintypes.LPCWSTR,                   # _In_opt_  lpExtension
        wintypes.DWORD,                     # _In_      nBufferLength
        wintypes.LPWSTR,                    # _Out_     lpBuffer
        ctypes.POINTER(wintypes.LPWSTR))    # _Out_opt_ lpFilePart
    def search_path(filename, path=None, ext='.exe'):
        length, new_length = 0, 260
        while new_length > length:
            length = new_length
            filepath = (ctypes.c_wchar * length)()
            new_length = kernel32.SearchPathW(path, filename, ext,
                                              length, filepath, None)
        return filepath.value

For example:

    >>> search_path('python')
    u'C:\\Program Files\\Python27\\python.exe'
    >>> import os            
    >>> search_path('python', os.environ['PATH'])

    >>> search_path('', os.environ['PATH'])
    >>> search_path('more', ext='.com')            

Date User Action Args
2022-04-11 14:58:19adminsetgithub: 68981
2015-08-05 11:55:12eryksunsetnosy: + eryksun
messages: + msg248030
2015-08-05 10:52:00paul.mooresetstatus: open -> closed
resolution: not a bug
messages: + msg248029
2015-08-05 09:07:24phbarnaclecreate