PEP 773: A Python Installation Manager for Windows

The Steering Council has been discussing PEP 773 for several weeks now. To be completely transparent, we’re at a bit of an impasse because the members of the SC lack deep Windows knowledge and experience. Normally in cases like this, we would delegate the PEP to our resident Windows Expert, however as that’s @steve.dower, and Steve is the author of the PEP, that’s not an appropriate option. We have implicit trust in Steve’s understanding of the needs of Windows users and if he wasn’t the author, delegating to him would be the logical approach. In all likelihood, if the PEP was written by anybody else, we expect Steve acting as PEP Delegate would accept it.

The SC attempted to find another Windows expert who could serve as the PEP Delegate, but this revealed another latent problem: the core developer team currently has a dearth of active Windows experts, and as such, no obvious choice for delegate among the core developers has been identified. We should work to expand our bench of Windows experts, but that’s a discussion for another thread.

Our next thought was to delegate the decision to the release manager of Python 3.14, and/or the group of past release managers. We contacted them, and while we’ve gotten good feedback, no one has stepped up to explicitly volunteer to be the PEP Delegate. Of course this is fine, but it leaves the SC in an awkward position regarding the PEP.

As much as the SC’s experience and knowledge of the situation goes, we think PEP 773 is well-written and likely worthy of acceptance. In our review of this DPO thread, we haven’t identified any blockers or other reasons not to accept this PEP. Longer term, it might be worth asking the PSF User Success Working Group to conduct user studies to better understand the needs of Windows users of Python. However, this process would take some time, and with 3.14 reaching beta status in May, such a study couldn’t realistically be completed in time. While accepting the new Windows installer isn’t strictly tied to Python 3.14 or the beta feature freeze, our understanding is that the deprecation of the existing installers is tied to Python 3.14, so there’s a lot of value in accepting this PEP for 3.14. We’re also confident that any issues that may come up as Python 3.14 matures and more people in the wider community use the new installer, can be easily fixed using the normal Python life cycle and maintenance guarantees.

For all of these reasons, the Steering Council will take the following action.

We intend to accept PEP 773 on Friday, April 25, unless someone can give us good reason not to. As they say “speak now or forever hold your peace”, which you can do by following up here.

This date gives Steve a little more than a week to commit the PEP 773 changes before beta 1, although we do have approval from the Python 3.14 Release Manager @hugovk to allow these changes after beta 1. The SC’s thinking that since we intend to accept it, there’s no reason to wait longer.

Everyone on the SC is grateful to Steve for continuing to care so deeply about the experience of Python users on Windows.

19 Likes

While I’m pleased by the confidence shown in me by the Steering Council, and the nice words said about the PEP, I’m also disappointed at the lack of other contributions in this area (and very thankful for those who have contributed, either in earlier discussions here or on the issue tracker).

To be clear, I don’t want this to be accepted just because I wrote it - I want it to be in the best shape it can be. I thrive on design-by-debate (as regular participants here have no doubt noticed :slight_smile: ), and while I think I’ve been responsible with this proposal, I want it to be challenged. A considerable amount of that happened early on, for which I’m grateful.

If the oncoming deadline is spurring anyone into activity, here are some things you can look at to help us make sure this is a viable plan:

  • There is a near fully functional prototype you can install and try out. and updated documentation (an updated version of this page). It will let you try out the core user experience of installing the install manager, listing and launching runtimes, etc. It doesn’t currently have a live package feed on python.org, but has a static feed that’ll grab our packages from nuget.org.

  • However, I will note that everything in this prototype can be changed like normal feature development without impacting the PEP. So the feedback would have to be “this is fundamentally and irredeemably less usable than (current situation)” to force a change - bugs can be fixed and features can be changed.

  • The How to teach this section of the PEP is worth reading and reviewing.

  • The most controversial (in my opinion) remaining changes from the current state of things is that our installers won’t have a “for all users” option[1], the existing py.exe launcher is replaced by a new one with the install/etc. commands, the existing py.ini file is replaced with a set of JSON configuration files, and we’ll start putting a JSON-based index on python.org so the tool can find packages rather than listing them all individually on the Downloads page. I would love to hear opinions/pushback/support for these aspects (I think I can defend them all, but need to be challenged to be sure!)

  • Less controversial, I hope, is to deprecate the current .exe installer from 3.14 and stop producing them for 3.16 onwards, and to immediately stop releasing new Windows Store apps but point those users towards the manager instead. NuGet remains unchanged, and the embeddable distro will remain listed on the Downloads page until 3.16 and then will only be found using the install manager.

I do need to add a couple of minor updates to the PEP to resolve the open issues (which I was leaving for a PEP delegate), and my intent on those is to repackage our existing releases back to 3.10 (so all non-EOL versions) and include references for the NuGet packages further back (to 3.5), so that they can be installed on request, and to generate separate packages containing the core test suite and debug symbols so that users can opt-in to a test install if they want one (most users will get a much smaller runtime package).


  1. The install manager itself is always essentially for all users, but each user has their own Python runtimes. ↩︎

8 Likes

For what it’s worth, I will note that I have a reasonable amount of Windows expertise, and as the standing PEP-delegate for packaging issues, I have an understanding of the concerns around making a decision on a PEP. With that background, I can confirm that I support this PEP.

However, I will note that I have very little experience of setting up Python in a large organisation, as a Windows system admin. There are probably challenges in that sort of environment that I wouldn’t know how to evaluate. But in all honesty, I think there are likely very few people other than Steve who do have the necessary knowledge to evaluate that aspect of the PEP, and a “speak now or forever hold your peace” approach may be the best we can achieve there.

8 Likes

I know this doesn’t help with “design-by-debate” here, but my only issue with this is one that is so far out of reasonable scope, I feel like bringing it up wouldn’t be constructive, and it has more to do with how windows handles certain things than anything you’ve put together (which to be clear, knowing the design constraints, good job, no reasonable complaints here).

1 Like

It’s hardcoded within a script of a specific version of the Chocolatey package, but that hardcoded version is bumped automatically, and the new version of the package is pushed to the Chocolatey community repository automatically, so there are actually no manual steps there. This can be seen in the file’s history (which, by the way, does not actually contain all package versions since the way “streams” work means that, while multiple new packages can be generated by it, only one commit is made per CI run so a script from only one of those versions is actually commited to the repo; actual packages are hosted as GitHub releases and in the Chocolatey community repository, of course).

Just for full clarity (though I think the post linked above already came to this conclusion), Chocolatey packages are based on nuget specs but the Python package doesn’t use Python distribution distributed by Python release team on Nuget - it uses the regular installer.

FYI, I don’t know if any of this really matters, but I was searching for Chocolatey mentions in this thread and felt it was worth it to at least clarify some things.


Also related to Chocolatey, I came here after seeing Steve’s last post mentioning that there’s no longer going to be a way to install specific Python versions system-wide. I imagine that this means that versioned Chocolatey packages for Python 3.16 and above will not necessarily be able to be created, and that the base Python package will have to be superseded and/or turned into a PyManager package with the individual users having to run py exec/py install. There are probably some alternative options with maybe using the nuget package or something that would allow the choco package to extract and install the Python files in a system-wide location, but that seems to go against the goals of this PEP with the new PyManager. Did someone ask at chocolatey-community/chocolatey-packages repo or, perhaps, did any of their maintainers reach out about this PEP?
Hopefully, from Chocolatey’s standpoint it will just be about figuring out the best migration path (because the lack of system-wide installs for language runtime is not really new - rustup is doing fine, even if I may personally dislike user-specific installs), I just want to make sure they’re made aware sooner than when their automation breaks in 2 years :upside_down_face:


Personally, I like that PyManager brings an equivalent for what Chocolatey package is already doing - python3.x aliases[1][2]! I wish it were possible to auto-add it to PATH through some command. There not being a way to install software system-wide is odd, though not as odd for language runtimes, I guess :stuck_out_tongue: The PEP does not seem very specific about what will be possible to configure in admin-only configuration, but I do have a question about this part from the PEP (emphasis mine):

The intent is for the main admin-only configuration to be a path to a new base_config configuration file that an administrator can deploy to any controlled location. This allows a network administrator to control the source of their users’ default Python runtimes, without forcibly restricting them, or to override the other sources for configuration files (apart from the command line option).

The intent is heard, but will there be a way to forcibly restrict this? I’m not a sysadmin, which I guess means I don’t really have any reason to do that, but call me curious :).


  1. Chocolatey calls these shims ↩︎

  2. I think MS Store version has these too, but I don’t want to use the MS Store version ↩︎

1 Like

Welp, of course I found another thing to ask about after posting…
Will PyManager install pip, and will it add pip to PATH (when outside venv)? That is one thing that I do my best to remove when installing Python on any platform whenever I can - on Linux, that means not installing a package named python3-pip (or similar), and on Windows, that means using the Include_pip=0 / deselecting the checkbox in the UI installer. Worryingly, I see no mention of any configurability of the installation in pymanager install (which also means no way to not install IDLE and some other components, not that I personally care for that). This would mean that even if there’s no pip in PATH, python -m pip could still end up doing things when outside venv. I know there are other ways to prevent pip from doing things (i.e. PIP_REQUIRE_VENV env var), but I’d rather not have it at all.
As for adding to PATH, the PEP only mentions pip when describing other methods of installation but does not mention it for PyManager - I’d kind of expect that whichever decision was made would be mentioned in it - either it’s being added to PATH and it’s part of PyManager spec or it’s not being added and that’s a deviation from existing install methods (a welcome one from my POV :smile:). I see that an earlier post in this thread mentions that there’s no pipX.Y but I couldn’t find any mention of whether pip without version numbers would be added.

Or alternatively, if Chocolatey is able to install files wherever they want, they could use PyManager at their build time to get the package (or the URL, or the files) and do the install themselves. Then they can put it into a system-wide location if they want, and create their own shortcuts/etc.

There’s no requirement to use PyManager, but from our position upstream we can’t just give ZIP files with no registration process (even though subdistributors like Chocolatey would probably prefer it, so can now get it), and we equally can’t name a distributor as the “official” source and not provide anything. The installer gap has to be filled by something owned by python.org, but it doesn’t have to be used by anyone downstream if they want to set up Python differently for their users.

Yeah, it is technically possible, but we can’t automatically clean it up later so I’m hesitant. But offering another command option that can do it is probably okay.

Only by blocking PyManager entirely (probably by metadata and/or signing certificate) or access to python.org. The default behaviour can be overridden, but really don’t want to allow admin restriction over py install --source <my own URL/file> ..., even if they’ve overridden the default install source.

Yes and no. pip is preinstalled into Lib\site-packages for Python distributions on Windows, so it’ll be there, but the Scripts directories are not added to PATH unless the user does it themselves. It’s one directory for each install, whereas the pythonX.Y aliases are managed independently because we don’t want one directory on PATH per install.

There’s mention being added shortly, but only really to say that there’s no configuration left :wink: The main option will be between py install X.Y and py install PythonTest\X.Y, where the latter will grab a package that’s 2-3x larger but contains the test suite and debug symbols. Otherwise, there isn’t enough benefit to customisation to be worth the option - if you really want them gone, creating your own index with repackaged runtimes without them is the way. Otherwise just ignore them or delete them after installing.

This is fair, I’ll add it (the mention, that is - pip won’t be on PATH by default, but python -m pip and venvs will work).

1 Like

Like Paul, I don’t have experience setting up Python as a system administrator, but for what it’s worth, I’ve been using the pymanager preview builds as my primary Python(s) for a while now, replacing the old py command and my ‘legacy’ Python installations.

The only minor annoyance I’ve had is having a longer path to type for setting up virtual environments – I need to use uv venv venv --python $(py list 3.12 -1 --f=exe) rather than a ‘static’ C:\Program Files\ path. The benefits from the ease of use of installing multiple versions of Python can’t be overstated, with a simple py install replacing fiddling with multiple different full-fat installers. Thanks again to Steve for the PEP and for developing this work!

A

4 Likes

Minor: Is using a JSON file for portability/simplicity? A file formats that has support for comments might be slightly nicer, e.g. if used by administrators to record reasons for X setting. I haven’t given this deep thought, so e.g. TOML/YAML may have drawbacks that you’ve already considered and rejected.

A

6 Likes

Pretty much all of my comments are minor things/bugs in the current implementation (0.1a16). I think in general it’s a good idea and probably just needs a wider test pool of users to work out the rough edges. Hopefully having this in the betas will help that.


Things I ran into in brief testing this morning:

If you run pymanager or pymanager help it gives a bunch of instructions with the command py which, for people who already have the current py launcher installed won’t work as the old version will be launched instead. Would it be possible for pymanager to detect if its copy of py is shadowed on PATH and warn the user, also possibly listing the commands with pymanager instead of py where appropriate (because of course some people will skip over the warning, better to give them something that will work than something to complain about).

pymanager <some nonsense> also just gives the help page, should it also show an invalid command message?

The paths to executable in pymanager installs currently have an unnecessary \\.\\ segment in the pymanager list --format=json output for the executables which is a bit odd. Not sure if that’s caused by the nuget packages or something else.

pymanager list --help does gives the help info I wanted but is also an unexpected argument. pymanager list help gives a confusing ‘No runtimes’ empty list and no help message.

pymanager install --update failed when given no arguments when it should update 3.12.9 to 3.12.10 I made a github issue for this.


If you install a version of Python where you already have an installation registered in PythonCore in the registry, the new install doesn’t overwrite this registry entry (good) but this means that tools that look in the registry to find Python installs won’t find it (less good) and there’s no indication when you install the runtime that this has happened.

The new py will list both, but will only run the one it has installed and manages with py -V:PythonCore\3.13 even if the registry entry for PythonCore\3.13 points to the old version. It also indicates on py --list that -V:3.13 would be the ‘old’ install but also launches the new one.


I’ve actually ended up implementing the TUI I gave as an example in the previous threads and intend to add pymanager support once it has been accepted and I know the commands/output are stable. Currently it will discover the runtimes if they’re in the registry so to some degree it already works with them… unless they clash with installs from the old installer.

2 Likes

My personal view would be that as a community, we don’t lose much (if anything at all) by delegating dealing with such environments to the ActiveStates and Anacondas of the world (since those environments often want commercial software support agreements in place as part of formal risk management plans anyway).

We can support them when it isn’t too much hassle, but in a case like this, it makes a lot of sense for the community distribution to focus on the needs of hobbyist and smaller user organisations, and let the big institutional users manage their own requirements (if they do differ).

2 Likes

Definitely not an expert, but thought I would at least chime in as someone who uses Python very heavily and uses Windows as my primary OS

Would definitely be happy to see the PEP accepted and have been meaning to try out the demo for a while[1]

This would be my biggest benefit from this PEP. My team at $work has ~10 people with a pretty wide range of development experience (We are both developing software to do data analysis/presentation and are then the primary consumers of our own analyses to then support other teams in the company).

We use Docker containers/WSL for the reproducible local development environments when working on our actual projects, but we will also often do ad-hoc data analysis/scripting locally and we don’t have a good consistent setup process for getting Python installed for everyone on our team.

Debugging any install problems/upgrading to new Python versions has been a mess when trying to help less experienced team members. We are a small/niche enough team that we don’t get any “official” corporate IT help, and we don’t have a great onboarding/setup process, but we have enough people that it would be really beneficial to have an easy way to get everyone set up exactly the same way.

Managing Python installations is an infrequent enough task that we haven’t put a ton of effort into any sort of standardized process, but that hands-off approach has ended up causing problems every once in a while that then pulls on time from more experienced people to help figure out what’s gone wrong and get everything fixed.

Having just a single dedicated tool to install that will then manage all the rest of the process of installing different Python versions would save me a lot of time and headaches, and would be really easy to document and explain in our shared OneNote notebook.

The sales pitch of “This is an official tool, specified in a PEP, and it is provided by Python.org” also makes a huge difference on a social level


  1. It definitely can’t already be mid-April, it feels like January was just a few days ago ↩︎

3 Likes

TOML would be a really nice choice (which PEP 518 explains far better than I could) over JSON or YAML, but JSON definitely isn’t a deal breaker if there’s some other reason that was chosen

I personally care about Chocolatey just because it’s the only way I’ve found to set up GitLab CI on Windows for my personal projects. I have no particular allegiance to this, so if there’s a better way, I’m all ears. But I’d be very bummed if some kind of similar approach were no longer possible.

1 Like

At the very least, a separate PyManager package can be created in the community repository (I’ll probably create that one personally once the PEP is accepted / repo is migrated to python org, and then later see if the migration to the chocolatey-community/chocolatey-packages is something they’d want to do), making the following possible:

choco install pymanager
py install 3.13
py install 3.12
py install 3.11
py install 3.10
py install 3.9
# then proceed with using py -3.x

The existing python package and potential new python316 will have to be updated in some way before 3.16, but there’s more than one way to approach that, so I’ll probably create a discussion on the chocolatey-community/chocolatey-packages repo.

Outside of Chocolatey, NuGet may be an alternative (the below is based on docs, I haven’t tried it):

nuget.exe install python -ExcludeVersion -Version 3.13.3 -OutputDirectory C:\Python313
nuget.exe install python -ExcludeVersion -Version 3.12.10 -OutputDirectory C:\Python312
# etc.

# usage:
C:\Python313\python\tools\python.exe ...
C:\Python312\python\tools\python.exe ...

Sadly, it’s not ideal due to a lack of support from NuGet to ask for e.g. latest 3.12.*. Also, there’s no py launcher here (not that it necessarily matters, if you know the exact paths to use).


@steve.dower I do have a question about how PyManager will be distributed - will python.org have some sort of API like it has for Python releases (https://www.python.org/api/v2/downloads/release_file/)? As far as I know, the PyManager releases are not going to be directly connected with Python releases, so the existing APIs might not expose this in any way. Scraping is certainly not unheard of in the Chocolatey world, but having APIs is nice.
Also / alternatively, do you think that GH Releases will be used for the foreseeable future, or are they only used while the GH repository is under your personal account (presumably due to not wanting to distribute on python.org before the PEP is accepted)?

1 Like

I bet you can use nuget, see upthread: PEP 773: A Python Installation Manager for Windows - #33 by ngoldbaum

1 Like

It’s definitely possible using PowerShell, it’s just that the command is annoyingly complicated compared to a simple choco install .... We’re using this for free-threaded Python installs:

A hypothetical choco install pymanager would be welcome indeed.

1 Like

You mean for the install manager itself? I’m not entirely sure, we do need to sort out how it will be listed on the download page, and that may naturally integrate into those APIs (which are part of the web site and not part of the distribution, hence PyManage won’t use them itself).

When installed from the MSIX, PyManager will have its own automatic updates, which involves there being an appinstaller file somewhere on python.org that references the latest release. That may be sufficient for someone who wants an API? But since Windows already uses the API for updates, it’s only really a benefit for the initial install, and for that you don’t actually need the MSIX - you can point the OS at the appinstaller file itself and it’ll get the right one.

I have a number of scripts that I use (at $work) for installing the latest build from our internal NuGet feeds, and yeah, it’s definitely not ideal.

JSON has more reliable string quoting and escaping rules than TOML, which matters a lot when dealing with paths on Windows. I do wish Python’s parser would allow comments in JSON, and if someone were to add it then PyManager would also support it, but as far as tradeoffs go it seemed like the right one. There’s nothing preventing a switch to TOML configuration files (support both formats) in the future, but I expect custom configurations to be fairly rare here, there aren’t that many knobs.

A nuget install python-freethreaded -Version 3.13.1 -o <dir> would likely be simpler (that package also includes a python.exe that runs the free-threaded version, in contravention of one of the free-threaded PEPs, but it seemed like the right thing to give users a consistent interface after they’ve specifically selected that build).

The equivalent under the install manager will be py install 3.13.1t; py -V:3.13t ...

1 Like

I see. Does it make the py executable available on PATH?

That would obviously be a nice improvement :slight_smile:

No, NuGet is specifically for unregistered installs, so after it extracts it you need to go into <dir>\python-freethreaded.3.13.1\tools\python.exe directly. It doesn’t modify PATH, registry, etc. at all.