No. It doesn’t change it:
Yes, my (admittedly minor) concern in this case was that someone might follow instructions that had them activate a venv, then later attempt to use python tool
for example and be confused as to why that no longer worked.
Oh, that’s a good point. Perhaps it should try and do that? My presumption was that creating a venv would use the direct link to the interpreter, so that your venv doesn’t change when you install another version, but that would mean it never gets a chance to process them.
Maybe we should add a global py
alias for the python.exe
launcher so that there’s an option to use in an activated venv?[1] Or it might be easier to make the venv redirectors aware of the subcommands and execute differently if they’re specified.
Noting that this doesn’t change the need for non-venv
python.exe
to have added functionality. ↩︎
I’m not sure how much flexibility there is with regard to the Windows store so I don’t know if you can have python.exe
and py.exe
with different behaviour? Is the issue that only one of these can be on PATH
by default or just that you don’t think people would use it if it’s not on python.exe
?
My guess is that if this functionality were instead added to py.exe
then people would have more of a reason to use it.
As it is right now it’s useful for selecting versions, but can’t install them itself - and the method for overriding its behaviour of picking prereleases by default requires creating an ini file or messing around with environment variables which isn’t a great interface.
The app can have multiple entry points (currently we have python3.13.exe
, pip3.13.exe
and idle3.13.exe
) or multiple aliases for the same executable (currently python.exe -> python3.13.exe
), so building more executables is possible. They do need to know that they are entry points though, so you generally can’t just drop a normal executable in there.
But yeah, the core problem is that people get this app by trying to run python
, and so they aren’t going to know that after running python
once they have to switch to another command, and we have no way to let them know (and arguably, they shouldn’t have to switch command, and running python
should do what they need).
The key thing for me is that if they run python
they should get python
(or at least, as close as possible to the standard interpreter). They shouldn’t learn extra commands that only exist for python
in some contexts.
My suggestion would then be to add some of the other commands to an improved py.exe
.
py install [version]
- manually download and install a particular versionpy list
- list installed versions- no arguments - equivalent to
py --list
--paths
- equivalent topy --list-paths
--json
- PEP-739 descriptions if that’s accepted?--max
--min
--compatible
- only list python versions satisfying constraints
- no arguments - equivalent to
py set-default
[1] - set the default python forpy.exe
(and windows storepython.exe
)--unset
- go back to automatically picking the latest python
py -[version]
launch that version, install if no matching version.py help
- improved help page,python help
could also potentially show this if the command would otherwise fail?
I think py tool
would also be nice to have, but I think that’s significantly broader in scope if you’re potentially replicating pipx
or uv tool
style tool management? These commands are limited to managing which python version is installed and how to access it (plus help).
Choose your own paint colour. Similar to only selecting one version in
pyenv global
for anyone familiar with pyenv. ↩︎
A reasonable suggestion, though there’s no intention to modify the “normal” py.exe
,[1] which means this would be a Store-only case again. And installing a normal py.exe
would override and break these extra commands.
Again, because people install/use it and require real compatibility. Opting into a Store install can vary here because it’s inherently a manual operation. ↩︎
Well part of the reasoning was:
py.exe
is generally a Windows only tool[1], so commands wouldn’t be expected to run on other platforms.py.exe
is not replaced when in a venv - it will detect and launch the venv python, but the executable itself is still the original .exe so the commands should still work- The commands you suggested (and I modified) are a superset of what
py
already does (listing and selecting python versions).- Were these commands included elsewhere
py
is redundant, but it’s using what would otherwise be a really good name for a command.
- Were these commands included elsewhere
You’re right on the compatibility issue (although I didn’t intend to remove the existing options or even suggest changing their output other than maybe a better default choice of Python version[2]). With regards to a normal py.exe
overriding it I don’t believe other distributions usually provide py.exe but you do at least have to deal with the Windows installer.
Short of changing the regular py.exe
[3] I can’t really see a way around this without either making the regular installer check if there’s a Windows Store version already installed and avoid breaking it, or having some mechanism in py.exe
that checks if someone has installed a store version and delegates its behaviour to that install.
If neither of those are acceptable, then yes this would need another name.
I know the Python launcher for Unix exists but to my understanding it’s unofficial and doesn’t come with any distribution of CPython. ↩︎
I have 3.14.0a2 installed to test that the annotations changes haven’t broken my libraries, it’s not supposed to be my default Python version! ↩︎
Caveat: personally I’d love to see
py.exe
replaced with something more useful. ↩︎
I’m not sure I understand some of the basic assumptions in this thread.
For the naive Windows users, why should they ever want a version other than the latest release?
So a user gets directed to a Windows store app which installs 3.13 + an installer tool. Updating that app eventually would update to 3.14 . (Is that the problem? Breakage at app upgrade time?)
Related question: what happens to the old Windows Store apps when versions go EOL?
I share the concerns about having two distinct CLIs with the same name, but I understand that we’re in the position of choosing a “least bad” option.
I’d expect the case would be that they want to run some script/tool/application written in Python that doesn’t yet support the latest release. Especially likely if the store Python updated immediately for new major releases. Replacing a 3.13 install directly with a 3.14 install would also probably break many existing virtual environments, if you keep the underlying installs then the venvs should still point to the correct versions of Python.
I also don’t think the Windows store Python is intended to be just for these users and is supposed to just be a general way to install Python. These users are more likely to want access to multiple versions.
I’m somewhat hopeful we can work towards a ‘good’ option!
Which is why I think it would be a good if the “app” that is downloaded is just the installer, updating the app only updates the installer itself, and it’s the installer that handles the updates to Python itself.
The same reasoning could be made for python.exe
. Why do you consider modifying python.exe
and not py.exe
, the latter being already specific to Windows ?
Would it be possible to add the py tool
command to the base py
, so that the behavior would always be the same ? It looks “easier” to do for py
rather than python
.
A significant constraint is that the vast majority of Store package installs come from people who have typed
python
orpython3
on a clean Windows machine. These are presumably users who know they want to run Python, but don’t know anything except that command.
I’m confused. If this is the target audience, I don’t quite see how the sub-commands will help. What makes them more useful/discoverable than installing specific versions from the store (and using python3.11.exe
) if you need a specific version?
What would be wrong if the global python
command would only:
- detect installed Python versions
- if none is found, install the latest one available from the Store
- run the latest stable detected Python, passing all the CLI arguments to it
The same reasoning could be made for
python.exe
. Why do you consider modifyingpython.exe
and notpy.exe
, the latter being already specific to Windows ?
Please find the rationale for this in the original post, and repeated 2-3 times already.
What makes them more useful/discoverable than installing specific versions from the store (and using
python3.11.exe
) if you need a specific version?
I’d like to stop creating new apps in the Store every year (see the search result screenshot in the original post).
My real preference would be for CPython releases to be compatible enough that we could silently upgrade users between them, but that’s a long way off
What would be wrong if the global
python
command would only:
- detect installed Python versions
- if none is found, install the latest one available from the Store
- run the latest stable detected Python, passing all the CLI arguments to it
Essentially being the launcher, yeah, as proposed (on the second point, we wouldn’t install from the Store, because that requires publishing to the Store, but we would download/extract binaries from somewhere we own).
This would still require management abilities, to be able to select/override a version, acquire a newer/older version, list versions, etc. Which becomes a new tool that is permanently unique to the Windows Store. People are mad enough about having to learn each new thing that I think this would be less popular than having subcommands. And equally, they would also expect/demand/request that it come to all platforms.
I’ll note that practically no other platform currently has a python
command. At most, there’s a symlink to python3
. So to some extent the name is unused, and it could be possible to bring more advanced functionality to other platforms under the same name (one of my long-term goals is to have commands between Windows and Linux be the same, so that projects can simplify their documentation).
Putting it under py
is possible, and Brett is no doubt fine with his non-Windows py
having equivalent commands[1]. But there are frankly more compatibility risks on Windows with changing/replacing py
than with changing only python
in the Store package. It also isn’t really a reserved name - anyone could make a py
tool (e.g. Brett has) - but we are the only ones who could make python
into a useful tool rather than a deprecated symlink.
Equivalent to whatever is decided, I mean. He’s previously stated a desire to have portable distros and a CLI installer on Linux. ↩︎
I’d expect the case would be that they want to run some script/tool/application written in Python that doesn’t yet support the latest release. Especially likely if the store Python updated immediately for new major releases. Replacing a 3.13 install directly with a 3.14 install would also probably break many existing virtual environments, if you keep the underlying installs then the venvs should still point to the correct versions of Python.
Yes, this is all accurate. The critical point is that while a user probably wants the latest on the day they install, they most likely want that same version tomorrow when they run their code again. In an automatic updates environment such as Windows, that can only be guaranteed by never releasing updates
I also don’t think the Windows store Python is intended to be just for these users and is supposed to just be a general way to install Python. These users are more likely to want access to multiple versions.
I mean, I’ve been using the Store Python exclusively for myself since 3.7 on all my own (Windows) machines. I’d definitely appreciate the ability to choose which version I get. (I also have visions of a python install 3.12 --target <dir> [--embeddable]
type command to create a standalone install in a specific directory, potentially as part of building a bigger overall app. But that’s just dreaming for now - once a different command is needed, you can do this already with nuget
, so there’s little value in inventing yet another command for something that can already be done and doesn’t have to be maintained)
I’ll note that practically no other platform currently has a
python
command
On most Linux distros you can install it from official repos, sometimes by the python
name. Some have it preinstalled. If not, sometimes you can even install it by typing python
, though that’ feature is somewhat controversial.
Per PEP 394, python
can be a symlink to python2
, python3
, or missing. In that sense, the name is taken.
(As an aside: if you use e.g. Docker to check what’s “in a distro”, be wary that you’re often getting a very slimmed-down version, not one built for ease of use.)
So to some extent the name is unused, and it could be possible to bring more advanced functionality to other platforms under the same name (one of my long-term goals is to have commands between Windows and Linux be the same, so that projects can simplify their documentation).
So, ideally the python
command in Linux would have run
/install
/list
subcommands too?
That could happen if they’re added to CPython itself, or if there’s a major, major change to the status quo.
Per PEP 394,
python
can be a symlink topython2
,python3
, or missing. In that sense, the name is taken.
It actually says “If the python
command is installed, it is expected to invoke either the same version of Python as the python3
command or as the python2
command.” So no requirement that it be a symlink, and no requirement that it doesn’t have additional functionality. But this is a semantic quibble - that’s our own informational PEP, and we can change it if we want
ideally the
python
command in Linux would haverun
/install
/list
subcommands too?
That could happen if they’re added to CPython itself, or if there’s a major, major change to the status quo.
That major change to the status quo would be if we started distributing our own standalone binaries for Linux, which is very much on the table (by other people, not me, though I’m encouraging it). At that point, we’re either instructing people to download and extract ZIP files, chmod
, and update profiles manually; or we’re providing a tool that can do it.
Now clearly uv
is going to get there first, with all those commands included, so the question is whether (a) anyone will care if we do it from core, and (b) whether we care to control our own distribution (which, historically, we have not, and so can’t really be too worried about e.g. uv
doing it).
But yes, I would argue that if we had a tool on Linux to manage our own standalone builds, it should have those commands (as well as defaulting to launching the latest installed version, and behaving like a proper venv, etc.). And I would suggest we reclaim the python
command to do, rather than inventing a new tool that isn’t clearly from core.
On most Linux distros you can install it from official repos, sometimes by the
python
name. Some have it preinstalled. If not, sometimes you can even install it by typingpython
, though that’ feature is somewhat controversial.
Per PEP 394,python
can be a symlink topython2
,python3
, or missing. In that sense, the name is taken.
Within a venv created by uv
, python
is also a symlink to whichever actual interpreter the venv is set up to use. In fact, in a uv
venv, python3
and python3.xx
are also in turn symlinks to python
.
Within a venv created by
uv
,python
is also a symlink to whichever actual interpreter the venv is set up to use. In fact, in auv
venv,python3
andpython3.xx
are also in turn symlinks topython
.
This is basically the same for venvs created by CPython’s stdlib venv
module too. For example, if I python3 -m venv foo
then foo/bin/python
and foo/bin/python3.13
are both relative symlinks to python3
which is then in turn an absolute symlink to the external python3
executable I invoked to create the venv. Or if I explicitly python3.14 -m venv bar
then bar/bin/python
and bar/bin/python3
are relative symlinks to python3.14
which is in turn an absolute symlink to my external python3.14
.
Thanks, I figured that was probably the case but didn’t want to overgeneralize without checking first.