Pre-PEP: A Python Installation Manager for Windows

This is practically my most recent proposal (not in the PEP text yet), with the one difference that python.exe will run your selected default version at any time (or one selected by a script shebang), rather than continuing to run the one that was originally bundled. This is important so that when we release a new version of Python, users don’t have to update the installer just to change what the default python launches.

No, the compatibility break is for users who do things like running scripts to download the installer from the website and run it with particular options. Not users of the final installed Python.

If the VIRTUALENV environment variable is set then it runs that instead of searching for an install. Personally I never use py in a venv - I always just use python - so I’m not sure how well it works. But Paul lives by this feature, so it clearly has a place :slight_smile:

Because a good tool has a home for all its commands, and py is a shortcut to one of those commands. (Compare with uv run and uvx.)

We would churn again for something that big. I’m more concerned about having had to churn people in order to support running the installer as a service account, or churning people to put python3 on PATH. Stuff that’s very unique to an install on Windows, and hasn’t been possible under the old system.

The advantage is faster installs, fewer security vulnerabilities in the installer, more flexible installation options, access to more versions, better scriptability of (per-user) installs. The cost is churn to installation steps, loss of per-machine installs, and loss of automatic PATH updates (but with py, python and python3 no longer requiring them).

Or (plan B) I should have read the whole thing, rather than stopping when I found something that confirmed what I thought I knew :roll_eyes:

Thanks for being explicit. The ability to specify a default in py.ini is something I’ve used (and I think others have too) - but only to override the fact that pre-release versions are selected in preference to the latest full release version.

Removing explicit path support in shebangs makes me nervous, because I’m pretty sure some people use it. But the main use case I know of is in entry point wrappers, which use the distlib launcher code, not the py one. Your proposal to deprecate in the old launcher and removing in the new one seems like a fair compromise here.

Raising in python-dev and then simply noting the changed functionality in the new PEP seems like a reasonable approach.

Cool - if the PEP makes that point explicitly, I’m happy. I’m concerned with impressions (and people saying “they broke everything again”) rather than the technical details, which I think are fine.

OK. I think you’re going to find people continue to think of it as “the launcher”, though - especially given that Brett has his “launcher for Unix” promoting the idea that the launcher is a better UI than the raw interpreter. Dissention in the ranks? :slightly_smiling_face:

But thanks for your patience with all this. I’ve monopolised a lot of your time, but I think we’re converging on a good solution.

Brett has done exactly that with his “Launcher for Unix”. It’s a 3rd party project, not a core Python one, though[1].

You’ve mentioned this a few times. It’s not something I have any experience of, and I don’t actually even know what it means. What precisely is the problem that this solves? I’m assuming it’s something that comes up often enough in your experience to be an important improvement - is it unique to specialised Windows environments or “corporate” setups, as the broader open source community doesn’t seem to be hitting it?

One thought - adding the Scripts directory (where tools install their entry points) to PATH has always been manual. So having it still be manual is fine. But will the relevant path now be in some obscurely-named system managed directory? I can see that being a matter of concern to some users. Obviously, we tend to recommend pipx or uv tool for this sort of usage, but not everyone follows that.


  1. I think at least in part because Brett had no desire to write it in C, and adding Rust to the core Python build chain is too much of an ask ↩︎

Yeah, it’s for corporate setups mostly. Personally I don’t think anyone should be doing it, but they do, and it used to work with the old old installer (pre-3.5) and stopped with the current one. A few people have complained - some to the point of being told they aren’t welcome - but it’s certainly not something individuals are going to encounter on their own machines.

Unfortunately yes. Again, it’ll be possible to add it, but as it’s per-install and not per-user/machine, there’ll be separate paths for each Python version. That wasn’t my decision/design, it’s just the way packages are specified to be installed. If the package managers agreed to use a single shared directory for all Python installs (except venvs), I’d be looking for a way to configure that to be in the PyManager install directory rather than somewhere unmanaged[1], but otherwise it’d get users down to a single PATH entry.


  1. That is, uninstalling all your environments won’t know to clean it up. ↩︎

Okay, I’m losing track of what is being discussed so I will wait for the PEP to be updated and then read it again.

I see uv as different here because it provides the full set of commands that are needed:

  • uv python install 3.13
  • uv venv
  • uv pip install -r requirements.txt
  • uv run myscript.py

With that everything is possible based on a single executable on PATH. I assume that the analogous steps here are:

  • pymanager install 3.13
  • pymanager run -3.13 -m venv .venv
  • .venv\Scripts\activate.bat
  • pymanager run -m pip install -r requirements.txt
  • pymanager run myscript.py (uses VIRTUALENV)

The missing step is as Brendan says is that you need to choose an environment before the run command makes sense. Having used pyenv and uv for a a few years now it seems awkward that the venv command is run from within an environment.

If thinking about potentially extending pymanager in future then I wonder if it should check for .venv in the current working directory in the way that some other tools do. This is not a feature that could be added easily in future if it wasn’t part of pymanager from the outset.

1 Like

Potentially yes, though the recommended approach would be to use python and py and only go to pymanager when you need the lack of ambiguity (e.g. because you’re running on systems that might have an old launcher, or might have messed up PATH).

So the equivalent of your steps that I would recommend to people is as follows:

  • python -m venv .venv (might auto-install 3.13, or whatever is latest)
  • .venv\Scripts\activate
  • python -m pip install -r requirements.txt (uses python.exe from the venv, found on PATH)
  • python myscript.py

It’s only if you’re trying to manage your installs that you would go to the new commands. Today you’d do the same by opening Installed Apps/Programs and Features/Add and Remove Programs[1] or re-running the installer.

Look up PEP 582 - this idea was pretty well rejected (much to my disappointment). I agree it would be impossible to introduce later, which also means it’s impossible to introduce now with the high demand for compatibility with the old stuff.


  1. This has changed names too many times… In the world of installers, we usually call it ARP for Add and Remove Programs, the earliest recent title. ↩︎

OK. That sucks, but I can’t see an obvious way round it. I don’t personally care (I never install anything in my system Python) but from my experience on pip, I know some people will be affected, and will complain. What annoys me is that they will almost certainly put the blame on Python packaging, because end users don’t care about the distinction between core and packaging. I guess I’ll just have to blame the core devs[1]

That sounds like a good candidate for a packaging standard. Feel free to propose it :wink:

IMO, PEP 582 failed because it made no attempt to work with the existing ecosystem. Checking for an existing .venv is different, precisely because virtual environments, and the tools for managing the packages in them, already work.

I don’t want to re-open the debate on PEP 582, but I did try quite hard to get Kushal (who was the author promoting it at the time) to accept the need to integrate it better with the existing ecosystem. He chose not to, though, and IMO that’s what resulted in it not being a sufficiently compelling proposition to persuade the SC (or the community) to accept it.

All of which is off-topic, except to say that having pymanager check for a .venv in the current directory is not equivalent to PEP 582, and should be considered more in terms of the parallels with uv (which does this quite successfully) and other workflow tools instead.


  1. and hope no-one notices I’m a core dev as well as a pip maintainer :slightly_smiling_face: ↩︎

2 Likes

I remember the PEP but I don’t think that the rejection of that PEP applies to any new pymanager command. It is not impossible now to decide that pymanager handles this case differently without breaking any compatibility since it is a new command.

If the hope is that pymanager might eventually become a standard cross platform interface then you have to think about that interface now. It is impossible to just add pymanager now without making decisions that would limit us in future.

1 Like

I’m trying not to prevent the interface being usable cross-platform in future, but it’s not a goal right now to design it. New functionality can be turned on later by command line switch or configuration.

Perhaps, but checking for .venv is an unreasonably narrow feature, IMHO. Users retain all the complexity of a venv, but think they can ignore it enough of the time that they’ll be confused when they can’t. We’re better off without this functionality right now.

Their complaint will be “I did pip install foo and it told me which path has the scripts in it” :slight_smile:

Other environment management tools all have ways of doing this whether it is .venv, .python-version, pyproject.toml etc. The .venv convention is not just used by uv but also things like pyright, vscode, etc. Some tools that look for .venv are not themselves typical command line tools so they don’t expect that a virtual environment would have been activated by activate.bat.

I questioned above why pymanager run is needed if py already exists and will continue to be the standard way to run things for now anyway. The reason I question why the run command is needed is because I don’t think that the ideal semantics of run are obvious. Basing run off of the py interface overlooks the fact that py predates widespread use of venvs and would likely be designed differently today.

This has now been published to the PEPs category with significantly reworked text. Please continue the discussion over there.

1 Like