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.

classification
Title: [Windows] installations should include pythonX.exe and pythonX.Y.exe executables
Type: enhancement Stage:
Components: Installation, Windows Versions: Python 3.10
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: ahiijny, edmorley, eryksun, loewis, paul.moore, steve.dower, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2014-05-14 11:36 by edmorley, last changed 2022-04-11 14:58 by admin.

Messages (14)
msg218521 - (view) Author: Ed Morley (edmorley) * Date: 2014-05-14 11:36
A python.org 2.7.6 release of the Windows MSI installer, results in only the following python binaries in the installation directory:
C:\Python27\python.exe
C:\Python27\pythonw.exe

In Mozilla bug https://bugzilla.mozilla.org/show_bug.cgi?id=957721 we would like to be able to force our 'mach' script to use Python2.7 (due to the assorted Python versions present on our CI machines), however doing so via the script shebang line breaks local developer workflows on Windows, since the default Python install doesn't include python2.7.exe and so the binary isn't found.

As such, it would be great if python.exe could be symlinked to pythonX.Y.exe (and also I guess pythonX.exe) as part of the Windows installation/build - giving us parity with Unix based platforms. 

This can be done on Windows using mklink (http://ss64.com/nt/mklink.html), eg:

c:\Python27>mklink python2.7.exe python.exe
symbolic link created for python2.7.exe <<===>> python.exe

c:\Python27>mklink python2.exe python.exe
symbolic link created for python2.exe <<===>> python.exe

c:\Python27>dir python*

10/11/2013  19:24            26,624 python.exe
14/05/2014  12:04    <SYMLINK>      python2.exe [python.exe]
14/05/2014  12:04    <SYMLINK>      python2.7.exe [python.exe]
10/11/2013  19:24            27,136 pythonw.exe

Alternatively, just a plain copy of the binary prior to creating the MSI would be just as helpful for us too.

I searched for a while to see if there were any bugs filed for this already, but the closest I could find was:
* http://legacy.python.org/dev/peps/pep-0397/ - which is about a smart launcher that uses the shebang lines to run the correct Python version when multiple are installed (and thus is quite a different request to that in this bug).
* and https://mail.python.org/pipermail/python-dev/2011-March/108850.html which suggests the idea as in this bug summary here, but it seems like a bug for it was never filed.

Many thanks :-)
msg218522 - (view) Author: Ed Morley (edmorley) * Date: 2014-05-14 11:38
Meant to add: the ActivePython release does this already - but it would be great if upstream did too.
msg218535 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2014-05-14 14:28
A similar thought I've had is to add a feature to the PEP397 launcher, allowing it to figure out Python version from a suffix on its executable name and add symlinks to it for each installed version of Python.  That way PATH wouldn't need to be modified to make every installed version accessible from a single optionless command.
msg218537 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2014-05-14 14:40
I don't deal with Python 2.7 anymore, so I have no opinion on this matter.
msg218549 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2014-05-14 15:32
As far as Python 2.7 is concerned, I will be avoiding making any changes to the installer at all.

For Python 3.5 I'm trying to work out a few of the install issues, one of them being not installing into Program Files. I think symlinks may be the way to make that change work, in which case it will be trivial to add two more. That said, I prefer the py.exe launcher anyway (especially since it handles 32/64-bit slightly better than this would), mostly since I intensely dislike permanently modifying PATH for anybody :)
msg218553 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2014-05-14 16:51
How about using hard links (mklink /H) instead? It's a minor issue, but there's a bug in Explorer that breaks opening symbolic links to EXE, COM, CMD, and BAT files (exefile, comfile, cmdfile, batfile). Explorer displays the error message "the specified path does not exist". These file types have shell\open\command set to "%1" %*, i.e. the file itself (%1) is used as the command. 

    C:\>reg query hkcr\exefile\shell\open\command /ve
    
    HKEY_CLASSES_ROOT\exefile\shell\open\command
        (Default)    REG_EXPAND_SZ    "%1" %*

I assume that's because these file types can be passed directly to CreateProcess. However, the Explorer bug isn't a problem with CreateProcess, or even ShellExecuteEx. Maybe it's due to an overly strict security policy. Anyway, my 2 cents is use hard links.
msg218554 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2014-05-14 16:59
> there's a bug in Explorer that breaks opening symbolic links to EXE, COM, CMD, and BAT files

Do you know which versions of Windows this applies to? It works fine for me (though I'm up to date), and the file associations have not changed.

I've seen some suggestions that creating a symlink without the right file extension (e.g. python2 <<===>> python.exe rather than python2.exe) will fail in some cases, but that's easily avoided by getting the symlink right.
msg218556 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2014-05-14 17:43
Here's a related superuser question: 

    http://superuser.com/q/304093

The message box shown in the older answer is what I get:

    http://i.stack.imgur.com/bqXBs.png

The problem is only with Explorer. I can execute a symbolic link to an EXE via cmd, subprocess.Popen, os.startfile (ShellExecute), and so on. Also, Explorer only does this for the executable file types that I mentioned. It has no problem opening symbolic links to .py files; the difference is the open command line for a Python.File includes a program to run:

    C:\>ftype Python.File
    Python.File="C:\Windows\py.exe" "%1" %*

It works if I change the shell\open\command for the exefile type to run via cmd /c. But that's just silly.
msg218565 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2014-05-14 18:46
Apparently there's a distinction between absolute and relative symlinks. Do you see a difference between:

> mklink python2.7.exe python.exe

and 

> mklink python2.7.exe C:\Python27\python.exe

?
msg218572 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2014-05-14 20:32
Using a relative target in the link isn't the problem for me here. (See issue 13702 for another problem with relative links.) I'm in the same boat as commenter weberc2. Same symptom; apparently a different problem.

I'm using an absolute path for the target:

C:\Program Files\Python\Scripts>mklink python2.7.exe "C:\Program Files\Python\Python27\python.exe"
symbolic link created for python2.7.exe <<===>> C:\Program Files\Python\Python27\python.exe

(Mirror the --user layout in %AppData%.)

This works fine from cmd, but not Explorer. Anyway, the link would be added to support shell scripts that use shebangs for environments such as MSYS, so executing with Explorer isn't the goal anyway. The shortcut in the start menu would target python.exe, not the symbolic/hard link.
msg251552 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2015-09-24 22:28
I've changed the version to 3.6 only as I just can't see this happening for any other.  For all I know this might have been sorted in 3.5, I'll leave that decision to our Windows gurus.
msg251559 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2015-09-25 00:52
Creating a symbolic link can't be relied on for a per-user installation. Administrators have to elevate to create symbolic links, and most regular users also lack this privilege.
msg251820 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-09-29 04:48
The file is so small that a second copy is just as cheap - literally everything is in the DLL. It could certainly be added to 3.6, and I'll probably get to it eventually, but right now I'm still focused on 3.5.
msg389043 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2021-03-18 22:07
One issues with versioned "X.Y" executables is interference with normal handling of the ".exe" extension. For example, in "python3.10" the ".10"  counts as an extension, so normally ".exe" won't be appended when searching for the name. 

This affects SearchPathW() searches that supply a default ".exe" extension, such as what CreateProcessW() uses to find the executable parsed from lpCommandLine. For example, subprocess.call('python3.9') won't append '.exe' to find "python3.9.exe" in the search path. 

It also affects the shell API's "App Paths" search, since the shell won't append ".exe" to a name that already has an extension. (The machine and user "App Paths" keys are the Windows shell equivalent of Unix "/usr/bin" and "$HOME/.local/bin", but more powerful.) For example, the store app distribution of Python 3.9 creates a "python3.9.exe" entry in the user's "App Paths", but os.startfile('python3.9') doesn't work; it has to be os.startfile('python3.9.exe').

Using "_" instead of "." would be compatible with Windows filename conventions -- e.g. "python3_10.exe". But this is an uphill battle against a Unix convention that's probably been in use since the 1970s or 1980s.
History
Date User Action Args
2022-04-11 14:58:03adminsetgithub: 65705
2021-03-18 22:07:25eryksunsettitle: Windows MSI installer should mklink (symlink) python.exe to python2.7.exe -> [Windows] installations should include pythonX.exe and pythonX.Y.exe executables
nosy: + paul.moore

messages: + msg389043

versions: + Python 3.10, - Python 3.6
components: - Build
2020-10-08 15:56:28ahiijnysetnosy: + ahiijny
2019-02-24 22:36:29BreamoreBoysetnosy: - BreamoreBoy
2015-09-29 04:48:48steve.dowersetmessages: + msg251820
2015-09-25 00:52:27eryksunsetmessages: + msg251559
2015-09-24 22:28:22BreamoreBoysetnosy: + BreamoreBoy

messages: + msg251552
versions: + Python 3.6, - Python 2.7, Python 3.4, Python 3.5
2014-05-14 20:32:52eryksunsetmessages: + msg218572
2014-05-14 18:46:30steve.dowersetmessages: + msg218565
2014-05-14 17:43:39eryksunsetmessages: + msg218556
2014-05-14 16:59:21steve.dowersetmessages: + msg218554
2014-05-14 16:51:45eryksunsetnosy: + eryksun
messages: + msg218553
2014-05-14 15:32:56steve.dowersetmessages: + msg218549
2014-05-14 14:40:50loewissetnosy: loewis, tim.golden, zach.ware, steve.dower, edmorley
messages: + msg218537
2014-05-14 14:28:38zach.waresetnosy: + tim.golden, zach.ware, steve.dower

messages: + msg218535
versions: + Python 3.4, Python 3.5
2014-05-14 11:38:02edmorleysetmessages: + msg218522
2014-05-14 11:36:10edmorleycreate