PEP 773: A Python Installation Manager for Windows

Basically I think that py install (rather than pymanager install) is an odd design choice that does not particularly help anyone and will be confusing. It blurs the usually clear distinction between a CLI that has subcommands and a CLI that does not. The normal usage of py has a positional first argument that is the script to run and install is a valid name for that script but you propose that it be special cased to run a subcommand instead. It also means that in transition there will be a period of time where the py install command is unpredictable for users.

I don’t see why this proposal needs to say anything about py when the actual proposal is to add pymanager which can easily have the install and run subcommands. My point about cross-platform reunification is that I would be much more inclined to mess around with the “recommended” commands on Windows if it was being done in a way that would reduce platform inconsistencies.

As it stands this proposal looks like introducing interfaces that I am possibly just not going to teach anyone to use. Note that in my students in a classroom situation very few are using Linux and I am happy to tell the ones who are to go figure it out themselves. Just having a consistent story across MacOS and Windows would be a big improvement though. If it is something that works on common Linux platforms such that I would use it myself then that is better because it means that I am also a user of the thing that I recommend.

The exact command for installing things and the exact command for running Python are different things. When I talk about reunification it is the “running Python” part that I am much more concerned about than the installing things part. That’s why I don’t like doing weird things with the py interface, especially if it is going to be the recommended interface for Windows users to run Python. It means we are getting further from the possibility that the “standard command to run Python” could be a thing again by pushing Windows users further towards CLIs that would never be replicated on other platforms.

2 Likes

Would it make more sense to have py --install ...?

It’s already recommended to use py -m pip install ... on Windows, although that’s for packages.

I guess it’s worth noting that the py launcher is defined in a PEP, so if you’d like to know more about why it was added and why it’s recommended, it’s in there and the original discussion (which will require some email archaeology, but it should all be archived).

Yes, where “juggle” includes “add, view and remove” :wink:

Probably also worth noting that my PEP repeats the recommendation of PEP 394 that python be the default command, and once a user adds the additional commands directory to PATH they will have all the python3.12 commands (though not the pip3.12 commands without adding a further directory - this is a packaging standardisation issue that I do not want to tackle right now. The issue exists today and will exist tomorrow).

py is the recommended command for installing, listing, removing, and launching a specific runtime. If you just want “the default”, then python is still the command you want, and that’s what the PEP says.

Not really. It’s very uncommon for Windows apps and breaks the subcommand concept entirely (and as we see, people are already upset about it being slightly broken by having an implied default subcommand :wink: ). Commands like signtool sign/signtool verify have been around for many years, so I believe subcommands are the way to go.

Only by changing the existing ones (which I propose to do, but only to add helpful error messages when you try to run the subcommands that aren’t there). Because of how we have historically installed them as the highest priority, there’s no way to be even higher.

(Side note, when we first moved from the old 3.4 installer to the new one in 3.5, we had to make poor design decisions in order to “upgrade” the launcher from earlier versions. This is why the per-user install would still do an all users install of the launcher, and why it would simply stomp all over a 3.4 launcher while safely updating newer versions. I’m sure people noticed that installing 3.4 after 3.5 would downgrade the launcher, but we got away with it :man_shrugging: )

1 Like

That can’t happen until there are pre-built binaries that can just be installed via a zip file like with Windows. Some of us have started talking with the python-build-standalone folks to try and get some of their changes upstreamed with hopes/dreams of solving this for macOS and Linux. And once that happens I’m hoping to implement the appropriate command for the Python Launcher for Unix.

5 Likes

I updated the demo build with a handful of fixes. I’m including the MSI this time as well, mainly for those who want to try it out on Wine or for compatibility with Cygwin.

MSIX: https://cpythonpackages.blob.core.windows.net/pkg/python-manager-0.1a5.msix
MSI: https://cpythonpackages.blob.core.windows.net/pkg/python-manager-0.1a5.msi

I’m also adding an extra paragraph to the PEP abstract, which you can see in the PR linked from the original post, but I’ve copied it here for convenience:

With the new installer, the recommended command to launch the default Python on Windows will be python, while the command for managing multiple versions (including launching a specific one) will be py. Users can also opt-in to having global python3.x commands by adding an extra entry to their PATH environment variable. We recommend starting with the “How to teach this” section for the most concise high-level overview of the features.

1 Like

I have several questions after reading the PEP:

  • Will it possible to install old versions such as 3.9 and 3.10 using py install ...?
  • What about the free-threaded interpreter? With current installers, one needs to enable a specific option for it to be installed. If I run py install 3.13, can I then use py -3.13t ...?
  • If python.exe does not point directly to a Python executable, does it have consequences for other programs launching Python in a subprocess? Are there subtle issues to know about?
2 Likes

Probably similar subtle consequences as when using py.exe (Example).

1 Like

Since it’s been brought up twice now, I will note that the pip developers do not recommend using the pipX.Y commands[1]. Our recommendation is pythonX.Y -m pip.


  1. in fact, we have seriously considered removing them ↩︎

2 Likes

I’ve used py like this since it appeared and witn its shebang processing its wonderful. Scripts can define which version they need to run and I can forget about it.

1 Like

Yes, either from NuGet if we’re lazy (doesn’t include Idle and Tkinter) or from newly packaged packages if we’re not. This is already answered in the PEP.

Yes. This might not be spelled out in the PEP (I don’t see the need to link in every experimental feature/platform, it does mention the embeddable distro though), but it’s possible today from the NuGet packages and we would presumably create new packages for experimental releases that would’ve been bundled into the traditional installer.

The main subtle issue is that the process handle returned from creating the process doesn’t match the process actually running your Python script. This is already the case for venv and py, and mainly only causes problems when you are trying to explicitly duplicate other handles into the process or activate native debugging. Normal tasks such as waiting for it to exit are not affected.[1]

If we ever get finalization fixed, it may be possible for the global python.exe to load standard CPython distros directly (we need to unload our embedded one before doing this), but in general a new subprocess is required. The global aliases (python3.13.exe, etc.) already load the DLL directly into its process whenever there is a python3.dll with a Py_Main available, since these don’t rely on the embedded runtime to find an install.


  1. The workaround is to use your established form of IPC (neither case works if you don’t have one) and have your script send its handle back to the parent. Or use named kernel objects or enable handle inheritance rather than sharing handles directly. ↩︎

Yeah, I think we’re mainly just using pipX.Y as a stand in for any script entry point installed by a package rather than being part of the runtime. We can switch to blackX.Y instead. (And FTR, I think everyone should prefer -m, but that’s not the world we live in and I’m trying to be accommodating rather than overruling.)

1 Like

This is on old windows10 with cmd.exe where you need to enable ANSI escape handling. In windows 11 and terminal this is no longer needed.

I use this code in my projects.

            import ctypes
            kernel32 = ctypes.windll.kernel32
            # turn on the console ANSI colour handling
            kernel32.SetConsoleMode( kernel32.GetStdHandle( -11 ), 7 )
1 Like

The decision to phase out other distribution formats is a bit puzzling to me. I get the idea of a new system for new users, but why intentionally break existing scripts and workflows?

The python setup .exe is named such that new users assume it is python and not an installer. Users run it over and over again and have no idea why the repair dialog appears. Leaving that .exe in place would continue to confuse new users.

Also, maintaining both installers is a significant amount of extra work. Not only for the Windows RM, in building the distribution packages, but also in support, helping users with unusual setups, or who simply made some sort of mistake, work out why their install failed and how to fix things.

1 Like

The remaining feedback seems to be of the sort that can only be resolved by a final decision, rather than more discussion (bearing in mind that this only begins implementation, and we develop, maintain and improve the manager over time).

So I’m proposing to submit the PEP to the steering council tomorrow, most likely to have a PEP delegate assigned and continue the discussion with a view to resolving the open issues.

If you feel your issue isn’t covered fairly by the PEP text (particularly the Rejected Ideas and Open Issues sections), please say something as soon as you can so that I can make updates. While I obviously don’t agree with the items under Rejected Ideas, I do want to make sure that they reflect actual ideas and not straw men, so if the SC chooses to nominate one of them as a thing we should do, it’ll be the actual thing.

3 Likes

Our intent is to immediately stop publishing individual versions to the Windows Store, and to deprecate and phase out the traditional installer by Python 3.16.

Will this impact uv python install ... on Windows? I’m not familiar with the internals of how uv works, such as if it uses it’s own python-build-standalone builds for Windows or relies on the traditional installer some how.

As a user of Python, it would be really great if we could unify the official CPython binaries such that this new Python manager, uv, Python.org downloads, etc could all pull from a single trusted source, which hosts optimized builds for each platform.

1 Like

If they want to use the same binaries, they can. I’m pretty sure they are building from source, which means they’ll be entirely unaffected unless they choose to take advantage of it.

Regarding Old py.exe launcher installed and Generate packages for old versions: Suppose we didn’t repackage old versions as MSIXs, someone started from a clean slate, installed the latest Python, got the new py, then later installed an old traditional installer, would that old installer install the old py in a way that shadows the new one, breaking their setup?