Python aliases under Windows?

eryk sun eryksun at
Tue Apr 3 15:04:22 EDT 2018

On Tue, Apr 3, 2018 at 3:43 PM, Ian Kelly <ian.g.kelly at> wrote:
> Because py.exe is really meant to solve a slightly different problem.
> On Unix if you have a .py script and you run it directly, without
> specifying which interpreter to use, the convention is to start the
> script with a shebang line, and the kernel will transparently use the
> interpreter specified there. Windows, however, doesn't respect shebang
> lines and instead associates programs with files by file extension.
> Here's the problem: Python 2 files have a .py extension. Python 3
> files also have a .py extension. Windows doesn't allow both Python
> binaries to be associated with the same extension. So how can we set
> things up so that launching a Python file will invoke the correct
> Python version? To solve this, Python ships with py.exe and associates
> *that* with the .py extension. py.exe knows what Python versions are
> installed, and it inspects the shebang line to decide which one to run
> for this particular script.
> The fact that py.exe can also intelligently select versions from
> command line arguments is just an added bonus.

Alternatively, there's the Windows Script Host (WSH) framework
(cscript.exe console, wscript.exe GUI), which supports a generic WSF
file extension that allows mixing multiple languages in a single
script, and integrates with COM, ASP, and native debuggers. PyWin32
supports WSH. This could have been adapted to support Python 3 as a
separate Windows scripting engine.

That said, for general use, the py launcher's registration+shebang
support is more flexible than the WSH registration-only approach. The
launcher supports virtual Unix shebangs for cross-platform scripts and
arbitrary executable paths for scripts that depend on virtual
environments. I use it for the .py[w] file association and creating
virtual environments. I still prefer `python` on the command line.
Even on Linux I don't frequently use `python3` or `python3.X`. I do
very little with the system Python.

If you really miss typing "python3.6", I suggest using relative
symbolic links (e.g. CMD's `mklink` command) created in the same
directory as python[w].exe. Using relative symlinks requires
installing Python on a NTFS volume that supports them, so it's not a
viable solution for external drives that use FAT32 or exFAT. In the
latter case, an alternative to batch scripts is to create a
"python[w]3.6.lnk" shell shortcut to "python[w].exe". Leave the "start
in" folder empty, so it will inherit the parent's working directory,
and add .LNK to the system PATHEXT environment variable. One caveat is
that, unlike symlinks or batch scripts, executing shell shortcuts
requires ShellExecute[Ex] (called from Explorer, CMD, PowerShell,
etc). CreateProcess (e.g. subprocess.Popen with shell=False) doesn't
know anything about .LNK files.

More information about the Python-list mailing list