Repository navigation
Fix uv wiring under no-sources = true (#564) - #1434
Merged
Merged
Conversation
Assisted-by: Claude Code:claude-opus-5-5
With `no-sources = true` in pyproject's [tool.uv] or a project uv.toml (or a PEP 723 script's [tool.uv]), uv ignores every [tool.uv.sources] entry. Hosted scan and vendor still wrote one and reported success, so `uv sync --locked` then failed and a plain `uv sync` installed the unpatched registry wheel. Both modes now refuse before writing anything: hosted reports redirect_uv_project_unsupported / redirect_uv_script_unsupported and vendored reports pypi_uv_no_sources. The check follows uv's own precedence: a uv.toml replaces pyproject's [tool.uv] settings, and a script's own [tool.uv] wins over uv.toml. Hosted mode now reads uv.toml as a read-only input. Fixes #564 Assisted-by: Claude Code:claude-opus-5-5
Add a CLI test that both hosted scan and vendor refuse a uv project with no-sources = true (in pyproject or uv.toml) and write nothing. Pin uv.toml in the hosted candidate list and describe the refusal in the uv compatibility notes. Refs #564 Assisted-by: Claude Code:claude-opus-5-5
A PEP 723 script without its own no-sources setting takes the project's: uv.toml if present, else pyproject's [tool.uv]. A script next to a pyproject with no-sources = true was still wired. uv.toml is now read only beside a uv lock, as advisory input, so a symlinked or unreadable uv.toml no longer refuses unrelated hosted runs. A uv.toml that fails to parse sets nothing here (uv reports it) instead of surfacing as a no-sources or lock-parse refusal. The vendored script check reads the project config once per run. Refs #564 Assisted-by: Claude Code:claude-opus-5-5
Mikola Lysenko (mikolalysenko)
marked this pull request as ready for review
October 12, 2026 16:44
Collaborator
Author
|
BugBot review Generated by Claude Code |
uv 0.10+ also drops the [tool.uv.sources] entries of the packages named in no-sources-package, so patching a listed package left the same unpatched install as no-sources = true. Read the list beside the boolean, with uv's rules: a uv.toml replaces pyproject's [tool.uv], a script's list combines with the project's, and an explicit no-sources = false disables it. Names are compared normalized. The vendored project check moves into check_target_guards, which knows the package being wired. Refs #564 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014C6hY72T6RCtYwyGvxAmoT
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 b069a70. Configure here.
Tanmay Singla (Tanmay182003)
approved these changes
Oct 12, 2026
Collaborator
Author
|
Ready for review (burn-down agent)
Generated by Claude Code |
This was referenced Oct 12, 2026
Merged
github-merge-queue Bot
pushed a commit
that referenced
this pull request
Oct 13, 2026
* ci(release): publish npm from release.yml, not publish-npm.yml Every socket-patch npm package's trusted publisher is registered against release.yml, and npm allows only one publisher per package. The 5.0.0 release dispatched publish-npm.yml, whose OIDC token named that file, so npm rejected it with E401 before staging anything. Move the npm leg back inline as release.yml's npm-publish job (same steps as publish-npm.yml) and delete publish-npm.yml, so the existing registration keeps working. Add an `npm-retry-version` input that skips the version gate, build, tag, GitHub release and crates.io jobs and re-stages npm from an existing release's assets; this retries 5.0.0 now and replaces the manual Publish npm dispatch. crates.io stays dispatched through publish-cargo.yml, since crates.io allows several publishers per crate. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore(release): fold 22 more PRs into the 5.0.0 notes Cover the PRs merged to main after #1432's base (1779317..4cb3643): Cargo source replacement and registry = "crates-io" (#338/#455, #386), pnpm lockfile=false (#1074), berry removed descriptors (#1435), yarnrc ${VAR} reads (#1100), CRLF .npmrc append (#1196), Composer vendor-dir cascade and global home (#439/#686, #586), Go +incompatible vex (#484), gem moved BUNDLE_GEMFILE and commented Gemfile revert (#952, #988), Poetry source = "pypi" (#1282) and Hatch path characters (#547). No entries for #1411 (macOS fix to code #1393 added in this release; the #1393 entry already describes the intended behavior), #1426 (perf regression introduced and fixed within 5.0.0) or the CI/test/bench PRs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore(release): cover #1419, #1434, #1440, #1442, #1444 in the 5.0.0 notes Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore(release): 5.0.1 Cut [Unreleased] into [5.0.1] — 2026-10-13 and stamp 5.0.1 with scripts/version-sync.sh. The 5.0.1 notes cover main through 501c6d9 (#1449), i.e. every PR after the v5.0.0 tag (6ad6add): the npm publish fix (5.0.0 never reached npm or crates.io, 5.0.1 is the first v5 there), #1465, #759, #1460, #1462, #1445, #869, #1447, #1450, #1467, and #1449 under Maintenance. CI/test-only PRs (#1448, #1452, #1454, #1457, #1459) have no entries. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore(release): 5.0.1 notes for PRs merged since the cut Covers #1469, #1470, #1474, #1475, #1478, #1479, #1480 and #1482; #1484 is CI-only. The notes now cover main through 285a5e8. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This was referenced Oct 13, 2026
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 #564
Summary
uv ignores every
[tool.uv.sources]entry whenno-sources = trueis set, and (uv 0.10+) the entries of the packages listed inno-sources-package. Hosted scan and vendor both wired the patch through such an entry anyway and reported success. Locked installs (uv sync --locked,uv lock --check) then failed, and a plainuv syncinstalled the unpatched registry wheel.Both modes now refuse before writing anything:
uv.lock)redirect_uv_project_unsupported(like the other uv shapes hosted can't wire)redirect_uv_script_unsupportedpypi_uv_no_sources(exit 1)pypi_uv_no_sourcesRoot cause
Both writers that add
[tool.uv.sources]never read uv'sno-sourcessetting:utils/python_script.rsrewrite_sources, reached fromplan_python_metadata_withinpatch/redirectvendor/pypi_uv.rs(projects) andvendor/pypi_lock.rs(script locks)The fix adds one shared check,
python_script::refuse_uv_no_sources, which all three call. It follows uv's precedence. I checked each rule against real uv 0.11.32 withuv lock --offlineand a local path source:[tool.uv]wins.uv.tomlreplaces pyproject's[tool.uv]settings completely. If auv.tomlexists without the key, a pyprojectno-sources = trueis ignored.uv.toml, else pyproject[tool.uv]).no-sources-packagelists from a script and the project combine; an explicitno-sources = falsedisables the list; names compare normalized.Hosted mode now reads
uv.tomlas advisory input beside a uv lock (hosted/engine.rs). It is never written. A symlinked or unreadable one is left out instead of refusing the run, the same as the other read-only inputs.Tests (red → green)
Before the fix, each new test failed on
main. All pass with it.no-sources = true: scan and vendor report success,uv sync --lockedthen fails, and a plainuv syncreinstalls the unpatched wheel #564 hosted project, pyproject[tool.uv]anduv.tomlvariants, plus precedence:patch::redirect::python_metadata_pairing_tests::no_sources_refuses_a_source_uv_would_ignoreno-sources = true: scan and vendor report success,uv sync --lockedthen fails, and a plainuv syncreinstalls the unpatched wheel #564 hosted script, its own[tool.uv],uv.toml, and the pyproject fallback: same testno-sources = true: scan and vendor report success,uv sync --lockedthen fails, and a plainuv syncreinstalls the unpatched wheel #564 vendored project, pyproject anduv.tomlvariants:vendor::pypi_uv::tests::guards_refuse_workspace_lock_version_fork_sources_and_dynamicno-sources = true: scan and vendor report success,uv sync --lockedthen fails, and a plainuv syncreinstalls the unpatched wheel #564 vendored script lock, script,uv.tomland pyproject variants, nothing written:vendor::pypi_lock::tests::script_no_sources_refuses_before_writingno-sources = true: scan and vendor report success,uv sync --lockedthen fails, and a plainuv syncreinstalls the unpatched wheel #564no-sources-package(review): normalized name,uv.toml, other packages, script+project merge,no-sources = false: the hosted and both vendored tests aboveno-sources = true: scan and vendor report success,uv sync --lockedthen fails, and a plainuv syncreinstalls the unpatched wheel #564 end to end through the CLI, both modes and both config files, tree byte-identical afterwards:mode_migration_pypi::uv_no_sources_is_refused_in_both_modesLocal checks
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleancargo test --workspace --all-features --no-fail-fast: everything passes except 13 tests that also fail in this sandbox for unrelated reasons. 12 depend onchmoddenying writes, which root bypasses; 4 of those were re-run asnobodyand pass. 1 (e2e_bun_lockb) needs the real patch API, which this sandbox can't reach. None of them touch uv.e2e_redirect_uv_build,e2e_vendor_pypi_build) need PyPI and were not run locally; CI covers them. No wrapper (npm/,pypi/,gem/) changes are needed: they only dispatch to the binary.Review notes (
/code-review high)Fixed: script fallback to pyproject
[tool.uv];uv.tomlread as advisory (a strict registry read would have refused unrelated hosted runs); an unparseable or unreadableuv.tomlno longer surfaces as a no-sources or lock-parse error; the vendored script check reads the config once per run.Not changed:
uv.toml. Not reproducible for wired projects. uv stops its settings lookup at a pyproject that has a[tool.uv]table, and the[tool.uv.sources]entry the wiring adds is one. Checked with uv 0.11.32.uv.toml,UV_NO_SOURCES,--no-sources. These belong to the installing machine, not the project, so the scan can't see them. This is documented indocs/testing/uv-compatibility.md.no-sources = truenow fails withpypi_uv_no_sourcesinstead of reporting InSync. That matches the existing load-time guards (dynamic deps, workspaces). Such a project is not actually patched under uv, so failing loudly is the intent.vendor --revertdoesn't go through this loader and still works.🤖 Generated with Claude Code
https://claude.ai/code/session_014C6hY72T6RCtYwyGvxAmoT
Generated by Claude Code