Vendored uv transitive package later added as a direct dependency (`uv add six==1.16.0`): `vendor --revert` / `remove` / `rollback` half-revert the pair, so `uv sync --locked` fails and `vendor --check` claims nothing references the wheel
维护者通常 1 天内回复
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 28/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 领域
- build-system, cli
调研方向
Start with revert_uv in crates/socket-patch-core/src/vendor/pypi_uv.rs (around line 795), which reverts only the recorded wiring fragments, then the residual-reference guard in crates/socket-patch-core/src/vendor/pypi.rs (around line 2416). Reproduce with the repro steps in the issue, then check that uv sync --locked passes and vendor --check agrees with uv.lock after vendor --revert. Done means the root requires-dist element is restored or the revert fails closed, and the check no longer reports a false 'wiring missing'.
由索引模型根据 Issue 内容生成。
描述
[agent] Found by the scheduled uv bug-hunt routine (ledger #310).
Summary
Vendor a transitive package in a uv project (here six, pulled in by python-dateutil and held at 1.16.0 by a user constraint-dependencies). Vendored mode wires it through [tool.uv] override-dependencies + [tool.uv.sources] and records five wiring entries: uv_override, uv_sources_entry, uv_lock_package, uv_lock_manifest_overrides and uv_lock_manifest_constraints.
Then the user promotes it to a direct dependency, for example to pin it: uv add six==1.16.0. uv writes a new root requires-dist element, { name = "six", path = ".socket/vendor/pypi/<uuid>/six-1.16.0-…whl" }, because the socket-written source routes it. socket-patch never recorded that element.
vendor --revert, remove six and rollback then revert every recorded fragment. They drop the sources line and the override, and put the lock's [[package]] and [manifest] back on PyPI. They leave the root requires-dist element still pointing at the wheel. Only after writing does the residual-reference guard notice that uv.lock still names the uuid dir, and it keeps the wheel and the ledger entry.
The result is a pair uv rejects:
uv sync --lockedfails with "The lockfile atuv.lockneeds to be updated".vendor --revertexits 0.removeandrollbackexit 1.vendor --checkthen exits 1 withwiring missing: no lockfile or config references .socket/vendor/pypi/<uuid> any more … re-run socket-patch vendor to rewire it. That's false, becauseuv.lockstill references it, and the remedy re-vendors the package the user just asked to unwind.
Impact
A user who pins a vendored transitive dependency directly, which is a normal uv add, can't unwind it cleanly. Every --locked / --frozen-checked CI install breaks after the revert. The only recovery is to know to run uv lock by hand and then vendor --revert again (that converges).
The same uv add after uv remove python-dateutil (the #1287 shape plus a direct re-add) fails the same way, on main and on PR #1337.
Repro
Requires a patch API serving a [email protected] patch. I used the routine's local mock with --api-url/--patch-server-url/--vendor-url http://127.0.0.1:8765, abbreviated sp below.
mkdir demo && cd demo
cat > pyproject.toml <<'EOF'
[project]
name = "demo"
version = "0.1.0"
requires-python = ">=3.9"
dependencies = ["attrs>=20"]
[tool.uv]
constraint-dependencies = ["six==1.16.0"]
EOF
uv add -q python-dateutil==2.9.0.post0 && uv sync -q
sp scan --mode vendored --yes # six wired via override + sources, exit 0
uv add -q six==1.16.0 # promote to direct; uv.lock root requires-dist now has { name = "six", path = ".socket/vendor/pypi/<uuid>/…" }
uv sync -q --locked # ok, six patched
sp vendor --check; echo $? # 0
sp vendor --revert --json; echo $? # 0: vendor_revert_residual_reference + vendor_artifact_kept + vendor_revert_kept
uv sync -q --locked # error: The lockfile at `uv.lock` needs to be updated
sp vendor --check; echo $? # 1: "wiring missing: no lockfile or config references … re-run socket-patch vendor"
grep -n aaaaaaaa uv.lock # requires-dist = [ …, { name = "six", path = ".socket/vendor/pypi/…/six-1.16.0-py2.py3-none-any.whl" } ]
After the revert, pyproject.toml has no sources or override, and [[package]] six is back on registry = "https://pypi.org/simple". The root [package.metadata] requires-dist still carries the path element.
Expected vs actual
- Expected: the revert leaves a pair
uv sync --lockedaccepts. Either restore the root element to the specifierpyproject.tomldeclares now ({ name = "six", specifier = "==1.16.0" }, the #840 respell rule for root requirement entries), or, failing that, write nothing and drift-keep both files (fail closed, as the PEP 723 script lane already does for this exact shape). CLI_CONTRACT's revert contract keeps the artifact when a file still references it. It doesn't allow a half-written uv pair, and #806 / #821 / #840 were the same class of half-revert. vendor --checkshould not claim "no lockfile or config references" the uuid dir whileuv.lockdoes.- Actual: pyproject and four of the five lock fragments are reverted, the root
requires-distpath element is left,uv sync --lockedfails, andvendor --revertexits 0.
Matrix (Linux, main 85105c9)
| unwind | uv 0.5.31 | uv 0.12.24 |
|---|---|---|
vendor --revert (parent kept, uv add six==1.16.0) |
fail: exit 0, --locked fails, check 1 |
fail (same) |
remove six --yes |
fail: exit 1, --locked fails |
fail |
rollback --yes |
fail: exit 1, --locked fails |
fail |
vendor --revert after uv remove python-dateutil + uv add six==1.16.0 |
fail (main and PR #1337) | fail (main and PR #1337) |
hosted takeover (scan --mode hosted) |
pass: redirect_vendored_revert_failed, files untouched |
pass |
PEP 723 script, uv add --script s.py six==1.16.0, then revert |
fail-closed: drift-keep, both files untouched, still patched | same |
recovery: uv lock, then vendor --revert |
pass, converges, check 0 | pass |
The checks are text-level uuid checks with no OS-specific branch, so I didn't run a probe.
Suspect code
crates/socket-patch-core/src/vendor/pypi_uv.rs:795(revert_uv): only the recorded records are reverted. The transitive wiring has nouv_lock_requires_distrecord, so a root element the user'suv addcreated through the socket-written source is never restored, and nothing checks the reverted pair for leftover uuid references before writing.crates/socket-patch-core/src/vendor/pypi.rs:2416(residual-reference guard): it runs after the flavor revert has already written, so it can only keep the artifact, not prevent the inconsistent write.- The
vendor --check"wiring missing" verdict ignores arequires-distpath element in uv.lock.
- 主要语言
- Rust
- 星标
- 8
- 派生
- 1
- 平均合并
- 19 小时 1 分钟
- 30 天内合并 PR
- 473
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
SocketDev/socket-patch 的其他 Issue
-
agent:triaged bug pm:go priority:p2
难度 2/5 1-3 小时 新手友好度 76/100
SocketDev/socket-patch#1409 · 1 条评论 ·
维护者通常 1 天内回复
-
agent:triaged bug bughunt pm:npm priority:p3 ux
难度 2/5 1-3 小时 新手友好度 75/100
SocketDev/socket-patch#1072 · 2 条评论 ·
维护者通常 1 天内回复
-
agent:triaged bug bughunt pm:yarn-berry priority:p1
难度 2/5 1-3 小时 新手友好度 73/100
SocketDev/socket-patch#783 · 1 条评论 ·
维护者通常 1 天内回复
-
Vendored cargo warns cargo_multi_version_old_cargo ("declares no rust-version") when the root package inherits rust-version from [workspace.package]可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭agent:triaged bug bughunt pm:cargo priority:p2
难度 2/5 1-3 小时 新手友好度 84/100
SocketDev/socket-patch#651 · 3 条评论 ·
维护者通常 1 天内回复
-
agent:triaged bench perf-regression pm:nuget priority:p3
难度 4/5 3-5 天 新手友好度 45/100
SocketDev/socket-patch#1425 · 1 条评论 ·
维护者通常 1 天内回复
查看 SocketDev/socket-patch 的全部 Issue
相似的 Issue
-
ai_p2
难度 2/5 1-3 小时 新手友好度 68/100
ClickHouse/ClickHouse#125522 ·
维护者通常 1 天内回复
-
[Bug]: OpenRouter streaming chunks report the requested router name instead of the model OpenRouter served可能已有人在做 @Mrun25 今天认领。 未关闭bug llm translation
难度 2/5 1-3 小时 新手友好度 75/100
BerriAI/litellm#46095 · 1 条评论 ·
维护者通常 1 天内回复
-
bug effort:low flow:bug
难度 2/5 1-3 小时 新手友好度 74/100
jaroslawherod/micold-ai-ide#788 ·
维护者通常 1 天内回复
-
Docs: refresh target-app-parity and file-format-parity against main可能已有人在做 @vangel76 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 70/100
storytold/photocraft#4417 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 75/100
bevyengine/dlss_wgpu#37 ·