Repository navigation
Read recovered uv/pdm wheel pins through the shared lock model (#1079) - #1121
Conversation
Assisted-by: Claude Code:claude-opus-5-5
repair and re-vendor rebuild a missing PyPI artifact from the uv or pdm [[package]] unit recorded in the vendor ledger. That unit was read by a string scanner that paired a pure wheel's URL with the first sha256 after it, even when that hash belonged to a later platform wheel, so a hashless pure wheel failed with a confusing digest mismatch instead of the honest "no fetchable registry URL" message. Recovery now parses the unit as TOML through the shared utils::python_lock::package_artifacts, so each URL keeps its own hash, and decides portability through the shared wheel classifier vendored and hosted mode use (#1048): cp311-none-any, pp310-none-any and py2-none-any wheels are no longer picked, and #sha256= / ?query URLs are classified by their file name. The string scanner and its private -none-any.whl suffix rule are deleted. Refs #1079 Assisted-by: Claude Code:claude-opus-5-5
|
[agent] Generated by Claude Code |
|
BugBot review Generated by Claude Code |
Assisted-by: Claude Code:claude-opus-5-5
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 fd8b7e6. Configure here.
|
[agent] Generated by Claude Code |
|
Ready for review (burn-down agent).
Nothing specific flagged for the reviewer beyond the PR description. Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1079 (slice 1: ledger recovery)
Summary
repairand re-vendor rebuild a missing PyPI artifact from the uv / pdm[[package]]unit recorded in the vendor ledger. That unit was read by a third uv.lock reader, a string scanner (pure_wheel_from_uv_unit). It paired a pure wheel's URL with the firsthash = "sha256:after it, even when that hash belonged to a later platform wheel. It also kept its own-none-any.whlsuffix rule, which drifted from the shared wheel classifier once #1053 (#1048) landed. Recovery now reads the unit through the shared lock model and the shared classifier.Why (leverage)
doc/06-discovery-vex.md{{E89}}.What changed
vendor/pypi_distribution.rs: newis_portable_wheel_url(url). It strips?/#, takes the last path segment, requires.whl, and askswheel_platform_from_filename, the rule vendored (vendor_platform_locked) and hosted (redirect_pypi_platform_wheel) mode already use.vendor/lock_inventory/recover.rs:pure_wheel_from_uv_unitparses the unit as TOML ([[package]]unit, or a bare artifact-array fragment). It reads artifacts throughutils::python_lock::package_artifacts(archive,wheels,wheel,files), so each URL keeps its own hash, and keeps the http(s) gate (http_url)..github/workflows/ci.yml: the setup-php pin comment# v2→# 2.37.2, ported from Label the setup-php pin in ci.yml with its real tag #1118 because zizmor fails every PR on main without it. It no-ops once Label the setup-php pin in ci.yml with its real tag #1118 merges.Deleted
-none-any.whlsuffix rule.git diff --stat: production +36 / −24 (recover.rs,pypi_distribution.rs), tests +88 (recover_tests.rs), CI +1 / −1.Remaining (slice 2, after #1058 / #1009 / #1045 / #768 land)
lock_inventory/pypi.rspython_package_archiveand the poetry site still useends_with("-none-any.whl"). Both move ontois_portable_wheel_url, and the inventory and recovery selectors become one function.pure_wheel_from_uv_unitand move its old test out oflock_inventory/{mod,tests}.rs.These files are changed by open PRs, so they're left alone here.
Behavior
Recovery only (
repair/ re-vendor of a missing vendored PyPI artifact from a uv or pdmstatic_urlsfragment):cp311-none-any,pp310-none-anyandpy2-none-anywheels are no longer picked as portable, matching vendored and hosted mode since Hosted Pipenv scan still pins an interpreter-boundcp311-none-anypatched wheel into Pipfile.lock with no warning, sopipenv syncfails on every other Python version (gap in the #932 fix) #1048.#sha256=…or?queryURL is classified by its file name. Before, it was never recognised as pure.url="…"with no spaces now parses. The old scanner neededurl = ".No change to inventory, lockfile bytes, JSON shape, error codes or exit codes.
Test evidence
recover_tests.rs:recover_uv_never_pairs_a_pure_wheel_with_another_wheels_hash: the Vendored uv repair pairs a hashless pure wheel with another wheel's hash, because ledger recovery re-parses uv.lock with its own scanner #1079 repro throughrecover_lock_entry.recovery_pure_wheel_matches_the_shared_portability_rule: an 11-row table, each row through a uvwheelsunit and a pdmfilesunit, checked againstwheel_platform_from_filename.recovery_pure_wheel_pairs_each_url_with_its_own_hash: the full unit withsdist,[package.metadata]and an uppercase digest, plus a non-TOMLrequirements_line.recover.rs, all 3 fail. On the branch, all pass. The existingcomposer_gem_uv_fragments_recover,recover_pypi_pdm_static_urls_recovers_pure_wheel,recover_pypi_urlless_locks_report_no_fetchable_urlandpure_wheel_rejects_short_hash_missing_hash_and_non_http_urlpass unchanged.cargo clippy --workspace --all-features -- -D warnings: clean.cargo test -p socket-patch-core --lib: 5742 passed, 4 failed. The 4 failures fail on main too because the sandbox runs as root (copy_tree::relax_loop_must_not_traverse_symlinked_root,vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry,pypi_poetry::wire_write_failure_maps_error_and_leaves_lock_untouched,pypi_requirements::wire_failure_rolls_back_already_written_files).cargo test -p socket-patch-cli --all-features --test repair: 125 passed, 2 failed. Both are the known root-only chmod tests.Risk
Low. The change is confined to the ledger-recovery path, which is rare and fail-closed: the fetch layer still verifies every digest. Recovery now parses the unit with
toml_edit, which costs ≈80 µs per call; it runs once per missing artifact.🤖 Generated with Claude Code
Note
Low Risk
Changes are limited to rare ledger-recovery code; fetches still verify digests, and unpinned or ambiguous cases remain fail-closed.
Overview
Fixes #1079 in the vendor-ledger recovery path (
repair/ re-vendor when a PyPI artifact is missing): uv and pdm[[package]]units are no longer read with a string scanner that could bind a portable wheel URL to another wheel’ssha256.Recovery now parses the unit as TOML and walks artifacts through
package_artifacts, so each URL keeps its own hash. Portable wheel selection uses a newis_portable_wheel_urlhelper (samewheel_platform_from_filenamerule as vendored/hosted mode) instead of a-none-any.whlsuffix check—so interpreter-tagged “any” wheels are excluded and query/fragment URLs classify correctly. Unpinned or non-portable wheels still fail closed with the existing “no fetchable registry URL” behavior.CI only updates the
setup-phppin comment (# v2→# 2.37.2) for zizmor. New tests cover the mis-pairing repro, portability matrix, and per-artifact hashing.Reviewed by Cursor Bugbot for commit fd8b7e6. Configure here.
Generated by Claude Code