fix(setup): resolve pip and python from PATH before installing - #781
Open
ffantl-ld wants to merge 10 commits into
Open
fix(setup): resolve pip and python from PATH before installing#781ffantl-ld wants to merge 10 commits into
ffantl-ld wants to merge 10 commits into
Conversation
3 tasks
cspath1
approved these changes
Aug 18, 2026
ffantl-ld
force-pushed
the
fix/setup-resolve-python-pip
branch
from
August 19, 2026 14:12
3ceb77b to
2ed8a45
Compare
ffantl-ld
force-pushed
the
fix/setup-resolve-python-pip
branch
from
August 19, 2026 16:08
7798f33 to
1797852
Compare
Recent macOS and Homebrew installs ship python3/pip3 with no bare python or pip, so the hardcoded `pip install` failed outright on a common developer box. Probe pip3 then pip, falling back to `<interpreter> -m pip` for interpreters installed without a pip shim. Every package manager is now checked for existence before being run, so a missing tool reports what to install instead of an exec "not found" error. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Debian and Ubuntu package pip separately from the interpreter, so a present python3 does not mean `python3 -m pip` can run. The pre-flight check only looked at the executable, so those boxes got "No module named pip" instead of guidance. Stub PATH in the two install tests that reached for a real npm, which the pre-flight check made environment-dependent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Using `python3 -m pip`, or bootstrapping pip with ensurepip, would install tooling onto the user's machine. Setup only ever uses a pip that is already there; when none is found it warns and runs nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
pip refuses to write into an OS-managed Python, which Homebrew and most current distributions now mark, so a project with no active virtualenv could not complete setup at all. A virtualenv's pip is used when the project or the environment has one, and the refusal is explained rather than passed through as pip's raw error. InstallArgs takes the project directory so the previewed command is the one that actually runs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
pipInstallCmd prefers VIRTUAL_ENV over anything on PATH, so running the suite inside an activated environment resolved install commands to that environment's pip and failed assertions about pip and pip3. Tests that want an active virtualenv opt in with stubVirtualEnv. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The install runs with its working directory set to the project, and a relative executable path is resolved after that change, so a relative project directory was applied twice: "app/.venv/bin/pip" run in "app" was looked for at "app/app/.venv/bin/pip" and the install failed even though the venv was found. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ffantl-ld
force-pushed
the
fix/setup-resolve-python-pip
branch
from
August 19, 2026 16:52
1797852 to
046e70c
Compare
`uv venv` creates a virtualenv without pip, which was read as no virtualenv at all: setup then reached for a pip on PATH, installing outside the project the user set up — or being refused by PEP 668 and advising them to create the virtualenv already sitting there. That case is now named, with how to install into it. A PEP 668 refusal no longer carries the command that refused. The done screen offers a non-empty command as "install it yourself with", which contradicted the reason telling them not to run it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The pip-less virtualenv guard sat only in Install, so the plan screen, --dry-run and the picker still previewed a pip from PATH that Install would refuse to run — and a command shown there is one a reader may run by hand, installing outside the project or hitting a raw PEP 668 error. The command now names the virtualenv's own pip whenever the project has one, present or not, so every surface and the runner agree. Install still explains why an unseeded virtualenv cannot be installed into. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ed dependency A virtualenv with no pip was always named bin/pip, so on Windows the plan and the previewed command pointed at a layout that environment never uses. The platform's own layout is named first, and both are still considered. A bare pip install also leaves the project's manifest untouched, so a fresh checkout and CI miss the SDK. poetry, uv and pipenv record it themselves and Ruby has `bundle add`; pip has no equivalent, and editing someone's manifest unasked is not something setup does, so a successful install now says what is still missing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e4f6310. Configure here.
A substring match read a related pin such as launchdarkly-server-sdk-otel as the SDK itself, so the warning stayed quiet while the project still lacked the dependency. The whole-name matcher the install-skipping check already uses does the job. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

Requirements
Related issues
REL-15432 — found in the
ldcli setupbug bash. Targetssetup-ld(#776), whereinternal/setup/installer.golives.Describe the solution you've provided
pip3andpipis on PATH instead of hardcodingpip. Recent macOS and Homebrew installs shippip3with no barepip, so the install failed outright on a common developer box.pip3is preferred so a stale Python 2pipis never selected.exec: "pip": executable file not found in $PATH.python3 -m pip, and will not bootstrap pip withensurepip. Only a pip that is already present is used; when none is found, setup warns and runs nothing.VIRTUAL_ENV, else.venv/bin/pip, elsevenv/bin/pip— in preference to any pip on PATH. Dependencies belong there, and on a PEP 668 interpreter it is the only place pip can write at all.externally-managed-environmentrefusal and explain it: name the project, give the two commands that create and activate a venv, and note that setup will use.venvautomatically once it exists. Previously this surfaced as pip's raw error with no next step.InstallArgstakes the project directory, so the command previewed on the plan screen is the one that actually runs, virtualenv pip included.Describe alternatives you've considered
python3 -m pipwhen no pip shim exists. Rejected: on Debian and Ubuntu the pip module is packaged separately, so this either fails anyway or amounts to installing tooling on the user's machine.python3 -m ensurepip --upgrade. Rejected for the same reason — modifying the user's Python installation is out of scope for a flag-setup wizard.--break-system-packagesto force the install through. Rejected outright: that is pip's own escape hatch for overwriting an OS-managed Python, and it can break tools the system shipped with..venvon the user's behalf when none exists. Rejected: the wizard would be inventing project structure. It uses a venv that exists and otherwise explains how to make one.Additional context
A project with no virtualenv at all on a PEP 668 interpreter still cannot install — that is the point of PEP 668, and forcing past it is not something setup should do. It now fails with instructions instead of pip's raw refusal. Poetry, uv, and pipenv projects were never affected, since those tools manage their own environment.
Also out of scope: known issue #3 from the bug bash —
pip installdoes not record the SDK inrequirements.txt, unlike poetry/uv/pipenv/bundler.Testing approaches
go test ./...passes.pip3, onlypip, both (pip3 wins), interpreters present but no pip (bare form kept, nothing run), nothing available.Installcoverage: a missing tool returnsFailedwith guidance and never calls the runner; a present tool runs the expected argv.npm, which the new pre-flight check made environment-dependent..venvbeats a systempip3; avenvdirectory works too; an activeVIRTUAL_ENVbeats a project one; an empty directory argument does not search relatively.Failedresult rather than an error, names the project directory and the venv commands, and never mentions--break-system-packages. Unrelated install failures keep their existing error path.EXTERNALLY-MANAGEDmarker: in a project with.venv, install resolves.venv/bin/pipand reports"success": true. In arequirements.txtproject with no venv, it reports the refusal with the venv instructions. With PATH reduced topython3only, it warns that pip is missing and runs nothing.Note
Overview
Makes
ldcli setupinstall Python SDKs into a real environment instead of hardcodingpip, which failed on common macOS/Homebrew boxes.InstallArgsnow takes the project directory. It prefersVIRTUAL_ENV, then.venv/venvpip (absolute path, platform layout), thenpip3overpipon PATH. Setup never bootstraps pip. Missing tools, pip-lessuv venvs, and PEP 668externally-managed-environmentrefusals return aFailedresult with next steps instead of a raw exec error. Successful bare pip installs warn whenrequirements.txtwas not updated.The wizard plan preview, dry-run, and done screen use the same resolved command and surface
Warning.Reviewed by Cursor Bugbot for commit c9f1d48. Bugbot is set up for automated code reviews on this repo. Configure here.