fix(python): force-reinstall bundled pip wheel to create Scripts/*.exe#271
Merged
Conversation
The Windows install of Python 3.14.2 (and other python-build-standalone releases) produced no pip.exe, pip3.exe, or pip3.X.exe even though "Configuring pip..." reported success. ensurepip --upgrade exited 0 and printed "Requirement already satisfied: pip" — but did not create any of the console scripts users expect. Root cause: python-build-standalone Windows tarballs ship pip's module tree already present in Lib/site-packages/pip-25.3.dist-info/ with the bundled wheel sitting at Lib/ensurepip/_bundled/pip-25.3-py3-none-any.whl. ensurepip --upgrade internally runs `pip install --upgrade --no-index --find-links <tmpdir>` against that bundled wheel. Because the wheel version matches the version already installed, pip short-circuits with "Requirement already satisfied" and skips the install — including skipping the .exe entry-point script generation. ensurepip exposes no --force flag, so the only way to materialize the scripts is to bypass ensurepip and call pip directly with --force-reinstall. This change adds a materializePipScripts step that runs after ensurepip: glob Lib/ensurepip/_bundled/pip-*.whl, then invoke python -m pip install --no-index --no-deps --force-reinstall <wheel> against it. --no-index keeps it offline (uses the wheel shipped with the distribution, no PyPI access). --no-deps avoids surprise upgrades. --force-reinstall is the part that defeats the "already satisfied" short-circuit and creates Scripts/pip.exe / pip3.exe / pip3.X.exe. ensurepip is kept as the first step because it still handles the case where pip isn't already in site-packages (e.g., python.org embeddable distributions). The force-reinstall is best-effort: minimal distributions may strip ensurepip's _bundled/ directory, and in that case we fall through with whatever ensurepip produced. Resolves #269
dab2ce1 to
b82f3cb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pip.exe,pip3.exe, orpip3.X.exeeven though our install spinner reported "pip configured successfully." Users hit asecondary executable not found: piperror from the shim at first invocation. This PR is the root-cause fix for #269; #270 is a complementary defense-in-depth fix that prevents install from creating phantom shims for executables that don't exist.Why ensurepip silently did nothing
python-build-standalone Windows tarballs ship pip's module tree already present in
Lib/site-packages/pip-25.3.dist-info/, with the bundled wheel atLib/ensurepip/_bundled/pip-25.3-py3-none-any.whl. Internally,ensurepip --upgraderuns:against that bundled wheel. Because the wheel version (25.3) matches the version already in site-packages, pip short-circuits with
Requirement already satisfied: pipand skips the install entirely — including skipping the.exeentry-point script generation. ensurepip exposes no--forceflag.Reproduced locally against the same tarball Brad installed from:
What this PR does
Add a
materializePipScriptsstep that runs after ensurepip. It globsLib/ensurepip/_bundled/pip-*.whland invokes:--no-indexkeeps it offline — uses the wheel that already shipped with the distribution, no PyPI access--no-depsavoids surprise upgrades to transitive packages--force-reinstalldefeats the "already satisfied" short-circuit, which is the entire point — this is what createsScripts/pip.exe/pip3.exe/pip3.X.exeVerified against the actual python-build-standalone tarball:
ensurepip is kept as the first step because it still handles the case where pip isn't already in site-packages (e.g., python.org embeddable distributions). The force-reinstall is best-effort: minimal distributions may strip ensurepip's
_bundled/directory, and in that case we fall through with whatever ensurepip produced.Test plan
./rnr check— gofmt clean, golangci-lint 0 issues, full test suite passes on WindowsTestFindBundledPipWheelcovers the glob helper: finds wheel when present, errors when bundled dir is empty / missing, ignores non-pip wheels (e.g., the historical setuptools wheel pre-3.12)https://builds.dtvem.io/python/3.14.2/windows-amd64.tar.gz: confirmedensurepipalone leavesScripts/empty; force-reinstall step createspip.exe,pip3.exe, andpip3.14.exeRelationship to #270