Skip to content

Fix Pipenv project falling back to system Python (#504, #947) - #950

Open
Mikola Lysenko (mikolalysenko) wants to merge 4 commits into
mainfrom
agent/fix-pipenv-global-fallback
Open

Mikola Lysenko (mikolalysenko) wants to merge 4 commits into
mainfrom
agent/fix-pipenv-global-fallback

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #504
Fixes #947

Summary

A Pipenv project with no Pipenv venv yet no longer has the OS Python's site-packages crawled as if they belonged to the project. This covers a fresh checkout before pipenv install, and a project that only has a plain venv/ or an opted-out .venv:

Root cause

PythonCrawler::get_site_packages_paths falls back to get_global_python_site_packages() whenever find_local_venv_site_packages returns nothing and is_python_project(cwd) holds. For a Pipenv project, the Pipenv branch returns only the venv Pipenv itself resolves (#388), so an empty result there is final: Pipenv has no venv yet and nothing is installed for the project. The caller couldn't tell that apart from "nothing probed", so it fell through to the global interpreters.

Fix

get_site_packages_paths now returns nothing for a Pipenv project once Pipenv's own venv lookup came back empty (crates/socket-patch-core/src/crawlers/python_crawler.rs). It is a single boundary: agent, hosted and vendored modes, rollback and the dispatch locator all crawl through it. Lock-only packages still join discovery from Pipfile.lock through the lockfile supplement, which the #947 test asserts. -g / --global-prefix are unchanged. No wrapper changes are needed under npm/, pypi/ or gem/, because they only dispatch to the binary.

Whether a plain ./venv should be patched again for a Pipfile project is still the maintainer decision raised in #504. This PR keeps the #388 rule (Pipenv never uses venv/), and the venv/ cell now patches nothing instead of the system Python.

Test changed on purpose: get_site_packages_paths_falls_back_via_pipfile_marker pinned the defect: it asserted that a Pipfile marker triggers the global fallback. It is replaced by get_site_packages_paths_pipenv_without_venv_never_falls_back_to_global, which asserts the opposite. Its original concern (a fresh Pipenv clone finding zero packages) is now covered by the lockfile supplement, not by the OS Python. The pyproject and uv.lock fallback tests are untouched.

Ported main fix: a21968e cherry-picks #878 ("Route Gradle digests through utils::digest"). main currently fails utils::digest::tests::production_digests_go_through_the_helpers, and that turned test (macos-latest) and coverage red on this PR. The commit no-ops once #878 lands.

Per-issue checklist

Test evidence

  • Red before the fix (main 9c43dfc): the core test got ["/usr/local/lib/python3.11/dist-packages", "/usr/lib/python3/dist-packages", …, "<HOME>/anaconda3/lib/python3.11/site-packages"]. Both CLI tests failed with unexpectedly discovered pkg:pypi/system-decoy@6.6.6, and the batch query also carried the whole system Python (pyyaml, cryptography, …).
  • Green after the fix: cargo test -p socket-patch-core --test crawler_python_e2e 61/61, cargo test -p socket-patch-cli --test in_process_python_envs 21/21.
  • cargo clippy --workspace --all-features -- -D warnings: clean.
  • cargo test --workspace --all-features --no-fail-fast: 10,820 passed, 12 failed. The 12 failures are chmod- or unremovable-file tests that can't fail when run as root (the sandbox runs as uid 0). The covgap_commands_vendor *_state_write_failure_*, in_process_redirect write-failure and vlt-heal, repair unremovable-lock and cleanup-failure tests, plus four core lib tests, were all re-run as uid 65534 and pass.
  • Pipenv e2e, as CI runs it: cargo test -p socket-patch-cli --all-features --test e2e_vex_build -- pipenv:: --ignored with SOCKET_PATCH_PIPENV_E2E_REQUIRED=1, for 2026.8.0 (Python 3.12) and 2022.12.19 (Python 3.8). Both pass. This suite runs hosted scan on a lock-only checkout, which is the Vendored scan of a fresh Pipenv checkout (no venv yet) fails with exit 1 on packages that exist only in the system Python, because the crawler falls back to the global site-packages #947 shape.
  • cargo fmt --all -- --check: the hunks this PR touches are formatted. main already has 466 rustfmt diffs under the pinned 1.93.1 toolchain, and CI doesn't run fmt, so I left the rest of the tree alone.
  • CI on a21968e: all 415 check runs pass (409 success, 6 skipped). Bugbot reviewed a21968e and found no issues.

🤖 Generated with Claude Code


Generated by Claude Code

Assisted-by: Claude Code:claude-opus-5-5
A Pipenv project with no Pipenv venv yet must not have the OS
Python's site-packages crawled as if they were the project's: agent
mode patched them in place (#504), and vendored mode tried to vendor
system-only packages into Pipfile.lock and exited 1 (#947).

Replace the test that pinned the global fallback for a Pipfile marker
with one asserting the opposite, and add CLI scans for agent, hosted
and vendored modes.

Assisted-by: Claude Code:claude-opus-5-5
When a Pipenv project had no Pipenv venv (a fresh checkout before
pipenv install, or a project that only has a plain venv/), scan read
the OS Python's site-packages instead. Agent mode then patched the
system Python in place and VEX attested the project as fixed (#504);
vendored mode tried to vendor system-only packages and failed with a
misleading 'run pipenv lock' error (#947).

A Pipenv project's env is only ever the one Pipenv resolves, so an
empty result there is final. Lock-only packages still come from
Pipfile.lock.

Fixes #504
Fixes #947

Assisted-by: Claude Code:claude-opus-5-5
main has failed socket-patch-core's lib tests since Gradle support
(#646) and the digest helpers (#865) both landed. The guard test
production_digests_go_through_the_helpers flags three files #646 added
that still hash inline: crawlers/gradle_cache.rs, patch/jvm_jar.rs and
patch/sidecars/maven.rs. That breaks test, test-release and coverage on
every open PR.

Each inline sha1/sha256 call now goes through sha1_hex_of or
sha256_hex_of, which compute the same lowercase hex. Behaviour is
unchanged.

Ported from #878 so CI on this PR runs against a green
base; it no-ops once #878 lands on main.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[agent] test (macos-latest) and coverage failed on e7836a4 in utils::digest::tests::production_digests_go_through_the_helpers. That failure comes from main, not from this PR: #646's Gradle files hash inline, and #865's guard rejects that. I ported #878's fix (a21968e, "Route Gradle digests through utils::digest") into this branch so CI runs against a green base. The commit no-ops once #878 lands.


Generated by Claude Code

@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 6, 2026 17:09
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit a21968e. Configure here.

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 6, 2026
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator Author

[agent] Ready for review.


Generated by Claude Code

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

3 participants