Repository navigation
Fix Pipenv remedy for base-interpreter copies (#1450) - #1455
Conversation
Assisted-by: Claude Code:claude-opus-5-5
When a --site-packages Pipenv virtualenv imports a package from its base interpreter (e.g. Debian's /usr/lib/python3/dist-packages), the stale-install warning told users to `pip uninstall` it and re-sync, or to recreate the virtualenv. pip refuses to remove a copy outside the venv and `pipenv sync` counts it as installed, so both left the package unpatched and the next scan printed the same advice. Hosted and vendored scans now tell a base-interpreter copy apart from the venv's own and, for one, print an install over it inside the venv (`pipenv requirements ... && pipenv run pip install --no-deps --ignore-installed -r ...`) instead, without claiming the lock protects fresh installs on that host. Fixes #1450 Assisted-by: Claude Code:claude-opus-5-5
Address review of the base-interpreter remedy: - When one Pipenv venv has its own stale copy and another imports the base interpreter's, the vendored warning now gives each dir its own remedy instead of only the base one. - Hosted scans no longer treat a base dir that only a Hatch env reaches as Pipenv's, and skip the probe when no Pipenv package is involved. - The remedy notes that `--categories` needs Pipenv 2022.12+ and tells users to delete the exported requirements file afterwards. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Hosted scans skipped every venv Hatch also claims when looking for inherited base-interpreter dirs, so a `.venv` Pipenv shares with Hatch (`path = ".venv"`) still got the uninstall-and-sync advice that cannot replace a base copy. Use Pipenv's own venv list, as the vendored warning does. The install-over remedy now also says that it reinstalls every package of the named lock categories, not only the stale one. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
|
bugbot run Generated by Claude Code |
2 similar comments
|
bugbot run Generated by Claude Code |
|
bugbot run Generated by Claude Code |
|
Ready for review at
Generated by Claude Code |
Final review briefWhat it does: When a Risk: low. Only warning text changes; nothing is written to disk and no patch logic moves. The extra filesystem work runs only when Pipenv venvs are present. Look here:
Verified:
Changes I made: none. Open questions (non-blocking; the PR fixes the reported base-only case and regresses nothing):
Auto-merge (squash) is armed, so approving sends it straight to the merge queue. Generated by Claude Code |
When a `--site-packages` Pipenv venv's own stale copy hides the same release in its base interpreter, the usual `pip uninstall && pipenv sync` remedy only exposed the base copy: `pipenv sync` counts it as installed, so the venv went on importing the unpatched base copy and the warning came back. Both the hosted and vendored warnings now give that copy the install-over remedy too. A different base release keeps the usual remedy, since `pipenv sync` installs the locked one over it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YCidp2ZuBQK2S7rDd2fvBM
|
[agent] Replies to the open questions in the final review:
Generated by Claude Code |
|
bugbot run Generated by Claude Code |
There was a problem hiding this comment.
✅ 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 76d2473. Configure here.
Final review brief (updated for 76d2473)What it does: A Risk: low. Only warning text changes; nothing is written to disk. A case that doesn't match exactly falls back to the old remedy. Look here:
Verified:
Changes I made: none. I disarmed auto-merge when 76d2473 landed after the earlier brief, and I re-armed it with this brief. Open questions (non-blocking):
Auto-merge (squash) is armed, so approving sends it straight to the merge queue. Generated by Claude Code |
|
Still Ready for review at Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1450
Summary
A
--site-packages(PIPENV_SITE_PACKAGES=1) Pipenv venv with no copy of its own imports a package from its base interpreter (e.g. Debian's/usr/lib/python3/dist-packages). Since #1419 the hosted and vendored stale-install warnings fire for that copy, but they printed the usual Pipenv remedy:pipenv run pip uninstall -y <pkg> && pipenv sync, orpipenv --rm && pipenv sync. pip refuses to uninstall a copy outside the venv, andpipenv sync(also in a recreated--site-packagesvenv) counts the base copy as installed. Both left the package unpatched, and the next scan printed the same advice.For a stale copy in a base-interpreter dir the venv inherits, the warning now prints an install over it inside the venv:
It also drops the "only protects fresh installs" claim, which is false on that host. A venv's own stale copy that hides the same release in its base interpreter gets the same install-over remedy, since uninstalling it would only expose the base copy to
pipenv sync. Other stale copies in the venv keep the existing remedy, and when several kinds are stale each dir gets its own remedy.Root cause
pypi_pipenv::stale_install_remedybuilt one remedy for every site dir. Both callers (scan/hosted/python.rs,vendor/pypi.rs) already held the stale dir but never asked whether it was the venv's own or an inherited base dir.Changes
crawlers/python_crawler.rs: newinherited_base_site_dirs(sites)returns the dirs amongsitesthat a--system-site-packagesvenv insitesreaches in its base interpreter. It reuses the In a--system-site-packagesvenv, pip keeps the base interpreter's unpatched copy after a hosted rewrite, no stale-install warning fires, andvexattests it as patched #409pyvenv.cfg/prefix logic.vendor/pypi_pipenv.rs:base_site_stale_install_remedy, with therequirementscategory args derived from the lock assync's are. The lock-section computation is factored intolock_sections.docs/testing/pipenv-compatibility.md: documents the base-copy case.Test evidence
vendor::pypi::tests::pipenv_stale_install_in_a_base_site_dir_installs_over_itcommands::scan::hosted::python::tests::pipenv_base_site_copy_gets_an_install_over_itcrawlers::python_crawler::tests::inherited_base_site_dirs_are_the_base_interpreters,vendor::pypi_pipenv::tests::base_site_stale_install_remedy_installs_over_the_base_copyTo get the red runs, I kept the new tests and stubbed the callers' inherited set to empty.
Real Pipenv 2026.8.0 check (Linux, py3.11, six 1.16.0 in
/usr/lib/python3/dist-packages,PIPENV_SITE_PACKAGES=1):pipenv run pip uninstall -y six→Not uninstalling six at /usr/lib/python3/dist-packages, outside environment …. This reproduces the issue.<venv>/lib/python3.11/site-packages/six.py, and the base copy is unchanged."file": "./.socket/vendor/pypi/<uuid>/six-1.16.0-py2.py3-none-any.whl"):pipenv requirementsexports the relative wheel path, pip installs it, and the venv imports its own copy.Local runs:
cargo fmt --all -- --check: ok.cargo clippy --workspace --all-features -- -D warnings: ok.cargo test -p socket-patch-cli --all-features --lib: 919 passed.cargo test -p socket-patch-core --all-features --lib: 6410 passed, 4 failed. The 4 failures arecopy_tree::relax_loop_must_not_traverse_symlinked_root,vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry,pypi_poetry::wire_write_failure…andpypi_requirements::wire_failure_rolls_back…. Each relies on chmod 0555 making a write fail, which can't happen as uid 0 in this container. This diff doesn't touch them.--test in_process_redirect_pipenv --test mode_migration_pypi: 11 + 61 passed.cargo test --workspaceran out of the container's disk allowance, so CI covers the rest.Review findings not fixed (
/code-review high)--hashtopipenv requirements: I didn't.pipenv requirements --hashexports the vendored wheel line without its hash (Vendored Pipenv lock breakspipenv requirements --hash|pip install -ron Pipenv 2023+: the vendored wheel is exported without a hash, so pip's hash-checking mode refuses the whole install #981; I confirmed this on 2026.8.0), so pip's hash-checking mode would refuse the whole vendored install. The hosted and vendored artifacts are the ones the lock already names.pipenv requirementsdoesn't exist there, and I couldn't verify thatpipenv lock -rleaves the lock alone on those releases, so the text says "Pipenv 2022.4+" (2022.12+ when--categoriesis needed; I checked that 2022.4.8 lacks it and 2022.12.19 has it).vex --product <purl>vsvex), and unifying them would change unrelated text.stale_install_sitesalready recomputes the search order per purl the same way. It's a handful ofpyvenv.cfgreads.Bugbot round 1 (558051a)
Final review (662432f)
--system-site-packagesvenv, pip keeps the base interpreter's unpatched copy after a hosted rewrite, no stale-install warning fires, andvexattests it as patched #409 (venv site-packages comes before the user site), so nothing to change.--hash: unchanged, for the reason above.Follow-ups
🤖 Generated with Claude Code
https://claude.ai/code/session_01YCidp2ZuBQK2S7rDd2fvBM
Generated by Claude Code