Repository navigation
Fix pylock projects dropping requirements.txt patch (#1758) - #1759
Conversation
Assisted-by: Claude Code:claude-opus-5-5
A pip project that installs from both requirements.txt and the pylock.toml `pip lock` wrote from it had only the pylock wired to the vendored wheel. requirements.txt was named as a file that "retains its existing sources", but a hosted -> vendored switch (plain `vendor` or `scan --mode vendored`) had just restored its hosted pin to plain PyPI, so `pip install -r requirements.txt` silently went from patched to unpatched while the run exited 0 and `vendor --check` then failed. The Python-lock flavor now wires an exact registry pin in requirements.txt (and in-root -r includes) to the same wheel, the way the Pipenv and uv flavors already wire their exported requirements (#612, #1368). The ledger entry records both files, so revert restores both, and an already-wired lock re-run wires a pin added since. Fixes #1758 Assisted-by: Claude Code:claude-opus-5-5
A settled re-run over a pip-lock project no longer names the wired requirements.txt in a pypi_multiple_lockfiles note. The rollback snapshot taken before wiring now skips symlinked files instead of rewriting them, the notes no longer call requirements.txt an export of the pylock, and the remedy shown when the ledger is missing names a re-lock instead of a revert that cannot help. Adds coverage for the dry run, the settled re-run, and a pin added after the pylock was wired. Refs #1758 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
If wiring requirements.txt fails after the pylock was wired, the rollback put back every lock and script it had read, so a symlinked uv script the run never rewrote was replaced by a regular copy. Now only the files the pylock wiring actually rewrote are put back. Refs #1758 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review 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 09523b8. Configure here.
|
Ready for review at
Generated by Claude Code |
Final review briefWhat it does — In a PEP 751 / script-lock project, a root Risk — low. It follows the existing Pipenv/uv sibling pattern (#612/#1368) and reuses Look here
Verified
Changes I made — none. Open questions (non-blocking)
Auto-merge is armed: approving sends it straight to the merge queue. Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1758
Summary
Take a pip project that installs from
requirements.txtand from thepylock.tomlthatpip lock -r requirements.txtwrote. Vendored mode now wires both files to the vendored wheel. Before this change only the pylock was wired. After a hosted → vendored switch (plainvendor, the eject, orscan --mode vendored),requirements.txthad just been restored from its hosted pin to plain PyPI. Sopip install -r requirements.txtwent from patched to unpatched, the run exited 0, and its ownvendor --checkthen failed withwiring contested.Root cause
detect_pypi_flavor(crates/socket-patch-core/src/vendor/pypi.rs) sends a project whose pylock holds the target to thePythonLocksflavor. That flavor namedrequirements.txtas a loser that "retains its existing sources". ThePipfile.lock/uv.lockflavors already wire an exact registry pin inrequirements.txttogether with the lock (#612, #1368:sibling_pin_wirable,wire_sibling_requirements,wire_in_sync_sibling), but the PythonLocks flavor never got that co-wiring. A takeover's upstream restore covers every hosted file, so the restoredrequirements.txtwas left unwired.Change
WiringPlan::PythonLockscarries asiblingflag, set like the uv flavor's in the fresh plan, the supersede re-plan and the in-sync path (sibling_pending).requirements.txtor an in-root-rinclude is wired to the same wheel right after the pylock.requirements_linerecords go into the same ledger entry, so every revert restores both files (revert_by_record_kindalready handles mixed entries; the vendored → hosted takeover already preflightsrequirements_linerecords in python-lock entries, Vendored requirements.txt can't be reverted or removed once a later scan also wires a pylock.toml: the entry flips to flavorpython-lock, whose revert calls its ownrequirements_linewiring "unexpected" drift (exit 0, nothing restored) #1524).pypi_multiple_lockfiles. A pin the wiring can't rewrite (a range, extras, a package requirements.txt doesn't list) is still named as a loser.sibling_lockgives the PythonLocks remedy as a re-lock, and the notes stop calling a pip-lockrequirements.txtan "export".pypi_multiple_lockfilesrow names the pylock case.Tests (red → green)
New tests in
crates/socket-patch-cli/tests/mode_migration_pypi.rsuse realpip lockoutput (pip 26.2.2):pip_lock_vendor_wires_requirements_with_the_pylockretain their existing sourcesvendor(eject) andscan --mode vendored, thenvendor --checkpip_lock_hosted_to_vendored_keeps_the_requirements_patchedsix==1.16.0from PyPIpip_lock_rerun_wires_a_requirements_pin_added_laterThe #1524 unit test
requirements_then_pylock_entry_reverts_both_filesnow asserts that requirements.txt isn't named at all. Before, it expected the "keeps its vendored wiring" clause, which is dropped.Local checks
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleancargo test --workspace --all-features --no-fail-fast: every pypi suite passes. 12 tests fail locally, and none touch this diff:repairlock/cleanup tests,in_process_redirectwrite-failure tests,copy_treesymlink-root perms,vlt_healunremovable lock, and thepypi_poetry/pypi_requirementswrite-failure rollbacks, which never reach the changed code.e2e_bun_lockbtests reachpatches-api.socket.dev, which this sandbox's proxy blocks.mainis green for all of them./code-review highran on the diff. Fixed: re-run warning noise, snapshot scope, remedy wording, stale docs, missing coverage. Not fixed:sibling_pin_wirableruns again per stage, as in the uv and Pipenv lanes. It's a small read of requirements.txt and doesn't justify a new plumbing path.https://claude.ai/code/session_011f9aeSBxGxNQ9baxh6k2cF
Generated by Claude Code