diff --git a/crates/socket-patch-cli/CLI_CONTRACT.md b/crates/socket-patch-cli/CLI_CONTRACT.md index 863dbcbca..9ade17ded 100644 --- a/crates/socket-patch-cli/CLI_CONTRACT.md +++ b/crates/socket-patch-cli/CLI_CONTRACT.md @@ -963,7 +963,7 @@ v5.0 replaces v4's per-purl reverts and whole-ledger reverse replay (`revert_rem * **vlt** — `vlt-lock.json`: slot [2] from the registry's `dist.integrity`, slot [3] per the lock's own convention (see the vlt hosted-mode contract); every hosted instance of the pin together. * **cargo** — `Cargo.lock` back on crates.io (source + the sparse index's checksum, `SOCKET_CRATES_INDEX`); every `Cargo.toml` declaration loses its `registry = "socket-patch-"` pin (the shorthand the rewriter produced collapses back); every `[registries.socket-patch-]` block no manifest or lock still references leaves the project cargo config — including a superseded patch generation's block an earlier re-pin left behind (#864). A declaration it cannot unpin refuses. * **golang** — the hosted `replace` and the socket module's go.sum lines go; the upstream module's two go.sum lines come back, hashed from the module proxy (`SOCKET_GOPROXY`, else `GOPROXY` / `GONOPROXY` / `GOPRIVATE` as go reads them) and cross-checked against the checksum database (`SOCKET_GOSUMDB_URL`, else `sum.golang.org` unless `GOSUMDB=off` / `GONOSUMDB` / `GOPRIVATE` say go would not ask it). A `replace` the user had before the hosted run is not recorded anywhere, so the restore lands on the plain upstream module. - * **pypi** — `Pipfile.lock`, `requirements.txt` (+ in-root `-r` includes), Hatch PEP 508 direct references (`pyproject.toml` / `hatch.toml`), `poetry.lock`, `pdm.lock`, `uv.lock`, PEP 723 script locks and PEP 751 `pylock*.toml` (+ the paired `pyproject.toml` / script metadata): hashes re-derived from PyPI's JSON API (`SOCKET_PYPI_JSON_API`). A restored `requirements.txt` line gets `--hash` options only when the file is in pip's hash-checking mode. The mode is read off the file's other requirement lines (an `-e` / `--editable` line means unhashed). When every requirement is a hosted pin, it is read off the hosted line itself (`--hash` vs a `#sha256=` url fragment) (#410). Refused: a `pdm.lock` without `cross_platform`, or a uv / script / pylock lock, whose release has a wheel that is not pure Python 3 (which files the lock keeps is not re-derivable); a uv lock whose options filter files (`exclude-newer`, `no-binary`, `no-build`), or whose other registry packages name no registry, several, or one other than PyPI's simple index; a pylock whose other registry packages show neither an `index` nor (as `uv pip compile` writes them) only PyPI files with none, which restores the entry without an `index` too; uv 0.2 `[[distribution]]` locks. Restored artifact fields keep the spelling the lock's other entries show, including the `upload_time` that uv 0.6.15–0.6.17 write. A restored pylock entry's `upload-time`s are whole seconds, as uv writes them, unless the lock's other entries show fractions. Its artifacts come back in the TOML spelling the other entries use: uv's inline `wheels = [{ … }]`, or the standard tables `pip lock` writes (`[[packages.wheels]]` with a `[packages.wheels.hashes]` sub-table, `[packages.sdist]`). A `pip lock` file (`created-by = "pip"`) records only the artifact pip selected, so the entry is restored with only the release's wheel (its sdist when it has none), and a release with several wheels is refused. A transitive `override-dependencies` entry hosted mode added is removed (`upstream_uv_override_removed`). + * **pypi** — `Pipfile.lock`, `requirements.txt` (+ in-root `-r` includes), Hatch PEP 508 direct references (`pyproject.toml` / `hatch.toml`), `poetry.lock`, `pdm.lock`, `uv.lock`, PEP 723 script locks and PEP 751 `pylock*.toml` (+ the paired `pyproject.toml` / script metadata): hashes re-derived from PyPI's JSON API (`SOCKET_PYPI_JSON_API`). A restored `requirements.txt` line gets `--hash` options only when the file is in pip's hash-checking mode. The mode is read off the file's other requirement lines (an `-e` / `--editable` line means unhashed). When every requirement is a hosted pin, it is read off the hosted line itself (`--hash` vs a `#sha256=` url fragment) (#410). Refused: a `pdm.lock` without `cross_platform`, or a uv / script / pylock lock, whose release has a wheel that is not pure Python 3 (which files the lock keeps is not re-derivable); a uv lock whose options filter files (`exclude-newer`, `no-binary`, `no-build`), or whose other registry packages name no registry, several, or one other than PyPI's simple index; a pylock whose other registry packages show neither an `index` nor (as `uv pip compile` writes them) only PyPI files with none, which restores the entry without an `index` too; uv 0.2 `[[distribution]]` locks. Restored artifact fields keep the spelling the lock's other entries show, including the `upload_time` that uv 0.6.15–0.6.17 write. A restored pylock entry's `upload-time`s are whole seconds, as uv writes them, unless the lock's other entries show fractions. Its artifacts come back in the TOML spelling the other entries use: uv's inline `wheels = [{ … }]`, or the standard tables `pip lock` writes (`[[packages.wheels]]` with a `[packages.wheels.hashes]` sub-table, `[packages.sdist]`). A `pip lock` file (`created-by = "pip"`) records only the artifact pip selected, so the entry is restored with only the release's wheel (its sdist when it has none), and a release with several wheels is refused. A transitive `override-dependencies` entry hosted mode added is removed (`upstream_uv_override_removed`). Hosted mode keeps no ledger, so it marks the entry it adds with a `# socket-patch hosted: …` comment line above it and removes only a marked entry; a user's own `==` override (which the hosted rewrite reuses rather than adding a second one) is kept, and the lock's `[manifest] overrides` record of it gets its specifier back. * **gem** — `Gemfile.lock` / `gems.locked` + `Gemfile` / `gems.rb`: the spec moves back into the upstream `GEM` section (or the Socket remote leaves a merged section), the `source "" do … end` block is undone, the `CHECKSUMS` entry is re-pinned from the rubygems.org compact index (`SOCKET_RUBYGEMS_URL`) and the `DEPENDENCIES` pin loses its `!`. The declaration's original constraint is not recorded, so it comes back as the exact pin `gem "", ""`. A transitive gem (one the manifest never declared) gets an appended block with a blank line before it; the restore removes that block, its blank line and the `DEPENDENCIES` entry, so the pair comes back byte for byte. An appended block with no blank line before it (written by a release before this one) can't be told apart from an in-place rewrite, so it still comes back as the exact pin. Refused: an ambiguous upstream section, an upstream remote other than rubygems.org. The manifest pair can't make a committed bundler cache upstream: a `-.gem` left in Bundler's cache dir that isn't the upstream archive is named by `upstream_gem_stale_cache`, never deleted. * **composer** — `composer.lock`: `dist` and the deleted `source` block from packagist's composer v2 metadata (`SOCKET_PACKAGIST_URL`). Refused unless the entry is packagist-sourced and packagist still serves the lock's `dist.reference` for the version. * **maven** — `pom.xml` (the `-socket.` version suffix, the added `` / `` entry) and the `.mvn/maven.config` / `.mvn/checksums/checksums.sha256` lines hosted mode writes: **no network**, so it restores under `--offline` too. `.mvn` files holding anything else keep the resolver lines (`maven_trusted_checksums_left`). @@ -1280,7 +1280,7 @@ Every `--json` invocation emits a single JSON object that follows the **unified | `vendor_state_unreadable` | rollback `warnings[]`; remove top-level error | corrupt-ledger containment (v5.0). Rollback: an unreadable vendor ledger skips the vendored leg + manifest cleanup + GC and drives `partial_failure` exit 1 while the agent and hosted legs still run. Remove: a hard top-level error before any mutation. Also the Bun vendored preflight's refusal code: `get` / `scan --mode vendored`, `vendor`'s pre-takeover check and the `--dry-run` `would_refuse` preview report an unreadable `.socket/vendor/state.json` as itself (`errorCode` in `patches[]` / `download.patches[]`, or `get `'s top-level `error.code`), fail-closed — nothing is exempt — instead of a Bun lock code. (v4's `redirect_state_unreadable` is no longer emitted: v5 never reads the redirect ledger on these paths.) | | `manifest_write_failed` | rollback `warnings[]` | rollback (v5.0): the post-rollback manifest update could not be written; no entries were removed (`manifest.removedEntries: []`) and the run exits `partial_failure` 1. | | `npm_allow_remote_left` / `pnpm_trust_lockfile_left` | rollback/remove `warnings[]`; vendor advisory event (takeover) | upstream restore (v5.0): no npm-family lock entry is hosted any more, but the project `.npmrc` keeps a top-level `allow-remote=all` (resp. `pnpm-workspace.yaml` keeps `trustLockfile: true`) in a file that is not exactly what hosted mode creates; the file is left untouched (v5 records no provenance), remove the line if nothing else needs it. A file that is exactly hosted mode's own is deleted silently. | -| `maven_trusted_checksums_left` / `nuget_default_config_left` / `upstream_uv_override_removed` | rollback/remove `warnings[]`; vendor advisory event (takeover) | upstream restore (v5.0): `.mvn` config keeps the trusted-checksums resolver lines because it holds more than hosted mode writes; `nuget.config` now holds only the nuget.org source (delete it if hosted mode created it); a transitive `override-dependencies` entry hosted mode added to `pyproject.toml` was removed. | +| `maven_trusted_checksums_left` / `nuget_default_config_left` / `upstream_uv_override_removed` | rollback/remove `warnings[]`; vendor advisory event (takeover) | upstream restore (v5.0): `.mvn` config keeps the trusted-checksums resolver lines because it holds more than hosted mode writes; `nuget.config` now holds only the nuget.org source (delete it if hosted mode created it); a transitive `override-dependencies` entry hosted mode added to `pyproject.toml` (the one under its `# socket-patch hosted` comment) was removed; a user-authored override is never removed and never reported. | | `upstream_registry_fallback` | rollback/remove `warnings[]`; vendor advisory event (takeover) | upstream restore: a yarn berry, pnpm or vlt entry is restored from the version document of the registry the project resolves it against (`.yarnrc.yml` `npmRegistryServer`, the pnpm lock's sibling `.npmrc` `registry` / `@scope:registry` or pnpm-workspace.yaml `registry` / `registries`, vlt's node registry); that registry could not be read (e.g. it needs credentials), so the default registry's document was used and the restored tarball URL may not be the mirror's. | | `upstream_gem_stale_cache` | rollback/remove `warnings[]`; vendor advisory event (takeover) | upstream restore (#1260): a restored gem's `-.gem` is still in Bundler's cache dir (`cache_path`, default `vendor/cache`, resolved as for the Gem stale-install guard) and its sha256 is not the upstream one (the restored `CHECKSUMS` entry, else the rubygems.org compact index), or it could not be checked (`--offline`, a registry error). Bundler installs from that dir first, so a `bundle cache` taken while the hosted pin was live makes every later install fail on the upstream checksum (exit 37) or, on bundler < 2.6 frozen installs, keep installing the patched bytes. The detail names the file. Remedy: delete it, then run `bundle cache` to cache the upstream gem in its place (or `bundle install` if the project does not commit its cache; with the cache dir committed, a frozen install reads only the cache). Read-only: the restore never deletes it. Not raised for an archive whose sha256 matches upstream. | | `upstream_pnpm_tarball_setting_guessed` | rollback/remove `warnings[]`; vendor advisory event (takeover) | upstream restore (#902): nothing showed which pnpm wrote a hosted `pnpm-lock.yaml` (no unpinned registry entry that shows the setting, no `node_modules/.modules.yaml` install record, no package.json `packageManager` pin; for a Rush lock, no rush.json `pnpmVersion`), so its entries were restored with or without `tarball:` by pnpm 10's reading of `lockfileIncludeTarballUrl` (pnpm-workspace.yaml, else `.npmrc` `lockfile-include-tarball-url`), and pnpm 9 (which reads only `.npmrc`) or pnpm >= 11 (which reads only pnpm-workspace.yaml) would have read it the other way. The detail names the lock, the setting followed, the pnpm that disagrees and the entries. Remedy: pin the pnpm (package.json `packageManager`, or reinstall so the install record names it; rush.json `pnpmVersion` for Rush), or give the two files the same value so every pnpm reads it alike; a rollback or remove can then be redone by restoring the lock from version control and re-running. Not raised when evidence decided, when both files read the same on every pnpm, or when the tarball is one pnpm records regardless. | diff --git a/crates/socket-patch-core/src/patch/redirect/upstream/uv.rs b/crates/socket-patch-core/src/patch/redirect/upstream/uv.rs index 69ad8ddc3..367881fde 100644 --- a/crates/socket-patch-core/src/patch/redirect/upstream/uv.rs +++ b/crates/socket-patch-core/src/patch/redirect/upstream/uv.rs @@ -43,7 +43,9 @@ //! `extra == ''` terms name the extra, the rest is the declaration's //! own marker). An `overrides` entry the rewrite added for //! a transitive dependency is removed with its `override-dependencies` -//! line; +//! line — the one under the rewrite's ownership comment +//! (`python_script::HOSTED_OVERRIDE_MARK`); a user's own pin of the same +//! release has none and is kept (#411); //! * the metadata's `[tool.uv.sources]. = { url }` is removed. //! //! uv 0.2 `[[distribution]]` locks are refused (their artifact grammar @@ -1480,7 +1482,9 @@ fn restore_requirements( ctx: &Ctx<'_>, ) -> Result<(), String> { // A transitive dependency's `overrides` entry is the rewrite's own when - // the metadata's `override-dependencies` holds exactly the pin it adds. + // the metadata's `override-dependencies` holds the pin it adds, under + // its ownership comment; a user's own pin is restored like any other + // declaration. let transitive_override = meta.is_some_and(|m| pushed_override(m, hit).is_some()); for package in doc .get_mut("package") @@ -1569,19 +1573,30 @@ fn declares_directly(meta: &Metadata, hit: &Hit) -> bool { .any(names) } -/// The index of the `override-dependencies` entry the rewrite adds for a -/// transitive `hit` (`==`), when present. +/// The index of the `override-dependencies` entry the rewrite added for a +/// transitive `hit` (`==` under +/// [`HOSTED_OVERRIDE_MARK`](crate::utils::python_script::HOSTED_OVERRIDE_MARK)), +/// when present. Hosted mode keeps no ledger, so that comment is the only +/// evidence of ownership: an unmarked entry of the same spelling is the +/// user's own pin (the rewrite reuses it rather than adding one) and stays, +/// along with the lock's `[manifest] overrides` record of it (#411). fn pushed_override(meta: &Metadata, hit: &Hit) -> Option { if declares_directly(meta, hit) { return None; } let want = format!("{}=={}", hit.name, hit.version); - strings(tool_uv(&meta.doc).and_then(|u| u.get("override-dependencies"))) + tool_uv(&meta.doc) + .and_then(|u| u.get("override-dependencies")) + .and_then(Item::as_array)? .iter() - .position(|spec| { + .position(|value| { + let Some(spec) = value.as_str() else { + return false; + }; let compact: String = spec.chars().filter(|c| !c.is_whitespace()).collect(); canonicalize_pypi_name(pep508_name(&compact)) == hit.name && compact[pep508_name(&compact).len()..] == want[hit.name.len()..] + && crate::utils::python_script::is_hosted_override(value) }) } @@ -1717,21 +1732,34 @@ mod tests { /// Hosted rewrite of `six` into `original`, then `restore_metadata`: /// the pyproject must come back byte-identically (#524). fn assert_metadata_round_trips(original: &str) { + metadata_round_trip(original, false); + } + + /// [`assert_metadata_round_trips`] for a project or (`script`) a PEP 723 + /// script; whether the restore reported removing an override. + fn metadata_round_trip(original: &str, script: bool) -> bool { use crate::utils::python_lock::ArtifactSource; - let rewritten = crate::utils::python_script::rewrite_project_metadata( - original, - "six", - "1.16.0", - ArtifactSource::Url(HOSTED_SIX), - ) - .unwrap() - .expect("the rewrite adds a source"); + let rewrite = if script { + crate::utils::python_script::rewrite_script_metadata + } else { + crate::utils::python_script::rewrite_project_metadata + }; + let rewritten = rewrite(original, "six", "1.16.0", ArtifactSource::Url(HOSTED_SIX)) + .unwrap() + .expect("the rewrite adds a source"); assert!(rewritten.contains(HOSTED_SIX), "{rewritten}"); + let body = if script { + crate::utils::python_script::script_metadata(&rewritten) + .unwrap() + .1 + } else { + rewritten.clone() + }; let mut meta = Metadata { rel: "pyproject.toml".into(), text: rewritten.clone(), - script: false, - doc: rewritten.parse().unwrap(), + script, + doc: body.parse().unwrap(), }; let hit = Hit { index: 0, @@ -1745,12 +1773,53 @@ mod tests { origins: &[], bun_lockb: false, }; - restore_metadata(&mut meta, &hit, &ctx); + let removed = restore_metadata(&mut meta, &hit, &ctx); assert_eq!( meta.render().unwrap(), original, "rewritten was:\n{rewritten}" ); + removed + } + + const DATEUTIL_HEAD: &str = "[project]\nname = \"uvp\"\nversion = \"0.1.0\"\nrequires-python = \">=3.9\"\ndependencies = [\"python-dateutil==2.8.2\"]\n"; + + /// #411: the user's own `override-dependencies` pin of the exact release + /// being patched is reused by the hosted rewrite, so the restore must + /// leave it (and report no removal) instead of guessing it was added. + #[test] + fn restore_keeps_a_user_authored_override_of_the_patched_release() { + for overrides in [ + "override-dependencies = [\"six==1.16.0\"]\n", + "override-dependencies = [\"idna==3.7\", \"six==1.16.0\"]\n", + "override-dependencies = [\n \"six==1.16.0\",\n]\n", + ] { + let original = format!("{DATEUTIL_HEAD}\n[tool.uv]\n{overrides}"); + assert!( + !metadata_round_trip(&original, false), + "a user-authored override is not the rewrite's to remove:\n{original}" + ); + } + let script = "# /// script\n# dependencies = [\"python-dateutil==2.8.2\"]\n#\n# [tool.uv]\n# override-dependencies = [\"six==1.16.0\"]\n# ///\nimport six\n"; + assert!(!metadata_round_trip(script, true)); + } + + /// The override the hosted rewrite adds for a transitive dependency + /// carries its ownership comment and is removed again, into an existing + /// user array as well as a new one. + #[test] + fn restore_removes_the_override_the_rewrite_added() { + for tool_uv in [ + "", + "\n[tool.uv]\noverride-dependencies = [\"idna==3.7\"]\n", + "\n[tool.uv]\noverride-dependencies = [\n \"idna==3.7\",\n]\n", + ] { + let original = format!("{DATEUTIL_HEAD}{tool_uv}"); + assert!(metadata_round_trip(&original, false), "{original}"); + } + let script = + "# /// script\n# dependencies = [\"python-dateutil==2.8.2\"]\n# ///\nimport six\n"; + assert!(metadata_round_trip(script, true)); } const SUB_TABLE_SOURCES: &str = "[tool.uv.sources.idna]\nurl = \"https://files.pythonhosted.org/packages/e5/3e/idna-3.7-py3-none-any.whl\"\n"; @@ -1873,6 +1942,38 @@ mod declaration_tests { const HEAD: &str = "[project]\nname = \"uvp\"\nversion = \"0.1.0\"\nrequires-python = \">=3.9\"\n"; + /// #411: the lock's `[manifest] overrides` record of a user's own + /// `override-dependencies` pin gets its specifier back instead of being + /// dropped as the rewrite's; the one the rewrite added (its pin under + /// the ownership comment) is still dropped. + #[test] + fn manifest_override_of_a_user_pin_is_restored_not_dropped() { + let lock_text = format!( + "{}\n[manifest]\noverrides = [{}]\n", + lock( + &[spec("==2.8.2", None).replace("six", "python-dateutil")], + &[] + ), + six(None) + ); + let user = format!( + "{HEAD}dependencies = [\"python-dateutil==2.8.2\"]\n\n[tool.uv]\n\ + override-dependencies = [\"six==1.16.0\"]\n" + ); + let out = unwind(&user, &lock_text).unwrap(); + assert!( + out.contains(&format!("overrides = [{}]", spec("==1.16.0", None))), + "{out}" + ); + let added = format!( + "{HEAD}dependencies = [\"python-dateutil==2.8.2\"]\n\n[tool.uv]\n\ + override-dependencies = [\n {}\n \"six==1.16.0\",\n]\n", + crate::utils::python_script::HOSTED_OVERRIDE_MARK + ); + let out = unwind(&added, &lock_text).unwrap(); + assert!(!out.contains("[manifest]"), "{out}"); + } + /// #606 (a): a pin in `dependencies` and a floor in an extra. #[test] fn dependencies_and_extra_with_different_specifiers() { diff --git a/crates/socket-patch-core/src/utils/python_script.rs b/crates/socket-patch-core/src/utils/python_script.rs index 79b044afc..3374bfc74 100644 --- a/crates/socket-patch-core/src/utils/python_script.rs +++ b/crates/socket-patch-core/src/utils/python_script.rs @@ -155,6 +155,7 @@ fn rewrite_sources( direct: bool, layout: SourcesLayout, ) -> Result<(), String> { + let hosted = matches!(artifact, ArtifactSource::Url(_)); let (key, location) = match artifact { ArtifactSource::Url(location) => ("url", location), ArtifactSource::Path(location) => ("path", location), @@ -220,6 +221,8 @@ fn rewrite_sources( "Python project already overrides {name}; revert it before applying a patch" )); } + } else if hosted { + push_hosted_override(overrides, specifier); } else { overrides.push(specifier); } @@ -227,6 +230,44 @@ fn rewrite_sources( Ok(()) } +/// The comment the hosted rewrite puts on the line above each +/// `override-dependencies` entry it adds. v5 hosted mode keeps no ledger, +/// so this comment is the only evidence the upstream restore has that the +/// entry is socket-patch's to remove: an entry without it, even one spelled +/// exactly `==`, is the user's own pin and is kept (#411). +pub(crate) const HOSTED_OVERRIDE_MARK: &str = + "# socket-patch hosted: pins a patched transitive dependency; rollback removes it"; + +/// Whether an `override-dependencies` element carries +/// [`HOSTED_OVERRIDE_MARK`] (the hosted rewrite added it). +pub(crate) fn is_hosted_override(value: &Value) -> bool { + value + .decor() + .prefix() + .and_then(|prefix| prefix.as_str()) + .is_some_and(|prefix| prefix.contains(HOSTED_OVERRIDE_MARK)) +} + +/// Append `specifier` to `overrides` on its own line, under +/// [`HOSTED_OVERRIDE_MARK`]. An array the rewrite just created (empty) is +/// laid out multi-line with a trailing comma; an existing array keeps its +/// other elements as they were. Removing the element again (its decor goes +/// with it) restores the array's original bytes. +fn push_hosted_override(overrides: &mut Array, specifier: String) { + const INDENT: &str = " "; + let created = overrides.is_empty(); + let mut value = Value::from(specifier); + value + .decor_mut() + .set_prefix(format!("\n{INDENT}{HOSTED_OVERRIDE_MARK}\n{INDENT}")); + value.decor_mut().set_suffix(""); + overrides.push_formatted(value); + if created { + overrides.set_trailing_comma(true); + overrides.set_trailing("\n"); + } +} + fn contains_dependency(item: Option<&Item>, name: &str) -> bool { item.and_then(Item::as_array).is_some_and(|dependencies| { dependencies @@ -574,7 +615,7 @@ mod rendering_tests { .unwrap(); assert_eq!( transitive, - format!("[project]\nname = \"p\"\ndependencies = [\"requests\"]\n\n[tool.uv]\noverride-dependencies = [\"alpha==1.0.0\"]\n\n[tool.uv.sources]\nalpha = {{ url = \"{URL}\" }}\n") + format!("[project]\nname = \"p\"\ndependencies = [\"requests\"]\n\n[tool.uv]\noverride-dependencies = [\n {HOSTED_OVERRIDE_MARK}\n \"alpha==1.0.0\",\n]\n\n[tool.uv.sources]\nalpha = {{ url = \"{URL}\" }}\n") ); assert_settled(&transitive); // An existing `[tool.uv]` header gains the sources as its own @@ -760,7 +801,7 @@ mod rendering_tests { .unwrap(); assert_eq!( transitive, - format!("[tool.ruff]\nline-length = 100\n\n[tool.uv]\noverride-dependencies = [\"alpha==1.0.0\"]\n\n[tool.uv.sources]\nalpha = {{ url = \"{URL}\" }}\n\n[project]\nname = \"p\"\ndependencies = [\"requests\"]\n") + format!("[tool.ruff]\nline-length = 100\n\n[tool.uv]\noverride-dependencies = [\n {HOSTED_OVERRIDE_MARK}\n \"alpha==1.0.0\",\n]\n\n[tool.uv.sources]\nalpha = {{ url = \"{URL}\" }}\n\n[project]\nname = \"p\"\ndependencies = [\"requests\"]\n") ); assert_settled(&transitive); @@ -820,7 +861,7 @@ mod rendering_tests { .unwrap(); assert_eq!( transitive, - format!("tool.uv.sources.other = {{ git = \"https://example.test/other\" }}\ntool.uv.sources.alpha = {{ url = \"{URL}\" }}\ntool.uv.override-dependencies = [\"alpha==1.0.0\"]\n\n[project]\nname = \"p\"\ndependencies = [\"other\"]\n") + format!("tool.uv.sources.other = {{ git = \"https://example.test/other\" }}\ntool.uv.sources.alpha = {{ url = \"{URL}\" }}\ntool.uv.override-dependencies = [\n {HOSTED_OVERRIDE_MARK}\n \"alpha==1.0.0\",\n]\n\n[project]\nname = \"p\"\ndependencies = [\"other\"]\n") ); assert_settled(&transitive); } @@ -848,7 +889,7 @@ mod rendering_tests { ), ( "# /// script\n# dependencies = [\"requests\", \"beta\"]\n#\n# [tool.uv.sources]\n# beta = { git = \"https://example.test/beta\" }\n# ///\nprint('x')\n", - format!("# /// script\n# dependencies = [\"requests\", \"beta\"]\n#\n# [tool.uv]\n# override-dependencies = [\"alpha==1.0.0\"]\n#\n# [tool.uv.sources]\n# beta = {{ git = \"https://example.test/beta\" }}\n# alpha = {{ url = \"{URL}\" }}\n# ///\nprint('x')\n"), + format!("# /// script\n# dependencies = [\"requests\", \"beta\"]\n#\n# [tool.uv]\n# override-dependencies = [\n# {HOSTED_OVERRIDE_MARK}\n# \"alpha==1.0.0\",\n# ]\n#\n# [tool.uv.sources]\n# beta = {{ git = \"https://example.test/beta\" }}\n# alpha = {{ url = \"{URL}\" }}\n# ///\nprint('x')\n"), ), ]; for (script, expected) in cases { diff --git a/crates/socket-patch-core/tests/equivalence/python_lock_rewrite.golden b/crates/socket-patch-core/tests/equivalence/python_lock_rewrite.golden index dcb427b11..e0e37c16d 100644 --- a/crates/socket-patch-core/tests/equivalence/python_lock_rewrite.golden +++ b/crates/socket-patch-core/tests/equivalence/python_lock_rewrite.golden @@ -1,302 +1,302 @@ # One seeded uv / pylock / PEP 723 lock set + overrides + wheel metadata. # 0-4 cd5cd36a37fa8c9b 48a0e144464b8f8a -5-9 f58e23b53c07f972 7df91de609aadf9a -10-14 63a0aa035a8a4e90 ce91f93cd49ca4f5 +5-9 f58e23b53c07f972 75999b38c69c4eb8 +10-14 63a0aa035a8a4e90 11acef318dd3f602 15-19 7cf3d76e36752625 590f305643295efc 20-24 c7c648dc10c3c7cd 9fa1deaf96f07fe2 -25-29 831189dc733b8849 3ab9faa9395cf06f +25-29 831189dc733b8849 84549312d5b50708 30-34 dcb109d643382adf ade5041ad97eb6f3 35-39 99a313947928f593 040d41e8e286d342 -40-44 cf5611d067871c91 b9005c5ab4e2d992 +40-44 cf5611d067871c91 bec1d86832e78be6 45-49 04f0e41a9e302f59 703a8fae640714d8 -50-54 03d58da62810b2e4 2637b4af5665545c -55-59 daf9f41b5decbf2c 34103170b8df8696 +50-54 03d58da62810b2e4 e8dd94ea74dd1d17 +55-59 daf9f41b5decbf2c c8555affaeef1b02 60-64 58413f6f2f266d0d e269d6e79181da6a 65-69 cd4f77526796ec70 ffec6efe319265a7 -70-74 3befe3b6747c7c5d b1e8a696d2d54b16 +70-74 3befe3b6747c7c5d 5db4b142bfc674a2 75-79 f704740390513318 42df63da4590a254 80-84 6bb2704eadd90bbb 5ca41094d0424e3d -85-89 2b41ca85da12924d 65b152efd83c3bd6 +85-89 2b41ca85da12924d 4fa8ca1b59e12b20 90-94 b4f4d21d57b4e3e6 0f3435d61d7a36c1 95-99 1fcae5cb34b3557b c47c75663ff48676 -100-104 22d4b081083ec3cf 630cb1f82af66ee9 -105-109 b33352ae7c78a21f e20dfee24af86bff -110-114 459ff3efdff5f2cc c6e5134cb2c1fd85 -115-119 291d724de0819b8d 8466395f3165a0ef -120-124 21a80a5bc6b9e421 41fc3cf934fc6087 +100-104 22d4b081083ec3cf c96c490301f692ed +105-109 b33352ae7c78a21f bea4bd35a69bdd15 +110-114 459ff3efdff5f2cc 81712bc6d977c7c0 +115-119 291d724de0819b8d f5448022649e1124 +120-124 21a80a5bc6b9e421 1eedfb98cce3fef5 125-129 8e678fbd38ff1c68 a47bfa725066c0f2 -130-134 a38ee386aaf54bc9 047307c34ed923f7 +130-134 a38ee386aaf54bc9 4c03a39f151a7e81 135-139 f3c8324bccf53c32 ec9316e47aaf4eab 140-144 7d6c4b160a757e64 56ac168022c5a5f6 -145-149 e366e05fd9c0ef0b f16c3c8253ab5ddc -150-154 7f552bc377ac439b 121853d116c28aa3 +145-149 e366e05fd9c0ef0b fb53672d3a8f3bd1 +150-154 7f552bc377ac439b d1b393713d916f80 155-159 5c987ad06f4c2cf3 853fcb9da6efea74 -160-164 2fd97b5cdeea8344 34d616cba9ff2f92 +160-164 2fd97b5cdeea8344 4a2af11d90d6bbc2 165-169 8f16946d73613e52 4ee31b57d3a5fb45 -170-174 72c1e1cb26500151 4d8622bd269f21c5 -175-179 4333d230209fdfdd fe0ef3c12d1a0cb2 -180-184 70af4e6d0a9804eb 849fc5b3c32d6b64 +170-174 72c1e1cb26500151 07da3560a0bf3737 +175-179 4333d230209fdfdd 1ce61cb74433885a +180-184 70af4e6d0a9804eb a50449016f534bed 185-189 6073f94564a728c8 42f8708863320edf 190-194 0976869c3d0f4aeb 03f687f9a1ef3754 -195-199 6e26da934df4169e a2787877f35e9517 +195-199 6e26da934df4169e 33c08ab4ccc5ce89 200-204 fbb5bb450083c437 31aad032ae8b9c21 205-209 5f65204b08f141e8 b0f2b706aaac0850 -210-214 5325f0b8e4f86617 78fbabe1106e949b +210-214 5325f0b8e4f86617 52244908f002b1ae 215-219 93c1a1fd0318dd14 4dd9af60759027c9 220-224 4b3c1e25ed139fda ea1624f09c3d14b2 -225-229 01df8d39a686d542 6351804ffd423e35 +225-229 01df8d39a686d542 8c7911dafdc13d2f 230-234 d8671c2aa0925484 0bac935606117b80 235-239 c2ffbce64c565d4e 69b3aa958f41d110 240-244 8840614f5d6ed107 8e780f81f0f963a3 -245-249 a3a20836097b17a3 a0c928a84a61285a -250-254 55507d905e78d536 d0f0d350180f3eee -255-259 ddb6e7f50dc7b9a4 d1e8dd678ec4364f -260-264 9e561d5848a362eb c28304e6d6901fde -265-269 d94a03864c991b66 aa18c672fc3c2eaf +245-249 a3a20836097b17a3 e7d647ebe4acb5c1 +250-254 55507d905e78d536 3db4ef078698537d +255-259 ddb6e7f50dc7b9a4 74573807d9a5ab22 +260-264 9e561d5848a362eb b8ca2b7ed478437b +265-269 d94a03864c991b66 a1e761f976f07a29 270-274 d0100fe28bcc0b9f 420f0773032cf669 -275-279 c991021006094a2d bb0f59f239f75d75 -280-284 9630c4201e5eb600 bfc9c9e993e9a71a +275-279 c991021006094a2d 6bbae3ade35f43ac +280-284 9630c4201e5eb600 276f9d4d7d5524b6 285-289 fb53958c9f671828 5f7f1a56d0410550 -290-294 c5bf6275b89317cf 2b87546cfa85399e +290-294 c5bf6275b89317cf 7e3341f6a56d0554 295-299 99fb36209f586bca e891c6658cee191a 300-304 5240085dd621df82 458bf378d060d912 305-309 616cfc3aae79162c 9773426cddea96c8 -310-314 a386fe7bc32fc73e aebfc7302ea42601 -315-319 5d7084c26ae0f3f2 2a770b1138e80898 -320-324 e0a4ea3772d1038a 7c2702afd192fef0 +310-314 a386fe7bc32fc73e 3f5f54be7cb93049 +315-319 5d7084c26ae0f3f2 63616a7462620995 +320-324 e0a4ea3772d1038a 73f4cabd6f62f2b1 325-329 0cb388111d9a1b86 6c57e6841ecf35c3 330-334 d1c41d95d297d164 35fdd17d28531ad6 335-339 2d6db0a042990332 61f544ab33b2cfd6 -340-344 acfe94db4b59c187 164a716794d54313 -345-349 f443e9c02e4c493c 1836f9a125c48b47 -350-354 6b8189fa7c7eb359 75535c0ded362ece -355-359 48640c9838b42488 135f6304ae30656f +340-344 acfe94db4b59c187 45ece0e56bd210c5 +345-349 f443e9c02e4c493c c69bdb6548e13ca0 +350-354 6b8189fa7c7eb359 09371ad1064ca8e6 +355-359 48640c9838b42488 279989c235a1b232 360-364 86adc1124beaf310 ee7e33f8f8305703 -365-369 c75c9390e1ec4dc0 159ef5b3c823d104 +365-369 c75c9390e1ec4dc0 b29e2441298ccb44 370-374 4b47480d5c6430c8 eb537062c9b097a3 -375-379 97cadfe0779bf656 0345c0b1783881a7 +375-379 97cadfe0779bf656 9ab1bbb442319fc5 380-384 bae2ef0777128159 394248e293242674 385-389 a72fe500fd93b54b a48cd849bf320b7b 390-394 1bda7f0386bcb4b2 8a4c74b37267fb35 395-399 662e2ce03cc70051 5fed6d12d2490ddc 400-404 27e91e5f8d9d0500 06b82bdf156dad07 405-409 d97cfed3b6019a84 4c43f9bf02b1c878 -410-414 9fc1135cea15545b 82c68ccb78463e3d +410-414 9fc1135cea15545b be2a91c3665da64a 415-419 ec0440f6f542cdbe 167b4bffef187ba6 -420-424 820d32ca97f38bf1 d23974a3a1068894 +420-424 820d32ca97f38bf1 0ecad2dddb4eea7d 425-429 a187a84aad4ddd82 f5d0b8ab277a2913 430-434 63cab5602f883c2b e5605a0a65a3449f -435-439 6b51186155d6b708 29d92ee2415d97a6 -440-444 d3c75dad29457c53 4565a668f3b1af38 +435-439 6b51186155d6b708 e538bd19340bb105 +440-444 d3c75dad29457c53 30d025363bf2622b 445-449 5b312af32839186f ae824a4613425ce3 -450-454 867d9e5d19789b27 509f4c37ddd7e5c0 -455-459 845c435d60d254cd ed317c05f75fc6d8 +450-454 867d9e5d19789b27 83fb356046a4d10e +455-459 845c435d60d254cd c252519be14e8275 460-464 fe6ab0fb975606e6 1c2cf9bde750b81e 465-469 cf94bc0890135d7d fd4b8e2927bebd03 470-474 5e2dbff33d066336 2d8a71aa7154e62a 475-479 0479e5e66eeb0b35 b85602f8b33a3a40 -480-484 728477d2aff05013 1f45e83958ffd0fc +480-484 728477d2aff05013 44b10c0e085711e8 485-489 71a0a6cd3a0f1dc4 209f6097b55a6075 490-494 778ed33daefe5147 f2ef44e740b04752 -495-499 3f3ef0e47bc79f65 14e10c33f2200fd2 +495-499 3f3ef0e47bc79f65 ae0ae1306e3ff6b9 500-504 aa9adf3185bd29fd 5cb08498d8c7701d 505-509 45a1e1c9fbf16b34 8d22ee5d9c4a28c1 510-514 818d16cd8b3bec8a ade0d01f88cdff6f 515-519 c7422c418ed92126 4a93055b7f3ee09a -520-524 a3e57516f4ee56fe 5cd6cc5bb8431e8a +520-524 a3e57516f4ee56fe 06a47c0e77469fcd 525-529 554002fd18293950 43a791951252a9e9 530-534 70f5bc4e1811144d 2d5fece8c7f51bcc 535-539 3bc9d29e9245a772 202e07f57fcd5ad4 540-544 f2d746650f56eb6a a412eafd24000b57 -545-549 3ebc5e64e438a7ed 67e8d3c608595c3b -550-554 b9d3351453b65997 b218188b3377d409 -555-559 37bcc4d58a6d31ef 46055bd9e4a3bb42 -560-564 e03fbe4bdb0ce235 2484d12a07617823 -565-569 0b1e0cc286d8e2db 29a97162543d8b50 -570-574 0eca795339181b14 9129c77c05f88fc1 +545-549 3ebc5e64e438a7ed 39ece5aa2758497b +550-554 b9d3351453b65997 68c9a15ecf308f27 +555-559 37bcc4d58a6d31ef a265f9a2caf4552c +560-564 e03fbe4bdb0ce235 c2b10fbe263818f5 +565-569 0b1e0cc286d8e2db ea3a72e1357f016a +570-574 0eca795339181b14 4d67dc6131e1e0d7 575-579 5ca964a495b608c9 dccc25c013660626 580-584 c526bfcdbdb19c13 2c2c062689744a81 585-589 c0f55f7b738667c8 cf5507fcd05366b8 -590-594 9a57465f007322f6 fe36de2dc975e97d -595-599 60d49df8b1a1ed60 d2a9ec7caa9fafd6 -600-604 eb8f971fa2c853f1 4c047a0a600ee68c +590-594 9a57465f007322f6 89832f8515a2ef5b +595-599 60d49df8b1a1ed60 e340ad56f3c2b7b2 +600-604 eb8f971fa2c853f1 c041b158a6e15cff 605-609 b9a0d832ab3703a4 33a266c3126b7268 610-614 b7cd2826e9ed4bad 1dae82316d44d372 615-619 dd6ea62b42964c5d efea9c54f9b7df69 -620-624 f8cafac82b3a2938 cc34678cbba8cbc4 +620-624 f8cafac82b3a2938 056ff72402397371 625-629 71dda2f6b4fcf3ad 35647b7151bbe854 630-634 c0625fb844d5bd9c b51049d5a507e712 -635-639 89ce072ed93bd8b3 97c29483a27d20fb +635-639 89ce072ed93bd8b3 0578500fea7bcf61 640-644 9a060a7b22a5ea63 3487fe4c2cec2c2a -645-649 4f18a0402cf96703 3a62197bc682135c +645-649 4f18a0402cf96703 bf14b749f94b2db2 650-654 799d0d7818b8ecdd 8a9bfc4768db7bb8 655-659 0f78bdef454a269d 8926ce36aa150d51 660-664 f1cd906360c54cfa e85fffa3833a1371 -665-669 a5564a8ea2270906 ca29a80390668675 +665-669 a5564a8ea2270906 148be46a43610317 670-674 c196359f0ba0e6c1 b7bf3747d5fbf62b 675-679 e0011b91b2f33aef 83b29f9e3c6941d3 -680-684 54159021ceb1a6a4 aee86cac7c126b10 +680-684 54159021ceb1a6a4 38d783f189586236 685-689 8121cfcade405227 420a3a319d2d57be -690-694 841fe56913ede31a 9a4bf80f37fc9789 -695-699 968e63891e83acad fa37072b6e4e7450 +690-694 841fe56913ede31a 2396629113d82883 +695-699 968e63891e83acad 7c71d615d9bf67fb 700-704 b53560cda70aadb8 bbaa6aa02e40ab6a 705-709 83bece44cdd8d964 8ce390034469015e -710-714 0096b81bcf606d08 a05f22cc7d6e9e1c +710-714 0096b81bcf606d08 8f7e9fd300bbcf23 715-719 afbe3acb8a936112 6c033a3cb4d2f9d3 720-724 e212d53b068c9367 aadfdb29a8bcc99e -725-729 b532d08326d3a1c1 091c5a374fc1377c +725-729 b532d08326d3a1c1 2de2fbb2c43c7f8a 730-734 fb89f0ab21e41184 491db122776600fc 735-739 7f21245b19048f6d 2138cf6efd2f4588 740-744 f5afc189901e25a7 e2e144556544337d 745-749 0d669a0c40d9ec06 b97784b37ffa6263 -750-754 a2da5259aa3dc6bb ea15a0ee1b498b25 +750-754 a2da5259aa3dc6bb 012fdbd877db9c91 755-759 d5fed3964610e80b f12a5d7653e27e6f 760-764 eb74f4ed1d526a82 959dc5c757d52c8d -765-769 446fbe655c39474a 049f159ef1f568d2 -770-774 3ed2f6336ae1d8b4 0166b4a53d4e4cef +765-769 446fbe655c39474a 36b1b969e02be22c +770-774 3ed2f6336ae1d8b4 93d42391b807598c 775-779 0c443aac3fea26b0 24950068997cf758 780-784 fff5de443b6d9df3 aea7405cafc4c5b7 -785-789 95fa315efc5c1f38 d09cb03d8bcaa1c0 +785-789 95fa315efc5c1f38 b468e5b40c9f7e5f 790-794 f7e4a7ca516970fa af6b032b8a30c9e4 795-799 c26cb82b9d6af0ae 7fe79ef93103d105 800-804 a278c8bb8be83819 6388df7540367932 -805-809 69d4f412ccd64cea 37cd7bcf3db57250 -810-814 76e6c0857a866513 e8dce9cbdaf9c660 +805-809 69d4f412ccd64cea 75694104c6c260c6 +810-814 76e6c0857a866513 a054910d270c4865 815-819 4bf0e13795a7faff 73bb5b3877877d35 820-824 e661808004ced5e0 b5ddf35a824246bf -825-829 d25f4793e042db64 d0a1e91738e2ec76 +825-829 d25f4793e042db64 c547d6d2f42aab92 830-834 e3d03e8ef8b1295d ece90eb006469f2c -835-839 c00270de24a49e16 cf44816b0061e2ae -840-844 865292082469a123 114514f32ba03093 +835-839 c00270de24a49e16 fff84b0888928de4 +840-844 865292082469a123 3a61750ab0484c76 845-849 0a2f4f3e161db2bd c5d2f7f0c3a95ec8 -850-854 d5b245a2d4762809 732ca28e3d4297b0 -855-859 d7a4147ec83ccdf3 6aa69904a771b1be -860-864 e0dfd4ee3b9b9115 bbfe2b44c90238ee +850-854 d5b245a2d4762809 7875eeafd9b0852c +855-859 d7a4147ec83ccdf3 77002587e0e6b904 +860-864 e0dfd4ee3b9b9115 0ecfe32c7b48c46a 865-869 3e913b7411e46c27 4306522989316626 -870-874 fdd6c8ad6bcba04e bad87cd34faa9fff -875-879 daeef0f506171b5e 68cb56df14f44059 +870-874 fdd6c8ad6bcba04e 1882f07d3fed58b1 +875-879 daeef0f506171b5e ecf437a4a9aaa27b 880-884 a19a9111ca539727 78f4d9f2f0dd1801 -885-889 4964fd890aa0994b 3c93b27e52621833 -890-894 50069923d0e0ff0c a3c5804a9da388fc +885-889 4964fd890aa0994b e784bc10d7654d18 +890-894 50069923d0e0ff0c 6abc83e6c4ad3382 895-899 45a6202dc931bd35 ddc86e63ebde42c6 900-904 3e4b61b6dfc3922b 83e3365600063210 -905-909 c91a83be7091fe1c 457ee81515713cc2 -910-914 8418b5e59791bc82 9306a002b60831fd +905-909 c91a83be7091fe1c 24162906c0e7bfe9 +910-914 8418b5e59791bc82 867fa3281db7acf2 915-919 5a056b11f328365b e87365882f0beeba 920-924 34137d01c0b33616 25eb24321c54f780 925-929 2bfe9d227e06cc61 36a2a2804e7199c0 -930-934 44414e0793c1989b c88f218576317d18 -935-939 2388bd7d5fdcaea3 599467bdcd4949b8 +930-934 44414e0793c1989b 1ad25b23895a8f7d +935-939 2388bd7d5fdcaea3 be8347aa8ab22131 940-944 9526b9c0ef958cfb 0bb7947f46f77e87 945-949 c82059b88e2418d3 0b69206a8bdd92aa 950-954 2af969418fd97751 0d8028b27ca53895 955-959 cb5af4f26e818f69 35a711c543af79eb 960-964 703724ea36030a9a fcdcb792020ab11d -965-969 a5f349b716e2c17b accc4d3b52b55f17 -970-974 2c51d78e4d21f34a d97e1ecca67f167c -975-979 02fe70fe43798656 1382eae2605e3b7d +965-969 a5f349b716e2c17b 9d66821879c38a70 +970-974 2c51d78e4d21f34a a2def4c7cf5ff7cd +975-979 02fe70fe43798656 7814a06ce9bc2f43 980-984 2dfdeb1d730d437f a0d94833e09775ea -985-989 c0ce894b61174b60 732049e217f02ccb +985-989 c0ce894b61174b60 19c66bd535d5d3ee 990-994 a4c96d873de9cde3 eb3b3c6230974260 -995-999 3b004642590efb27 d7ebad60ceec36e0 -1000-1004 1e11b2228a87e2cd 0727318c8714df42 +995-999 3b004642590efb27 e3d1abbe834ad7fc +1000-1004 1e11b2228a87e2cd 12b7aab35f50be29 1005-1009 863857d4840e1755 355fdf9286f05798 1010-1014 f32eb531a0227019 b9b5a3a04eecda96 -1015-1019 5df98b07a3f6fa22 de4ce5e33e0d1833 +1015-1019 5df98b07a3f6fa22 13becee02a1664a2 1020-1024 7788148d1188683a 489900f10b3cb72c -1025-1029 2a42ee2c74e792bf 434d0d92660eb334 -1030-1034 8615096392ecaf53 e781914100066bf6 +1025-1029 2a42ee2c74e792bf 1ea623632db51651 +1030-1034 8615096392ecaf53 eb809bbae88c2982 1035-1039 c24e3d3e2b5b3a7c eacecb30a4ac9cb7 1040-1044 7940b56d09ea5bc3 2eb630023ef89bd6 -1045-1049 5be1c725b126b43d 36356c5c4b00e9bd +1045-1049 5be1c725b126b43d e2be386d181e5b93 1050-1054 baf53597dd1ee0f7 bc2a9fe2197ec4b7 -1055-1059 89da0c30103093c2 9cc3743396a581ac +1055-1059 89da0c30103093c2 2aa998e0f1f21b96 1060-1064 088462cc1aad7bca 48a9e7854dbc4dc5 1065-1069 b3d2b22d55140c4d 5565fb9078c47532 1070-1074 744a72bd25aa8f8a 068bb08e149f4464 1075-1079 b865bc68064f3bf3 fef6ee44b83a0b99 -1080-1084 22a031b03ca02431 1e2593e8af06cfbd +1080-1084 22a031b03ca02431 6c8443bf709e07a0 1085-1089 7fc382e8a1cfb392 9b87d1e77b5a7538 1090-1094 09636a2b50a36582 319c81aa9068c32e -1095-1099 848d4cb5147266ea abb36a2405d57084 +1095-1099 848d4cb5147266ea 4aee1674aed627ed 1100-1104 717a47c102e234ea 5579c18523a5832c -1105-1109 b86d27ca80e7477d 51c62ff51c8af2e4 +1105-1109 b86d27ca80e7477d 00301364a11e3c8a 1110-1114 e75533c276ca26b6 d7616af8e73b78de -1115-1119 0967dca7a3b7f0db e6760b2ab436b96a +1115-1119 0967dca7a3b7f0db 9f9f702b1ebf2b52 1120-1124 2b3d27a962eeecaa 6bbca72310c14bb7 -1125-1129 4c0f197f16fdc203 ae282d0c8193cd22 -1130-1134 b8c883083e2354b4 6b874f3cfe5a8fc9 -1135-1139 052826a8ca213062 6bda0887d04230ba -1140-1144 643000c4068a73dc 3fb8ade336a5c7d6 +1125-1129 4c0f197f16fdc203 01b4ba3d9dfd2cb1 +1130-1134 b8c883083e2354b4 e45c7b0c69d9f2b3 +1135-1139 052826a8ca213062 7cf591ec1d8fbd99 +1140-1144 643000c4068a73dc 3e49d60c36f682fd 1145-1149 a20dbdc962bf496d 480ad4ea25e080c5 1150-1154 a8ff0a76fb490212 64986e06854ec675 -1155-1159 265ef1e7e4d619b0 e1c407246e3db283 +1155-1159 265ef1e7e4d619b0 39f15128482bd634 1160-1164 fd031848e1246ce5 be60639cbdf765b0 -1165-1169 46392bbe676ae180 85e1f076d383b5fb -1170-1174 9ed9aa2666accf82 8ce01f5933288267 +1165-1169 46392bbe676ae180 4576a4072bbea30b +1170-1174 9ed9aa2666accf82 08224ec1b23ea5db 1175-1179 42ba5427c32b6a50 f74c503679d95c63 -1180-1184 ec53e605cb4007b0 9c2343af621629d9 -1185-1189 a9bca1c3f2f28d14 730d26cf221de4a6 -1190-1194 99c3c937889a535d 6c0326f584d4cc47 +1180-1184 ec53e605cb4007b0 c99cfb38d4eb1f79 +1185-1189 a9bca1c3f2f28d14 380cee83a22a9e81 +1190-1194 99c3c937889a535d 832e7d93f711a7a4 1195-1199 516dc4d7731053d5 b805922b219f6337 -1200-1204 615780e5c51bd99d 1283e8e570bda37e -1205-1209 2ba50ff0fb6738c8 9da0a95622af4322 +1200-1204 615780e5c51bd99d 3bad989b2e4a0c9d +1205-1209 2ba50ff0fb6738c8 f6fcc74b42dd88e7 1210-1214 945fc79f04d19aaa 00119cb67fa3ecd6 1215-1219 0f1fd24ee8266b2f e7b94f1e48147a90 1220-1224 d00cf5cc9e90ba28 231dd0874c6755f5 1225-1229 d297953e40966981 df2a03c51d6c3fdc -1230-1234 2b75e34b10cb22be 670c47a3cce7618c -1235-1239 299fb21e399aef5d 821efaa24f2b62b9 +1230-1234 2b75e34b10cb22be ed005080d9665ba7 +1235-1239 299fb21e399aef5d 9efbbdd5f61c814e 1240-1244 c0ae0ef2eacb1d20 3edd06583588d801 1245-1249 8cece7e0363ae620 512797b949f264fd -1250-1254 124798b1ca2185da 57a14aa19e34660c +1250-1254 124798b1ca2185da b109b99694d7f831 1255-1259 32bb20f47d09e0fd f88d92dd1bcada2c 1260-1264 a90cc7dbee7863ee a4f79bdb0ab09720 -1265-1269 9601afdc614c3378 4611ad1016b5130b +1265-1269 9601afdc614c3378 c0724f621dccf436 1270-1274 e4027cab6820ab9c 6ce85e6ae2c08b17 -1275-1279 52f35f77c626c7a9 7d0b26ff90d6b6e2 +1275-1279 52f35f77c626c7a9 3abae8154491db24 1280-1284 54db489225a8498f 9ced5547bd54c1a9 -1285-1289 503688b417683963 5b7faaa1a0713bfd -1290-1294 0ec750caf91a885a b95d052756067610 +1285-1289 503688b417683963 aef1aee8bc4ac267 +1290-1294 0ec750caf91a885a b76dabc7bb1ae36b 1295-1299 57b68256c467948e 48c3046250deef23 1300-1304 f69a72cf286243a6 7a99eefa76f2470d 1305-1309 5427028ca0307488 b63f19108a0245c6 -1310-1314 687bd0b688c5245a 928623220e0baeef +1310-1314 687bd0b688c5245a b59934dfd01b315c 1315-1319 a3c063f7319cc243 d45a129e78008a8e 1320-1324 f71d4ea9b4e443ea 48b0bff72e8cc16c -1325-1329 36b1c933b4769bef 66255eb274356b46 -1330-1334 12fec017822c9408 bb5cb44c0018f1f2 +1325-1329 36b1c933b4769bef d3794598cba32e40 +1330-1334 12fec017822c9408 5e641f7a680d56c8 1335-1339 f2554c70f5b6c871 4f78edd9e58c2c92 1340-1344 eb3f9210aee55fa0 2421aa9dc78a887f -1345-1349 2227034cb8224e92 4d638b363a59f14a -1350-1354 d1c3cc3f3053abef 6517564f58e88568 +1345-1349 2227034cb8224e92 6e9c0ec28caf5ebb +1350-1354 d1c3cc3f3053abef 628e65bcd7739e72 1355-1359 837b255beca431d9 ea6849feb7fcc751 1360-1364 5a0320d1b8d0c441 41b409e99d3d6407 1365-1369 bc3c4bdab54f5895 8e01f8a9337c54eb -1370-1374 5b91bc73f002c848 5ce79828e38e3251 -1375-1379 b942d2d527e313bb f8bc89701ecdb22f +1370-1374 5b91bc73f002c848 871b91e8470daec6 +1375-1379 b942d2d527e313bb 659eee69e96502c0 1380-1384 ba26e589d1e33e42 c16656410a682f46 -1385-1389 814d598e06f65107 4e0785c55962a338 +1385-1389 814d598e06f65107 da581797f0d135d1 1390-1394 b086f62b2050c60c 86d8cf73e159021f 1395-1399 b26420e6d29fdb12 4e4a263e2423589f -1400-1404 f9fe3b626f1686b5 7e7fb731f6c82704 +1400-1404 f9fe3b626f1686b5 cef2ca1c367efd3c 1405-1409 4e57a3753006f235 bce4cb677d18c7a8 1410-1414 115e306882ded7e8 71313b54a3fa6c86 1415-1419 434caf3c3910b014 bf4169615aefe9c5 1420-1424 05902fd403f63f45 0944208a7b10e1f2 1425-1429 8ab91ea0295bfb52 a24c343175848041 1430-1434 3484e596f0cec9e4 4888e0644305f3e7 -1435-1439 13c16ded50903e22 c3274156d1ccc915 +1435-1439 13c16ded50903e22 c4ffe4dd5943efca 1440-1444 31e0740b70544201 2c7a5fe6c18d9400 1445-1449 8be55a7cd8438be9 67b24598732fa3fe 1450-1454 e9d1c354908dc7d5 029a1152a0c94435 -1455-1459 c8229a6a88eec0ac 8768bc139f54bb69 -1460-1464 ce73f815cae74496 de3ace466142c7e6 +1455-1459 c8229a6a88eec0ac 80d9c92c73325cb7 +1460-1464 ce73f815cae74496 bb6784e45e8f2626 1465-1469 1695babf780735fd cd1492eabdb7ef4a 1470-1474 7285c5cca58b9f85 9ebcb3c0e2ee91ad -1475-1479 826e8660179fe16a 83cc3b42bc69dce7 +1475-1479 826e8660179fe16a 66fd8f473ce0d8ea 1480-1484 8ecf1216c69ed810 69f317816faa2b4b -1485-1489 8a3905febae9ece0 03ac60bf7554ad65 +1485-1489 8a3905febae9ece0 f893373add948ea0 1490-1494 2f1c19a2427058be 0a940a145b4b89ca 1495-1499 952ea603e646e84a 077b55523590479c diff --git a/docs/testing/uv-compatibility.md b/docs/testing/uv-compatibility.md index 97b67ecec..36f33b95c 100644 --- a/docs/testing/uv-compatibility.md +++ b/docs/testing/uv-compatibility.md @@ -117,7 +117,10 @@ frozen, locked, and ordinary installation outcomes separately where supported. the repointed entry under `--locked`, 0.5.5 accepts it — the effective boundary is 0.5.5; the advisory keeps its `0_5_6` name. - Transitive targets are wired through `[tool.uv] override-dependencies` plus - a `[tool.uv.sources]` entry. uv applies sources to overrides only from + a `[tool.uv.sources]` entry. Hosted mode puts a `# socket-patch hosted: …` + comment line above the override entry it adds; rollback / remove remove + only a marked entry, so a user's own `==` override survives + the round trip (#411). uv applies sources to overrides only from 0.5.6: on 0.2.35–0.5.3 `--frozen` installs the patched wheel from the lock, but a plain `uv sync` re-resolves the override against the registry and reinstalls the pristine wheel (and rewrites the lock). The CLI cannot tell