Repository navigation
Fix requirements pin spellings not contesting VEX (#1602) - #1632
Open
Mikola Lysenko (mikolalysenko) wants to merge 4 commits into
Open
Mikola Lysenko (mikolalysenko) wants to merge 4 commits into
Mikola Lysenko (mikolalysenko) wants to merge 4 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
A requirements.txt line that pins the wired release as `===1.2.3`, `==1.2.3.0` or `==v1.2.3` installs the same upstream wheel as `==1.2.3`, but only the canonical spelling contested another lock's Socket wiring. `vex` attested `not_affected` for a project whose `pip install -r requirements.txt` ships the unpatched release. The requirements reader now records any pin that can only select one release (an `==` pin in any valid PEP 440 spelling, or `===`), and the cross-lock contest compares PyPI versions under PEP 440 equality, the way pip resolves the pin. Ranges and wildcards are still not evidence, since what they install depends on the index. Fixes #1602 Assisted-by: Claude Code:claude-opus-5-5
Review follow-ups for the pin-spelling contest: - pip compares a `===X` pin as a string, so it now contests only a wiring of exactly that version string. `===1.16` no longer withholds an attestation for release 1.16.0, which pip can't install from it. - A lock tree that wires the release itself, under another PEP 440 spelling, is no longer counted as a contester of the other lock. - Reuse purl_key::pypi_same_release instead of a second copy of it. Assisted-by: Claude Code:claude-opus-5-5
The repo's lint test requires purl types to be read through Ecosystem::from_purl rather than an inline prefix check. Assisted-by: Claude Code:claude-opus-5-5
Mikola Lysenko (mikolalysenko)
marked this pull request as ready for review
October 17, 2026 17:42
Collaborator
Author
|
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 1b96ed7. Configure here.
Collaborator
Author
|
Labeled Ready for review (burn-down agent).
Slack announcement not sent this run (the Slack send tool was unavailable). The next run will retry. Generated by Claude Code |
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.
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1602
Summary
A requirements.txt line that pins the wired release as
===1.2.3,==1.2.3.0,==v1.2.3(orsix==1.16for 1.16.0) installs the same upstream wheel as==1.2.3. Before this PR, only the canonical spelling contested another lock's Socket wiring, sovexattestednot_affected(exit 0) for a project whosepip install -r requirements.txtships the unpatched release. Now every one of those spellings withholds the statement withpatched_ref_unattributable, the same way==1.2.3already did.Root cause
The requirements reader (
vex/discover/pypi_other.rs,registry_pin) took evidence only throughutils::requirements::exact_pin. That function rejects===and versions that don't start with a digit, and it returns1.2.3.0verbatim. The cross-lock contest (ResolvedElsewhere::covers) then compared canonical purl strings, so@1.2.3.0never matched@1.2.3.Fix
registry_pinrecords any requirement that can only select one release:==pin in any valid PEP 440 spelling;===pin, recorded with the newResolvedElsewhere::as_spelledflag because pip compares===as a string.ResolvedElsewhere::coverscompares PyPI versions under PEP 440 equality (purl_key::pypi_same_release), except foras_spelledentries. It checks names first, so the PEP 440 parse runs only for pairs with the same name.six@1.16.0while another lock wiressix@1.16would now be counted as a contester.~=1.2.3,==1.2.*) are still not evidence. What they install depends on the index, which the issue also calls a design question.exact_pincomment in the lock inventory says how the two readers differ.The npm, PyPI and gem wrappers don't need changes: this is Rust discovery logic only.
Tests
===X,==X.0,==vX, padded + marker (real CLI, Pipfile.lock wired)e2e_vex_lockfile pipenv::requirements_pin_spellings_contest_the_lock_wiringvexexit 0, atvex_pipenv_pip_common/mod.rs:1385)===,==1.16.0.0,==v1.16.0,==1.16, case/marker/extras/hash) contests;==1.16.1,~=,==1.16.*,===1.16, other name don'tsocket-patch-core vex::discover::pypi_other::tests::issue_1602_requirements_pin_spellings_contest_wiring...::issue_1602_a_tree_wiring_another_spelling_contests_nothingCommands run locally:
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleancargo test -p socket-patch-core --all-features --lib -- vex::discover production_code_classifies_purls: 416 passed on 1b96ed7cargo test --workspace --all-features --no-fail-fast(on 65efed5): 232 test targets ok. The 10 failures are sandbox-only. Nine are read-only-permission / write-failure tests that can't fail when running as root (uid 0):copy_tree::relax_loop_must_not_traverse_symlinked_root("removal cannot succeed under a read-only parent"),vlt_heal::an_unremovable_hidden_lock…,pypi_poetry::wire_write_failure…,pypi_requirements::wire_failure_rolls_back…, 3 inin_process_redirect, 2 inrepair. The tenth,e2e_bun_lockb::binary_shared_bundled_record_hosted_pin_is_managed, failed because the sandbox proxy blocked patches-api.socket.dev. The one real failure, the purl-type lint, is fixed in 1b96ed7./code-review high
Fixed: the wiring exclusion compared strings exactly;
===was read under PEP 440; duplicate helper; the hard-coded version in the e2e case; the staleexact_pincomment.Not fixed, with reasons:
==Xpin also matchesX+localunder PEP 440. That gap already existed before this PR (a canonical==2.1.0never contested a wired2.1.0+cpu). Lock entries resolve exact versions, so folding local labels intocoverswould be wrong for them. It needs a requirements-only rule, which is a separate follow-up.PurlKey.PurlKeykeys maps across every ecosystem, and PyPI is kept spelling-exact there on purpose (pypi_equivalent_purlsexists for this). Changing it would touch much more than this fix needs.===line, so the contest persists. That's correct: pip installs upstream for that line, so the attestation must stay withheld until the user changes it.===now matches only its exact string.https://claude.ai/code/session_01FuB4p2UQANHrpx4dHRwddS
Generated by Claude Code