fix(vendor/pypi_uv): reconstruct [package.metadata] for path-sourced uv packages - #167
Open
Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
Open
fix(vendor/pypi_uv): reconstruct [package.metadata] for path-sourced uv packages#167Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
Conversation
…uv packages
Vendored-mode uv.lock rewriting converts the target package to a `path`
source but dropped the `[package.metadata]` block (requires-dist +
provides-extras) that a path source needs. Registry packages omit that
block (uv fetches metadata from the index), but a path source has no
index behind it, so uv records it inline. Without it, right after
`scan --mode vendored`, `uv lock --check` and `uv sync --locked` fail
("lockfile needs to be updated") and a plain `uv sync` silently rewrites
uv.lock to re-add the block — lock churn that also defeats a byte-exact
`vendor --revert`.
Reconstruct the block from the vendored wheel's own core METADATA
(Requires-Dist / Provides-Extra) at wire time and append it inside the
single `uv_lock_package` wiring fragment, so `uv lock --check` stays
green immediately and `vendor --revert` byte-restores the registry lock.
The block is emitted only when the wheel declares requirements/extras, so
packages like `six` (none) still match the byte-identical fixtures. uv
compares metadata semantically, so the raw METADATA markers/order are
accepted with zero churn (verified against uv 0.11.19, urllib3==1.26.18:
lock --check, sync --locked, and a no-op plain sync).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Problem
In vendored mode, the uv.lock rewriter (
crates/socket-patch-core/src/vendor/pypi_uv.rs) converts the target[[package]]to apathsource but omitted the[package.metadata]block (requires-dist+provides-extras) that a path source requires. Registry packages legitimately omit that block (uv fetches metadata from the index), but apathsource has no index behind it, so uv records it inline.Confirmed against real prod (uv 0.11.19,
urllib3==1.26.18): right afterscan --json --yes --mode vendored,uv lock --checkexits 1 ("lockfile needs to be updated") anduv sync --lockedfails identically. A plainuv syncthen silently REWRITES uv.lock to re-add the dropped block (requires-dist for brotli/certifi/cryptography/… extras +provides-extras = ["brotli","secure","socks"]) — lock churn that also defeats a byte-exactvendor --revert.The module doc claims the surgical edit keeps
uv lock --checkgreen — this restores that invariant.Fix
Reconstruct the block from the vendored wheel's own core METADATA and append it inside the target unit rewrite, so the whole edit stays in the single
uv_lock_packagewiring fragment (revert byte-restores as one unit).wire_uv(pypi_uv.rs:491-508): read the wheel atroot.join(rel_wheel)and build the block before the lock surgery.wheel_metadata_block/wheel_metadata_text(pypi_uv.rs:1035-1090): best-effort read of*.dist-info/METADATAfrom the wheel zip (size-capped).parse_core_metadata_fields(pypi_uv.rs:1097): collectRequires-Dist/Provides-Extra, header block only (aRequires-Dist:line quoted in the long-description body can't leak).parse_requires_dist(pypi_uv.rs:1124): PEP 508 → name (PEP 503-canonical) / extras / specifier (parens stripped, whitespace-compacted) / verbatim marker.render_package_metadata_block/render_requires_dist_entry(pypi_uv.rs:1173-1233): emit uv's inline-table shape; double-quoted markers TOML-escaped.rewrite_target_package_unit(pypi_uv.rs:775-844): append the block after the[[package]]body (]\n\n[package.metadata]…).Emitted only when the wheel declares requirements/extras, so packages like
six(none) still match the existing byte-identical fixtures. uv compares metadata semantically, so the raw METADATA markers/order are accepted without re-serialization — verified:uv lock --checkanduv sync --lockedpass and a plainuv syncproduces zero churn for the exact bytes this code emits (urllib3==1.26.18).Test
Extends the
pypi_uvunit tests (all hermetic, no network):direct_wiring_reconstructs_package_metadata_block_and_reverts— builds a minimal wheel (zip + METADATA) with an extra-gated dep, a legacy parenthesized base dep, and a poisoned description body; runswire_uv; asserts the path-sourced unit gains the reconstructed[package.metadata]block, the body line never leaks, andvendor --revertbyte-restores the original registry lock. Verified FAILS before the fix (no block appended), PASSES after.parse_requires_dist_pulls_apart_name_extras_specifier_marker,core_metadata_fields_stop_at_the_header_block,render_block_reconstructs_requires_dist_and_provides_extras,render_block_escapes_double_quoted_markers_for_toml— pure-function coverage.cargo test -p socket-patch-core --lib vendor::pypi_uv→ 18 passed. Broadervendor::pypi(109) andvendor::toml_surgery(7) still green; clippy and rustfmt clean.Scope
Single file (
crates/socket-patch-core/src/vendor/pypi_uv.rs). No signature changes visible outside the module (wire_uvreads the wheel it is already handed viarel_wheel). Kills sweep findingsuv-lock-rewrite-omits-package-metadata(P1) and its revert-byte-restore consequence.🤖 Generated with Claude Code
Note
Medium Risk
Changes lock-file surgery for uv vendoring; incorrect metadata could break
uv lock --checkor revert fidelity, but scope is one module with strong tests and fail-closed parsing when METADATA is malformed.Overview
When vendoring rewrites a registry
[[package]]inuv.lockto a path wheel source, it now reconstructs and appends the[package.metadata]block (requires-dist,provides-extras) that uv expects for path sources but omits for registry entries.wire_uvreads the vendored wheel’s*.dist-info/METADATA(size-capped), parses PEP 508Requires-Dist/Provides-Extrafrom the RFC822 header only, and renders uv-shaped inline tables;rewrite_target_package_unitfolds that block into the sameuv_lock_packagewiring fragment sovendor --revertstill byte-restores the lock.Packages with no deps/extras (e.g.
six) still emit no block, preserving existing byte-identical fixtures. New unit tests cover parsing, TOML escaping, and a widget wheel scenario with revert.Reviewed by Cursor Bugbot for commit 97f972a. Configure here.