From d8e2b06bddbceb8167b7d9cbda9fe617607541b5 Mon Sep 17 00:00:00 2001 From: Mikola Lysenko Date: Thu, 17 Sep 2026 19:58:41 -0400 Subject: [PATCH 1/3] Support hosted and vendored PDM patches on a shared pdm.lock rewriter Adds hosted PDM redirects and refactors the vendored PDM backend onto one validated `pdm.lock` rewriter (`utils/pdm_lock.rs`). Hosted `scan --mode hosted` rewrites the target `[[package]]` to the hosted wheel URL + patched SHA-256 (`redirect_pdm_lock_package`); vendored wires the same unit to a committed wheel. Both support the legacy `[metadata.files]` table and `extras` entries, preserve line endings and non-canonical spacing, are idempotent, and leave `pyproject.toml` / `content_hash` untouched. Supported lock formats are `2` (PDM 0.12-1.4) and `4.3`-`4.5.1` (PDM 2.8+); `3.1` / `4.0`-`4.2` (PDM 1.8-2.7) and unknown formats are refused before any write. Hardening beyond the original change: - Hosted lock-only checkouts are discovered and redirected: the lock inventory now reads `pdm.lock` (discovery-only, mirroring poetry). Vendored keeps refusing a lock-only checkout since PDM installs into `__pypackages__`, which the crawler does not probe. - A re-scan after an external `pdm lock` rebases the ledger's edits onto the relocked text. PDM un-patches AND may reflow line endings (CRLF -> LF) on relock, so for the pdm edit kind the rebase adopts the fresh `original` (the relocked registry fragment); poetry's relock keeps the patch and keeps its older original, so its path is unchanged. - When several Python lockfiles coexist, `uv.lock` and `poetry.lock` drive hosted PyPI redirects ahead of `pdm.lock`; a leftover `pdm.lock` neither blocks a live redirect nor is falsely attested. The same predicate gates the redirect dispatch and the hosted confirmation filter. Adds byte-exact `pdm-native` fixtures and CLI-level hosted regression tests (lock-only redirect + attest + rollback, legacy `[metadata.files]`, and relock-reflow convergence). Co-Authored-By: Claude Opus 4.8 --- .gitattributes | 2 + crates/socket-patch-cli/CLI_CONTRACT.md | 3 +- .../src/commands/scan/hosted.rs | 34 +- .../tests/in_process_redirect_pdm.rs | 420 ++++++++++++++ .../src/patch/redirect/mod.rs | 56 +- .../src/patch/redirect/pdm.rs | 129 +++++ .../src/patch/redirect/replay.rs | 7 +- crates/socket-patch-core/src/utils/mod.rs | 1 + .../socket-patch-core/src/utils/pdm_lock.rs | 426 +++++++++++++++ .../src/vendor/lock_inventory.rs | 64 ++- .../socket-patch-core/src/vendor/pypi_pdm.rs | 514 ++++++------------ .../fixtures/pdm-native/0.12.3-extras.lock | 42 ++ .../tests/fixtures/pdm-native/0.12.3.lock | 16 + .../tests/fixtures/pdm-native/1.15.5.lock | 16 + .../tests/fixtures/pdm-native/2.0.3.lock | 16 + .../tests/fixtures/pdm-native/2.1.5.lock | 16 + .../tests/fixtures/pdm-native/2.10.4.lock | 18 + .../tests/fixtures/pdm-native/2.11.2.lock | 19 + .../tests/fixtures/pdm-native/2.17.3.lock | 22 + .../fixtures/pdm-native/2.29.2-extras.lock | 49 ++ .../tests/fixtures/pdm-native/2.29.2.lock | 22 + .../tests/fixtures/pdm-native/2.3.4.lock | 16 + .../tests/fixtures/pdm-native/2.6.1.lock | 21 + .../tests/fixtures/pdm-native/2.7.4.lock | 21 + .../tests/fixtures/pdm-native/2.8.2.lock | 19 + .../tests/fixtures/pdm-native/2.9.3.lock | 19 + .../tests/fixtures/pdm-native/README.md | 7 + 27 files changed, 1634 insertions(+), 361 deletions(-) create mode 100644 crates/socket-patch-cli/tests/in_process_redirect_pdm.rs create mode 100644 crates/socket-patch-core/src/patch/redirect/pdm.rs create mode 100644 crates/socket-patch-core/src/utils/pdm_lock.rs create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/0.12.3-extras.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/0.12.3.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/1.15.5.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.0.3.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.1.5.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.10.4.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.11.2.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.17.3.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.29.2-extras.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.29.2.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.3.4.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.6.1.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.7.4.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.8.2.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/2.9.3.lock create mode 100644 crates/socket-patch-core/tests/fixtures/pdm-native/README.md diff --git a/.gitattributes b/.gitattributes index 92ff3b6a..57f48b05 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,3 +3,5 @@ # golden.test.ts). EOL conversion on checkout (Windows CRLF) breaks the # byte-for-byte comparison, so they are checked out exactly as committed. crates/socket-patch-core/tests/fixtures/redirect/** -text + +crates/socket-patch-core/tests/fixtures/pdm-native/*.lock -text diff --git a/crates/socket-patch-cli/CLI_CONTRACT.md b/crates/socket-patch-cli/CLI_CONTRACT.md index fff18dde..6558d95a 100644 --- a/crates/socket-patch-cli/CLI_CONTRACT.md +++ b/crates/socket-patch-cli/CLI_CONTRACT.md @@ -120,7 +120,7 @@ For a **9.0 root lock**, the CLI ensures `pnpm-workspace.yaml` carries `trustLoc `scan --mode hosted` (== `--redirect`) swaps the in-place apply for the registry-redirect pipeline: discover → resolve hosted-patch references (grant token + integrity + per-dep registry override) → rewrite ONLY the patched dependencies' lockfile / registry-config entries to point at the hosted packages. A dep counts as **redirected** only when its hosted-artifact URL (or per-dep registry index URL, or — for golang — the `patch.socket.dev/gopatch/` module path) actually landed in a project file — a granted reference whose rewriter found nothing to edit is neither recorded nor attested. Re-runs over already-rewritten output record zero new edits. JSON output gains a `redirect` sub-object: `{ mode: "hosted", redirected, rewrittenFiles, skipped, warnings, dryRun }` (`mode` is additive so consumers can dispatch without inferring it). Rewriter warnings carry stable `redirect_*` codes (e.g. `redirect_npm_no_lockfile`, `redirect_gradle_manual_snippet`, `redirect_golang_unsupported`); new codes are additive (MINOR). Refusals stay fail-closed with a diagnosis that names the actual cause: a yarn-berry lock entry resolving through a non-`npm:` protocol keeps `redirect_yarn_berry_unsupported_protocol` with the entry's ACTUAL protocol in the detail — except socket-patch's OWN vendored wiring (a `file:` range into `.socket/vendor/`), which gets the distinct `redirect_yarn_berry_vendored_entry` code whose detail names the retirement path (`remove ` per package, or `vendor --revert` which unwinds every vendored package, then re-run `scan --mode hosted`). Both leave the entry byte-identical; neither changes exit code or status. -The rewriter reads a fixed set of candidate files from the project root: the npm-family locks (`package-lock.json`, `npm-shrinkwrap.json`, `pnpm-lock.yaml`, `shrinkwrap.yaml`, `yarn.lock`, plus `.yarnrc.yml` for the berry cache-config gate and `bun.lock`), `requirements.txt` / `uv.lock` / `Pipfile.lock` (pipfile-spec 6; see the Pipenv section below) / `poetry.lock` (every Poetry lock generation from 1.0 on — the 0.12 `[metadata.hashes]` layout is refused because that installer ignores URL sources; a Poetry < 1.4 writer additionally gets `redirect_poetry_stale_install_risk`, see `docs/testing/poetry-compatibility.md`), `Cargo.toml` / `Cargo.lock` / `.cargo/config.toml` (plus the legacy extensionless `.cargo/config` — cargo reads that spelling in preference when both exist, so the managed `[registries.…]` block is written into whichever one is present), `composer.lock`, `nuget.config` / `packages.lock.json`, `Gemfile` / `Gemfile.lock`, `pom.xml` (+ `.mvn/maven.config` / `.mvn/checksums/checksums.sha256` for maven Trusted Checksums merge, and the Gradle build scripts read only to trigger the manual-snippet warning). **npm-family flavor coverage**: package-lock / npm-shrinkwrap, pnpm (root OR any nested `*/pnpm-lock.yaml`), yarn classic, **yarn berry** (`yarn.lock` entry only — `resolution: ::__archiveUrl=` + `yarnBerry10c0` checksum; cacheKey `10c0` and `.yarnrc.yml compressionLevel 0` gated by `redirect_yarn_berry_cache_unsupported`), and **bun** (text `bun.lock` lockfileVersion 1 or 2 — bun 1.3/1.4 share one emitted grammar; a binary `bun.lockb` with no text lock is auto-migrated to text via `bun install --save-text-lockfile --frozen-lockfile --lockfile-only` before the read, recorded as a `removed` FileEdit; `redirect_bun_lockb_would_migrate` on `--dry-run`, `redirect_bun_lockb_unsupported` when the migration is unavailable). **Rush monorepos**: when `rush.json` is present the rewriter also reads `common/config/rush/pnpm-lock.yaml` and each `common/config/subspaces//pnpm-lock.yaml` (sorted for determinism) under their repo-relative keys and repoints them in place; editing them emits `redirect_rush_repo_state_stale` when `common/config/rush/repo-state.json` exists (the `pnpmShrinkwrapHash` desync is refreshed by `rush update`, which the redirect survives). **maven** is fail-closed via version suffixing: a `mavenSuffixedVersion` + `mavenPomSha256` override pins the Socket-only `-socket.` by rewriting the literal `` (`redirect_maven_dep_version`) or adding a `` entry (`redirect_maven_dep_management_added`), plus optional Trusted Checksums (`redirect_maven_trusted_checksums`, conflicts as `redirect_maven_trusted_checksums_conflict`); a `${property}` version is refused (`redirect_maven_dep_unpinned`), a non-matching literal skipped (`redirect_maven_dep_version_mismatch`), and an override without a suffixed version falls back to same-GAV repository injection (`redirect_maven_same_gav_fallback`, NOT fail-closed). +The rewriter reads a fixed set of candidate files from the project root: the npm-family locks (`package-lock.json`, `npm-shrinkwrap.json`, `pnpm-lock.yaml`, `shrinkwrap.yaml`, `yarn.lock`, plus `.yarnrc.yml` for the berry cache-config gate and `bun.lock`), `requirements.txt` / `uv.lock` / `Pipfile.lock` (pipfile-spec 6; see the Pipenv section below) / `poetry.lock` (every Poetry lock generation from 1.0 on — the 0.12 `[metadata.hashes]` layout is refused because that installer ignores URL sources; a Poetry < 1.4 writer additionally gets `redirect_poetry_stale_install_risk`, see `docs/testing/poetry-compatibility.md`) / `pdm.lock` (PDM lock formats `2` and `4.3`–`4.5.1`; the identity-losing `3.1` / `4.0`–`4.2` formats and unknown future formats are refused with `redirect_pdm_refused`, and a lock-format-`2` writer additionally gets `redirect_pdm_legacy_sync_required`, see `docs/testing/pdm-compatibility.md`; when `uv.lock` or `poetry.lock` sits beside it they drive and `pdm.lock` is left alone), `Cargo.toml` / `Cargo.lock` / `.cargo/config.toml` (plus the legacy extensionless `.cargo/config` — cargo reads that spelling in preference when both exist, so the managed `[registries.…]` block is written into whichever one is present), `composer.lock`, `nuget.config` / `packages.lock.json`, `Gemfile` / `Gemfile.lock`, `pom.xml` (+ `.mvn/maven.config` / `.mvn/checksums/checksums.sha256` for maven Trusted Checksums merge, and the Gradle build scripts read only to trigger the manual-snippet warning). **npm-family flavor coverage**: package-lock / npm-shrinkwrap, pnpm (root OR any nested `*/pnpm-lock.yaml`), yarn classic, **yarn berry** (`yarn.lock` entry only — `resolution: ::__archiveUrl=` + `yarnBerry10c0` checksum; cacheKey `10c0` and `.yarnrc.yml compressionLevel 0` gated by `redirect_yarn_berry_cache_unsupported`), and **bun** (text `bun.lock` lockfileVersion 1 or 2 — bun 1.3/1.4 share one emitted grammar; a binary `bun.lockb` with no text lock is auto-migrated to text via `bun install --save-text-lockfile --frozen-lockfile --lockfile-only` before the read, recorded as a `removed` FileEdit; `redirect_bun_lockb_would_migrate` on `--dry-run`, `redirect_bun_lockb_unsupported` when the migration is unavailable). **Rush monorepos**: when `rush.json` is present the rewriter also reads `common/config/rush/pnpm-lock.yaml` and each `common/config/subspaces//pnpm-lock.yaml` (sorted for determinism) under their repo-relative keys and repoints them in place; editing them emits `redirect_rush_repo_state_stale` when `common/config/rush/repo-state.json` exists (the `pnpmShrinkwrapHash` desync is refreshed by `rush update`, which the redirect survives). **maven** is fail-closed via version suffixing: a `mavenSuffixedVersion` + `mavenPomSha256` override pins the Socket-only `-socket.` by rewriting the literal `` (`redirect_maven_dep_version`) or adding a `` entry (`redirect_maven_dep_management_added`), plus optional Trusted Checksums (`redirect_maven_trusted_checksums`, conflicts as `redirect_maven_trusted_checksums_conflict`); a `${property}` version is refused (`redirect_maven_dep_unpinned`), a non-matching literal skipped (`redirect_maven_dep_version_mismatch`), and an override without a suffixed version falls back to same-GAV repository injection (`redirect_maven_same_gav_fallback`, NOT fail-closed). **Gem stale-install guard (additive warning — the canonical narrative; other mentions point here)**: the gem hosted rewrite is pure Gemfile/lock text, so a gem ALREADY materialized under the project's bundle paths keeps its upstream bytes — the next `bundle install` prints `Using ` and never refetches, on **every** bundler major (live-verified 2026-08-19 on 1.17.3 / 2.7.2 / 4.0.18: bundler 4's CHECKSUMS verify at download time only, and nothing is downloaded; `bundle install --force`/`--redownload` re-install from the stale cached `.gem` instead of re-fetching — bundler 1 silently, bundler 4 with an exit-37 checksum refusal that still leaves the upstream bytes installed; the **verified** remedy is removing the installed dir + cache `.gem` + `specifications` entry, then `bundle install`). After the rewrite, a hosted run therefore probes the installed-gem discovery paths (the same ruby-crawler discovery `apply` uses, honoring `--global`/`--global-prefix` like scan's own discovery) for each confirmed gem redirect and judges the materialization against the patch record's `afterHash` file map. Judgment rules: records are found **by uuid** — this run's fetched records first, then the redirect ledger's persisted ones, so a transiently failed `/patches/view` fetch cannot retire the warning (it re-fires on every re-scan until the stale materialization is gone); a materialization with every file at `afterHash` is already patched and never warns (an agent→hosted migration stays quiet by construction), and when several confirmed variant purls resolve to one installed dir, ANY of them judging it patched keeps it quiet; staleness needs **positive evidence** — at least one record file whose bytes were actually read and hash to neither state's expectation — so missing or unreadable files never produce a warning. Warnings emit `redirect_gem_stale_install` (JSON `redirect.warnings[]` + a code-tagged stderr line) in three flavors: a PROJECT-LOCAL dir gets the verified delete-list remedy (installed dir, cache `.gem`, `specifications` entry — plus the project's committed `vendor/cache/.gem` when present and not proven to be the patched artifact, since bundler installs from `vendor/cache` in preference to fetching); a SHARED gem-env home gets a caveat that the home is shared machine-wide and prefers migrating the project to a local bundle path over deleting shared files; and a committed `vendor/cache` archive whose sha256 differs from the patched artifact's warns standalone even with no installed dir at all (a fresh checkout with a committed stale cache re-materializes the upstream bytes forever). A stale-flagged purl is additionally **excluded from the same run's `--vex` `assume_applied` set** — the envelope must never attest a CVE its own warning says is live; the purl falls back to normal installed-tree verification (a patched install still attests, a stale one is omitted). The probe is read-only (nothing is deleted) and skipped on `--dry-run` — deliberately explicit, since nothing was rewritten but the ledger fallback could otherwise judge an already-redirected project. Exit code and `status` are unchanged (warning-only, the hosted-refusal posture); a same-run `--vex` may still fail on "nothing to attest" per the embedded-VEX contract. @@ -1087,6 +1087,7 @@ Every `--json` invocation emits a single JSON object that follows the **unified | `pypi_poetry_integrity_unverified` | `skipped` (warning) | vendor (pypi / poetry): the lock was written by Poetry < 1.4 (0.12 `[metadata.hashes]`, lock 1.0/1.1, or a 2.0 lock without a `@generated by Poetry X.Y.Z` header — 1.3 wrote those). That installer does not verify local wheel hashes (the committed wheel bytes are the protection) and does not replace an already-installed package at the same version; recreate the virtualenv or `pip uninstall` the package before `poetry install`, or upgrade Poetry. | | `redirect_poetry_stale_install_risk` | `redirect.warnings[]` (warning) | scan `--mode hosted` (poetry): same writer test as above — a warm virtualenv keeps the upstream package after the redirect on Poetry < 1.4 (1.4+ re-installs from the new source); fresh installs pick up the patched wheel. Emitted once per rewritten lock, only on the run that rewrites it. | | `redirect_poetry_entry_not_found` / `redirect_poetry_missing_sha256` / `redirect_poetry_lock_unsupported` | `redirect.warnings[]` (warning) | scan `--mode hosted` (poetry): the lock has no `[[package]]` at the granted version (uv-parity twin of `redirect_uv_entry_not_found`); the grant carries no SHA-256 (gated once per dep, not per lock); the lock is refused — Poetry 0.12 layout (URL sources ignored), an unsupported `lock-version`, a forked package listed at several versions, a user-authored `[package.source]` on another origin (an earlier Socket URL for the same wheel is superseded in place), a malformed `[metadata.files]`/`[metadata.hashes]`, or a wheel whose filename does not match the locked package. Exit code and `status` unchanged (hosted-refusal posture). | +| `redirect_pdm_refused` / `redirect_pdm_legacy_sync_required` | `redirect.warnings[]` (warning) | scan `--mode hosted` (pdm): the `pdm.lock` rewrite was refused — an unsupported `[metadata] lock_version` (the identity-losing `3.1` / `4.0`–`4.2` formats or an untested future format), an unsupported `strategy`, a package listed at several versions (fork) or absent, a user-authored `url`/`path`/VCS/`editable` source, hash-less or malformed `files`, or a wheel whose filename does not match the locked package (`redirect_pdm_refused`); or the lock was written in format `2` (PDM 0.12–1.4), whose upstream freshness bug lets `pdm install` regenerate the lock — use `pdm sync` (`redirect_pdm_legacy_sync_required`). A refused uuid is withheld from every other PyPI rewriter when `pdm.lock` is the install driver, and its patch is not confirmed. Exit code and `status` unchanged (hosted-refusal posture). | | `vendor_prebuilt_stub_invalid` | `failed` / `skipped` (warning) | vendor (gem, `--vendor-source`): the served stub gemspec fails the rubygems `summary`/`authors` bar, so bundler would refuse the vendored path source at install time. `service`: refusal naming the missing attributes; `auto`: loud warning + local-build fallback — or, when the gem is also not installed locally (no stub to derive), a refusal naming the served defect and the install-the-gem remedy. | | `gem_spec_invalid` | `failed` | vendor (gem): the LOCAL `specifications/` stub gemspec fails the same rubygems `summary`/`authors` bar (a corrupted or hand-edited gem home); the refusal names the file — reinstall the gem (`gem pristine ` / fresh `bundle install`). | | `vendor_*` / `pypi_*` / `gemfile_*` / `lock_*` / `locked_version_mismatch` / `user_authored_*` / `native_extensions_unsupported` / `platform_gem_unsupported` | `failed`/`skipped` | vendor: per-ecosystem refusal + drift vocabulary; see the Vendor command contract section. New tags are additive (MINOR). | diff --git a/crates/socket-patch-cli/src/commands/scan/hosted.rs b/crates/socket-patch-cli/src/commands/scan/hosted.rs index 033c0274..0b0e036b 100644 --- a/crates/socket-patch-cli/src/commands/scan/hosted.rs +++ b/crates/socket-patch-cli/src/commands/scan/hosted.rs @@ -18,7 +18,7 @@ mod python; /// Fragment-edit kinds whose lockfile the package manager re-lays in place /// (keeping the Socket source) — a re-scan REBASES their ledger edits instead /// of appending; see the ledger merge below. -const REBASE_KINDS: &[&str] = &["redirect_poetry_lock_package"]; +const REBASE_KINDS: &[&str] = &["redirect_poetry_lock_package", "redirect_pdm_lock_package"]; const REDIRECT_CANDIDATE_FILES: &[&str] = &[ "package-lock.json", @@ -1717,6 +1717,26 @@ pub(crate) async fn run_redirect_selected( if rewrite.refused_pipenv_uuids.contains(uuid) { return false; } + // pdm is transactional like cargo: a refused uuid is never + // confirmed, and when `pdm.lock` is the PyPI install driver + // (no `uv.lock` / `poetry.lock`) a pypi dep is confirmed ONLY + // by the pdm rewriter's own report — the URL landing in a + // sibling `requirements.txt` the project does not install from + // pins nothing. When uv/poetry drive, their own lock proof + // below still confirms them. This check precedes the hatch + // gate: a PDM project may declare `hatchling` as its build + // backend, which registers every pypi uuid as hatch-owned while + // the lock's presence keeps hatch from confirming any of them. + if rewrite.refused_pdm_uuids.contains(uuid) { + return false; + } + if purl.starts_with("pkg:pypi/") + && files.contains_key("pdm.lock") + && !files.contains_key("uv.lock") + && !files.contains_key("poetry.lock") + { + return rewrite.confirmed_pdm_uuids.contains(uuid); + } if rewrite.python_lock_uuids.contains(uuid) { return rewrite.confirmed_python_lock_uuids.contains(uuid) && !rewrite.refused_python_lock_uuids.contains(uuid); @@ -1918,6 +1938,18 @@ pub(crate) async fn run_redirect_selected( .unwrap_or(0); if let Some(&target) = siblings.get(nth) { if !rebased.contains(&target) { + // `pdm lock` fully un-patches the lock (registry source + // restored) and may reflow line endings (CRLF → LF), so + // the fresh run's `original` IS the correct + // relocked-registry rollback target and the stale + // recorded one would restore a mismatched fragment. + // Poetry's relock instead KEEPS the Socket source (it + // only drops the inserted `files` line), so its oldest + // `original` — the true pre-patch fragment — must + // survive; only its `new` is refreshed. + if edit.kind == "redirect_pdm_lock_package" { + ledger.edits[target].original = edit.original.clone(); + } ledger.edits[target].new = edit.new.clone(); ledger.edits[target].action = edit.action.clone(); rebased.push(target); diff --git a/crates/socket-patch-cli/tests/in_process_redirect_pdm.rs b/crates/socket-patch-cli/tests/in_process_redirect_pdm.rs new file mode 100644 index 00000000..8badb3ba --- /dev/null +++ b/crates/socket-patch-cli/tests/in_process_redirect_pdm.rs @@ -0,0 +1,420 @@ +//! In-process CLI test for `scan --mode hosted` on a PDM project: mocks the API +//! (discovery + reference + view) via wiremock, lays down a native `pdm.lock` +//! (the committed backtest fixtures) with NO installed package — the lock-only +//! fresh-checkout / CI shape — and asserts the lock is repointed at the hosted +//! wheel, the redirect ledger is written, the same-run `--vex` attests the +//! redirect, a re-scan is idempotent, and `rollback` restores every byte. It +//! also covers the PDM-specific relock convergence: `pdm lock` un-patches the +//! lock AND can reflow its line endings (CRLF → LF), so a re-scan must rebase +//! the ledger onto the relocked bytes — adopting the fresh `original` — for +//! `rollback` to still land on the relocked lock. The rewriter bytes themselves +//! are pinned by the core `utils::pdm_lock` tests; this covers the CLI wiring. + +use std::path::Path; + +use serial_test::serial; +use socket_patch_cli::args::GlobalArgs; +use socket_patch_cli::commands::rollback::{self, RollbackArgs}; +use socket_patch_cli::commands::scan::{run, ScanArgs}; +use socket_patch_cli::commands::vex::VexEmbedArgs; +use socket_patch_core::hash::git_sha256::compute_git_sha256_from_bytes; +use wiremock::matchers::{method, path, path_regex}; +use wiremock::{Mock, MockServer, ResponseTemplate}; + +const ORG: &str = "test-org"; +/// Discovery names the base purl (the lock inventory's spelling)… +const PURL: &str = "pkg:pypi/urllib3@1.26.18"; +/// …while the patch record carries the API's artifact-qualified purl, which is +/// what the redirect ledger is keyed by. +const RECORD_PURL: &str = "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl"; +const UUID: &str = "e828efa5-5c6d-43f3-9909-03f5ac232b98"; +const HOSTED_URL: &str = "http://patch.test/patch/pypi/urllib3/1.26.18/22222222-2222-4222-8222-222222222222/e828efa5-5c6d-43f3-9909-03f5ac232b98/urllib3-1.26.18-py2.py3-none-any.whl"; +const GHSA: &str = "GHSA-gm62-xv2j-4w53"; +const UPSTREAM: &[u8] = b"upstream response implementation\n"; +const PATCHED: &[u8] = b"patched response implementation\n"; + +/// PDM 2.29.2 native lock (lock_version 4.5.1, inline `files`). +const LOCK: &str = include_str!("../../socket-patch-core/tests/fixtures/pdm-native/2.29.2.lock"); +/// PDM 0.12.3 native lock (lock_version 2, legacy `[metadata.files]`). +const LOCK_LEGACY: &str = + include_str!("../../socket-patch-core/tests/fixtures/pdm-native/0.12.3.lock"); + +const PYPROJECT: &str = "[project]\nname = \"x\"\nversion = \"0.0.0\"\nrequires-python = \">=3.8\"\ndependencies = [\"urllib3==1.26.18\"]\n\n[tool.pdm]\ndistribution = false\n"; + +fn sha256() -> String { + "c".repeat(64) +} + +fn global(cwd: &Path, api_url: String) -> GlobalArgs { + GlobalArgs { + cwd: cwd.to_path_buf(), + org: Some(ORG.to_string()), + api_token: Some("fake".to_string()), + api_url: Some(api_url), + json: true, + yes: true, + ..GlobalArgs::default() + } +} + +fn hosted_args(cwd: &Path, api_url: String, vex: Option<&Path>) -> ScanArgs { + ScanArgs { + paths: Vec::new(), + common: global(cwd, api_url), + batch_size: 100, + apply: false, + prune: false, + sync: false, + vendor: false, + detached: false, + redirect: true, + mode: None, + all_releases: false, + vex: VexEmbedArgs { + vex: vex.map(Path::to_path_buf), + ..Default::default() + }, + } +} + +async fn mock_api(server: &MockServer) { + Mock::given(method("POST")) + .and(path(format!("/v0/orgs/{ORG}/patches/batch"))) + .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({ + "packages": [{ + "purl": PURL, + "patches": [{ + "uuid": UUID, "purl": RECORD_PURL, "tier": "free", + "cveIds": ["CVE-2025-66418"], "ghsaIds": [GHSA], "severity": "HIGH", + "title": "pdm redirect fixture" + }] + }], + "canAccessPaidPatches": false, + }))) + .mount(server) + .await; + Mock::given(method("GET")) + .and(path_regex(format!("^/v0/orgs/{ORG}/patches/by-package/.+$"))) + .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({ + "patches": [{ + "uuid": UUID, "purl": RECORD_PURL, + "publishedAt": "2026-07-29T20:20:47Z", + "description": "x", "license": "MIT", "tier": "free", + "vulnerabilities": {} + }], + "canAccessPaidPatches": false, + }))) + .mount(server) + .await; + Mock::given(method("POST")) + .and(path(format!("/v0/orgs/{ORG}/patches/package"))) + .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({ + "results": { + UUID: { + "status": "granted", + "url": HOSTED_URL, + "purl": PURL, + "artifacts": [{ + "kind": "tarball", + "url": HOSTED_URL, + "integrity": { "sha256": sha256() } + }], + "registryOverride": null + } + } + }))) + .mount(server) + .await; + Mock::given(method("GET")) + .and(path(format!("/v0/orgs/{ORG}/patches/view/{UUID}"))) + .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({ + "uuid": UUID, + "purl": RECORD_PURL, + "publishedAt": "2026-07-29T20:20:47Z", + "files": { + "urllib3/response.py": { + "beforeHash": compute_git_sha256_from_bytes(UPSTREAM), + "afterHash": compute_git_sha256_from_bytes(PATCHED), + } + }, + "vulnerabilities": { + GHSA: { + "cves": ["CVE-2025-66418"], + "summary": "pdm redirect vex fixture", + "severity": "HIGH", + "description": "d" + } + }, + "description": "x", "license": "MIT", "tier": "free" + }))) + .mount(server) + .await; +} + +/// A PDM project with nothing installed: the lock is the only source of the +/// dependency. An EMPTY in-project venv keeps the crawl hermetic (without it +/// the project-marker fallback would walk this machine's global interpreters). +fn write_project(root: &Path, lock: &str) { + std::fs::write(root.join("pyproject.toml"), PYPROJECT).unwrap(); + std::fs::write(root.join("pdm.lock"), lock).unwrap(); + let site = if cfg!(windows) { + root.join(".venv").join("Lib").join("site-packages") + } else { + root.join(".venv") + .join("lib") + .join("python3.12") + .join("site-packages") + }; + std::fs::create_dir_all(site).unwrap(); +} + +fn read(path: &Path) -> String { + std::fs::read_to_string(path).unwrap() +} + +/// Lock-only hosted redirect regression: before the `pdm.lock` inventory +/// reader, a fresh checkout with nothing installed surfaced no package to the +/// batch API, so `redirected` was 0 and nothing was attested. +#[tokio::test] +#[serial] +async fn lock_only_pdm_project_redirects_attests_rescans_and_rolls_back() { + let server = MockServer::start().await; + mock_api(&server).await; + let tmp = tempfile::tempdir().unwrap(); + write_project(tmp.path(), LOCK); + let lock_path = tmp.path().join("pdm.lock"); + let vex_path = tmp.path().join("out.vex.json"); + + // 1. Hosted redirect with same-run --vex on the lock-only checkout. + let code = run(hosted_args(tmp.path(), server.uri(), Some(&vex_path))).await; + assert_eq!(code, 0, "hosted redirect + same-run vex must succeed"); + let redirected = read(&lock_path); + assert!(redirected.contains(HOSTED_URL), "{redirected}"); + assert!( + redirected.contains(&format!("hash = \"sha256:{}\"", sha256())), + "{redirected}" + ); + assert!( + redirected.contains(&format!("url = \"{HOSTED_URL}\"")), + "the package unit gains the hosted url: {redirected}" + ); + assert!( + !redirected.contains("urllib3-1.26.18.tar.gz"), + "the stale registry sdist hash is dropped: {redirected}" + ); + assert_eq!( + read(&tmp.path().join("pyproject.toml")), + PYPROJECT, + "pyproject untouched" + ); + let ledger: serde_json::Value = + serde_json::from_str(&read(&tmp.path().join(".socket/vendor/redirect-state.json"))).unwrap(); + assert!( + ledger["records"][RECORD_PURL].is_object(), + "ledger keyed by the artifact-qualified purl: {ledger}" + ); + assert_eq!( + ledger["edits"][0]["kind"].as_str(), + Some("redirect_pdm_lock_package"), + "{ledger}" + ); + // The redirect is attested from the ledger even though the base purl the + // run confirmed differs from the record's qualified purl only by its + // `?artifact_id=` qualifier (the shared qualifier-strip in vex). + let vex: serde_json::Value = serde_json::from_str(&read(&vex_path)).unwrap(); + let statements = vex["statements"].as_array().expect("statements"); + assert_eq!(statements.len(), 1, "{vex}"); + assert_eq!( + statements[0]["vulnerability"]["name"].as_str(), + Some(GHSA), + "{vex}" + ); + + // 2. Idempotent re-scan: no further edits, lock byte-identical. + let code = run(hosted_args(tmp.path(), server.uri(), None)).await; + assert_eq!(code, 0); + assert_eq!(read(&lock_path), redirected, "re-scan must not touch the lock"); + + // 3. rollback unwinds the redirect and drops the record. + let code = rollback::run(RollbackArgs { + targets: Vec::new(), + common: global(tmp.path(), server.uri()), + one_off: false, + preserve_state: false, + }) + .await; + assert_eq!(code, 0, "rollback must succeed"); + assert_eq!( + read(&lock_path), + LOCK, + "rollback must restore the pristine lock byte for byte" + ); + let ledger_path = tmp.path().join(".socket/vendor/redirect-state.json"); + if ledger_path.exists() { + let ledger: serde_json::Value = serde_json::from_str(&read(&ledger_path)).unwrap(); + assert!( + ledger["records"] + .as_object() + .is_none_or(|records| records.is_empty()), + "no redirect record may survive rollback: {ledger}" + ); + } +} + +/// A PDM project whose `pyproject.toml` names `hatchling` as its build +/// backend is still a PDM project. The hatch rewriter claims every pypi uuid +/// for such a project and then yields to the lock without confirming any, so +/// hosted confirmation must key off the pdm rewriter's own report BEFORE the +/// hatch gate can veto it — otherwise the lock is rewritten but nothing is +/// recorded or attested. +#[tokio::test] +#[serial] +async fn hatchling_build_backend_does_not_veto_the_pdm_lock_redirect() { + let server = MockServer::start().await; + mock_api(&server).await; + let tmp = tempfile::tempdir().unwrap(); + write_project(tmp.path(), LOCK); + let pyproject = format!( + "{PYPROJECT}\n[build-system]\nrequires = [\"hatchling\"]\nbuild-backend = \"hatchling.build\"\n" + ); + std::fs::write(tmp.path().join("pyproject.toml"), &pyproject).unwrap(); + let lock_path = tmp.path().join("pdm.lock"); + + let code = run(hosted_args(tmp.path(), server.uri(), None)).await; + assert_eq!(code, 0, "hosted redirect must succeed"); + let redirected = read(&lock_path); + assert!(redirected.contains(HOSTED_URL), "{redirected}"); + assert_eq!( + read(&tmp.path().join("pyproject.toml")), + pyproject, + "pyproject untouched" + ); + let ledger: serde_json::Value = + serde_json::from_str(&read(&tmp.path().join(".socket/vendor/redirect-state.json"))).unwrap(); + assert!( + ledger["records"][RECORD_PURL].is_object(), + "the pdm redirect must be confirmed and recorded despite the hatch backend: {ledger}" + ); + assert_eq!( + ledger["edits"][0]["kind"].as_str(), + Some("redirect_pdm_lock_package"), + "{ledger}" + ); + + let code = rollback::run(RollbackArgs { + targets: Vec::new(), + common: global(tmp.path(), server.uri()), + one_off: false, + preserve_state: false, + }) + .await; + assert_eq!(code, 0, "rollback must succeed"); + assert_eq!(read(&lock_path), LOCK, "rollback must restore the pristine lock"); +} + +/// The legacy `[metadata.files]` lock (lock_version 2) redirects the package +/// unit AND the integrity-table entry, and warns about the freshness bug. +#[tokio::test] +#[serial] +async fn legacy_metadata_files_lock_redirects_both_fragments_and_warns() { + let server = MockServer::start().await; + mock_api(&server).await; + let tmp = tempfile::tempdir().unwrap(); + write_project(tmp.path(), LOCK_LEGACY); + let lock_path = tmp.path().join("pdm.lock"); + + let code = run(hosted_args(tmp.path(), server.uri(), None)).await; + assert_eq!(code, 0); + let redirected = read(&lock_path); + assert!(redirected.contains(HOSTED_URL), "{redirected}"); + let ledger: serde_json::Value = + serde_json::from_str(&read(&tmp.path().join(".socket/vendor/redirect-state.json"))).unwrap(); + assert_eq!( + ledger["edits"].as_array().unwrap().len(), + 2, + "package unit + [metadata.files] entry: {ledger}" + ); + + // rollback restores both fragments byte for byte. + let code = rollback::run(RollbackArgs { + targets: Vec::new(), + common: global(tmp.path(), server.uri()), + one_off: false, + preserve_state: false, + }) + .await; + assert_eq!(code, 0); + assert_eq!(read(&lock_path), LOCK_LEGACY, "byte-identical revert"); +} + +/// `pdm lock` un-patches the lock (registry source restored) and — this is the +/// PDM-specific hazard — can reflow its line endings (CRLF → LF). The re-scan +/// must rebase the ledger onto the relocked bytes, adopting the fresh +/// `original`, so `rollback` lands on the RELOCKED lock rather than restoring a +/// stale CRLF fragment into an LF file. Appending instead would leave a chain +/// whose older link matches nothing and make rollback refuse. +#[tokio::test] +#[serial] +async fn relock_reflow_then_rescan_keeps_rollback_invertible() { + // A CRLF checkout that `pdm lock` normalizes to LF, and a pure-LF one. + for start in ["\r\n", "\n"] { + let lock = LOCK.replace("\r\n", "\n").replace('\n', start); + // `pdm lock` output: registry lock, always LF, patch dropped. + let relocked = LOCK.replace("\r\n", "\n"); + assert_relock_roundtrip(&lock, &relocked).await; + } +} + +async fn assert_relock_roundtrip(lock: &str, relocked: &str) { + let server = MockServer::start().await; + mock_api(&server).await; + let tmp = tempfile::tempdir().unwrap(); + write_project(tmp.path(), lock); + let lock_path = tmp.path().join("pdm.lock"); + + assert_eq!(run(hosted_args(tmp.path(), server.uri(), None)).await, 0); + let redirected = read(&lock_path); + assert!(redirected.contains(HOSTED_URL)); + let ledger_path = tmp.path().join(".socket/vendor/redirect-state.json"); + let before: serde_json::Value = serde_json::from_str(&read(&ledger_path)).unwrap(); + let n_edits = before["edits"].as_array().unwrap().len(); + + // The user runs `pdm lock`: the patch is gone and the file is LF now. + assert!(!relocked.contains(HOSTED_URL), "relock un-patches the lock"); + std::fs::write(&lock_path, relocked).unwrap(); + + // Re-scan re-applies and rebases the ledger (no appended chain). + assert_eq!(run(hosted_args(tmp.path(), server.uri(), None)).await, 0); + let rescanned = read(&lock_path); + assert!(rescanned.contains(HOSTED_URL), "the re-scan re-redirects"); + let after: serde_json::Value = serde_json::from_str(&read(&ledger_path)).unwrap(); + let edits = after["edits"].as_array().unwrap(); + assert_eq!(edits.len(), n_edits, "rebased, not appended: {after}"); + for edit in edits { + let original = edit["original"].as_str().unwrap(); + assert!( + !original.contains(HOSTED_URL), + "originals describe the relocked registry lock: {original}" + ); + assert!( + rescanned.contains(edit["new"].as_str().unwrap()), + "new fragments describe the current lock: {after}" + ); + } + + // rollback lands on the relocked (LF, registry) lock — the user's `pdm + // lock` is preserved, only the Socket patch is unwound. + let code = rollback::run(RollbackArgs { + targets: Vec::new(), + common: global(tmp.path(), server.uri()), + one_off: false, + preserve_state: false, + }) + .await; + assert_eq!(code, 0, "rollback after relock + re-scan must succeed"); + assert_eq!( + read(&lock_path), + relocked, + "rollback restores the relocked lock byte for byte" + ); +} diff --git a/crates/socket-patch-core/src/patch/redirect/mod.rs b/crates/socket-patch-core/src/patch/redirect/mod.rs index f4961682..e4f0d016 100644 --- a/crates/socket-patch-core/src/patch/redirect/mod.rs +++ b/crates/socket-patch-core/src/patch/redirect/mod.rs @@ -24,6 +24,7 @@ use crate::crawlers::composer_crawler::normalize_version; use crate::vendor::yarn_berry_lock::yarnrc_compression_level; pub mod golang_local; +mod pdm; mod pipenv; mod pnpm; mod poetry; @@ -175,6 +176,17 @@ pub struct RewriteResult { pub confirmed_cargo_uuids: std::collections::BTreeSet, pub confirmed_pipenv_uuids: std::collections::BTreeSet, pub refused_pipenv_uuids: std::collections::BTreeSet, + /// Patch uuids whose `pdm.lock` redirect fully landed (written by this run + /// or already present). Like cargo, pdm confirmation keys off this set, + /// never off substring presence: a lock can carry the URL in one extras + /// variant while another variant still resolves the registry wheel. + pub confirmed_pdm_uuids: std::collections::BTreeSet, + /// Patch uuids the pdm rewriter REFUSED (unsupported lock format, forked + /// package, conflicting source, malformed hashes). When pdm.lock is the + /// project's PyPI install driver they are withheld from every later pypi + /// rewriter, so no sibling file can attest a patch the installing lock will + /// never honor. + pub refused_pdm_uuids: std::collections::BTreeSet, /// An incomplete pnpm rewrite must not be confirmed by finding its URL /// in another instance, a comment, or another lockfile. pub refused_pnpm_uuids: std::collections::BTreeSet, @@ -241,6 +253,31 @@ pub fn rewrite_registry_redirect_with_pipenv_version( pipenv_major: Option, ) -> RewriteResult { let mut result = RewriteResult::default(); + // pdm runs FIRST, but only when `pdm.lock` is the project's PyPI install + // driver: a `uv.lock` or `poetry.lock` beside it takes precedence (mirroring + // the vendored flavor precedence uv > poetry > pdm > pipenv), so a leftover + // `pdm.lock` neither blocks nor is attested through them. When pdm does + // drive, a patch it refuses is withheld from every other pypi rewriter so a + // sibling `Pipfile.lock` / `requirements.txt` cannot attest a patch the + // installing lock will never honor. + let pdm_drives = files.contains_key("pdm.lock") + && !files.contains_key("uv.lock") + && !files.contains_key("poetry.lock"); + if pdm_drives { + pdm::rewrite(files, overrides, &mut result); + } + let usable: Vec<_> = overrides + .iter() + .filter(|dep| !result.refused_pdm_uuids.contains(&dep.patch_uuid)) + .cloned() + .collect(); + let overrides = if pdm_drives { + usable.as_slice() + } else { + overrides + }; + // Pipenv next: a CONFLICT in a live Pipfile.lock vetoes the sibling pypi + // rewriters too (see `pipenv::rewrite`). pipenv::rewrite(files, overrides, pipenv_major, &mut result); let overrides: Vec<_> = overrides .iter() @@ -13300,7 +13337,14 @@ mod hatch_tests { for (filename, text) in [ ("uv.lock", "version = 2"), ("pylock.toml", "lock-version = '2.0'"), - ("pdm.lock", "[metadata]\nlock_version = '4.5.1'"), + // A real PDM lock that CONTAINS the package: the pdm writer runs + // ahead of hatch and confirms through its own transactional set + // (asserted below); a package-less stub would instead be refused + // and withheld from every later pypi rewriter, hatch included. + ( + "pdm.lock", + include_str!("../../../tests/fixtures/pdm-native/2.29.2.lock"), + ), ("Pipfile.lock", "{}"), ( "poetry.lock", @@ -13314,6 +13358,16 @@ mod hatch_tests { assert!(result.confirmed_hatch_uuids.is_empty(), "{filename}"); assert!(result.confirmed_python_lock_uuids.is_empty(), "{filename}"); } + let mut files = base.clone(); + files.insert( + "pdm.lock".into(), + include_str!("../../../tests/fixtures/pdm-native/2.29.2.lock").into(), + ); + let result = rewrite_registry_redirect(&files, &[patch()]); + assert!(result.confirmed_pdm_uuids.contains("test-uuid")); + assert!(result.refused_pdm_uuids.is_empty()); + assert!(result.files.contains_key("pdm.lock")); + assert!(!result.files.contains_key("pyproject.toml")); let mut files = base; files.insert( "poetry.lock".into(), diff --git a/crates/socket-patch-core/src/patch/redirect/pdm.rs b/crates/socket-patch-core/src/patch/redirect/pdm.rs new file mode 100644 index 00000000..ffccc456 --- /dev/null +++ b/crates/socket-patch-core/src/patch/redirect/pdm.rs @@ -0,0 +1,129 @@ +use std::collections::BTreeMap; + +use serde_json::json; + +use super::{DepOverride, FileEdit, RewriteResult, RewriteWarning}; +use crate::utils::pdm_lock::{pdm_lock_edits, rewrite_pdm_lock}; + +pub(super) fn rewrite( + files: &BTreeMap, + overrides: &[DepOverride], + result: &mut RewriteResult, +) { + let Some(original) = files.get("pdm.lock") else { + return; + }; + let mut text = original.clone(); + for dep in overrides.iter().filter(|dep| dep.ecosystem == "pypi") { + match plan(&text, dep) { + Ok((rewritten, edits)) => { + result.confirmed_pdm_uuids.insert(dep.patch_uuid.clone()); + let lock = rewritten.parse::().ok(); + if lock + .as_ref() + .and_then(|lock| crate::utils::pdm_lock::lock_version(lock).ok()) + == Some("2") + { + result.warnings.push(RewriteWarning { code: "redirect_pdm_legacy_sync_required".into(), detail: "PDM 0.x may regenerate freshly generated locks during install; use `pdm sync` to preserve this patch, or upgrade PDM".into() }); + } + text = rewritten; + result.edits.extend(edits); + } + Err(detail) => { + result.refused_pdm_uuids.insert(dep.patch_uuid.clone()); + result.warnings.push(RewriteWarning { + code: "redirect_pdm_refused".into(), + detail, + }); + } + } + } + if text != *original { + result.files.insert("pdm.lock".into(), text); + } +} + +fn plan(text: &str, dep: &DepOverride) -> Result<(String, Vec), String> { + let sha256 = dep + .integrity + .sha256 + .as_deref() + .ok_or("missing PDM SHA-256")?; + let url = reqwest::Url::parse(&dep.artifact_url).map_err(|e| e.to_string())?; + if !matches!(url.scheme(), "http" | "https") + || url.fragment().is_some() + || url.query().is_some() + { + return Err("unsupported PDM artifact URL".into()); + } + let filename = url + .path_segments() + .and_then(|mut segments| segments.next_back()) + .ok_or("missing PDM wheel filename")?; + let rewritten = rewrite_pdm_lock( + text, + &dep.name, + &dep.version, + ("url", &dep.artifact_url), + filename, + sha256, + )?; + let edits = pdm_lock_edits(text, &rewritten, &dep.name)? + .into_iter() + .map(|(old, new)| FileEdit { + path: "pdm.lock".into(), + kind: "redirect_pdm_lock_package".into(), + action: "rewritten".into(), + key: Some(dep.name.clone()), + original: Some(json!(old)), + new: Some(json!(new)), + }) + .collect(); + Ok((rewritten, edits)) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::patch::redirect::Integrity; + + fn dep() -> DepOverride { + DepOverride { + ecosystem: "pypi".into(), name: "urllib3".into(), version: "1.26.18".into(), + patch_uuid: "e828efa5-5c6d-43f3-9909-03f5ac232b98".into(), + artifact_url: "https://patch.socket.dev/patch/pypi/urllib3/1.26.18/7e52b8b6-53f2-4dc8-860a-1ae7ebd8be0e/e828efa5-5c6d-43f3-9909-03f5ac232b98/urllib3-1.26.18-py2.py3-none-any.whl".into(), + integrity: Integrity { sha256: Some("a".repeat(64)), ..Default::default() }, + namespace: None, token: "token".into(), berry_zip_url: None, registry_override: None, + } + } + + #[test] + fn confirms_only_semantic_pdm_edits_and_replays() { + let original = include_str!("../../../tests/fixtures/pdm-native/2.29.2.lock"); + let (rewritten, edits) = plan(original, &dep()).unwrap(); + assert_eq!(edits.len(), 1); + assert!(rewritten.contains(&dep().artifact_url)); + let (same, edits) = plan(&rewritten, &dep()).unwrap(); + assert_eq!(same, rewritten); + assert!(edits.is_empty()); + for text in [ + original.replace("4.5.1", "4.2"), + original.replace("version = \"1.26.18\"", "version = '1.26.19'"), + original.replace( + "name = \"urllib3\"", + "name = 'urllib3'\nurl = 'https://example.com/original.whl'", + ), + ] { + let mut result = RewriteResult::default(); + rewrite( + &BTreeMap::from([("pdm.lock".into(), text)]), + &[dep()], + &mut result, + ); + assert!(result.files.is_empty()); + assert!(result.edits.is_empty()); + assert!(result.confirmed_pdm_uuids.is_empty()); + assert!(result.refused_pdm_uuids.contains(&dep().patch_uuid)); + } + } +} diff --git a/crates/socket-patch-core/src/patch/redirect/replay.rs b/crates/socket-patch-core/src/patch/redirect/replay.rs index 20229a8a..938676af 100644 --- a/crates/socket-patch-core/src/patch/redirect/replay.rs +++ b/crates/socket-patch-core/src/patch/redirect/replay.rs @@ -89,9 +89,10 @@ enum Inverse { fn classify(kind: &str, action: &str) -> (&'static str, Inverse) { match kind { "redirect_pipenv_entry" => ("pypi", Inverse::PipenvEntry), - "redirect_requirements_line" | "redirect_uv_lock_wheel" | "redirect_poetry_lock_package" => { - ("pypi", Inverse::ReplaceFragment) - } + "redirect_requirements_line" + | "redirect_uv_lock_wheel" + | "redirect_poetry_lock_package" + | "redirect_pdm_lock_package" => ("pypi", Inverse::ReplaceFragment), "redirect_hatch_document" => ("pypi", Inverse::HatchDocument), "redirect_composer_dist" => ("composer", Inverse::ReplaceFragment), "redirect_cargo_toml_dep" | "redirect_cargo_lock_entry" => { diff --git a/crates/socket-patch-core/src/utils/mod.rs b/crates/socket-patch-core/src/utils/mod.rs index 77efcd3e..fea8b05d 100644 --- a/crates/socket-patch-core/src/utils/mod.rs +++ b/crates/socket-patch-core/src/utils/mod.rs @@ -1,6 +1,7 @@ pub mod env_compat; pub mod fs; pub(crate) mod http; +pub mod pdm_lock; pub mod pipenv; pub mod poetry_lock; pub mod process; diff --git a/crates/socket-patch-core/src/utils/pdm_lock.rs b/crates/socket-patch-core/src/utils/pdm_lock.rs new file mode 100644 index 00000000..a0cc2459 --- /dev/null +++ b/crates/socket-patch-core/src/utils/pdm_lock.rs @@ -0,0 +1,426 @@ +use toml_edit::{value, Array, DocumentMut, InlineTable, Item, Table, Value}; + +use crate::crawlers::python_crawler::canonicalize_pypi_name; +use crate::utils::python_lock::preserve_line_endings; + +pub fn lock_version(lock: &DocumentMut) -> Result<&str, String> { + let version = lock + .get("metadata") + .and_then(|metadata| metadata.get("lock_version")) + .and_then(Item::as_str) + .ok_or("missing PDM lock_version")?; + if matches!(version, "2" | "4.3" | "4.4" | "4.4.1" | "4.5.0" | "4.5.1") { + Ok(version) + } else { + Err(format!("unsupported PDM lock_version {version:?}")) + } +} + +pub fn validate_strategy(lock: &DocumentMut) -> Result, String> { + let mut result = Vec::new(); + if let Some(strategy) = lock + .get("metadata") + .and_then(|metadata| metadata.get("strategy")) + { + for item in strategy.as_array().ok_or("invalid PDM strategy")? { + let value = item.as_str().ok_or("invalid PDM strategy flag")?; + if !matches!( + value, + "inherit_metadata" | "static_urls" | "cross_platform" | "direct_minimal_versions" + ) { + return Err(format!("unsupported PDM lock strategy {value:?}")); + } + result.push(value.to_string()); + } + } + Ok(result) +} + +pub fn legacy_files_key(package: &Table) -> Option { + let name = canonicalize_pypi_name(package.get("name")?.as_str()?); + let version = package.get("version")?.as_str()?; + let mut extras: Vec<&str> = package + .get("extras") + .and_then(Item::as_array) + .map(|items| items.iter().filter_map(Value::as_str).collect()) + .unwrap_or_default(); + extras.sort(); + let suffix = if extras.is_empty() { + String::new() + } else { + format!("[{}]", extras.join(",")) + }; + Some(format!("{name}{suffix} {version}")) +} + +pub fn files_for<'a>(lock: &'a DocumentMut, package: &'a Table) -> Option<&'a Array> { + package.get("files").and_then(Item::as_array).or_else(|| { + lock.get("metadata")? + .get("files")? + .get(&legacy_files_key(package)?)? + .as_array() + }) +} + +pub fn wheel_matches(filename: &str, name: &str, version: &str) -> bool { + let parts: Vec<_> = filename.split('-').collect(); + filename.ends_with(".whl") + && !filename.contains(['/', '\\']) + && matches!(parts.len(), 5 | 6) + && canonicalize_pypi_name(parts[0]) == canonicalize_pypi_name(name) + && parts[1] == version +} + +pub fn rewrite_pdm_lock( + text: &str, + name: &str, + version: &str, + source: (&str, &str), + filename: &str, + sha256: &str, +) -> Result { + let (kind, location) = source; + if !matches!(kind, "url" | "path") + || sha256.len() != 64 + || !sha256.bytes().all(|byte| byte.is_ascii_hexdigit()) + { + return Err("invalid PDM artifact source or SHA-256".into()); + } + if !wheel_matches(filename, name, version) { + return Err("PDM patch wheel does not match package".into()); + } + let mut lock: DocumentMut = text.parse().map_err(|e| format!("invalid PDM lock: {e}"))?; + lock_version(&lock)?; + validate_strategy(&lock)?; + let packages = lock + .get("package") + .and_then(Item::as_array_of_tables) + .ok_or("missing PDM packages")?; + let indices: Vec<_> = packages + .iter() + .enumerate() + .filter(|(_, package)| { + package + .get("name") + .and_then(Item::as_str) + .is_some_and(|candidate| { + canonicalize_pypi_name(candidate) == canonicalize_pypi_name(name) + }) + }) + .map(|(index, _)| index) + .collect(); + if indices.is_empty() { + return Err("missing PDM package".into()); + } + let mut variants = std::collections::BTreeSet::new(); + let mut edits = Vec::new(); + for index in indices { + let package = packages.get(index).ok_or("missing PDM package")?; + if package.get("version").and_then(Item::as_str) != Some(version) { + return Err("PDM locked version differs from installed version".into()); + } + let mut extras = Vec::new(); + if let Some(value) = package.get("extras") { + for extra in value.as_array().ok_or("invalid PDM extras")? { + extras.push(extra.as_str().ok_or("invalid PDM extra")?.to_string()); + } + } + extras.sort(); + if !variants.insert(extras) { + return Err("forked PDM package".into()); + } + for field in [ + "url", "path", "git", "hg", "svn", "bzr", "editable", "source", + ] { + if let Some(existing) = package.get(field) { + if field != kind || existing.as_str() != Some(location) { + return Err(format!("refusing existing PDM {field} source")); + } + } + } + let original_files = files_for(&lock, package).ok_or("missing PDM file hashes")?; + if original_files.is_empty() + || original_files.iter().any(|file| { + !file + .as_inline_table() + .and_then(|file| file.get("hash")) + .and_then(Value::as_str) + .is_some_and(|hash| { + hash.strip_prefix("sha256:").is_some_and(|hex| { + hex.len() == 64 && hex.bytes().all(|byte| byte.is_ascii_hexdigit()) + }) + }) + }) + { + return Err("invalid PDM file hashes".into()); + } + let files_key = legacy_files_key(package).ok_or("missing PDM files key")?; + edits.push((index, package.contains_key("files"), files_key)); + } + for (index, inline_files, files_key) in edits { + let mut file = InlineTable::new(); + file.insert("file", Value::from(filename)); + file.insert( + "hash", + Value::from(format!("sha256:{}", sha256.to_ascii_lowercase())), + ); + let mut files = Array::new(); + files.push(file); + let package = lock + .get_mut("package") + .and_then(Item::as_array_of_tables_mut) + .and_then(|packages| packages.get_mut(index)) + .ok_or("missing PDM package")?; + package.insert(kind, value(location)); + if inline_files { + package.insert("files", value(files)); + } else { + let table = lock + .get_mut("metadata") + .and_then(|metadata| metadata.get_mut("files")) + .and_then(Item::as_table_like_mut) + .ok_or("missing PDM metadata.files")?; + table.insert(&files_key, value(files)); + } + } + let rendered = preserve_line_endings(text, lock.to_string()); + let mut result = text.to_string(); + for (old, new) in pdm_lock_edits(text, &rendered, name)? { + result = result.replacen(&old, &new, 1); + } + Ok(result) +} + +pub fn pdm_lock_edits( + original: &str, + rewritten: &str, + name: &str, +) -> Result, String> { + fn fragments(text: &str, name: &str) -> Result, String> { + let lock = toml_edit::Document::parse(text).map_err(|e| e.to_string())?; + let packages = lock + .get("package") + .and_then(Item::as_array_of_tables) + .ok_or("missing PDM packages")?; + let mut result = Vec::new(); + let mut integrity_keys = std::collections::BTreeSet::new(); + for package in packages.iter().filter(|package| { + package + .get("name") + .and_then(Item::as_str) + .is_some_and(|candidate| { + canonicalize_pypi_name(candidate) == canonicalize_pypi_name(name) + }) + }) { + fn extend_span(table: &Table, span: &mut std::ops::Range) { + for (_, item) in table.iter() { + if let Some(own) = item.span() { + span.start = span.start.min(own.start); + span.end = span.end.max(own.end); + } + if let Some(child) = item.as_table() { + extend_span(child, span); + } + } + } + let mut span = package.span().ok_or("missing PDM package span")?; + extend_span(package, &mut span); + span.end += text[span.end..] + .find(['\r', '\n']) + .unwrap_or(text.len() - span.end); + result.push(text[span].to_string()); + if !package.contains_key("files") { + let key = legacy_files_key(package).ok_or("missing PDM files key")?; + if !integrity_keys.insert(key.clone()) { + continue; + } + let table = lock + .get("metadata") + .and_then(|metadata| metadata.get("files")) + .and_then(Item::as_table) + .ok_or("missing PDM metadata.files")?; + let start = table + .key(&key) + .and_then(|key| key.span()) + .ok_or("missing PDM files key")? + .start; + let end = table + .get(&key) + .and_then(Item::span) + .ok_or("missing PDM files span")? + .end; + result.push(text[start..end].to_string()); + } + } + if result.is_empty() { + return Err("missing PDM package fragments".into()); + } + Ok(result) + } + let before = fragments(original, name)?; + let after = fragments(rewritten, name)?; + if before.len() != after.len() { + return Err("PDM package fragments changed shape".into()); + } + let mut edits = Vec::new(); + for (old, new) in before.into_iter().zip(after) { + if old == new { + continue; + } + if original.matches(&old).count() != 1 || rewritten.matches(&new).count() != 1 { + return Err("ambiguous PDM rollback fragment".into()); + } + edits.push((old, new)); + } + Ok(edits) +} + +#[cfg(test)] +mod tests { + use super::*; + + const WHEEL: &str = "urllib3-1.26.18-py2.py3-none-any.whl"; + const PATH: &str = "./.socket/vendor/pypi/e828efa5-5c6d-43f3-9909-03f5ac232b98/urllib3-1.26.18-py2.py3-none-any.whl"; + + fn fixture(name: &str) -> String { + std::fs::read_to_string( + std::path::Path::new(env!("CARGO_MANIFEST_DIR")) + .join("tests/fixtures/pdm-native") + .join(format!("{name}.lock")), + ) + .unwrap() + } + + #[test] + fn native_formats_rewrite_and_reverse_byte_exactly() { + for version in [ + "0.12.3", + "2.8.2", + "2.9.3", + "2.10.4", + "2.11.2", + "2.17.3", + "2.29.2", + "0.12.3-extras", + "2.29.2-extras", + ] { + for ending in ["\n", "\r\n"] { + let original = fixture(version).replace('\n', ending); + for (kind, source) in [("path", PATH), ("path", &PATH.replace('/', "\\")), ("url", "https://patch.socket.dev/patch/pypi/urllib3/1.26.18/7e52b8b6-53f2-4dc8-860a-1ae7ebd8be0e/e828efa5-5c6d-43f3-9909-03f5ac232b98/urllib3-1.26.18-py2.py3-none-any.whl")] { + let rewritten = rewrite_pdm_lock(&original, "urllib3", "1.26.18", (kind, source), WHEEL, &"a".repeat(64)).unwrap(); + let lock: DocumentMut = rewritten.parse().unwrap(); + let old: DocumentMut = original.parse().unwrap(); + assert_eq!(old["metadata"]["content_hash"].as_str(), lock["metadata"]["content_hash"].as_str()); + for pkg in lock["package"].as_array_of_tables().unwrap() { + if pkg["name"].as_str() != Some("urllib3") { continue; } + assert_eq!(pkg[kind].as_str(), Some(source)); + let files = files_for(&lock, pkg).unwrap(); + assert_eq!(files.len(), 1); + assert_eq!(files.get(0).unwrap().as_inline_table().unwrap()["hash"].as_str(), Some(format!("sha256:{}", "a".repeat(64)).as_str())); + } + assert_eq!(rewrite_pdm_lock(&rewritten, "urllib3", "1.26.18", (kind, source), WHEEL, &"a".repeat(64)).unwrap(), rewritten); + let mut reverted = rewritten.clone(); + for (before, after) in pdm_lock_edits(&original, &rewritten, "urllib3").unwrap().into_iter().rev() { + reverted = reverted.replacen(&after, &before, 1); + } + assert_eq!(reverted, original); + if ending == "\r\n" { assert!(!rewritten.replace("\r\n", "").contains('\n')); } + } + } + } + } + + #[test] + fn native_installers_that_lose_source_identity_refuse() { + for version in ["1.15.5", "2.0.3", "2.1.5", "2.3.4", "2.6.1", "2.7.4"] { + let original = fixture(version); + assert!(rewrite_pdm_lock( + &original, + "urllib3", + "1.26.18", + ("path", PATH), + WHEEL, + &"a".repeat(64) + ) + .unwrap_err() + .contains("unsupported PDM lock_version")); + } + } + + #[test] + fn unsafe_sources_forks_and_integrity_refuse_transactionally() { + let original = fixture("2.29.2"); + for field in [ + "url = 'https://example.com/archive.whl'", + "path = '../custom.whl'", + "git = 'https://example.com/repo'", + "hg = 'https://example.com/repo'", + "svn = 'https://example.com/repo'", + "bzr = 'https://example.com/repo'", + "editable = false", + "source = 'private'", + ] { + let text = original.replace( + "name = \"urllib3\"", + &format!("name = \"urllib3\"\n{field}"), + ); + assert!( + rewrite_pdm_lock( + &text, + "urllib3", + "1.26.18", + ("path", PATH), + WHEEL, + &"a".repeat(64) + ) + .is_err(), + "{field}" + ); + } + let duplicate = format!("{original}\n[[package]]\nname = 'urllib3'\nversion = '1.26.18'\n"); + assert!(rewrite_pdm_lock( + &duplicate, + "urllib3", + "1.26.18", + ("path", PATH), + WHEEL, + &"a".repeat(64) + ) + .is_err()); + for text in [ + original.replace("sha256:", "md5:"), + original.replace("4.5.1", "4.6.0"), + original.replace("inherit_metadata", "unknown"), + original.replace("version = \"1.26.18\"", "version = '1.26.19'"), + original.replace("files = [", "files = 42\ninvalid = ["), + ] { + assert!(rewrite_pdm_lock( + &text, + "urllib3", + "1.26.18", + ("path", PATH), + WHEEL, + &"a".repeat(64) + ) + .is_err()); + } + assert!(rewrite_pdm_lock( + &original, + "requests", + "1.26.18", + ("path", PATH), + WHEEL, + &"a".repeat(64) + ) + .is_err()); + assert!(rewrite_pdm_lock( + &original, + "urllib3", + "1.26.18", + ("path", PATH), + WHEEL, + "invalid" + ) + .is_err()); + } +} diff --git a/crates/socket-patch-core/src/vendor/lock_inventory.rs b/crates/socket-patch-core/src/vendor/lock_inventory.rs index 786453a4..ab611f58 100644 --- a/crates/socket-patch-core/src/vendor/lock_inventory.rs +++ b/crates/socket-patch-core/src/vendor/lock_inventory.rs @@ -1094,9 +1094,9 @@ fn parse_gem_spec_line(line: &str) -> Option<(String, String)> { /// (URL + sha256 of a pure `py3-none-any` wheel) comes from `uv.lock`; /// `poetry.lock` and `--hash`-pinned `requirements.txt` contribute /// DISCOVERY-only entries (no recorded URL; platform-independent wheel -/// choice is not derivable offline). Pipfile.lock contributes -/// entries whose integrity is its digest SET (see `inventory_pipfile_lock`); -/// pdm.lock: not yet read. +/// choice is not derivable offline). `pdm.lock` contributes discovery-only +/// entries. Pipfile.lock contributes entries whose integrity is its digest SET +/// (see `inventory_pipfile_lock`). async fn inventory_pypi_locks(project_root: &Path) -> Option> { let mut out = Vec::new(); let mut found = false; @@ -1130,6 +1130,9 @@ async fn inventory_pypi_locks(project_root: &Path) -> Option> if let Some(entries) = inventory_poetry_lock(project_root).await { found = true; out.extend(entries); + } else if let Some(entries) = inventory_pdm_lock(project_root).await { + found = true; + out.extend(entries); } else { // Pipfile.lock and requirements.txt are read TOGETHER: Pipenv // projects routinely ship both (`pipenv requirements` exports the @@ -1541,6 +1544,61 @@ async fn inventory_pipfile_lock(project_root: &Path) -> Option Option> { + let text = read_regular_to_string(&project_root.join("pdm.lock")) + .await + .ok()?; + let mut out = Vec::new(); + let mut in_package = false; + let mut name: Option = None; + for line in text.lines() { + let t = line.trim(); + if t == "[[package]]" { + in_package = true; + name = None; + continue; + } + if t.starts_with('[') && t != "[[package]]" { + in_package = false; + continue; + } + if !in_package { + continue; + } + if let Some(v) = t.strip_prefix("name = ") { + name = Some(canonicalize_pypi_name(v.trim_matches('"'))); + } else if let Some(v) = t.strip_prefix("version = ") { + if let Some(n) = name.take() { + let v = v.trim_matches('"').to_string(); + if path_safety::is_safe_single_segment(&n) + && path_safety::is_safe_single_segment(&v) + { + out.push(LockfileEntry { + ecosystem: "pypi", + purl: format!("pkg:pypi/{n}@{v}"), + name: n, + version: v, + resolved: None, + integrity: LockIntegrity::None, + }); + } + } + } + } + if out.is_empty() { + return None; + } + Some(dedup_prefer_integrity(out)) +} + /// requirements.txt with exact `==` pins — discovery only. async fn inventory_requirements_txt(project_root: &Path) -> Option> { let text = read_regular_to_string(&project_root.join("requirements.txt")) diff --git a/crates/socket-patch-core/src/vendor/pypi_pdm.rs b/crates/socket-patch-core/src/vendor/pypi_pdm.rs index 4b35bc3d..1355ce85 100644 --- a/crates/socket-patch-core/src/vendor/pypi_pdm.rs +++ b/crates/socket-patch-core/src/vendor/pypi_pdm.rs @@ -1,25 +1,4 @@ -//! pdm-project wiring: a lock-ONLY `[[package]]` splice (pdm.lock -//! lock_version 4.5.x). -//! -//! pdm's `content_hash` covers the pyproject requirements only — identical -//! between strategy variants of the same pyproject — so a per-package lock -//! splice can never trip `pdm install --check` / `pdm lock --check` -//! freshness. The spike-captured D1 shape is a RELATIVE `path = "./…"` key -//! (inserted between `requires_python` and `summary`, exactly where pdm's own -//! serializer puts it) plus `files = []` reduced to the single patched-wheel -//! hash; `pdm sync` / `--check` / `--frozen-lockfile` all pass byte-stably -//! and unearth hash-verifies the local wheel fail-closed (D4). See -//! `spikes/pdm/` and the pdm section of `spikes/PHASE0-V2-FINDINGS.txt`. -//! -//! Drift caveat (spike D5): `pdm lock` and `pdm update ` silently revert -//! the splice with exit 0 (only plain `pdm install` preserves it); the lock's -//! files[] hash is the drift oracle. `pyproject.toml` and `content_hash` are -//! NEVER written by this backend. -//! -//! Spike caveat (D6, partial): only the `inherit_metadata` and `static_urls` -//! strategy shapes were captured, so any other `[metadata] strategy` flag -//! refuses; pdm 2.27 can no longer produce hash-less locks, so a files entry -//! without a sha256 refuses too (both fail-closed, not warnings). +//! PDM lock-only wheel redirects. The manifest and unrelated lock entries stay byte-identical. use std::path::Path; @@ -30,11 +9,10 @@ use crate::utils::fs::atomic_write_bytes_preserving_mode; use super::common::{ item_get, lock_units_named, pep508_name, pep621_declared_names, record, - revert_lock_fragment_splice, unit_has_canon_name, + revert_lock_fragment_splice, }; use super::path::parse_vendor_path; use super::state::{PdmMeta, VendorEntry, WiringAction, WiringRecord}; -use super::toml_surgery::{find_unit_span, package_unit_lines, replace_files_array}; use super::{RevertOutcome, VendorWarning}; /// The only file this backend ever writes (and the revert allowlist). @@ -43,10 +21,6 @@ const LOCK_FILE: &str = "pdm.lock"; /// The `WiringRecord.kind` discriminator this backend owns. const KIND_LOCK_PACKAGE: &str = "pdm_lock_package"; -/// The `[metadata] strategy` flags whose lock shapes the spike captured -/// (D1 default + D6 static_urls). Any other flag refuses fail-closed. -const SUPPORTED_STRATEGIES: [&str; 2] = ["inherit_metadata", "static_urls"]; - /// Guarded read shared in shape with the sibling backend twins: /// `open_regular_file` opens with `O_NONBLOCK` and rejects non-regular /// files, so a FIFO planted as `pdm.lock` (or the diagnostics-only @@ -119,58 +93,18 @@ pub async fn load_pdm_project(root: &Path) -> Result= 2.17"), + format!("{LOCK_FILE} has no [metadata] lock_version; re-lock with a supported PDM release"), ) })?; let mut warnings = Vec::new(); - match lock_version_series(&lock_version) { - // The fixture series (pdm 2.27 writes 4.5.0). - LockVersionSeries::Supported => {} - // A newer 4.x minor keeps the shapes we rewrite (additive schema); - // warn instead of refusing — `pdm lock --check` is the backstop. - LockVersionSeries::NewerMinor => warnings.push(VendorWarning::new( - "pypi_pdm_lock_version_untested", - format!( - "pdm.lock lock_version {lock_version} is newer than the fixture-tested 4.5.x; \ - verify with `pdm install --check` after vendoring" - ), - )), - LockVersionSeries::Unsupported => { - return Err(( - "pypi_pdm_lock_version_unsupported", - format!( - "pdm.lock lock_version {lock_version:?} is outside the supported 4.5+ \ - series; re-lock with a current pdm" - ), - )) - } + if lock_version == "2" { + warnings.push(VendorWarning::new("pypi_pdm_legacy_sync_required", "PDM 0.x may regenerate freshly generated locks during install; use `pdm sync` to preserve this patch, or upgrade PDM")); } + crate::utils::pdm_lock::lock_version(&lock) + .map_err(|detail| ("pypi_pdm_lock_version_unsupported", detail))?; - // SECURITY/correctness: strategies change the files[]/unit shapes; only - // the fixture-captured set is splice-proven (spike D6 was partial) — - // anything else refuses fail-closed rather than guessing an emitter shape. - let strategy: Vec = metadata - .and_then(|m| item_get(m, "strategy")) - .and_then(Item::as_array) - .map(|arr| { - arr.iter() - .filter_map(Value::as_str) - .map(str::to_string) - .collect() - }) - .unwrap_or_default(); - if let Some(unknown) = strategy - .iter() - .find(|s| !SUPPORTED_STRATEGIES.contains(&s.as_str())) - { - return Err(( - "pypi_pdm_lock_strategy_unsupported", - format!( - "pdm.lock [metadata] strategy contains {unknown:?}; only \ - inherit_metadata/static_urls locks are fixture-tested" - ), - )); - } + let strategy = crate::utils::pdm_lock::validate_strategy(&lock) + .map_err(|detail| ("pypi_pdm_lock_strategy_unsupported", detail))?; let pyproject_text = read_regular_to_string(&root.join("pyproject.toml")) .await @@ -200,6 +134,25 @@ fn classify_dependency(p: &PdmProject, canon_name: &str) -> &'static str { }; let mut declared: Vec = Vec::new(); pep621_declared_names(&doc, &mut declared); + if let Some(pdm) = doc + .get("tool") + .and_then(|tool| item_get(tool, "pdm")) + .and_then(Item::as_table_like) + { + for (section, dependencies) in pdm.iter() { + if section == "dependencies" || section.ends_with("-dependencies") { + if let Some(table) = dependencies.as_table_like() { + declared.extend( + table + .iter() + .filter(|(_, spec)| spec.as_array().is_none()) + .map(|(name, _)| name.to_string()), + ); + } + } + } + } + for groups in [ doc.get("tool") .and_then(|t| item_get(t, "pdm")) @@ -248,23 +201,72 @@ pub(super) fn check_target_guards( format!("{LOCK_FILE} has no [[package]] entry for {canon_name}; run `pdm lock` first"), )); } - // Cross-platform/marker forks list the same name at multiple versions; - // one surgical rewrite would mispin the other forks — refuse (mirrors uv). - if units.len() > 1 { + let mut variants = std::collections::BTreeSet::new(); + let mut fresh = false; + let mut in_sync = false; + for unit in units { + let extras = unit + .get("extras") + .map(ToString::to_string) + .unwrap_or_default(); + if !variants.insert(extras) { + return Err(( + "pypi_pdm_lock_forked_package", + "duplicate or forked PDM package".into(), + )); + } + match check_target_unit(p, unit, canon_name, version, record_uuid)? { + PdmTarget::Fresh => fresh = true, + PdmTarget::InSync => in_sync = true, + } + } + if fresh && in_sync { return Err(( - "pypi_pdm_lock_forked_package", + "pypi_pdm_source_already_exists", + "PDM extras have inconsistent sources".into(), + )); + } + Ok(if in_sync { + PdmTarget::InSync + } else { + PdmTarget::Fresh + }) +} + +fn check_target_unit( + p: &PdmProject, + unit: &toml_edit::Table, + canon_name: &str, + version: &str, + record_uuid: &str, +) -> Result { + if unit.get("version").and_then(Item::as_str) != Some(version) { + return Err(( + "pypi_pdm_lock_package_missing", format!( - "{LOCK_FILE} resolves {canon_name} at multiple versions/markers (a forked \ - resolution); vendoring would mispin the other forks" + "PDM locked version {:?} differs from installed {version}", + unit.get("version").and_then(Item::as_str) ), )); } - let unit = units[0]; - + if ["url", "git", "hg", "svn", "bzr", "editable", "source"] + .iter() + .any(|key| unit.contains_key(key)) + || unit.get("path").is_some_and(|item| item.as_str().is_none()) + { + return Err(( + "pypi_pdm_source_already_exists", + "PDM package has an existing source".into(), + )); + } if let Some(path) = unit.get("path").and_then(Item::as_str) { return match parse_vendor_path(path) { // Ours, same patch generation: the in-sync hot path. - Some(parts) if parts.eco == "pypi" && parts.uuid == record_uuid => { + Some(parts) + if parts.eco == "pypi" + && parts.uuid == record_uuid + && crate::utils::pdm_lock::wheel_matches(&parts.leaf, canon_name, version) => + { Ok(PdmTarget::InSync) } // Ours, but a STALE patch generation: wiring over it would lose @@ -289,23 +291,10 @@ pub(super) fn check_target_guards( )), }; } - // Direct URL / VCS units carry unit-level url/git keys — also user-owned. - if unit.get("url").is_some() || unit.get("git").is_some() { - return Err(( - "pypi_pdm_source_already_exists", - format!( - "{LOCK_FILE} resolves {canon_name} from a user-declared url/vcs source; \ - refusing to overwrite it" - ), - )); - } - // Splicing a hashed entry into a hash-less lock is untested (spike D6: // `--no-hashes` no longer exists in pdm 2.27, so this only arises from // older tools) — refuse rather than mix verification regimes. - let hashed_entries = unit - .get("files") - .and_then(Item::as_array) + let hashed_entries = crate::utils::pdm_lock::files_for(&p.lock, unit) .map(|arr| { !arr.is_empty() && arr @@ -323,18 +312,6 @@ pub(super) fn check_target_guards( )); } - // The splice keeps the unit's version line verbatim, so the lock must - // already resolve the version being patched (lock/venv drift otherwise). - let locked_version = unit.get("version").and_then(Item::as_str).unwrap_or(""); - if locked_version != version { - return Err(( - "pypi_pdm_lock_package_missing", - format!( - "{LOCK_FILE} resolves {canon_name} at {locked_version:?}, not the patched \ - {version}; re-lock so the lock matches the installed version" - ), - )); - } Ok(PdmTarget::Fresh) } @@ -370,14 +347,17 @@ pub async fn wire_pdm( PdmTarget::Fresh => {} } - let (old_unit, new_unit) = rewrite_target_package_unit( + let new_lock = crate::utils::pdm_lock::rewrite_pdm_lock( &p.lock_text, canon_name, - rel_wheel, + version, + ("path", &format!("./{rel_wheel}")), wheel_file_name, wheel_sha256_hex, - )?; - let new_lock = p.lock_text.replacen(&old_unit, &new_unit, 1); + ) + .map_err(|detail| ("pypi_pdm_lock_parse_failed", detail))?; + let fragments = crate::utils::pdm_lock::pdm_lock_edits(&p.lock_text, &new_lock, canon_name) + .map_err(|detail| ("pypi_pdm_lock_parse_failed", detail))?; // Mode-preserving: the lock is a user-owned file we merely edit, so the // swapped-in inode must keep its permission bits rather than reset them // to umask defaults (same class as the revert leg in common.rs). @@ -390,14 +370,19 @@ pub async fn wire_pdm( ) })?; - let wiring = vec![record( - LOCK_FILE, - KIND_LOCK_PACKAGE, - WiringAction::Rewritten, - canon_name, - Some(old_unit), - new_unit, - )]; + let wiring = fragments + .into_iter() + .map(|(old_unit, new_unit)| { + record( + LOCK_FILE, + KIND_LOCK_PACKAGE, + WiringAction::Rewritten, + canon_name, + Some(old_unit), + new_unit, + ) + }) + .collect(); let meta = PdmMeta { dep_class: classify_dependency(p, canon_name).to_string(), lock_version: p.lock_version.clone(), @@ -415,84 +400,6 @@ pub async fn revert_pdm(entry: &VendorEntry, root: &Path, dry_run: bool) -> Reve // ── helpers ────────────────────────────────────────────────────────────── -enum LockVersionSeries { - Supported, - NewerMinor, - Unsupported, -} - -/// `4.5.x` is the fixture series; a newer `4.` warns; everything else -/// (older minors, other majors, unparseable) refuses. -fn lock_version_series(v: &str) -> LockVersionSeries { - let mut it = v.split('.'); - let major = it.next().and_then(|s| s.parse::().ok()); - let minor = it.next().and_then(|s| s.parse::().ok()); - match (major, minor) { - (Some(4), Some(5)) => LockVersionSeries::Supported, - (Some(4), Some(m)) if m > 5 => LockVersionSeries::NewerMinor, - _ => LockVersionSeries::Unsupported, - } -} - -/// Rewrite the target `[[package]]` unit to the D1-captured local-file -/// shape: insert `path = "./"` right after `requires_python` -/// (falling back to `version`/`name` — pdm's own key order) and reduce -/// `files = [...]` to the single `{file = "", hash = "sha256:"}` -/// element. Every other line is preserved verbatim. Returns -/// `(old_unit, new_unit)` for the wiring record. -fn rewrite_target_package_unit( - lock_text: &str, - canon: &str, - rel_wheel: &str, - wheel_file_name: &str, - wheel_sha256_hex: &str, -) -> Result<(String, String), (&'static str, String)> { - let span = - find_unit_span(lock_text, |lines| unit_has_canon_name(lines, canon)).ok_or_else(|| { - ( - "pypi_pdm_lock_package_missing", - format!("{LOCK_FILE} has no [[package]] entry for {canon}"), - ) - })?; - let unit = package_unit_lines(&lock_text[span]); - let old_unit = unit.join("\n"); - // The splice is a literal-text replace of this LF-joined fragment; a lock - // whose physical lines differ from the logical ones (CRLF endings) would - // silently no-op the replace while still recording the wiring — refuse. - if !lock_text.contains(&old_unit) { - return Err(( - "pypi_pdm_lock_parse_failed", - format!( - "the {canon} [[package]] entry does not match {LOCK_FILE} byte-for-byte \ - (CRLF line endings?); re-lock with pdm so the lock is LF-normalized" - ), - )); - } - let mut out = - replace_files_array(&unit, wheel_file_name, wheel_sha256_hex).ok_or_else(|| { - // The hash guard already requires hashed files entries; reaching here - // means the parsed and textual views disagree — fail closed. - ( - "pypi_pdm_lock_parse_failed", - format!("the {canon} [[package]] entry has no files array to rewrite"), - ) - })?; - - let anchor = out - .iter() - .position(|l| l.starts_with("requires_python = ")) - .or_else(|| out.iter().position(|l| l.starts_with("version = "))) - .or_else(|| out.iter().position(|l| l.starts_with("name = "))) - .ok_or_else(|| { - ( - "pypi_pdm_lock_parse_failed", - format!("the {canon} [[package]] entry has no key to anchor the path after"), - ) - })?; - out.insert(anchor + 1, format!("path = \"./{rel_wheel}\"")); - Ok((old_unit, out.join("\n"))) -} - #[cfg(test)] mod tests { use super::*; @@ -559,12 +466,10 @@ requires_python = "==3.14.*" name = "six" version = "1.16.0" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -path = "./.socket/vendor/pypi/9f6b2c4e-1d3a-4f6b-8c2d-7e5a9b1c3d5f/six-1.16.0-py2.py3-none-any.whl" summary = "Python 2 and 3 compatibility utilities" groups = ["default"] -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:7015f5a42a0f83fd1b7d3ca0ba10d8777a207c19b6ffebb39e2e1c03af6a281b"}, -] +files = [{ file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:7015f5a42a0f83fd1b7d3ca0ba10d8777a207c19b6ffebb39e2e1c03af6a281b" }] +path = "./.socket/vendor/pypi/9f6b2c4e-1d3a-4f6b-8c2d-7e5a9b1c3d5f/six-1.16.0-py2.py3-none-any.whl" "#; /// The transitive "before": [metadata] + python-dateutil unit verbatim @@ -643,12 +548,10 @@ files = [ name = "six" version = "1.16.0" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -path = "./.socket/vendor/pypi/9f6b2c4e-1d3a-4f6b-8c2d-7e5a9b1c3d5f/six-1.16.0-py2.py3-none-any.whl" summary = "Python 2 and 3 compatibility utilities" groups = ["default"] -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:7015f5a42a0f83fd1b7d3ca0ba10d8777a207c19b6ffebb39e2e1c03af6a281b"}, -] +files = [{ file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:7015f5a42a0f83fd1b7d3ca0ba10d8777a207c19b6ffebb39e2e1c03af6a281b" }] +path = "./.socket/vendor/pypi/9f6b2c4e-1d3a-4f6b-8c2d-7e5a9b1c3d5f/six-1.16.0-py2.py3-none-any.whl" "#; /// The D6-captured static_urls shape: strategy gains "static_urls" and @@ -830,9 +733,30 @@ distribution = false /// D6 (partial leg): strategy sets outside the fixtures refuse — their /// unit shapes were never captured. + #[tokio::test] + async fn legacy_declarations_are_direct_and_bad_strategy_types_refuse() { + for section in ["dependencies", "dev-dependencies", "feature-dependencies"] { + let manifest = format!( + "[tool.pdm.{section}]\nsix = {{version = '==1.16.0', extras = ['feature']}}\n" + ); + let tmp = write_project(LOCK_DIRECT_REGISTRY, &manifest).await; + let project = load_pdm_project(tmp.path()).await.unwrap(); + assert_eq!(classify_dependency(&project, "six"), "direct"); + } + for strategy in ["42", "['inherit_metadata', 42]"] { + let lock = LOCK_DIRECT_REGISTRY.replace("[\"inherit_metadata\"]", strategy); + let tmp = write_project(&lock, PYPROJECT_DIRECT).await; + assert_eq!( + load_pdm_project(tmp.path()).await.unwrap_err().0, + "pypi_pdm_lock_strategy_unsupported" + ); + assert_eq!(read_lock(tmp.path()).await, lock); + } + } + #[tokio::test] async fn unsupported_strategy_refuses() { - for flag in ["cross_platform", "direct_minimal_versions", "no_hashes"] { + for flag in ["unknown_strategy", "no_hashes"] { let lock = LOCK_DIRECT_REGISTRY.replace( "strategy = [\"inherit_metadata\"]", &format!("strategy = [\"inherit_metadata\", \"{flag}\"]"), @@ -883,7 +807,7 @@ distribution = false let tmp = write_project("[[package]]\nname = \"six\"\n", PYPROJECT_DIRECT).await; let err = load_pdm_project(tmp.path()).await.unwrap_err(); assert_eq!(err.0, "pypi_pdm_lock_version_unsupported"); - for bad in ["4.4.1", "3.0", "5.0.0", "garbage"] { + for bad in ["3.1", "4.0", "4.1", "4.2", "4.6.0", "5.0.0", "garbage"] { let lock = LOCK_DIRECT_REGISTRY.replace( "lock_version = \"4.5.0\"", &format!("lock_version = \"{bad}\""), @@ -959,18 +883,14 @@ distribution = false } #[tokio::test] - async fn newer_minor_lock_version_warns_not_refuses() { - let lock = - LOCK_DIRECT_REGISTRY.replace("lock_version = \"4.5.0\"", "lock_version = \"4.6.0\""); + async fn unknown_lock_version_refuses_before_writing() { + let lock = LOCK_DIRECT_REGISTRY.replace("4.5.0", "4.6.0"); let tmp = write_project(&lock, PYPROJECT_DIRECT).await; - let p = load_pdm_project(tmp.path()).await.unwrap(); - assert_eq!(p.warnings.len(), 1); - assert_eq!(p.warnings[0].code, "pypi_pdm_lock_version_untested"); - assert_eq!(p.lock_version, "4.6.0"); - // The wiring itself still works on the warned lock. - let (wiring, meta) = wire_default(&p, tmp.path()).await; - assert_eq!(wiring.len(), 1); - assert_eq!(meta.lock_version, "4.6.0"); + assert_eq!( + load_pdm_project(tmp.path()).await.unwrap_err().0, + "pypi_pdm_lock_version_unsupported" + ); + assert_eq!(read_lock(tmp.path()).await, lock); } /// Re-running vendor on an already-wired lock with the SAME uuid is the @@ -1217,106 +1137,28 @@ distribution = false ); } - /// A CRLF lock (e.g. a `core.autocrlf` checkout) parses fine but its - /// physical lines differ from the LF-joined splice fragment, so the - /// literal-text replace would match nothing — wiring must refuse - /// fail-closed rather than report success with the lock never rewired. - #[tokio::test] - async fn crlf_lock_refuses_instead_of_silently_not_wiring() { - let crlf = LOCK_DIRECT_REGISTRY.replace('\n', "\r\n"); - let tmp = write_project(&crlf, PYPROJECT_DIRECT).await; - let p = load_pdm_project(tmp.path()).await.unwrap(); - assert_eq!( - check_target_guards(&p, "six", "1.16.0", UUID).unwrap(), - PdmTarget::Fresh, - "the parsed view accepts CRLF; only the splice must refuse" - ); - - let err = wire_pdm( - &p, - tmp.path(), - "six", - "1.16.0", - REL_WHEEL, - WHEEL_NAME, - WHEEL_SHA, - UUID, - ) - .await - .unwrap_err(); - assert_eq!(err.0, "pypi_pdm_lock_parse_failed"); - assert_eq!(read_lock(tmp.path()).await, crlf, "refusal writes nothing"); - } - - /// The parsed and textual lock views can diverge on hand-edited spelling: - /// TOML accepts `name="six"` / `files=[` without spaces, but the textual - /// scanner pins pdm's own `key = ` serialization. The parsed-view guards - /// pass, so the splice-time rescan must refuse fail-closed — never report - /// success while the literal-text replace matched nothing (the CRLF twin - /// above is the same class). #[tokio::test] - async fn textual_parsed_view_divergence_refuses_fail_closed() { - // Direct probe: an absent package misses find_unit_span. - let err = rewrite_target_package_unit( - LOCK_DIRECT_REGISTRY, - "absent-pkg", - REL_WHEEL, - WHEEL_NAME, - WHEEL_SHA, - ) - .unwrap_err(); - assert_eq!(err.0, "pypi_pdm_lock_package_missing"); - assert!(err.1.contains("absent-pkg"), "{}", err.1); - - // `name="six"`: the parsed guards pass, the unit-span scan misses. - let lock = LOCK_DIRECT_REGISTRY.replace("name = \"six\"", "name=\"six\""); - let tmp = write_project(&lock, PYPROJECT_DIRECT).await; - let p = load_pdm_project(tmp.path()).await.unwrap(); - assert_eq!( - check_target_guards(&p, "six", "1.16.0", UUID).unwrap(), - PdmTarget::Fresh, - "the parsed view accepts the no-space spelling; only the splice must refuse" - ); - let err = wire_pdm( - &p, - tmp.path(), - "six", - "1.16.0", - REL_WHEEL, - WHEEL_NAME, - WHEEL_SHA, - UUID, - ) - .await - .unwrap_err(); - assert_eq!(err.0, "pypi_pdm_lock_package_missing"); - assert_eq!(read_lock(tmp.path()).await, lock, "refusal writes nothing"); - - // `files=[`: the parsed guards see the hashed array, the textual - // files rewrite finds no `files = [` line. - let lock = LOCK_DIRECT_REGISTRY.replace("files = [", "files=["); - let tmp = write_project(&lock, PYPROJECT_DIRECT).await; - let p = load_pdm_project(tmp.path()).await.unwrap(); - assert_eq!( - check_target_guards(&p, "six", "1.16.0", UUID).unwrap(), - PdmTarget::Fresh, - "the parsed view sees the hashed files entries; only the splice must refuse" - ); - let err = wire_pdm( - &p, - tmp.path(), - "six", - "1.16.0", - REL_WHEEL, - WHEEL_NAME, - WHEEL_SHA, - UUID, - ) - .await - .unwrap_err(); - assert_eq!(err.0, "pypi_pdm_lock_parse_failed"); - assert!(err.1.contains("no files array to rewrite"), "{}", err.1); - assert_eq!(read_lock(tmp.path()).await, lock, "refusal writes nothing"); + async fn crlf_and_noncanonical_spacing_round_trip() { + for lock in [ + LOCK_DIRECT_REGISTRY.replace('\n', "\r\n"), + LOCK_DIRECT_REGISTRY.replace("name = ", "name="), + LOCK_DIRECT_REGISTRY.replace("files = [", "files=["), + ] { + let tmp = write_project(&lock, PYPROJECT_DIRECT).await; + let project = load_pdm_project(tmp.path()).await.unwrap(); + let (wiring, meta) = wire_default(&project, tmp.path()).await; + let rewritten = read_lock(tmp.path()).await; + assert!(rewritten.contains(REL_WHEEL)); + if lock.contains("\r\n") { + assert!(!rewritten.replace("\r\n", "").contains('\n')); + } + assert!( + revert_pdm(&entry_for(wiring, meta), tmp.path(), false) + .await + .success + ); + assert_eq!(read_lock(tmp.path()).await, lock); + } } /// mkfifo(2) directly rather than shelling out to the `mkfifo` binary — @@ -1497,36 +1339,4 @@ distribution = false "drifted lock left alone" ); } - - #[test] - fn lock_version_series_classifier() { - assert!(matches!( - lock_version_series("4.5.0"), - LockVersionSeries::Supported - )); - assert!(matches!( - lock_version_series("4.5.1"), - LockVersionSeries::Supported - )); - assert!(matches!( - lock_version_series("4.6.0"), - LockVersionSeries::NewerMinor - )); - assert!(matches!( - lock_version_series("4.10.2"), - LockVersionSeries::NewerMinor - )); - assert!(matches!( - lock_version_series("4.4.1"), - LockVersionSeries::Unsupported - )); - assert!(matches!( - lock_version_series("5.0.0"), - LockVersionSeries::Unsupported - )); - assert!(matches!( - lock_version_series("garbage"), - LockVersionSeries::Unsupported - )); - } } diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/0.12.3-extras.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/0.12.3-extras.lock new file mode 100644 index 00000000..6b8d335a --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/0.12.3-extras.lock @@ -0,0 +1,42 @@ +[[package]] +name = "PySocks" +sections = ["default"] +version = "1.7.1" +summary = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." + +[[package]] +name = "urllib3" +sections = ["default"] +version = "1.26.18" +summary = "HTTP library with thread-safe connection pooling, file post, and more." + +[[package]] +name = "urllib3" +sections = ["default"] +version = "1.26.18" +extras = ["socks"] +summary = "HTTP library with thread-safe connection pooling, file post, and more." + +[package.dependencies] +PySocks = "!=1.5.7,<2.0,>=1.5.6" +urllib3 = "==1.26.18" + +[metadata] +lock_version = "2" +content_hash = "sha256:eabdc6e14803b58cb0df233197afbdd3439fbc3251e0b664153014ae97a3a223" + + +[metadata.files] +"pysocks 1.7.1" = [ + {file = "PySocks-1.7.1-py27-none-any.whl", hash = "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299"}, + {file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"}, + {file = "PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"}, +] +"urllib3 1.26.18" = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] +"urllib3[socks] 1.26.18" = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/0.12.3.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/0.12.3.lock new file mode 100644 index 00000000..09a5c108 --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/0.12.3.lock @@ -0,0 +1,16 @@ +[[package]] +name = "urllib3" +sections = ["default"] +version = "1.26.18" +summary = "HTTP library with thread-safe connection pooling, file post, and more." + +[metadata] +lock_version = "2" +content_hash = "sha256:545dba5a99e3f872c46498f788bd003980b3b767c1deea7ead60fee8526dd537" + + +[metadata.files] +"urllib3 1.26.18" = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/1.15.5.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/1.15.5.lock new file mode 100644 index 00000000..db697c12 --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/1.15.5.lock @@ -0,0 +1,16 @@ +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." + +[metadata] +lock_version = "3.1" +content_hash = "sha256:46a748fce6f07860973ddae400d3c212b6f5d094da5fecf45a625f1e6b577f05" + + +[metadata.files] +"urllib3 1.26.18" = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.0.3.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.0.3.lock new file mode 100644 index 00000000..f89dcc5c --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.0.3.lock @@ -0,0 +1,16 @@ +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." + +[metadata] +lock_version = "4.0" +content_hash = "sha256:46a748fce6f07860973ddae400d3c212b6f5d094da5fecf45a625f1e6b577f05" + + +[metadata.files] +"urllib3 1.26.18" = [ + {url = "https://files.pythonhosted.org/packages/0c/39/64487bf07df2ed854cc06078c27c0d0abc59bd27b32232876e403c333a08/urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, + {url = "https://files.pythonhosted.org/packages/b0/53/aa91e163dcfd1e5b82d8a890ecf13314e3e149c05270cc644581f77f17fd/urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.1.5.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.1.5.lock new file mode 100644 index 00000000..f89dcc5c --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.1.5.lock @@ -0,0 +1,16 @@ +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." + +[metadata] +lock_version = "4.0" +content_hash = "sha256:46a748fce6f07860973ddae400d3c212b6f5d094da5fecf45a625f1e6b577f05" + + +[metadata.files] +"urllib3 1.26.18" = [ + {url = "https://files.pythonhosted.org/packages/0c/39/64487bf07df2ed854cc06078c27c0d0abc59bd27b32232876e403c333a08/urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, + {url = "https://files.pythonhosted.org/packages/b0/53/aa91e163dcfd1e5b82d8a890ecf13314e3e149c05270cc644581f77f17fd/urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.10.4.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.10.4.lock new file mode 100644 index 00000000..dc9d47d2 --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.10.4.lock @@ -0,0 +1,18 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default"] +strategy = ["cross_platform"] +lock_version = "4.4" +content_hash = "sha256:46a748fce6f07860973ddae400d3c212b6f5d094da5fecf45a625f1e6b577f05" + +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." +files = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.11.2.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.11.2.lock new file mode 100644 index 00000000..41ca4b3e --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.11.2.lock @@ -0,0 +1,19 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default"] +strategy = ["cross_platform", "inherit_metadata"] +lock_version = "4.4.1" +content_hash = "sha256:46a748fce6f07860973ddae400d3c212b6f5d094da5fecf45a625f1e6b577f05" + +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." +groups = ["default"] +files = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.17.3.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.17.3.lock new file mode 100644 index 00000000..689aa18a --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.17.3.lock @@ -0,0 +1,22 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default"] +strategy = ["inherit_metadata"] +lock_version = "4.5.0" +content_hash = "sha256:68a0e962e677b7f765a49a6df99753b78d8a99dfe60e5694e6994dcc8efb44bc" + +[[metadata.targets]] +requires_python = ">=3.8" + +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." +groups = ["default"] +files = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.29.2-extras.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.29.2-extras.lock new file mode 100644 index 00000000..6731aed7 --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.29.2-extras.lock @@ -0,0 +1,49 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default"] +strategy = ["inherit_metadata"] +lock_version = "4.5.1" +content_hash = "sha256:be6a4f2e21aefe4681b73194c04212ecb9466f9ad98528ca82ae38c782a00b36" + +[[metadata.targets]] +requires_python = ">=3.8" + +[[package]] +name = "pysocks" +version = "1.7.1" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +summary = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." +groups = ["default"] +files = [ + {file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"}, + {file = "PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"}, +] + +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." +groups = ["default"] +files = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] + +[[package]] +name = "urllib3" +version = "1.26.18" +extras = ["socks"] +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." +groups = ["default"] +dependencies = [ + "PySocks!=1.5.7,<2.0,>=1.5.6", + "urllib3==1.26.18", +] +files = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.29.2.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.29.2.lock new file mode 100644 index 00000000..5b439b90 --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.29.2.lock @@ -0,0 +1,22 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default"] +strategy = ["inherit_metadata"] +lock_version = "4.5.1" +content_hash = "sha256:68a0e962e677b7f765a49a6df99753b78d8a99dfe60e5694e6994dcc8efb44bc" + +[[metadata.targets]] +requires_python = ">=3.8" + +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." +groups = ["default"] +files = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.3.4.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.3.4.lock new file mode 100644 index 00000000..239a0d49 --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.3.4.lock @@ -0,0 +1,16 @@ +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." + +[metadata] +lock_version = "4.1" +content_hash = "sha256:46a748fce6f07860973ddae400d3c212b6f5d094da5fecf45a625f1e6b577f05" + + +[metadata.files] +"urllib3 1.26.18" = [ + {url = "https://files.pythonhosted.org/packages/0c/39/64487bf07df2ed854cc06078c27c0d0abc59bd27b32232876e403c333a08/urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, + {url = "https://files.pythonhosted.org/packages/b0/53/aa91e163dcfd1e5b82d8a890ecf13314e3e149c05270cc644581f77f17fd/urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.6.1.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.6.1.lock new file mode 100644 index 00000000..7a0beaaa --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.6.1.lock @@ -0,0 +1,21 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." + +[metadata] +lock_version = "4.2" +cross_platform = true +groups = ["default"] +content_hash = "sha256:46a748fce6f07860973ddae400d3c212b6f5d094da5fecf45a625f1e6b577f05" + + +[metadata.files] +"urllib3 1.26.18" = [ + {url = "https://files.pythonhosted.org/packages/0c/39/64487bf07df2ed854cc06078c27c0d0abc59bd27b32232876e403c333a08/urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, + {url = "https://files.pythonhosted.org/packages/b0/53/aa91e163dcfd1e5b82d8a890ecf13314e3e149c05270cc644581f77f17fd/urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.7.4.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.7.4.lock new file mode 100644 index 00000000..7a0beaaa --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.7.4.lock @@ -0,0 +1,21 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." + +[metadata] +lock_version = "4.2" +cross_platform = true +groups = ["default"] +content_hash = "sha256:46a748fce6f07860973ddae400d3c212b6f5d094da5fecf45a625f1e6b577f05" + + +[metadata.files] +"urllib3 1.26.18" = [ + {url = "https://files.pythonhosted.org/packages/0c/39/64487bf07df2ed854cc06078c27c0d0abc59bd27b32232876e403c333a08/urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, + {url = "https://files.pythonhosted.org/packages/b0/53/aa91e163dcfd1e5b82d8a890ecf13314e3e149c05270cc644581f77f17fd/urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.8.2.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.8.2.lock new file mode 100644 index 00000000..c3b3ba89 --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.8.2.lock @@ -0,0 +1,19 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default"] +cross_platform = true +static_urls = false +lock_version = "4.3" +content_hash = "sha256:46a748fce6f07860973ddae400d3c212b6f5d094da5fecf45a625f1e6b577f05" + +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." +files = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/2.9.3.lock b/crates/socket-patch-core/tests/fixtures/pdm-native/2.9.3.lock new file mode 100644 index 00000000..c3b3ba89 --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/2.9.3.lock @@ -0,0 +1,19 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default"] +cross_platform = true +static_urls = false +lock_version = "4.3" +content_hash = "sha256:46a748fce6f07860973ddae400d3c212b6f5d094da5fecf45a625f1e6b577f05" + +[[package]] +name = "urllib3" +version = "1.26.18" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +summary = "HTTP library with thread-safe connection pooling, file post, and more." +files = [ + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, +] diff --git a/crates/socket-patch-core/tests/fixtures/pdm-native/README.md b/crates/socket-patch-core/tests/fixtures/pdm-native/README.md new file mode 100644 index 00000000..b196223a --- /dev/null +++ b/crates/socket-patch-core/tests/fixtures/pdm-native/README.md @@ -0,0 +1,7 @@ +These locks were generated by the named, unmodified PDM releases against PyPI on 2026-09-17. The direct project pins urllib3 1.26.18; the extras projects request urllib3[socks]. Versions cover every stable PDM major family and each relevant 2.x lock format boundary. + +The shared hosted/vendored rewriter supports lock versions 2, 4.3, 4.4, 4.4.1, 4.5.0 and 4.5.1, including legacy metadata.files and separate extras entries. Native PDM 1.15.5 and 2.0–2.7 lose URL/path candidate identity before dependency lookup; their formats 3.1/4.0/4.1/4.2 refuse before any write. Future formats also refuse until tested. + +PDM 0.x requires `pdm sync`: its own freshly generated locks with inline dependency specifications can fail its freshness check, so ordinary `pdm install` can regenerate them and discard redirects. The CLI warns for this format. Explicit re-lock/update can discard lock-only patches on any version; rerun Socket after changing dependencies. + +Pure rewriter tests validate all supported versions with LF/CRLF, hosted URLs, POSIX and Windows path spellings, both base/extras integrity tables, repeated rewrites, exact rollback, source conflicts, malformed hashes and unsupported formats. Native installer backtests live in the companion depscan PR and verify actual patched file hashes, integrity rejection, repeated scans, unchanged manifests, rollback and Windows/Linux execution. From c99fa2a64e972571192ffe71a40db4fc71d2f940 Mon Sep 17 00:00:00 2001 From: Mikola Lysenko Date: Thu, 17 Sep 2026 19:58:49 -0400 Subject: [PATCH 2/3] docs, matrix harness, and CI for PDM patch compatibility Documents hosted PDM support (ecosystems.md, hosted-production-e2e.md, CLI_CONTRACT.md new codes, CHANGELOG) and adds the per-release matrix: docs/testing/pdm-compatibility.md with a generated table, scripts/backtest-pdm.py (real PDM releases via uv, hosted/vendored/agent, installed-byte verification, tamper rejection, relock convergence, rollback), and .github/workflows/pdm-compatibility.yml (Linux/Windows/macOS). Measured 0.12-2.29 across 17 shapes x 3 modes: 523 pass, 268 refused as expected (identity-losing 3.1/4.0-4.2, forked two-version locks, non-default lock filenames), 46 unsupported (`__pypackages__` agent/vendored, a documented layout limitation), 0 failures. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/pdm-compatibility.yml | 142 + CHANGELOG.md | 25 + docs/ecosystems.md | 2 +- docs/testing/hosted-production-e2e.md | 15 +- docs/testing/pdm-compatibility.md | 142 + docs/testing/pdm-compatibility/results.json | 28820 ++++++++++++++++++ scripts/backtest-pdm.py | 1373 + 7 files changed, 30510 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/pdm-compatibility.yml create mode 100644 docs/testing/pdm-compatibility.md create mode 100644 docs/testing/pdm-compatibility/results.json create mode 100644 scripts/backtest-pdm.py diff --git a/.github/workflows/pdm-compatibility.yml b/.github/workflows/pdm-compatibility.yml new file mode 100644 index 00000000..cdc38ef6 --- /dev/null +++ b/.github/workflows/pdm-compatibility.yml @@ -0,0 +1,142 @@ +name: PDM patch compatibility + +# Native PDM installer matrix: builds the CLI once per OS, bootstraps pinned +# PDM releases with uv, and runs `scripts/backtest-pdm.py` — hosted, vendored +# and agent mode against the public urllib3 free patch, verifying the +# INSTALLED bytes, lock/manifest stability, hash rejection and rollback. No +# Socket API token is needed. See docs/testing/pdm-compatibility.md. + +on: + pull_request: + paths: + - '.github/workflows/pdm-compatibility.yml' + - 'scripts/backtest-pdm.py' + - 'crates/socket-patch-core/src/utils/pdm_lock.rs' + - 'crates/socket-patch-core/src/patch/redirect/**' + - 'crates/socket-patch-core/src/vendor/pypi*.rs' + - 'crates/socket-patch-core/src/vendor/common.rs' + - 'crates/socket-patch-core/src/vendor/lock_inventory.rs' + - 'crates/socket-patch-cli/src/commands/scan/**' + - 'crates/socket-patch-cli/src/commands/rollback.rs' + - 'crates/socket-patch-core/tests/fixtures/pdm-native/**' + push: + branches: [main] + paths: + - 'scripts/backtest-pdm.py' + - 'crates/socket-patch-core/src/utils/pdm_lock.rs' + - 'crates/socket-patch-core/src/patch/redirect/pdm.rs' + - 'crates/socket-patch-core/src/vendor/pypi_pdm.rs' + workflow_dispatch: + inputs: + versions: + description: 'Space-separated PDM versions (empty = the required matrix below)' + required: false + default: '' + shapes: + description: 'Space-separated shapes (empty = every shape)' + required: false + default: '' + +permissions: + contents: read + +concurrency: + group: pdm-compat-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + SOCKET_NO_CONFIG: '1' + SOCKET_NO_UPDATE_CHECK: '1' + PDM_CHECK_UPDATE: 'false' + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2 + with: + key: pdm-compat + - run: cargo build --locked -p socket-patch-cli + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: pdm-cli-${{ matrix.os }} + path: | + target/debug/socket-patch + target/debug/socket-patch.exe + if-no-files-found: error + retention-days: 7 + + native: + needs: build + strategy: + fail-fast: false + matrix: + # Every stable PDM major family (0.x, 1.x, 2.x) and each 2.x lock-format + # boundary, on Linux and Windows; macOS samples the ends of the range. + os: [ubuntu-latest, windows-latest] + pdm: ['0.12.3', '1.15.5', '2.0.3', '2.1.5', '2.3.4', '2.6.1', '2.7.4', '2.8.2', '2.9.3', '2.10.4', '2.11.2', '2.17.3', '2.20.1', '2.25.9', '2.29.2'] + include: + - { os: macos-latest, pdm: '0.12.3' } + - { os: macos-latest, pdm: '2.8.2' } + - { os: macos-latest, pdm: '2.29.2' } + runs-on: ${{ matrix.os }} + timeout-minutes: 45 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: pdm-cli-${{ matrix.os }} + path: native-cli + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + with: + python-version: '3.12' + # uv bootstraps every pinned PDM release (and its interpreter) itself; + # pinning uv keeps the bootstrap reproducible across runner images. + - run: python -m pip install uv==0.11.19 + - name: Exercise the native PDM installers + shell: bash + env: + PDM_VERSION: ${{ matrix.pdm }} + VERSIONS_OVERRIDE: ${{ github.event.inputs.versions }} + SHAPES_OVERRIDE: ${{ github.event.inputs.shapes }} + run: | + chmod +x native-cli/socket-patch* || true + cli="native-cli/socket-patch" + if [ "$RUNNER_OS" = "Windows" ]; then cli="native-cli/socket-patch.exe"; fi + versions="$PDM_VERSION" + if [ -n "$VERSIONS_OVERRIDE" ]; then versions="$VERSIONS_OVERRIDE"; fi + shapes_arg=() + if [ -n "$SHAPES_OVERRIDE" ]; then shapes_arg=(--shapes $SHAPES_OVERRIDE); fi + python3 scripts/backtest-pdm.py \ + --socket-patch "$cli" \ + --socket-patch-revision "$GITHUB_SHA" \ + --output native-pdm \ + --versions $versions \ + --modes hosted vendored agent \ + "${shapes_arg[@]}" \ + --jobs 3 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + if: always() + with: + name: pdm-results-${{ matrix.os }}-${{ matrix.pdm }} + path: | + native-pdm/summary.json + native-pdm/summary.md + native-pdm/*.log + native-pdm/original/**/pdm.lock + native-pdm/original/**/pyproject.toml + native-pdm/captures/**/result.json + native-pdm/captures/**/cli-output.json + native-pdm/captures/**/pdm.lock + native-pdm/captures/**/*.log + retention-days: 14 diff --git a/CHANGELOG.md b/CHANGELOG.md index 73791aeb..c51af03a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -88,6 +88,31 @@ into the new version's section — see docs/releasing.md. the verified remedy (`pipenv run pip uninstall -y && pipenv sync`, or a clean `pipenv --rm && pipenv sync`), and the stale purl is excluded from the same-run `--vex`. +- **PDM projects take hosted patches, and hosted and vendored patches share + one validated `pdm.lock` rewriter.** `scan --mode hosted` rewrites `pdm.lock` + to point the target `[[package]]` at the hosted wheel URL with the patched + SHA-256 (`redirect_pdm_lock_package`), and `scan --mode vendored` wires the + same unit to a committed wheel through the shared rewriter + (`utils/pdm_lock.rs`). Both preserve line endings and non-canonical spacing, + support the legacy `[metadata.files]` table and separate `extras` entries, + are idempotent, and leave `pyproject.toml` and `content_hash` untouched. + Supported lock formats are `2` (PDM 0.12–1.4) and `4.3`–`4.5.1` (PDM 2.8+); + the identity-losing `3.1` / `4.0`–`4.2` formats (PDM 1.8–2.7) and unknown + future formats are refused before any write (`redirect_pdm_refused` / + `pypi_pdm_lock_version_unsupported`), leaving the registry lock installable. + A `pdm.lock` written by PDM 0.x/1.x (lock format `2`) warns + `redirect_pdm_legacy_sync_required`: those releases have an upstream + freshness bug, so `pdm install` can regenerate the lock — use `pdm sync`. + Verified end-to-end against real PDM 0.12–2.29 across hosted, vendored and + agent mode on Linux, Windows and macOS; see + `docs/testing/pdm-compatibility.md` and `scripts/backtest-pdm.py`. When + several Python lockfiles coexist, `uv.lock` and `poetry.lock` drive hosted + PyPI redirects ahead of `pdm.lock`, so a leftover `pdm.lock` beside them + neither blocks a live redirect nor is falsely attested. A hosted lock-only + `pdm.lock` checkout is discovered and redirected (the lock inventory now + reads `pdm.lock`), and a re-scan after an external `pdm lock` rebases the + ledger's recorded edits onto the relocked text so `rollback` stays + byte-invertible even when PDM reflows the lock's line endings. - **Poetry projects take hosted patches, and vendored patches now cover every `poetry.lock` generation.** `scan --mode hosted` rewrites `poetry.lock` to a `[package.source] type = "url"` pointing at the Socket-hosted, SHA-256-pinned diff --git a/docs/ecosystems.md b/docs/ecosystems.md index 57a061d2..a30984d3 100644 --- a/docs/ecosystems.md +++ b/docs/ecosystems.md @@ -15,7 +15,7 @@ The backticked slug in each row is the value `-e`/`--ecosystems` accepts (e.g. | Ecosystem | agent (`--mode agent`) | vendored (`--mode vendored`) | hosted (`--mode hosted`) | |-----------|------------------------|------------------------------|--------------------------| | npm (`npm`) — pnpm / yarn / berry / bun | ✅ any install layout; `setup` postinstall hook | ✅ six lockfile flavors: package-lock, yarn classic, yarn berry (node-modules linker; PnP refused), pnpm v9, pnpm legacy v5.4/v6.0 (`pnpm 7/8` — frozen installs are path-bound because those majors absolutize `file:` override specifiers; moved checkouts run one `pnpm install --offline --no-frozen-lockfile`, surfaced as `vendor_pnpm_legacy_absolute_specifier`), bun `bun.lock` (binary `bun.lockb` refused with a `--save-text-lockfile` pointer). Rush monorepos refused (`vendor_rush_unsupported`) — see [Rush notes](#npm-rush-monorepos) | ✅ package-lock / npm-shrinkwrap, pnpm-lock.yaml and legacy shrinkwrap.yaml (pnpm majors 1–12; block and flow resolutions), yarn classic, yarn berry, bun — pnpm, berry, and bun carry constraints, see [npm hosted-mode notes](#npm-hosted-mode-notes) | -| PyPI (`pypi`) — uv / poetry / pdm / pipenv / pip | ✅ `.pth` startup hook via `setup` | ✅ uv project/script locks, PEP 751 `pylock.toml` / `pylock..toml`, poetry, pdm, pipenv (Pipenv 2018 or later — every `Pipfile.lock` category is rewired, lock-only checkouts included; Pipenv 2023+ does not hash-check local wheels — `vendor_integrity_unverified`; a venv still holding the upstream release is reported as `pypi_pipenv_stale_install`; see [Pipenv compatibility](testing/pipenv-compatibility.md)), and requirements.txt. Native uv vendoring requires uv ≥ 0.2.35 (the `[[package]]` lock grammar); hosted mode covers native `uv.lock` from uv 0.1.45 (the first release whose `uv lock` writes one) and requirements from uv 0.0.5; see [uv compatibility](testing/uv-compatibility.md). | ✅ requirements.txt including hash continuations, uv project/script locks, and PEP 751 locks. Version/source ambiguity is refused; see [uv compatibility](testing/uv-compatibility.md). Poetry 1.x and 2.x locks are supported; Poetry 0.x ignores URL sources and is refused. See [Poetry compatibility](testing/poetry-compatibility.md). Pipenv `Pipfile.lock` (pipfile-spec 6 — Pipenv 7 and later; `path` references for 7–11, `file` from 2018; lock-only checkouts and Pipenv's out-of-tree venv are discovered; a warm venv that Pipenv will not reinstall over warns `redirect_pypi_stale_install`; see [Pipenv compatibility](testing/pipenv-compatibility.md)). **pdm locks are not rewritten** — use vendored | +| PyPI (`pypi`) — uv / poetry / pdm / pipenv / pip | ✅ `.pth` startup hook via `setup` | ✅ uv project/script locks, PEP 751 `pylock.toml` / `pylock..toml`, poetry, pdm, pipenv (Pipenv 2018 or later — every `Pipfile.lock` category is rewired, lock-only checkouts included; Pipenv 2023+ does not hash-check local wheels — `vendor_integrity_unverified`; a venv still holding the upstream release is reported as `pypi_pipenv_stale_install`; see [Pipenv compatibility](testing/pipenv-compatibility.md)), and requirements.txt. Native uv vendoring requires uv ≥ 0.2.35 (the `[[package]]` lock grammar); hosted mode covers native `uv.lock` from uv 0.1.45 (the first release whose `uv lock` writes one) and requirements from uv 0.0.5; see [uv compatibility](testing/uv-compatibility.md). | ✅ requirements.txt including hash continuations, uv project/script locks, and PEP 751 locks. Version/source ambiguity is refused; see [uv compatibility](testing/uv-compatibility.md). Poetry 1.x and 2.x locks are supported; Poetry 0.x ignores URL sources and is refused. See [Poetry compatibility](testing/poetry-compatibility.md). Pipenv `Pipfile.lock` (pipfile-spec 6 — Pipenv 7 and later; `path` references for 7–11, `file` from 2018; lock-only checkouts and Pipenv's out-of-tree venv are discovered; a warm venv that Pipenv will not reinstall over warns `redirect_pypi_stale_install`; see [Pipenv compatibility](testing/pipenv-compatibility.md)). `pdm.lock` is supported for the lock formats PDM 0.12–1.4 and 2.8+ write (`lock_version` 2 / 4.3–4.5.1); the identity-losing 3.1 / 4.0–4.2 formats (PDM 1.8–2.7) are refused. See [PDM compatibility](testing/pdm-compatibility.md). | | Cargo (`cargo`) | ✅ in-place + `.cargo-checksum.json` rewrite (shared registry-cache caveat — see [Cargo: shared registry cache](#cargo-shared-registry-cache)) | ✅ `[patch.crates-io]` path entry | ✅ per-patch sparse registry (`[registries.socket-patch-]` + Cargo.lock source/checksum) | | RubyGems (`gem`) | ✅ Bundler plugin via `setup` — needs bundler ≥ 2.2 (1.x cannot load `plugin ... path:` directives; `setup` refuses below the floor and `setup --check` red-flags a wired 1.x project) | ✅ Gemfile + Gemfile.lock path pair (`Gemfile` spelling only — a `gems.rb` project cannot vendor yet) | ✅ per-dep `source` block — edits `gems.rb` + `gems.locked` when present (bundler prefers them over `Gemfile`; spellings that diverge beyond Socket's own edits fail closed with `redirect_gem_gemfile_spellings_diverge`); the `CHECKSUMS` pin needs bundler ≥ 2.6 (older locks get a `redirect_gem_no_checksums_section` warning); a stale pre-redirect materialization that `bundle install` would reuse instead of refetching is flagged `redirect_gem_stale_install` with a prescriptive remedy (see CLI_CONTRACT.md's "Gem stale-install guard") | | Go (`golang`) | ✅ `go.mod` `replace` → `.socket/go-patches/` — see [Go: directory replaces and go.sum](#go-directory-replaces-and-gosum) | ✅ `replace` → the committed vendor tree | ✅ (free tier) fork-style `replace` → `patch.socket.dev/gopatch/` + committed `go.sum` pin; see [golang-hosted.md](design/golang-hosted.md). Paid tier stays ❌ ([golang-hosted-no-go.md](design/golang-hosted-no-go.md)); `redirect_golang_unsupported` names the vendored remedy | diff --git a/docs/testing/hosted-production-e2e.md b/docs/testing/hosted-production-e2e.md index a35da37d..5bd9393d 100644 --- a/docs/testing/hosted-production-e2e.md +++ b/docs/testing/hosted-production-e2e.md @@ -101,15 +101,14 @@ history of this demotion shows every piece to restore (catalog constants, preflight registration, the install-proof leg, and these tables) in both production suites. -PyPI's pdm lock is **not** rewritten by hosted mode (see the -[matrix](../ecosystems.md#mode--ecosystem-matrix)); that flavor is vendored-mode -only, so there is no hosted leg to write for it. `poetry.lock` IS rewritten -(Poetry 1.0+); its live coverage is the per-release matrix in +PyPI's `poetry.lock`, `pdm.lock` and `Pipfile.lock` ARE rewritten by hosted +mode (Poetry 1.0+; PDM lock formats `2` and `4.3`–`4.5.1`; Pipenv 7+); their +live coverage is the per-release matrices in [poetry-compatibility.md](poetry-compatibility.md) (`scripts/backtest-poetry.py`), -and `Pipfile.lock` IS rewritten (Pipenv 7+); its live coverage is the per-release -matrix in [pipenv-compatibility.md](pipenv-compatibility.md) -(`scripts/backtest-pipenv.py`). Both install the redirected lock with every -release rather than one pinned installer, so they are not duplicated as legs here. +[pdm-compatibility.md](pdm-compatibility.md) (`scripts/backtest-pdm.py`) and +[pipenv-compatibility.md](pipenv-compatibility.md) (`scripts/backtest-pipenv.py`), +which install the redirected lock with every release rather than one pinned +installer, so they are not duplicated as legs here. Two supported hosted shapes are deliberately **not** covered here: diff --git a/docs/testing/pdm-compatibility.md b/docs/testing/pdm-compatibility.md new file mode 100644 index 00000000..4bfd971b --- /dev/null +++ b/docs/testing/pdm-compatibility.md @@ -0,0 +1,142 @@ +# PDM compatibility and production backtests + +`socket-patch` supports hosted and vendored Python patches in the `pdm.lock` +generations PDM has written since the lock gained per-file hashes, plus agent +mode (in-place patching of the project's environment) on every release that +records a supported lock. The tests use real PDM releases bootstrapped with uv, +real PyPI artifacts, and the public Socket patch service. Successful rewriting +alone is not an installation result: the backtest reinstalls from the rewritten +lock and compares the installed bytes with the published patch. + +This supplements the [hosted](hosted-production-e2e.md) and +[vendored](vendored-production-e2e.md) production suites and mirrors the +[uv](uv-compatibility.md) and [Poetry](poetry-compatibility.md) matrices. See +the [ecosystem matrix](../ecosystems.md#mode--ecosystem-matrix) for other +package managers. + +## Formats and rewrite behavior + +A shared rewriter (`utils/pdm_lock.rs`) drives both modes: it validates the +`[metadata] lock_version` and `strategy`, rewrites the target `[[package]]` +unit's source (`url` for hosted, local `path` for vendored) and its `files` +hashes — including the PDM 0.x/1.x legacy `[metadata.files]` table and separate +`extras` entries — preserves line endings and non-canonical spacing through +span-based edits, and produces byte-exact fragments for replay. The +`pyproject.toml` and `[metadata] content_hash` are never touched. + +| Lock generation (writer) | `lock_version` | Hosted (`scan --mode hosted`) | Vendored (`scan --mode vendored`) | +| --- | --- | --- | --- | +| PDM ≤ 0.11 | none | **Refused** (`…lock_version` missing): the lock records no per-file hashes to rewrite coherently. | Refused for the same reason. | +| PDM 0.12 – 1.4 | `2` | `url` + `files = [{file, hash}]` (or the legacy `[metadata.files]` entry). PDM 0.x/1.x has an upstream freshness bug — a freshly generated lock can fail its own hash check, so ordinary `pdm install` may regenerate it and discard the redirect. The CLI warns `redirect_pdm_legacy_sync_required`; use `pdm sync`. | Local-file `path` + `files` hash; same freshness advisory (`pypi_pdm_legacy_sync_required`). | +| PDM 1.8 – 1.15 | `3.1` | **Refused** (`unsupported PDM lock_version`): native dependency lookup loses URL/path candidate identity before install, so a rewrite would not resolve. The original registry lock still installs. | Refused for the same reason. | +| PDM 2.0 – 2.7 | `4.0` / `4.1` / `4.2` | **Refused** (same identity loss). | Refused. | +| PDM 2.8 – current | `4.3` / `4.4` / `4.4.1` / `4.5.0` / `4.5.1` | `url` + single `{file, hash}`; `static_urls` locks keep their `{url, hash}` file shape. | Local-file `path` + `{file, hash}`. | +| Any future `lock_version` | unknown | **Refused** until the format is tested (fail-closed). | Refused. | + +Both modes retain the package version, extras, groups, markers and the +`content_hash`; no `pyproject.toml` edit is required. A repeated scan leaves the +lock unchanged (idempotent). Rollback restores the recorded original +fragments — one per patch, plus the legacy integrity-table entry — so a +`pdm.lock` the tool rewrote returns byte-for-byte to its pre-scan state. +Refused before any write: a `[[package]]` locked at several versions (a marker +fork), a user-authored `url`/`path`/VCS/`editable` source, an unsupported +`lock_version` or `strategy`, hash-less `files`, malformed hashes, and a wheel +whose filename does not match the locked package. + +## Installer boundaries (measured) + +| PDM | `lock_version` | Hosted | Vendored | Agent | Verifies the lock hash on install | Notes | +| --- | --- | --- | --- | --- | --- | --- | +| 0.12 | 2 | supported | supported | supported | yes | `pdm sync`; `pdm install` may regenerate the lock (freshness bug). | +| 1.0 – 1.4 | 2 | supported | supported | supported | yes | as 0.12; 1.0 cannot self-install a dev-group project natively. | +| 1.8 – 1.15 | 3.1 | refused | refused | supported | — | native install of the original registry lock is unaffected. | +| 2.0 – 2.7 | 4.0–4.2 | refused | refused | supported | — | same identity-loss boundary. | +| 2.8 – current | 4.3–4.5.1 | supported | supported | supported | yes | `pdm sync` + `pdm install --check`; static_urls, extras, markers, multi-target and PEP 735 dependency-groups all pass. | + +Measured details: + +- **A relock discards a lock-only patch on every release.** `pdm lock`, + `pdm lock --refresh` and `pdm update ` re-resolve the entry back to the + registry source. `content_hash` is unchanged by that, so `pdm lock --check` + cannot detect the loss: re-run `socket-patch scan --mode …` after any of them, + or gate CI on `socket-patch vex`. A re-scan after a relock re-applies the + patch and **rebases** the ledger's recorded edits onto the relocked text + (pristine → current, never an appended chain), so `rollback` still lands on the + pristine lock afterwards. This matters most for CRLF locks, which PDM + re-renders to a different byte layout on relock. +- **Hosted mode verifies the lock's file hash** on install for every supported + release (tamper the hash and `pdm sync` fails closed). Vendored mode's + protection is the committed wheel bytes, verified by the same hash. +- **`__pypackages__` (PEP 582) projects are not covered.** PDM 0.x/1.x default + to `__pypackages__`, and 2.x does so under `python.use_venv = false`; the + installed-set crawler probes virtualenvs (`VIRTUAL_ENV`, `./.venv`), so agent + and vendored mode need a virtualenv install. Run PDM with `python.use_venv` + on, or use hosted mode. +- **A non-default lock filename (`pdm lock -L custom.lock`) is invisible** to the + scan, which only reads `pdm.lock`. A package locked at two versions (a marker + fork) is refused (`pypi_pdm_lock_forked_package` / a version-mismatch refusal), + leaving the lock unchanged. +- Precedence when several Python lockfiles coexist: `uv.lock` and `poetry.lock` + drive hosted PyPI redirects ahead of `pdm.lock`, so a leftover `pdm.lock` + beside them neither blocks nor is attested; it is rewritten only when it is the + project's PyPI install driver. + +## Mode notes + +- **Hosted** (`scan --mode hosted`) rewrites `pdm.lock` in place and needs no + install; it works from a lock-only checkout. +- **Vendored** (`scan --mode vendored`) commits a rebuilt wheel under + `.socket/vendor/pypi//` and points the lock's `path` at it; the package + must be resolvable so its wheel can be rebuilt. +- **Agent** mode patches the interpreter the crawler finds. +- `rollback` (or `remove `) restores the pristine lock and drops the + ledger/manifest state for all three modes. + +## Backtest harness + +`scripts/backtest-pdm.py` bootstraps each pinned PDM release with uv, generates a +project per shape (direct, transitive/override, dev and optional groups, extras, +markers, platform markers, CRLF, `static_urls`, PEP 735 dependency-groups, +multi-target, Unicode paths), runs each of hosted/vendored/agent, and asserts: +the patch applies exactly once, a re-scan is byte-idempotent, `pdm sync` installs +the patched `urllib3/response.py` (git-blob SHA-256 matches the ledger +`afterHash`), ordinary `pdm install` keeps the lock stable, a tampered hash is +rejected, a relock-then-rescan keeps rollback invertible, and rollback restores +the lock and `pyproject.toml` byte for byte. `.github/workflows/pdm-compatibility.yml` +runs it on Linux, Windows and macOS across every PDM major family. The matrix +needs no Socket API token (the `urllib3@1.26.18` patch is a free tier). + + + +Run captured 2026-09-17 on macOS-26.6.2-arm64-arm-64bit-Mach-O with socket-patch `socket-patch 4.0.0` (source `fixed`, binary sha256 `99a0977e83aad0d01371b41147104a123f7eaa8bfb3f85ac1b2dc64a5b6f093d`), 25 PDM releases, shapes: direct, transitive, dev, optional, extras, marker, marker-excluded, platform-linux, platform-windows, crlf, static-urls, space-unicode, dependency-groups, multi-target, two-versions, custom-lockfile, pep582. + +| PDM | Python | lock_version | hosted | vendored | agent | tamper rejected (H/V) | `pdm install` keeps lock (H/V) | relock keeps patch (H/V) | notes | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 0.8.7 | 3.8 | — | refused (11 shapes) | 10/11 (11 shapes) | 7/8 (8 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version absent unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); agent mode on a `__pypackages__` project patched the PATH interpreter's site-packages; refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | +| 0.12.3 | 3.8 | 2 | pass (12 shapes) | 11/12 (12 shapes) | 8/9 (9 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); agent mode on a `__pypackages__` project patched the PATH interpreter's site-packages; relock dropped urllib3 1.26.18 (`transitive`: pinned resolution, no overrides on this release); re-scan then has nothing to redirect and rollback of the stale ledger exits 0/1; `pdm install` re-locked (extras,marker,marker-excluded,platform-linux,platform-windows): PDM's own freshness check flags its freshly generated lock as stale; patched install afterwards=false/true; use `pdm sync` | +| 1.0.0 | 3.8 | 2 | pass (12 shapes) | 11/12 (12 shapes) | 8/9 (9 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); agent mode on a `__pypackages__` project patched the PATH interpreter's site-packages; relock dropped urllib3 1.26.18 (`transitive`: pinned resolution, no overrides on this release); re-scan then has nothing to redirect and rollback of the stale ledger exits 0/1 | +| 1.4.5 | 3.8 | 2 | pass (12 shapes) | 11/12 (12 shapes) | 8/9 (9 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); agent mode on a `__pypackages__` project patched the PATH interpreter's site-packages; relock dropped urllib3 1.26.18 (`transitive`: pinned resolution, no overrides on this release); re-scan then has nothing to redirect and rollback of the stale ledger exits 0/1 | +| 1.8.5 | 3.8 | 3.1 | refused (11 shapes) | 10/11 (11 shapes) | 7/8 (8 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version 3.1 unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); agent mode on a `__pypackages__` project patched the PATH interpreter's site-packages; refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | +| 1.12.8 | 3.8 | 3.1 | refused (12 shapes) | 11/12 (12 shapes) | 8/9 (9 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version 3.1 unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); agent mode on a `__pypackages__` project patched the PATH interpreter's site-packages; refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | +| 1.15.5 | 3.8 | 3.1 | refused (12 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version 3.1 unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | +| 2.0.3 | 3.11 | 4.0 | refused (12 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version 4.0 unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | +| 2.1.5 | 3.11 | 4.0 | refused (12 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version 4.0 unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | +| 2.2.1 | 3.11 | 4.0 | refused (12 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version 4.0 unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | +| 2.3.4 | 3.11 | 4.1 | refused (12 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version 4.1 unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | +| 2.6.1 | 3.11 | 4.2 | refused (12 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version 4.2 unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | +| 2.7.4 | 3.11 | 4.2 | refused (12 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version 4.2 unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | +| 2.8.2 | 3.11 | 4.3 | pass (13 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | +| 2.9.3 | 3.11 | 4.3 | pass (13 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | +| 2.10.4 | 3.11 | 4.4 | pass (13 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | +| 2.11.2 | 3.11 | 4.4.1 | pass (14 shapes) | 13/14 (14 shapes) | 9/10 (10 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | +| 2.12.4 | 3.11 | 4.4.1 | pass (14 shapes) | 13/14 (14 shapes) | 9/10 (10 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | +| 2.15.4 | 3.11 | 4.4.1 | pass (14 shapes) | 13/14 (14 shapes) | 9/10 (10 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | +| 2.17.3 | 3.11 | 4.5.0 | pass (16 shapes) | 15/16 (16 shapes) | 10/11 (11 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | +| 2.20.1 | 3.11 | 4.5.0 | pass (17 shapes) | 16/17 (17 shapes) | 11/12 (12 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | +| 2.22.4 | 3.12 | — | n/a | n/a | n/a | n/a / n/a | n/a / n/a | n/a / n/a | lock_version absent | +| 2.25.9 | 3.12 | — | n/a | n/a | n/a | n/a / n/a | n/a / n/a | n/a / n/a | lock_version absent | +| 2.27.0 | 3.13 | 4.5.0 | pass (17 shapes) | 16/17 (17 shapes) | 11/12 (12 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | +| 2.29.2 | 3.13 | 4.5.1 | pass (17 shapes) | 16/17 (17 shapes) | 11/12 (12 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | + + diff --git a/docs/testing/pdm-compatibility/results.json b/docs/testing/pdm-compatibility/results.json new file mode 100644 index 00000000..cd588ee9 --- /dev/null +++ b/docs/testing/pdm-compatibility/results.json @@ -0,0 +1,28820 @@ +{ + "provenance": { + "capturedAt": "2026-09-17T23:40:37.750526+00:00", + "cliPath": "/private/tmp/claude-501/-Users-mikolalysenko-Projects-socket-patch/9840a7e8-5cf9-4f42-8960-54a9c23b7cd7/scratchpad/socket-patch-fixed", + "cliRevision": "fixed", + "cliSha256": "99a0977e83aad0d01371b41147104a123f7eaa8bfb3f85ac1b2dc64a5b6f093d", + "cliVersion": "socket-patch 4.0.0", + "hostPython": "3.14.3", + "modes": [ + "hosted", + "vendored", + "agent" + ], + "patchUuid": "e828efa5-5c6d-43f3-9909-03f5ac232b98", + "pdmVersions": [ + "0.8.7", + "0.12.3", + "1.0.0", + "1.4.5", + "1.8.5", + "1.12.8", + "1.15.5", + "2.0.3", + "2.1.5", + "2.2.1", + "2.3.4", + "2.6.1", + "2.7.4", + "2.8.2", + "2.9.3", + "2.10.4", + "2.11.2", + "2.12.4", + "2.15.4", + "2.17.3", + "2.20.1", + "2.22.4", + "2.25.9", + "2.27.0", + "2.29.2" + ], + "platform": "macOS-26.6.2-arm64-arm-64bit-Mach-O", + "shapes": [ + "direct", + "transitive", + "dev", + "optional", + "extras", + "marker", + "marker-excluded", + "platform-linux", + "platform-windows", + "crlf", + "static-urls", + "space-unicode", + "dependency-groups", + "multi-target", + "two-versions", + "custom-lockfile", + "pep582" + ], + "toolsDir": "/private/tmp/claude-501/-Users-mikolalysenko-Projects-socket-patch/9840a7e8-5cf9-4f42-8960-54a9c23b7cd7/scratchpad/pdm-venvs", + "uvVersion": "uv 0.11.19 (7b2cff1c3 2026-06-03 aarch64-apple-darwin)" + }, + "shapes": null, + "results": [ + { + "pdm": "0.8.7", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.8.7", + "shape": "crlf", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 37 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "crlf", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.8.7", + "shape": "dev", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 37 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "dev", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.8.7", + "shape": "direct", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 37 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "direct", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "python": "3.8", + "baselineFresh": false, + "info": { + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": false + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.8.7", + "shape": "extras", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 38 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "extras", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "python": "3.8", + "baselineFresh": false, + "info": { + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.8.7", + "shape": "marker", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 37 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "marker", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 37 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.8.7", + "shape": "optional", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 37 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "optional", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "patchedOutsideProject": { + "applied": 1, + "crawled": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ] + }, + "applied": 1, + "codes": [ + "package_not_installed" + ], + "rollbackOutsideProject": { + "exit": 0, + "rolledBack": 1 + } + } + }, + { + "pdm": "0.8.7", + "shape": "pep582", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_version_unsupported", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 37 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 37 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "space-unicode", + "mode": "agent", + "outcome": "SKIP", + "python": "3.8", + "baselineFresh": true, + "info": {} + }, + { + "pdm": "0.8.7", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 37 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.8.7", + "shape": "transitive", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 0, + "scannedPackages": 41 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.8.7", + "shape": "transitive", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "python": "3.8", + "expected": "refused: lock_version None is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.12.3", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": false, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": false, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.12.3", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.12.3", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.12.3", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": false + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 39 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": false + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.12.3", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": false + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": false + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": false + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": false + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.12.3", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "2", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "patchedOutsideProject": { + "applied": 1, + "crawled": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ] + }, + "applied": 1, + "codes": [ + "package_not_installed" + ], + "rollbackOutsideProject": { + "exit": 0, + "rolledBack": 1 + } + } + }, + { + "pdm": "0.12.3", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "2", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_package_missing", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": false + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": false + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": false + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": false, + "info": { + "ordinaryInstall": { + "baselineFresh": false, + "exit": 0, + "lockStable": false + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.12.3", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "0.12.3", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "0.12.3", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "note": "relock dropped urllib3 1.26.18 from the lock; re-scan/rollback recorded only", + "pyprojectUnchanged": true, + "targetKept": false + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "rollbackAfterRelock": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + } + } + }, + { + "pdm": "0.12.3", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rescanAfterRelock": { + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_package_missing", + "vendor_fetch_unverifiable" + ], + "exit": 1, + "patchInLock": false + }, + "relock": { + "crlfKept": null, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "note": "relock dropped urllib3 1.26.18 from the lock; re-scan/rollback recorded only", + "pyprojectUnchanged": true, + "targetKept": false + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "rollbackAfterRelock": { + "exit": 1, + "failed": [], + "lockEqualsRelocked": true, + "status": "partial_failure" + } + } + }, + { + "pdm": "1.0.0", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.0.0", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": false, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": false, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 1, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.0.0", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 1, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 1, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.0.0", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.0.0", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 39 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.0.0", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.0.0", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "2", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "patchedOutsideProject": { + "applied": 1, + "crawled": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ] + }, + "applied": 1, + "codes": [ + "package_not_installed" + ], + "rollbackOutsideProject": { + "exit": 0, + "rolledBack": 1 + } + } + }, + { + "pdm": "1.0.0", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 1, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "2", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_package_missing", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.0.0", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 38 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.0.0", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.0.0", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "note": "relock dropped urllib3 1.26.18 from the lock; re-scan/rollback recorded only", + "pyprojectUnchanged": true, + "targetKept": false + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "rollbackAfterRelock": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + } + } + }, + { + "pdm": "1.0.0", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rescanAfterRelock": { + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_package_missing", + "vendor_fetch_unverifiable" + ], + "exit": 1, + "patchInLock": false + }, + "relock": { + "crlfKept": null, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "note": "relock dropped urllib3 1.26.18 from the lock; re-scan/rollback recorded only", + "pyprojectUnchanged": true, + "targetKept": false + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "rollbackAfterRelock": { + "exit": 1, + "failed": [], + "lockEqualsRelocked": true, + "status": "partial_failure" + } + } + }, + { + "pdm": "1.4.5", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.4.5", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": false, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 47 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": false, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.4.5", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 47 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.4.5", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 47 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.4.5", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 48 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.4.5", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 47 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 47 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.4.5", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 47 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "2", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "patchedOutsideProject": { + "applied": 2, + "crawled": [ + "pkg:pypi/jaraco-context@6.0.1", + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ] + }, + "applied": 2, + "codes": [ + "package_not_installed" + ], + "rollbackOutsideProject": { + "exit": 0, + "rolledBack": 2 + } + } + }, + { + "pdm": "1.4.5", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "2", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_package_missing", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 47 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 47 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.4.5", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 47 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "1.4.5", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.4.5", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "note": "relock dropped urllib3 1.26.18 from the lock; re-scan/rollback recorded only", + "pyprojectUnchanged": true, + "targetKept": false + }, + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@1.26.20" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 51 + }, + "applied": 1, + "codes": [ + "redirect_pdm_legacy_sync_required", + "redirect_pypi_stale_install" + ], + "rollbackAfterRelock": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + } + } + }, + { + "pdm": "1.4.5", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "2", + "python": "3.8", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rescanAfterRelock": { + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_package_missing", + "vendor_fetch_unverifiable" + ], + "exit": 1, + "patchInLock": false + }, + "relock": { + "crlfKept": null, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "note": "relock dropped urllib3 1.26.18 from the lock; re-scan/rollback recorded only", + "pyprojectUnchanged": true, + "targetKept": false + }, + "applied": 1, + "codes": [ + "pypi_pdm_legacy_sync_required", + "vendor_prebuilt_downloaded" + ], + "rollbackAfterRelock": { + "exit": 1, + "failed": [], + "lockEqualsRelocked": true, + "status": "partial_failure" + } + } + }, + { + "pdm": "1.8.5", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.8.5", + "shape": "crlf", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 35 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "crlf", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.8", + "info": {} + }, + { + "pdm": "1.8.5", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.8", + "info": {} + }, + { + "pdm": "1.8.5", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.8.5", + "shape": "dev", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 35 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "dev", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.8.5", + "shape": "direct", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 35 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "direct", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "extras", + "mode": "agent", + "outcome": "SKIP", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": {} + }, + { + "pdm": "1.8.5", + "shape": "extras", + "mode": "hosted", + "outcome": "SKIP", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 36 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "extras", + "mode": "vendored", + "outcome": "SKIP", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.8.5", + "shape": "marker", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 35 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "marker", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 35 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.8.5", + "shape": "optional", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 35 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "optional", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "patchedOutsideProject": { + "applied": 1, + "crawled": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ] + }, + "applied": 1, + "codes": [ + "package_not_installed" + ], + "rollbackOutsideProject": { + "exit": 0, + "rolledBack": 1 + } + } + }, + { + "pdm": "1.8.5", + "shape": "pep582", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_version_unsupported", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 35 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 35 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.8.5", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 35 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.8.5", + "shape": "transitive", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 4, + "redirected": 0, + "scannedPackages": 38 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.8.5", + "shape": "transitive", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.12.8", + "shape": "crlf", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 36 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "crlf", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.8", + "info": {} + }, + { + "pdm": "1.12.8", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.8", + "info": {} + }, + { + "pdm": "1.12.8", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.12.8", + "shape": "dev", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 36 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "dev", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.12.8", + "shape": "direct", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 36 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "direct", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.12.8", + "shape": "extras", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 37 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "extras", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.12.8", + "shape": "marker", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 36 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "marker", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 36 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.12.8", + "shape": "optional", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 36 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "optional", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "patchedOutsideProject": { + "applied": 1, + "crawled": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ] + }, + "applied": 1, + "codes": [ + "package_not_installed" + ], + "rollbackOutsideProject": { + "exit": 0, + "rolledBack": 1 + } + } + }, + { + "pdm": "1.12.8", + "shape": "pep582", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_version_unsupported", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 36 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 36 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.12.8", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 36 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.12.8", + "shape": "transitive", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 4, + "redirected": 0, + "scannedPackages": 39 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.12.8", + "shape": "transitive", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.15.5", + "shape": "crlf", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 25 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "crlf", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 24 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "1.15.5", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.15.5", + "shape": "dev", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 25 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "dev", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.15.5", + "shape": "direct", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 25 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "direct", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.15.5", + "shape": "extras", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 26 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "extras", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.15.5", + "shape": "marker", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 25 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "marker", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 25 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.15.5", + "shape": "optional", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 25 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "optional", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "pep582", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 25 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 25 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.15.5", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 25 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "3.1", + "python": "3.8", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "1.15.5", + "shape": "transitive", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 0, + "scannedPackages": 29 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "1.15.5", + "shape": "transitive", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "3.1", + "python": "3.8", + "expected": "refused: lock_version '3.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.0.3", + "shape": "crlf", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "crlf", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.0.3", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.0.3", + "shape": "dev", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "dev", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.0.3", + "shape": "direct", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "direct", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.0.3", + "shape": "extras", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 45 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "extras", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.0.3", + "shape": "marker", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "marker", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.0.3", + "shape": "optional", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "optional", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "pep582", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.0.3", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.0.3", + "shape": "transitive", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 0, + "scannedPackages": 48 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.0.3", + "shape": "transitive", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.1.5", + "shape": "crlf", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "crlf", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.1.5", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.1.5", + "shape": "dev", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "dev", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.1.5", + "shape": "direct", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "direct", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.1.5", + "shape": "extras", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "extras", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.1.5", + "shape": "marker", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "marker", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.1.5", + "shape": "optional", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "optional", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "pep582", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.1.5", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.1.5", + "shape": "transitive", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 0, + "scannedPackages": 47 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.1.5", + "shape": "transitive", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.2.1", + "shape": "crlf", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "crlf", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.2.1", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.2.1", + "shape": "dev", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "dev", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.2.1", + "shape": "direct", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "direct", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.2.1", + "shape": "extras", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "extras", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.2.1", + "shape": "marker", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "marker", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.2.1", + "shape": "optional", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "optional", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "pep582", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.2.1", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.2.1", + "shape": "transitive", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 0, + "scannedPackages": 47 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.2.1", + "shape": "transitive", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.0", + "python": "3.11", + "expected": "refused: lock_version '4.0' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.3.4", + "shape": "crlf", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "crlf", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 41 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.3.4", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.3.4", + "shape": "dev", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "dev", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.3.4", + "shape": "direct", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "direct", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.3.4", + "shape": "extras", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "extras", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.3.4", + "shape": "marker", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "marker", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.3.4", + "shape": "optional", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "optional", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "pep582", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.3.4", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.3.4", + "shape": "transitive", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 0, + "scannedPackages": 46 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.3.4", + "shape": "transitive", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.1", + "python": "3.11", + "expected": "refused: lock_version '4.1' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.6.1", + "shape": "crlf", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "crlf", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 41 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.6.1", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.6.1", + "shape": "dev", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "dev", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.6.1", + "shape": "direct", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "direct", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.6.1", + "shape": "extras", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "extras", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.6.1", + "shape": "marker", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "marker", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.6.1", + "shape": "optional", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "optional", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "pep582", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.6.1", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.6.1", + "shape": "transitive", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 0, + "scannedPackages": 46 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.6.1", + "shape": "transitive", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.7.4", + "shape": "crlf", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "crlf", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 41 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.7.4", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.7.4", + "shape": "dev", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "dev", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.7.4", + "shape": "direct", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "direct", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.7.4", + "shape": "extras", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "extras", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.7.4", + "shape": "marker", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "marker", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.7.4", + "shape": "optional", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "optional", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "pep582", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.7.4", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.2", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.7.4", + "shape": "transitive", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 0, + "scannedPackages": 46 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.7.4", + "shape": "transitive", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.2", + "python": "3.11", + "expected": "refused: lock_version '4.2' is not supported by the rewriter", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_lock_version_unsupported" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.8.2", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.3", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 41 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.8.2", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.3", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.8.2", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.8.2", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.8.2", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.8.2", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.8.2", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.3", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.8.2", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.3", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.8.2", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.8.2", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 46 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.8.2", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.9.3", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.3", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.9.3", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.3", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.9.3", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.9.3", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.9.3", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.9.3", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.9.3", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.3", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.9.3", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.3", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.9.3", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.9.3", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 47 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.9.3", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.3", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.10.4", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.4", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 42 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.10.4", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.4", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.10.4", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.10.4", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.10.4", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.10.4", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.10.4", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.4", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.10.4", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.4", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.10.4", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.10.4", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 47 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.10.4", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.11.2", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.11.2", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.11.2", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.11.2", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.11.2", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.11.2", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.11.2", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.11.2", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.11.2", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "static-urls", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.11.2", + "shape": "static-urls", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "static-urls", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.11.2", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 48 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.11.2", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.12.4", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.12.4", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.12.4", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.12.4", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.12.4", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.12.4", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.12.4", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.12.4", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.12.4", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "static-urls", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.12.4", + "shape": "static-urls", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 44 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "static-urls", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.12.4", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 48 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.12.4", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.15.4", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 41 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.15.4", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.15.4", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.15.4", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.15.4", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.15.4", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.15.4", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.15.4", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.4.1", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.15.4", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "static-urls", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.15.4", + "shape": "static-urls", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "static-urls", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.15.4", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 46 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.15.4", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.4.1", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 41 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "multi-target", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "multi-target", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "multi-target", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "static-urls", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "static-urls", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "static-urls", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.17.3", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 46 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "two-versions", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "refused: two locked urllib3 versions (forked package)", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.17.3", + "shape": "two-versions", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "refused: two locked urllib3 versions (forked package)", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl", + "pkg:pypi/urllib3@2.2.3?artifact_id=py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_forked_package", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": true, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 41 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "dependency-groups", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "dependency-groups", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "dependency-groups", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 43 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "multi-target", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "multi-target", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "multi-target", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "static-urls", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "static-urls", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 42 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "static-urls", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.20.1", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 46 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.11", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "two-versions", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "refused: two locked urllib3 versions (forked package)", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 43 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.20.1", + "shape": "two-versions", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.11", + "expected": "refused: two locked urllib3 versions (forked package)", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl", + "pkg:pypi/urllib3@2.2.3?artifact_id=py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_forked_package", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.22.4", + "shape": "crlf", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "crlf", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "crlf", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "dependency-groups", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "dependency-groups", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "dependency-groups", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "dev", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "dev", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "dev", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "direct", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "direct", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "direct", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "extras", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "extras", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "extras", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "marker", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "marker", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "marker", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "multi-target", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "multi-target", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "multi-target", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "optional", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "optional", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "optional", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "pep582", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "pep582", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "pep582", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "space-unicode", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "static-urls", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "static-urls", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "static-urls", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "transitive", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "transitive", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "transitive", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "two-versions", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.22.4", + "shape": "two-versions", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "crlf", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "crlf", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "crlf", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "dependency-groups", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "dependency-groups", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "dependency-groups", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "dev", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "dev", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "dev", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "direct", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "direct", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "direct", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "extras", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "extras", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "extras", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "marker", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "marker", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "marker", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "multi-target", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "multi-target", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "multi-target", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "optional", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "optional", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "optional", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "pep582", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "pep582", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "pep582", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "space-unicode", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "static-urls", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "static-urls", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "static-urls", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "transitive", + "mode": "agent", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "transitive", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "transitive", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "two-versions", + "mode": "hosted", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.25.9", + "shape": "two-versions", + "mode": "vendored", + "outcome": "SKIP", + "python": "3.12", + "info": {} + }, + { + "pdm": "2.27.0", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": false, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": false, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.13", + "expected": "no-op: the CLI only reads pdm.lock", + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 44 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.13", + "expected": "no-op: the CLI only reads pdm.lock", + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "dependency-groups", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "dependency-groups", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "dependency-groups", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 46 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "multi-target", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "multi-target", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "multi-target", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.5.0", + "python": "3.13", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.5.0", + "python": "3.13", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "static-urls", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "static-urls", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 45 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "static-urls", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.27.0", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.0", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "two-versions", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.13", + "expected": "refused: two locked urllib3 versions (forked package)", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 46 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.27.0", + "shape": "two-versions", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.0", + "python": "3.13", + "expected": "refused: two locked urllib3 versions (forked package)", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl", + "pkg:pypi/urllib3@2.2.3?artifact_id=py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_forked_package", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "crlf", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "crlf", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": false, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "crlf", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": false, + "equalsOriginal": false, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "custom-lockfile", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.1", + "python": "3.13", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [], + "exit": 0, + "lockfileOnlyPackages": 0, + "redirected": 0, + "scannedPackages": 48 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "custom-lockfile", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.1", + "python": "3.13", + "expected": "no-op: the CLI only reads pdm.lock", + "baselineFresh": false, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "pypi_pdm_no_lockfile" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "dependency-groups", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "dependency-groups", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "dependency-groups", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "dev", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "dev", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "dev", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "direct", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "direct", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "direct", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "extras", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "extras", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 1, + "scannedPackages": 50 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "extras", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "marker", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "marker", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "marker", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "marker-excluded", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "marker-excluded", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "multi-target", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "multi-target", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "multi-target", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "optional", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "optional", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "optional", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "pep582", + "mode": "agent", + "outcome": "UNSUPPORTED", + "lockVersion": "4.5.1", + "python": "3.13", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "pep582", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "pep582", + "mode": "vendored", + "outcome": "UNSUPPORTED", + "lockVersion": "4.5.1", + "python": "3.13", + "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "baselineFresh": true, + "info": { + "applied": 0, + "codes": [ + "package_not_installed", + "vendor_fetch_unverifiable" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "platform-linux", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "platform-linux", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "platform-windows", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "platform-windows", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": false, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "space-unicode", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "space-unicode", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "space-unicode", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "static-urls", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "static-urls", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 1, + "redirected": 1, + "scannedPackages": 49 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "static-urls", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "transitive", + "mode": "agent", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "applied": 1, + "codes": [] + } + }, + { + "pdm": "2.29.2", + "shape": "transitive", + "mode": "hosted", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "lockOnlyHosted": { + "codes": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], + "exit": 0, + "lockfileOnlyPackages": 5, + "redirected": 1, + "scannedPackages": 53 + }, + "applied": 1, + "codes": [ + "redirect_pypi_stale_install" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "transitive", + "mode": "vendored", + "outcome": "PASS", + "lockVersion": "4.5.1", + "python": "3.13", + "baselineFresh": true, + "info": { + "tamper": { + "installExit": 1, + "installedPatchedAnyway": false, + "mentionsHash": true + }, + "ordinaryInstall": { + "baselineFresh": true, + "exit": 0, + "lockStable": true + }, + "ordinaryInstallPatched": true, + "rollbackAfterRelockPristine": { + "exit": 0, + "failed": [], + "lockEqualsRelocked": true, + "status": "success" + }, + "rescanAfterRelock": { + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ], + "exit": 0, + "patchInLock": true + }, + "relock": { + "crlfKept": null, + "equalsOriginal": true, + "exit": 0, + "keepsPatch": false, + "lockBytesUnchanged": false, + "pyprojectUnchanged": true, + "targetKept": true + }, + "applied": 1, + "codes": [ + "vendor_prebuilt_downloaded" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "two-versions", + "mode": "hosted", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.1", + "python": "3.13", + "expected": "refused: two locked urllib3 versions (forked package)", + "baselineFresh": true, + "info": { + "lockOnlyHosted": { + "codes": [ + "redirect_pdm_refused" + ], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18", + "pkg:pypi/urllib3@2.2.3" + ], + "exit": 0, + "lockfileOnlyPackages": 2, + "redirected": 0, + "scannedPackages": 50 + }, + "manifestLeftover": [], + "applied": 0, + "codes": [ + "redirect_pdm_refused" + ] + } + }, + { + "pdm": "2.29.2", + "shape": "two-versions", + "mode": "vendored", + "outcome": "REFUSED-EXPECTED", + "lockVersion": "4.5.1", + "python": "3.13", + "expected": "refused: two locked urllib3 versions (forked package)", + "baselineFresh": true, + "info": { + "manifestLeftover": [ + "pkg:pypi/urllib3@1.26.18?artifact_id=py2-py3-none-any-whl", + "pkg:pypi/urllib3@2.2.3?artifact_id=py3-none-any-whl" + ], + "applied": 0, + "codes": [ + "package_not_installed", + "pypi_pdm_lock_forked_package", + "vendor_fetch_unverifiable" + ] + } + } + ], + "errors": [] +} \ No newline at end of file diff --git a/scripts/backtest-pdm.py b/scripts/backtest-pdm.py new file mode 100644 index 00000000..42a62694 --- /dev/null +++ b/scripts/backtest-pdm.py @@ -0,0 +1,1373 @@ +#!/usr/bin/env python3 +"""Drive the real socket-patch CLI and real PDM releases through hosted, +vendored and agent mode on native pdm.lock generations. + +For every PDM version the harness bootstraps that exact release with uv +(per-era dependency pins, see `pins_for`), generates a native lock for a +one-dependency project (urllib3 1.26.18, which has a public free-tier Socket +patch) in a number of project shapes, then for each mode: + + hosted scan --mode hosted -> pdm sync -> installed bytes == patch + vendored scan --mode vendored -> pdm sync -> installed bytes == patch + agent pdm sync -> scan --mode agent -> installed bytes == patch + +and checks idempotent re-scans, unchanged pyproject, lock byte-stability +across `pdm sync` / `pdm install`, `pdm lock --check`, tampered-hash +rejection, what PDM's own relock does to the patch source (and whether a +re-scan + rollback still restores the relocked bytes), `pdm export`, and +`rollback` restoring every byte. Lock formats the CLI does not support +(lock_version 3.1 / 4.0 / 4.1 / 4.2, PDM 0.8's version-less lock) must be +REFUSED with the lock untouched while the native install keeps working; the +`two-versions` and `custom-lockfile` shapes are likewise expected no-ops. + +Shapes: direct, transitive (overrides / pinned resolution), dev, optional, +extras, marker, marker-excluded, platform-linux, platform-windows, crlf, +static-urls (>= 2.11), space-unicode, dependency-groups (PEP 735, >= 2.20), +multi-target (>= 2.17), two-versions (>= 2.17), custom-lockfile (`-L`), +pep582 (`__pypackages__` layout). + +Every case is fully isolated: its own project dir, HOME, PDM config + cache, +and venv. Needs network (PyPI + patch.socket.dev), uv, and no Socket token. + +Usage: + scripts/backtest-pdm.py --socket-patch target/debug/socket-patch \\ + --socket-patch-revision --output /tmp/pdm-backtest \\ + [--versions 2.29.2 ...] [--modes hosted vendored agent] \\ + [--shapes direct ...] [--jobs 4] [--tools-dir -venvs>] + scripts/backtest-pdm.py --render-doc-table /tmp/pdm-backtest/summary.json +""" + +import argparse +import concurrent.futures +import hashlib +import json +import os +import platform +import re +import shutil +import signal +import subprocess +import sys +import threading +import time +import traceback +from datetime import datetime, timezone +from pathlib import Path + +VERSIONS = [ + "0.8.7", "0.12.3", + "1.0.0", "1.4.5", "1.8.5", "1.12.8", "1.15.5", + "2.0.3", "2.1.5", "2.2.1", "2.3.4", "2.4.9", "2.5.6", "2.6.1", "2.7.4", + "2.8.0", "2.8.2", "2.9.0", "2.9.3", "2.10.0", "2.10.4", "2.11.0", "2.11.2", + "2.12.4", "2.13.3", "2.14.0", "2.15.4", "2.16.1", "2.17.0", "2.17.3", + "2.18.2", "2.19.3", "2.20.0", "2.20.1", "2.21.0", "2.22.0", "2.22.4", + "2.23.1", "2.24.2", "2.25.0", "2.25.9", "2.26.0", "2.26.9", "2.27.0", + "2.28.2", "2.29.0", "2.29.2", +] +MODES = ["hosted", "vendored", "agent"] +SHAPES = [ + "direct", "transitive", "dev", "optional", "extras", "marker", + "marker-excluded", "platform-linux", "platform-windows", "crlf", + "static-urls", "space-unicode", "dependency-groups", "multi-target", + "two-versions", "custom-lockfile", "pep582", +] +# What the PR's shared rewriter accepts; anything else must be refused. +SUPPORTED_LOCK_VERSIONS = {"2", "4.3", "4.4", "4.4.1", "4.5.0", "4.5.1"} +# Shapes where the CLI is EXPECTED to leave the lock alone. +EXPECTED_NOOP_SHAPES = {"two-versions", "custom-lockfile"} +# Shapes whose requirement marker excludes this host (package never installed). +def excluded_shape(shape): + return ( + shape == "marker-excluded" + or (shape == "platform-windows" and os.name != "nt") + or (shape == "platform-linux" and platform.system() != "Linux") + ) + +PROJECT_NAME = "pdm-patch-backtest" +PATCH_UUID = "e828efa5-5c6d-43f3-9909-03f5ac232b98" +PURL_BASE = "pkg:pypi/urllib3@1.26.18" +HOSTED_MARKER = b"patch.socket.dev" +VENDORED_MARKER = b".socket/vendor/pypi" +TRANSITIVE_PINS = [ + ("urllib3", "1.26.18"), + ("charset-normalizer", "3.3.2"), + ("idna", "3.6"), + ("certifi", "2024.2.2"), +] +FIXTURES = Path(__file__).resolve().parents[1] / "crates/socket-patch-core/tests/fixtures/pdm-native" + +ORACLE = """import hashlib,importlib.util,json,pathlib,sys +spec=importlib.util.find_spec('urllib3') +root=pathlib.Path(spec.origin).parent.parent if spec and spec.origin else pathlib.Path('/missing') +checks={} +for name,expected in json.loads(sys.argv[1]).items(): + p=root/name + data=p.read_bytes() if p.is_file() else b'' + checks[name]=p.is_file() and hashlib.sha256(('blob %d\\0'%len(data)).encode()+data).hexdigest()==expected +print(json.dumps(dict(installed=spec is not None, origin=(spec.origin if spec else None), files=checks))) +""" +# Content hash + freshness through PDM's own API (constructor changed in +# 1.12 and the hash method moved in 2.x, hence the fallbacks). +HASH_SNIPPET = """import json,sys +algo=sys.argv[1] +def project(): + from pdm.project.core import Project + try: + return Project() + except TypeError: + from pdm.core import Core + core=Core() + try: + return core.create_project('.') + except Exception: + return Project(core, '.') +p=project() +out={} +try: + out['hash']=p.get_content_hash(algo) +except Exception: + try: + out['hash']=p.pyproject.content_hash(algo) + except Exception as e: + out['hashError']=repr(e) +try: + out['fresh']=bool(p.is_lockfile_hash_match()) +except Exception as e: + out['freshError']=repr(e) +print(json.dumps(out)) +""" +NETWORK_RE = re.compile( + r"ConnectionError|ConnectTimeout|ReadTimeout|Temporary failure|timed out|" + r"Connection reset|RemoteDisconnected|Max retries exceeded|" + r"HTTP Error 5\d\d|503|502|Failed to (fetch|download)|error sending request|" + r"network is unreachable|NewConnectionError|SSLError", + re.I, +) +DEFAULT_TIMEOUT = int(os.environ.get("BACKTEST_TIMEOUT", "600")) + + +def vtuple(v): + return tuple(int(x) for x in v.split(".")) + + +def python_for(version): + v = vtuple(version) + if v < (2, 0): + return "3.8" + if v < (2, 21): + return "3.11" + if v < (2, 27): + return "3.12" + return "3.13" + + +def pins_for(version): + """Per-era bootstrap pins. 0.x and 1.x carry unpinned upper bounds that + modern PyPI resolves to incompatible releases (pythonfinder >= 2 lost + `pythonfinder.models.python`, packaging >= 22 lost LegacyVersion, pip + moved the shims PDM 1.x imports, resolvelib >= 0.6 renamed the identify + argument PDM 1.0 uses). Verified on macOS arm64 against real binaries.""" + v = vtuple(version) + pins = ["pdm==" + version, "setuptools==57.5.0", "wheel==0.37.1"] + if v < (1, 0): + pins += [ + "pip==20.2.4" if v < (0, 9) else "pip==20.3.4", + "six==1.17.0", "toml==0.10.2", "tomlkit==0.7.2", "click==7.1.2", + "pythonfinder==1.2.10", "resolvelib==0.5.5", "packaging==20.9", + "requests==2.27.1", + ] + elif v < (1, 15): + if v < (1, 5): + pins += ["pip==20.3.4", "requests==2.27.1"] + elif v < (1, 12): + pins += ["pip==21.3.1", "requests==2.31.0"] + else: + pins += ["pip==22.0.4", "requests==2.31.0"] + pins += ["six==1.17.0", "toml==0.10.2", "pythonfinder==1.2.10", "packaging==20.9"] + if v < (1, 1): + pins.append("resolvelib==0.5.5") + elif v < (2, 0): + pins += ["pip==22.0.4", "requests==2.31.0"] + else: + pins += ["pip==24.0"] + return pins + + +def required_pins(version): + """Subset of pins whose absence means a reused venv is broken.""" + v = vtuple(version) + if v >= (1, 15): + return [] + return [p for p in pins_for(version) if p.split("==")[0] in ("pip", "pythonfinder", "packaging", "toml", "six", "resolvelib")] + + +def legacy_manifest(version, shape=None): + """PDM < 1.5: `[tool.pdm]` metadata, flat `-dependencies` tables, + `-s SECTION` selection. 1.5 introduced dependency groups and `-G`. + + Exception: the transitive shape on 1.0-1.4 uses PEP 621 `[project]` + metadata (which those releases accept) because PDM 1.0-1.4 rewrite + legacy metadata into `[project]` on every lock/install, and the + pinned-resolution trick restores the manifest after locking.""" + v = vtuple(version) + if shape == "transitive" and (1, 0) <= v < (1, 5): + return False + return v < (1, 5) + + +def honours_config_file(version): + """PDM_CONFIG_FILE is honoured from 1.15; earlier releases read only + ~/.pdm/config.toml (so each case gets its own HOME).""" + return vtuple(version) >= (1, 15) + + +def shape_applies(version, shape): + v = vtuple(version) + if shape == "static-urls": + return v >= (2, 11) + if shape == "dependency-groups": + return v >= (2, 20) + if shape in ("multi-target", "two-versions"): + return v >= (2, 17) + if shape == "custom-lockfile": + return v >= (1, 5) # `pdm lock -L` (checked again against --help) + return True + + +def wanted(version, shape, mode): + if not shape_applies(version, shape): + return False + if mode == "agent" and (excluded_shape(shape) or shape in EXPECTED_NOOP_SHAPES): + return False + return True + + +def save(path, data): + Path(path).write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def sha256_file(path): + return hashlib.sha256(Path(path).read_bytes()).hexdigest() + + +def lock_version_of(text): + m = re.search(r'lock_version = "([^"]+)"', text) + return m.group(1) if m else None + + +class Run: + """Run a command with a per-case env, log everything, kill the whole + process group on timeout, optionally retry once on network flakes.""" + + def __init__(self, cmd, cwd, env, log, timeout=None, retry=False): + self.cmd = [str(c) for c in cmd] + timeout = timeout or DEFAULT_TIMEOUT + attempts = 0 + while True: + attempts += 1 + self.rc, self.out = self._exec(cwd, env, timeout) + if self.rc == 0 or not retry or attempts >= 2 or not NETWORK_RE.search(self.out): + break + time.sleep(5) + self.attempts = attempts + Path(log).write_text( + "$ " + " ".join(self.cmd) + f"\n# cwd {cwd}\n# exit {self.rc} (attempts {attempts})\n--- output\n{self.out}", + encoding="utf-8", + ) + + def _exec(self, cwd, env, timeout): + with subprocess.Popen( + self.cmd, cwd=str(cwd), env=env, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + start_new_session=os.name != "nt", + ) as proc: + try: + out, _ = proc.communicate(timeout=timeout) + except subprocess.TimeoutExpired: + if os.name == "nt": + subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], check=False, capture_output=True) + else: + try: + os.killpg(proc.pid, signal.SIGKILL) + except ProcessLookupError: + pass + out, _ = proc.communicate() + return 124, out.decode("utf-8", "replace") + f"\nTIMEOUT after {timeout}s" + return proc.returncode, out.decode("utf-8", "replace") + + def ok(self): + return self.rc == 0 + + def tail(self, n=500): + return self.out[-n:] + + def json(self): + i = self.out.find("{") + if i < 0: + raise RuntimeError("no JSON in output: " + self.out[-2000:]) + return json.loads(self.out[i:]) + + def json_or_empty(self): + try: + return self.json() + except Exception: + return {} + + +def require(r, what): + if not r.ok(): + raise RuntimeError(f"{what} failed (exit {r.rc}):\n{r.tail(4000)}") + return r + + +def base_env(): + env = { + k: v for k, v in os.environ.items() + if not k.startswith(("PDM_", "PIP_", "PYTHON", "SOCKET_", "UV_", "VIRTUAL_ENV", "CONDA_")) + } + env.update( + PDM_CHECK_UPDATE="false", + PDM_PYPI_URL="https://pypi.org/simple", + PIP_CONFIG_FILE=os.devnull, + PIP_DISABLE_PIP_VERSION_CHECK="1", + PYTHONIOENCODING="utf-8", + PYTHONDONTWRITEBYTECODE="1", + NO_COLOR="1", + SOCKET_NO_CONFIG="1", + SOCKET_NO_UPDATE_CHECK="1", + SOCKET_TELEMETRY_DISABLED="1", + ) + return env + + +# --------------------------------------------------------------- manifests + +def requirement(shape): + target = "requests==2.31.0" if shape == "transitive" else "urllib3==1.26.18" + if shape == "extras": + target = "urllib3[socks]==1.26.18" + if shape in ("marker", "marker-excluded"): + target += "; python_version " + (">" if shape == "marker-excluded" else "<") + " '4'" + if shape.startswith("platform-"): + target += "; sys_platform == '" + ("win32" if shape == "platform-windows" else "linux") + "'" + return target + + +def project_text(version, shape, overrides=True): + """pyproject.toml for `shape` as `version` understands it.""" + if legacy_manifest(version, shape): + text = f'[tool.pdm]\nname = "{PROJECT_NAME}"\nversion = "0.0.0"\npython_requires = ">=3.8"\n' + group = {"dev": "dev-dependencies", "optional": "feature-dependencies"}.get(shape, "dependencies") + if group != "dependencies": + text += "\n[tool.pdm.dependencies]\n" + text += f"\n[tool.pdm.{group}]\n" + if shape == "extras": + text += 'urllib3 = {version = "==1.26.18", extras = ["socks"]}\n' + elif shape in ("marker", "marker-excluded") or shape.startswith("platform-"): + marker = requirement(shape).split("; ", 1)[1] + text += "urllib3 = {version = \"==1.26.18\", marker = " + json.dumps(marker) + "}\n" + else: + name, pin = requirement(shape).split("==") + text += f'{name} = "=={pin}"\n' + return text + text = f'[project]\nname = "{PROJECT_NAME}"\nversion = "0.0.0"\nrequires-python = ">=3.8"\n' + if shape == "two-versions": + text += 'dependencies = [\n "urllib3==1.26.18; python_version < \'3.10\'",\n "urllib3==2.2.3; python_version >= \'3.10\'",\n]\n' + elif shape in ("dev", "optional", "dependency-groups"): + text += "dependencies = []\n" + if shape == "dev": + text += "\n[tool.pdm.dev-dependencies]\nqa = " + json.dumps([requirement(shape)]) + "\n" + elif shape == "optional": + text += "\n[project.optional-dependencies]\nfeature = " + json.dumps([requirement(shape)]) + "\n" + else: + text += "\n[dependency-groups]\ndev = " + json.dumps([requirement(shape)]) + "\n" + else: + text += "dependencies = " + json.dumps([requirement(shape)]) + "\n" + text += "\n[tool.pdm]\ndistribution = false\n" + if shape == "transitive" and overrides and vtuple(version) >= (2, 0): + table = "[tool.pdm.resolution.overrides]" if vtuple(version) >= (2, 11) else "[tool.pdm.overrides]" + text += "\n" + table + "\n" + "".join(f'{n} = "=={p}"\n' for n, p in TRANSITIVE_PINS) + return text + + +def transitive_pinned_text(version): + """PDM < 2.0 has no resolution overrides: lock with the pins as direct + requirements, then restore the real manifest and recompute the content + hash (same trick as the depscan reference harness).""" + if legacy_manifest(version, "transitive"): + return project_text(version, "transitive") + "".join(f'{n} = "=={p}"\n' for n, p in TRANSITIVE_PINS) + deps = ["requests==2.31.0"] + [f"{n}=={p}" for n, p in TRANSITIVE_PINS] + return project_text(version, "transitive").replace( + "dependencies = " + json.dumps(["requests==2.31.0"]), "dependencies = " + json.dumps(deps) + ) + + +def host_platform(): + return {"Darwin": "macos", "Linux": "linux", "Windows": "windows"}.get(platform.system(), "linux") + + +# ------------------------------------------------------------------- main + +def main(): + ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + ap.add_argument("--socket-patch", type=Path, help="socket-patch CLI binary") + ap.add_argument("--socket-patch-revision", help="git revision of the CLI, recorded in the summary") + ap.add_argument("--output", type=Path, help="output directory (tools, originals, cases, summary)") + ap.add_argument("--versions", nargs="+", default=VERSIONS) + ap.add_argument("--modes", nargs="+", default=MODES, choices=MODES) + ap.add_argument("--shapes", nargs="+", default=SHAPES, choices=SHAPES) + ap.add_argument("--jobs", type=int, default=4) + ap.add_argument("--tools-dir", type=Path, help="reuse / PDM venvs (re-bootstrapped in place when broken)") + ap.add_argument("--keep-environments", action="store_true", help="keep each case's venv, HOME and PDM cache (default: pruned after the case, logs and result.json stay)") + ap.add_argument("--render-doc-table", type=Path, metavar="SUMMARY_JSON", help="print the docs table from an existing summary.json and exit") + args = ap.parse_args() + if args.render_doc_table: + summary = json.loads(args.render_doc_table.read_text(encoding="utf-8")) + print(render_doc_table(summary)) + return + missing = [f for f, v in [("--socket-patch", args.socket_patch), ("--socket-patch-revision", args.socket_patch_revision), ("--output", args.output)] if v is None] + if missing: + ap.error("the following arguments are required: " + ", ".join(missing)) + + root = args.output.resolve() + root.mkdir(parents=True, exist_ok=True) + cli = args.socket_patch.resolve() + tools_root = args.tools_dir.resolve() if args.tools_dir else root / "tools" + tools_root.mkdir(parents=True, exist_ok=True) + (root / "tool-logs").mkdir(exist_ok=True) + env = base_env() + env["UV_CACHE_DIR"] = str(root / "uv-cache") + say_lock = threading.Lock() + + def say(*a): + with say_lock: + print(*a, flush=True) + + provenance = { + "capturedAt": datetime.now(timezone.utc).isoformat(), + "platform": platform.platform(), + "hostPython": sys.version.split()[0], + "cliPath": str(cli), + "cliRevision": args.socket_patch_revision, + "cliSha256": sha256_file(cli), + "cliVersion": subprocess.run([str(cli), "--version"], capture_output=True, text=True, env=env).stdout.strip(), + "uvVersion": subprocess.run(["uv", "--version"], capture_output=True, text=True, env=env).stdout.strip(), + "pdmVersions": args.versions, + "modes": args.modes, + "shapes": args.shapes, + "patchUuid": PATCH_UUID, + "toolsDir": str(tools_root), + } + + # ------------------------------------------------------------ tools + def tool_paths(version): + venv = tools_root / version + return venv, venv / "bin/pdm", venv / "bin/python" + + def tool_healthy(version, log_prefix): + venv, pdm, python = tool_paths(version) + if not pdm.exists(): + return False, "missing" + r = Run([pdm, "--version"], root, env, log_prefix + "-version.log", timeout=120) + if not r.ok() or "version" not in r.out.lower(): + return False, "pdm --version failed: " + r.tail(300).strip().splitlines()[-1] if r.out.strip() else "pdm --version failed" + frozen = Run(["uv", "pip", "freeze", "--python", python], root, env, log_prefix + "-freeze.log", timeout=120).out + missing = [p for p in required_pins(version) if p not in frozen] + if missing: + return False, "pins missing: " + " ".join(missing) + return True, frozen + + def bootstrap(version): + venv, pdm, python = tool_paths(version) + log_prefix = str(root / "tool-logs" / version) + record = {"version": version, "python": python_for(version), "pins": pins_for(version), "reused": venv.exists(), "path": str(venv)} + healthy, detail = tool_healthy(version, log_prefix) + if not healthy: + record["rebootstrapReason"] = detail if venv.exists() else "not installed" + if venv.exists(): + shutil.rmtree(venv) + r = Run(["uv", "venv", "--quiet", "--python", python_for(version), venv], root, env, log_prefix + "-venv.log", timeout=600, retry=True) + if not r.ok(): + record["error"] = "uv venv: " + r.tail(600) + return record + r = Run(["uv", "pip", "install", "--quiet", "--python", python, *pins_for(version)], root, env, log_prefix + "-install.log", timeout=900, retry=True) + if not r.ok(): + record["error"] = "uv pip install: " + r.tail(1200) + return record + healthy, detail = tool_healthy(version, log_prefix) + if not healthy: + record["error"] = "unhealthy after bootstrap: " + detail + return record + record["frozen"] = [l for l in detail.splitlines() if "==" in l] + record["ok"] = True + return record + + # per-(version, subcommand) --help text cache + help_cache, help_lock = {}, threading.Lock() + + def pdm_help(version, subcommand): + key = (version, subcommand) + with help_lock: + if key in help_cache: + return help_cache[key] + _, pdm, _ = tool_paths(version) + r = Run([pdm, subcommand, "--help"], root, env, root / "tool-logs" / f"{version}-help-{subcommand}.log", timeout=120) + with help_lock: + help_cache[key] = r.out + return r.out + + def install_cmd(version, verb, groups, lockfile=None): + _, pdm, _ = tool_paths(version) + cmd = [pdm, verb] + if "--no-self" in pdm_help(version, verb): + cmd.append("--no-self") + cmd += groups + if lockfile: + cmd += ["-L", lockfile] + return cmd + + def group_flags(version, shape): + legacy = legacy_manifest(version, shape) + if shape == "dev": + return ["-d"] if legacy else ["-d", "-G", "qa"] + if shape == "optional": + return ["-s", "feature"] if legacy else ["-G", "feature"] + if shape == "dependency-groups": + return ["-d", "-G", "dev"] + return [] + + # ------------------------------------------------------ environments + def write_configs(version, project, home, cache, pep582): + """Per-case PDM config: PDM_CONFIG_FILE for >= 1.15, ~/.pdm/config.toml + (via the case HOME) for older releases. `use_venv` makes 0.x/1.x + install into the project venv instead of __pypackages__.""" + (home / ".pdm").mkdir(parents=True, exist_ok=True) + cache.mkdir(parents=True, exist_ok=True) + v = vtuple(version) + lines = ["cache_dir = " + json.dumps(str(cache))] + if honours_config_file(version): + lines.append("check_update = false") + lines.append("python.use_venv = " + ("false" if pep582 else "true")) + else: + if v >= (1, 5): + lines.append("check_update = false") + lines.append("use_venv = " + ("false" if pep582 else "true")) + text = "\n".join(lines) + "\n" + (project / "native-config.toml").write_text(text, encoding="utf-8") + (home / ".pdm" / "config.toml").write_text(text, encoding="utf-8") + + def pdm_env(version, project, home, cache, venv=None): + _, pdm, _ = tool_paths(version) + e = dict(env) + e["HOME"] = str(home) + e["PATH"] = str(pdm.parent) + os.pathsep + e.get("PATH", "") + e["PDM_CONFIG_FILE"] = str(project / "native-config.toml") + e["PDM_CACHE_DIR"] = str(cache) + if venv is not None: + # Select the project venv through VIRTUAL_ENV: `pdm use -f + # /bin/python` dereferences the uv venv symlink to the base + # interpreter on 0.x, 1.x and early 2.x (2.0.3 then silently + # installs into __pypackages__), while VIRTUAL_ENV + use_venv is + # honoured by every release tested (0.12 .. 2.29). + e["VIRTUAL_ENV"] = str(venv) + return e + + def cli_env(version, home): + _, pdm, _ = tool_paths(version) + e = dict(env) + e["HOME"] = str(home) + e["PATH"] = str(pdm.parent) + os.pathsep + e.get("PATH", "") + return e + + def select_python(version, project, penv, log, venv=None): + """Point PDM at the case interpreter. With a venv, VIRTUAL_ENV in + `penv` does the selecting (see `pdm_env`); for the PEP 582 layout + `pdm use -f ` so no release mistakes the PDM tool + venv on PATH for the target.""" + _, pdm, tool_python = tool_paths(version) + if venv is not None: + return None + base_python = Path(os.path.realpath(tool_python)) + return Run([pdm, "use", "-f", base_python], project, penv, log, timeout=300) + + def make_venv(version, venv, cwd, log, packages=()): + _, _, tool_python = tool_paths(version) + require(Run(["uv", "venv", "--quiet", "--python", tool_python, venv], cwd, env, log, timeout=300, retry=True), "uv venv") + if packages: + require(Run(["uv", "pip", "install", "--quiet", "--python", venv / "bin/python", *packages], cwd, env, str(log) + ".pip", timeout=600, retry=True), "venv bootstrap") + + def content_hash(version, project, penv, log, algo="sha256"): + _, _, tool_python = tool_paths(version) + r = Run([tool_python, "-c", HASH_SNIPPET, algo], project, penv, log, timeout=300) + try: + return json.loads(r.out.strip().splitlines()[-1]) + except Exception: + return {"error": r.tail(800)} + + # ------------------------------------------------------- originals + original_locks = {} + original_guard = threading.Lock() + + def original_lock_for(version, shape): + key = (version, shape) + with original_guard: + if key not in original_locks: + original_locks[key] = threading.Lock() + lock = original_locks[key] + with lock: + return generate_original(version, shape) + + def lock_filename(shape): + return "custom.lock" if shape == "custom-lockfile" else "pdm.lock" + + def generate_original(version, shape): + """Generate (once) the pristine pyproject + lock for version/shape. + Returns the directory plus generation metadata.""" + original = root / "original" / version / shape + meta_path = original / "generation.json" + if meta_path.exists(): + return original, json.loads(meta_path.read_text(encoding="utf-8")) + if original.exists(): + shutil.rmtree(original) + original.mkdir(parents=True) + home, cache = original / "home", original / "native-cache" + write_configs(version, original, home, cache, pep582=True) + penv = pdm_env(version, original, home, cache) + _, pdm, _ = tool_paths(version) + meta = {"version": version, "shape": shape, "lockfile": lock_filename(shape), "seededFromFixture": False} + lock_help = pdm_help(version, "lock") + if shape == "custom-lockfile" and "-L" not in lock_help: + meta["skip"] = "pdm lock has no -L/--lockfile on this release" + save(meta_path, meta) + return original, meta + pinned = shape == "transitive" and vtuple(version) < (2, 0) + (original / "pyproject.toml").write_text(transitive_pinned_text(version) if pinned else project_text(version, shape), encoding="utf-8") + use = select_python(version, original, penv, original / "use.log") + if use is not None and not use.ok(): + meta["skip"] = "pdm use failed: " + use.tail(400) + save(meta_path, meta) + return original, meta + # Seed from the checked-in native fixture when one exists and PDM + # itself agrees it is fresh for this pyproject. + fixture = FIXTURES / (version + ("-extras" if shape == "extras" else "") + ".lock") + if shape in ("direct", "extras") and fixture.exists(): + (original / "pdm.lock").write_bytes(fixture.read_bytes()) + fresh = content_hash(version, original, penv, original / "fixture-freshness.log") + if fresh.get("fresh") is True: + meta["seededFromFixture"] = str(fixture) + else: + meta["fixtureRejected"] = fresh + (original / "pdm.lock").unlink() + if not (original / meta["lockfile"]).exists(): + commands = [] + if shape == "multi-target": + alt = "windows" if host_platform() != "windows" else "linux" + commands = [[pdm, "lock", "--platform", host_platform()], [pdm, "lock", "--platform", alt, "--append"]] + elif shape == "two-versions": + commands = [[pdm, "lock", "--python", ">=3.8,<3.10"], [pdm, "lock", "--python", ">=3.10", "--append"]] + else: + cmd = [pdm, "lock"] + if shape == "optional" and "--group" in lock_help: + cmd += ["-G", "feature"] + if shape == "dependency-groups" and "--group" in lock_help: + cmd += ["-G", "dev"] + if shape == "static-urls": + cmd += ["--strategy", "static_urls"] + if shape == "custom-lockfile": + cmd += ["-L", "custom.lock"] + commands = [cmd] + for i, cmd in enumerate(commands): + r = Run(cmd, original, penv, original / f"generation-{i}.log", timeout=900, retry=True) + if not r.ok(): + meta["skip"] = f"pdm lock failed (exit {r.rc}): " + r.tail(600) + save(meta_path, meta) + return original, meta + meta["lockCommands"] = [[str(c) for c in cmd[1:]] for cmd in commands] + lock_path = original / meta["lockfile"] + written = transitive_pinned_text(version) if pinned else project_text(version, shape) + # PDM 1.0-1.4 rewrite legacy `[tool.pdm]` metadata into `[project]` + # while locking; the migrated file is what the cases start from. + meta["pyprojectMigratedByPdm"] = (original / "pyproject.toml").read_text(encoding="utf-8") != written + if pinned: + (original / "pyproject.toml").write_text(project_text(version, shape), encoding="utf-8") + algo = "md5" if b'content_hash = "md5:' in lock_path.read_bytes() else "sha256" + digest = content_hash(version, original, penv, original / "content-hash.log", algo) + if digest.get("hash"): + lock_path.write_text( + re.sub(r'content_hash = "(sha256|md5):[a-f0-9]+"', f'content_hash = "{algo}:{digest["hash"]}"', lock_path.read_text(encoding="utf-8")), + encoding="utf-8", + ) + meta["contentHashRecomputed"] = True + else: + meta["contentHashRecomputeFailed"] = digest + if shape == "crlf": + for name in ("pyproject.toml", "pdm.lock"): + p = original / name + p.write_bytes(p.read_bytes().replace(b"\r\n", b"\n").replace(b"\n", b"\r\n")) + text = lock_path.read_text(encoding="utf-8", errors="replace") + meta["lockVersion"] = lock_version_of(text) + meta["lockHasTarget"] = re.search(r'name = "urllib3"\s*\n(?:[^\n]*\n)*?version = "1\.26\.18"', text) is not None or re.search(r'"urllib3(\[[^\]]*\])? 1\.26\.18"', text) is not None + if not meta["lockHasTarget"]: + meta["skip"] = "native lock does not pin urllib3 1.26.18 for this shape" + freshness = content_hash(version, original, penv, original / "freshness.log", "md5" if b'content_hash = "md5:' in lock_path.read_bytes() else "sha256") + meta["baselineFresh"] = freshness.get("fresh") + meta["freshness"] = freshness + for junk in ("__pypackages__", ".venv"): + shutil.rmtree(original / junk, ignore_errors=True) + save(meta_path, meta) + return original, meta + + # -------------------------------------------------------- one case + def cli_cmd(project, *rest): + return [cli, *rest, "--cwd", project, "--json", "--yes", "--no-telemetry"] + + def applied_count(mode, envelope): + if mode == "hosted": + return envelope.get("redirect", {}).get("redirected", 0) + if mode == "vendored": + return envelope.get("vendor", {}).get("summary", {}).get("applied", 0) + return envelope.get("apply", {}).get("applied", 0) + + def refusal_codes(mode, envelope): + if mode == "hosted": + return sorted({w.get("code") for w in envelope.get("redirect", {}).get("warnings", []) if w.get("code")}) + if mode == "vendored": + return sorted({e.get("errorCode") for e in envelope.get("vendor", {}).get("events", []) if e.get("errorCode")}) + return sorted({p.get("errorCode") for p in envelope.get("apply", {}).get("patches", []) if p.get("errorCode")}) + + def record_hashes(project, mode): + ledger = project / (".socket/vendor/redirect-state.json" if mode == "hosted" else ".socket/manifest.json") + if not ledger.exists(): + return {}, {}, None + data = json.loads(ledger.read_text(encoding="utf-8")) + recs = data.get("records" if mode == "hosted" else "patches") or {} + if not recs: + return {}, {}, None + rec = next(iter(recs.values())) + files = rec.get("files", {}) + return ( + {n: i["afterHash"] for n, i in files.items()}, + {n: i["beforeHash"] for n, i in files.items() if i.get("beforeHash")}, + rec.get("uuid"), + ) + + def ledger_cleared(project, mode): + if mode == "hosted": + p = project / ".socket/vendor/redirect-state.json" + return not p.exists() or not json.loads(p.read_text(encoding="utf-8")).get("records") + mf = project / ".socket/manifest.json" + cleared = not mf.exists() or json.loads(mf.read_text(encoding="utf-8")).get("patches") in ({}, None) + if mode == "vendored": + st = project / ".socket/vendor/state.json" + cleared = cleared and (not st.exists() or not json.loads(st.read_text(encoding="utf-8")).get("entries")) + return cleared + + def oracle(version, project, penv, hashes, log): + _, pdm, _ = tool_paths(version) + r = Run([pdm, "run", "python", "-c", ORACLE, json.dumps(hashes)], project, penv, log, timeout=300) + try: + return json.loads(r.out.strip().splitlines()[-1]) + except Exception: + return {"error": r.tail(600)} + + def patched(res, hashes): + return bool(hashes) and res.get("installed") is True and all(res.get("files", {}).get(n) for n in hashes) + + def self_install_only(text): + """PDM < 1.5 has no --no-self and cannot build the fixture project + (0.8: `Installation failed: `, 1.0-1.4: `Install 0.0.0 + failed` after egg_info / PEP 621 validation); the dependency install + itself completes before that error. Only counts when no dependency + install line failed.""" + name = re.escape(PROJECT_NAME) + return ( + re.search(rf"Installation failed: {name}|Install {name} 0\.0\.0 failed", text) is not None + and re.search(r"Install (?!" + name + r")\S+ [^\n]*failed", text) is None + ) + + def prune(case, project): + if args.keep_environments: + return + for path in (project / ".venv", project / "__pypackages__", case / "home", case / "native-cache", case / "saved-socket", project / ".socket"): + shutil.rmtree(path, ignore_errors=True) + + def backtest(job): + version, shape, mode = job + started = time.time() + row = {"pdm": version, "python": python_for(version), "shape": shape, "mode": mode, "checks": {}, "info": {}, "passed": None, "outcome": None} + checks, info = row["checks"], row["info"] + + def check(name, value, note=None): + checks[name] = bool(value) + if note is not None: + info[name] = note + return bool(value) + + def finish(outcome): + row["outcome"] = outcome + row["passed"] = outcome in ("PASS", "REFUSED-EXPECTED") + row["durationSeconds"] = round(time.time() - started, 1) + origin = info.get("installedOrigin") or info.get("upstreamOrigin") or "" + if "__pypackages__" in origin: + row["layout"] = "__pypackages__" + elif "/.venv/" in origin or "\\.venv\\" in origin: + row["layout"] = ".venv" + if row.get("caseDir"): + save(Path(row["caseDir"]) / "result.json", row) + prune(Path(row["caseDir"]), Path(row["caseDir"]) / ("project space café" if shape == "space-unicode" else "project")) + return row + + def native_broken(reason, tail): + """A native PDM install that fails on the PRISTINE lock is a PDM + defect for this version/shape, not a patch outcome: SKIP it.""" + info["skip"] = f"native `pdm sync` fails on this release/shape ({reason}): " + tail[-400:].replace("\n", " ") + return finish("SKIP") + + original, meta = original_lock_for(version, shape) + row["lockVersion"] = meta.get("lockVersion") + row["baselineFresh"] = meta.get("baselineFresh") + row["seededFromFixture"] = bool(meta.get("seededFromFixture")) + if meta.get("skip"): + info["skip"] = meta["skip"] + return finish("SKIP") + lockname = meta["lockfile"] + case = root / "cases" / version / shape / mode + if case.exists(): + shutil.rmtree(case) + case.mkdir(parents=True) + row["caseDir"] = str(case) + project = case / ("project space café" if shape == "space-unicode" else "project") + project.mkdir() + for name in ("pyproject.toml", lockname): + shutil.copyfile(original / name, project / name) + pristine_lock = (project / lockname).read_bytes() + pristine_pyproject = (project / "pyproject.toml").read_bytes() + home, cache = case / "home", case / "native-cache" + pep582 = shape == "pep582" + row["layout"] = "__pypackages__" if pep582 else ".venv" + write_configs(version, project, home, cache, pep582) + venv = None if pep582 else project / ".venv" + penv = pdm_env(version, project, home, cache, venv) + cenv = cli_env(version, home) + _, pdm, tool_python = tool_paths(version) + groups = group_flags(version, shape) + lockflag = "custom.lock" if shape == "custom-lockfile" else None + sync = install_cmd(version, "sync", groups, lockflag) + install = install_cmd(version, "install", groups, lockflag) + excluded = excluded_shape(shape) + v = vtuple(version) + + def native_sync(log): + r = Run(sync, project, penv, case / log, timeout=900, retry=True) + ok = r.ok() or self_install_only(r.out) + return r, ok + + def uninstall(log): + if pep582: + shutil.rmtree(project / "__pypackages__", ignore_errors=True) + return + Run(["uv", "pip", "uninstall", "--quiet", "--python", venv / "bin/python", "urllib3"], project, env, case / log, timeout=300) + + # ----------------------------------------------------- hosted probe + if mode == "hosted" and not pep582: + r0 = Run(cli_cmd(project, "scan", "--mode", "hosted"), project, cenv, case / "scan-lockonly.log", timeout=600, retry=True) + e0 = r0.json_or_empty() + info["lockOnlyHosted"] = {"exit": r0.rc, "redirected": applied_count("hosted", e0), "codes": refusal_codes("hosted", e0), "lockfileOnlyPackages": e0.get("lockfileOnlyPackages"), "scannedPackages": e0.get("scannedPackages"), "crawledUrllib3": sorted(p["purl"] for p in e0.get("packages", []) if "urllib3" in p.get("purl", ""))} + shutil.rmtree(project / ".socket", ignore_errors=True) + (project / lockname).write_bytes(pristine_lock) + + # ----------------------------------------------------- environment + if pep582: + use = select_python(version, project, penv, case / "use.log") + if use is not None and not use.ok(): + raise RuntimeError("pdm use failed: " + use.tail(600)) + r, ok = native_sync("install-upstream.log") + info["upstreamInstall"] = {"exit": r.rc, "tail": r.tail(300)} + if not ok: + return native_broken("upstream install", r.out) + else: + make_venv(version, venv, project, case / "venv.log", packages=() if mode == "agent" else ("urllib3==1.26.18",)) + use = select_python(version, project, penv, case / "use.log", venv) + if use is not None and not use.ok(): + raise RuntimeError("pdm use failed: " + use.tail(600)) + if mode == "agent": + r, ok = native_sync("install-upstream.log") + info["upstreamInstall"] = {"exit": r.rc, "tail": r.tail(300)} + if not ok: + return native_broken("upstream install", r.out) + if mode == "agent" or pep582: + pre = oracle(version, project, penv, {}, case / "oracle-upstream.log") + info["upstreamOrigin"] = pre.get("origin") + + # ----------------------------------------------------------- scan + scan_mode = ["--mode", mode] + r = Run(cli_cmd(project, "scan", *scan_mode), project, cenv, case / "scan.log", timeout=900, retry=True) + info["scanExit"] = r.rc + envelope = r.json() + save(case / "cli-output.json", envelope) + applied = applied_count(mode, envelope) + info["applied"] = applied + info["scannedPackages"] = envelope.get("scannedPackages") + codes = refusal_codes(mode, envelope) + info["codes"] = codes + crawled = sorted(p.get("purl", "") for p in envelope.get("packages", [])) + info["crawledWithPatches"] = crawled + lock_after = (project / lockname).read_bytes() + check("pyprojectUnchanged", (project / "pyproject.toml").read_bytes() == pristine_pyproject) + + if pep582 and ( + mode in ("agent", "vendored") + or not any(p.startswith(PURL_BASE) for p in crawled) + ): + # PDM installs into a `__pypackages__` tree the crawler never + # probes. Hosted redirect rewrites the lock without an install, so + # a discovered coordinate is enough (handled below); agent (patches + # installed files) and vendored (rebuilds from, and re-verifies, + # the install) cannot serve this layout — with no venv the crawler + # falls through to the `python` on PATH, which is NOT this + # project's install. Documented `__pypackages__` limitation. + row["expected"] = "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)" + check("lockUnchanged", lock_after == pristine_lock) + if applied: + info["patchedOutsideProject"] = {"applied": applied, "crawled": crawled} + rb = Run(cli_cmd(project, "rollback"), project, cenv, case / "rollback.log", timeout=900) + info["rollbackOutsideProject"] = {"exit": rb.rc, "rolledBack": rb.json_or_empty().get("rolledBack")} + return finish("UNSUPPORTED" if checks["lockUnchanged"] else "FAIL") + + expected_refusal = mode != "agent" and (row["lockVersion"] not in SUPPORTED_LOCK_VERSIONS or shape in EXPECTED_NOOP_SHAPES) + if expected_refusal: + if shape in EXPECTED_NOOP_SHAPES: + row["expected"] = {"two-versions": "refused: two locked urllib3 versions (forked package)", "custom-lockfile": "no-op: the CLI only reads pdm.lock"}[shape] + else: + row["expected"] = f"refused: lock_version {row['lockVersion']!r} is not supported by the rewriter" + check("appliedZero", applied == 0, {"applied": applied, "codes": codes}) + if shape != "custom-lockfile": + check("refusalCodeReported", bool(codes), codes) + check("lockUnchanged", lock_after == pristine_lock) + if mode == "hosted": + check("noPatchWiring", ledger_cleared(project, "hosted")) + else: + st = project / ".socket/vendor/state.json" + entries = json.loads(st.read_text(encoding="utf-8")).get("entries") if st.exists() else None + check("noPatchWiring", not entries and not any((project / ".socket/vendor/pypi").glob("*/*.whl")), {"vendorEntries": sorted(entries or {})}) + # A refused vendored patch still leaves a `.socket/manifest.json` + # record behind (observed on the PR head); recorded, not judged. + mf = project / ".socket/manifest.json" + leftover = sorted((json.loads(mf.read_text(encoding="utf-8")).get("patches") or {}) if mf.exists() else {}) + info["manifestLeftover"] = leftover + uninstall("uninstall.log") + r, ok = native_sync("native-install.log") + if not ok and applied == 0: + return native_broken("pristine lock", r.out) + check("nativeInstallOk", ok, {"exit": r.rc, "tail": r.tail(300)}) + res = oracle(version, project, penv, {}, case / "oracle-native.log") + check("nativeInstallsPackage", res.get("installed") is (not excluded), res) + info["installedOrigin"] = res.get("origin") + if applied != 0: + # Not refused after all: run the full flow and say so. + row["unexpected"] = "the CLI rewrote a lock the harness expected it to refuse" + else: + if leftover: + rb = Run(cli_cmd(project, "rollback"), project, cenv, case / "rollback.log", timeout=900) + info["rollbackAfterRefusal"] = {"exit": rb.rc, "manifestCleared": ledger_cleared(project, "agent"), "lockUnchanged": (project / lockname).read_bytes() == pristine_lock} + return finish("REFUSED-EXPECTED" if all(checks.values()) else "FAIL") + + if mode == "agent": + found = envelope.get("apply", {}).get("found", 0) + info["found"] = found + if not check("appliedExactlyOne", applied == 1, {"applied": applied, "found": found, "codes": codes, "status": envelope.get("status")}): + return finish("FAIL") + check("lockUnchanged", lock_after == pristine_lock) + after, before, uuid = record_hashes(project, "agent") + info["uuid"] = uuid + check("recordHasFiles", bool(after)) + res = oracle(version, project, penv, after, case / "oracle-1.log") + info["installedOrigin"] = res.get("origin") + check("installedBytesPatched", patched(res, after), res) + r2 = Run(cli_cmd(project, "scan", *scan_mode), project, cenv, case / "rescan.log", timeout=900, retry=True) + e2 = r2.json_or_empty() + res2 = oracle(version, project, penv, after, case / "oracle-2.log") + check("rescanIdempotent", r2.ok() and patched(res2, after) and (project / lockname).read_bytes() == pristine_lock, {"exit": r2.rc, "applied": applied_count("agent", e2)}) + rs, ok = native_sync("sync-again.log") + res3 = oracle(version, project, penv, after, case / "oracle-3.log") + check("survivesSync", ok and patched(res3, after), {"exit": rs.rc, "oracle": res3}) + ri = Run(install, project, penv, case / "install-again.log", timeout=900, retry=True) + res4 = oracle(version, project, penv, after, case / "oracle-4.log") + check("survivesInstall", (ri.ok() or self_install_only(ri.out)) and patched(res4, after), {"exit": ri.rc, "oracle": res4}) + lock_now = (project / lockname).read_bytes() + info["ordinaryInstall"] = {"exit": ri.rc, "lockStable": lock_now == pristine_lock, "baselineFresh": row["baselineFresh"]} + # The agent never touches the lock; a regenerated lock here is + # PDM's own doing (0.x calls its fresh lock stale) and is judged + # like the hosted/vendored ordinary-install check. + check("lockUnchangedAfterInstalls", lock_now == pristine_lock or row["baselineFresh"] is not True, info["ordinaryInstall"]) + rb = Run(cli_cmd(project, "rollback"), project, cenv, case / "rollback.log", timeout=900) + erb = rb.json_or_empty() + check("rollbackExit0", rb.ok(), rb.tail(600) if not rb.ok() else None) + res5 = oracle(version, project, penv, before, case / "oracle-rollback.log") + check("rollbackRestoresUpstreamBytes", patched(res5, before), res5) + check("rollbackClearsManifest", ledger_cleared(project, "agent")) + check("rollbackKeepsPyproject", (project / "pyproject.toml").read_bytes() == pristine_pyproject) + check("rollbackKeepsLock", (project / lockname).read_bytes() == lock_now) + info["rollbackEnvelope"] = {k: erb.get(k) for k in ("status", "rolledBack", "failed") if k in erb} + return finish("PASS" if all(checks.values()) else "FAIL") + + # ------------------------------------------------ hosted / vendored + if not check("appliedExactlyOne", applied == 1, {"applied": applied, "codes": codes, "status": envelope.get("status")}): + return finish("FAIL") + check("lockRewritten", lock_after != pristine_lock) + if shape == "crlf": + check("crlfPreserved", b"\n" not in lock_after.replace(b"\r\n", b"")) + marker = HOSTED_MARKER if mode == "hosted" else VENDORED_MARKER + check("lockHasPatchSource", marker in lock_after) + after, before, uuid = record_hashes(project, mode) + info["uuid"] = uuid + check("recordHasFiles", bool(after)) + if mode == "vendored": + wheel_dir = project / ".socket/vendor/pypi" / (uuid or "") + check("vendoredWheelPresent", wheel_dir.is_dir() and any(wheel_dir.glob("*.whl"))) + # idempotent re-scan + r2 = Run(cli_cmd(project, "scan", *scan_mode), project, cenv, case / "rescan.log", timeout=900, retry=True) + e2 = r2.json_or_empty() + check("rescanIdempotent", r2.ok() and (project / lockname).read_bytes() == lock_after and (project / "pyproject.toml").read_bytes() == pristine_pyproject, {"exit": r2.rc, "applied": applied_count(mode, e2), "status": e2.get("status")}) + # lock-driven install of the patched artifact + uninstall("uninstall.log") + r, ok = native_sync("install.log") + info["install"] = {"exit": r.rc, "selfInstallOnly": self_install_only(r.out), "tail": r.tail(300)} + if not ok: + # Is it the patched lock, or does this PDM release fail the + # pristine lock just the same? Re-run against the pristine lock. + (project / lockname).write_bytes(pristine_lock) + uninstall("baseline-uninstall.log") + rb0, ok0 = native_sync("baseline-install.log") + (project / lockname).write_bytes(lock_after) + info["nativeBaseline"] = {"exit": rb0.rc, "ok": ok0, "tail": rb0.tail(300)} + if not ok0: + return native_broken("pristine lock fails too", rb0.out) + check("nativeInstallOk", ok, info["install"]) + res = oracle(version, project, penv, after, case / "oracle-1.log") + info["installedOrigin"] = res.get("origin") + if excluded: + check("installedBytesPatched", res.get("installed") is False, {"expected": "not installed (marker excludes this host)", "oracle": res}) + else: + check("installedBytesPatched", patched(res, after), res) + check("lockUnchangedByInstall", (project / lockname).read_bytes() == lock_after) + # ordinary `pdm install` + ri = Run(install, project, penv, case / "ordinary-install.log", timeout=900, retry=True) + ordinary_stable = (project / lockname).read_bytes() == lock_after + info["ordinaryInstall"] = {"exit": ri.rc, "lockStable": ordinary_stable, "baselineFresh": row["baselineFresh"], "tail": ri.tail(300)} + check("ordinaryInstallOk", ri.ok() or self_install_only(ri.out), info["ordinaryInstall"]) + check("ordinaryInstallKeepsLock", ordinary_stable or row["baselineFresh"] is not True, info["ordinaryInstall"]) + if not ordinary_stable: + shutil.copyfile(project / lockname, case / "ordinary-result.lock") + (project / lockname).write_bytes(lock_after) + res_o = oracle(version, project, penv, after, case / "oracle-ordinary.log") + info["ordinaryInstallPatched"] = patched(res_o, after) + # `pdm lock --check` where it exists (2.11+) + if "--check" in pdm_help(version, "lock"): + lc = Run([pdm, "lock", "--check"] + (["-L", lockflag] if lockflag else []), project, penv, case / "lock-check.log", timeout=300) + info["lockCheck"] = {"exit": lc.rc, "tail": lc.tail(200)} + # `pdm export` + ex_help = pdm_help(version, "export") + if "usage" in ex_help.lower() and "invalid choice" not in ex_help: + ex = Run([pdm, "export", "-f", "requirements", *groups] + (["-L", lockflag] if lockflag else []), project, penv, case / "export.log", timeout=300) + info["export"] = {"exit": ex.rc, "mentionsPatchSource": marker.decode() in ex.out, "mentionsUrllib3": "urllib3" in ex.out} + # tampered hash must be rejected by the installer + if not excluded: + uninstall("tamper-uninstall.log") + shutil.rmtree(cache, ignore_errors=True) + cache.mkdir(parents=True, exist_ok=True) + bad = re.sub(rb"sha256:[a-f0-9]{64}", b"sha256:" + b"0" * 64, lock_after) + (project / lockname).write_bytes(bad) + tam, _ = native_sync("tamper-install.log") + tres = oracle(version, project, penv, after, case / "tamper-oracle.log") + (project / lockname).write_bytes(lock_after) + info["tamper"] = {"installExit": tam.rc, "mentionsHash": bool(re.search(r"hash|digest|checksum|integrity", tam.out, re.I)), "installedPatchedAnyway": patched(tres, after)} + check("integrityRejected", tam.rc != 0 and not info["tamper"]["installedPatchedAnyway"], info["tamper"]) + uninstall("tamper-uninstall2.log") + r, ok = native_sync("reinstall.log") + check("reinstallOk", ok, r.tail(300)) + # relock -> re-scan -> rollback (must restore the relocked bytes) + saved = case / "saved-socket" + shutil.copytree(project / ".socket", saved) + if excluded: + # The marker kept PDM from installing urllib3, so put the upstream + # copy back for discovery (the starting condition of this case). + Run(["uv", "pip", "install", "--quiet", "--python", venv / "bin/python", "urllib3==1.26.18"], project, env, case / "relock-reinstall.log", timeout=600, retry=True) + rl = Run([pdm, "lock"] + (["-L", lockflag] if lockflag else []), project, penv, case / "relock.log", timeout=900, retry=True) + relocked = (project / lockname).read_bytes() + shutil.copyfile(project / lockname, case / "relocked.lock") + info["relock"] = {"exit": rl.rc, "keepsPatch": marker in relocked, "lockBytesUnchanged": relocked == lock_after, "equalsOriginal": relocked == pristine_lock, "crlfKept": b"\r\n" in relocked if shape == "crlf" else None, "pyprojectUnchanged": (project / "pyproject.toml").read_bytes() == pristine_pyproject, "tail": rl.tail(200)} + if rl.ok(): + relocked_text = relocked.decode("utf-8", "replace") + target_kept = re.search(r'name = "urllib3"\s*\r?\n(?:[^\n]*\n)*?version = "1\.26\.18"', relocked_text) is not None or re.search(r'"urllib3(\[[^\]]*\])? 1\.26\.18"', relocked_text) is not None + info["relock"]["targetKept"] = target_kept + rs = Run(cli_cmd(project, "scan", *scan_mode), project, cenv, case / "rescan-after-relock.log", timeout=900, retry=True) + ers = rs.json_or_empty() + rescanned = (project / lockname).read_bytes() + info["rescanAfterRelock"] = {"exit": rs.rc, "applied": applied_count(mode, ers), "codes": refusal_codes(mode, ers), "patchInLock": marker in rescanned} + rb1 = Run(cli_cmd(project, "rollback"), project, cenv, case / "rollback-after-relock.log", timeout=900) + erb1 = rb1.json_or_empty() + shutil.copyfile(project / lockname, case / "rollback-after-relock.lock") + failures = (erb1.get("hosted") or {}).get("failed") or erb1.get("vendoredFailed") or [] + rollback_note = {"exit": rb1.rc, "status": erb1.get("status"), "failed": failures[:3], "lockEqualsRelocked": (project / lockname).read_bytes() == relocked} + if target_kept: + check("rescanAfterRelockApplies", rs.ok() and marker in rescanned, info["rescanAfterRelock"]) + check("rollbackAfterRelockPristine", rb1.ok() and rollback_note["lockEqualsRelocked"], rollback_note) + else: + # The relock resolved urllib3 away from 1.26.18 (PDM < 2.0 + # has no overrides, so the pinned transitive resolution does + # not survive `pdm lock`): nothing left to redirect, so the + # re-scan and the rollback of the stale ledger are recorded + # for the doc, not judged. + info["relock"]["note"] = "relock dropped urllib3 1.26.18 from the lock; re-scan/rollback recorded only" + info["rollbackAfterRelock"] = rollback_note + shutil.rmtree(project / ".socket", ignore_errors=True) + shutil.copytree(saved, project / ".socket") + (project / lockname).write_bytes(lock_after) + # final rollback restores every byte + rb = Run(cli_cmd(project, "rollback"), project, cenv, case / "rollback.log", timeout=900) + erb = rb.json_or_empty() + check("rollbackExit0", rb.ok(), rb.tail(600) if not rb.ok() else None) + check("rollbackRestoresLockBytes", (project / lockname).read_bytes() == pristine_lock) + check("rollbackKeepsPyproject", (project / "pyproject.toml").read_bytes() == pristine_pyproject) + check("rollbackClearsLedger", ledger_cleared(project, mode)) + if mode == "vendored": + check("rollbackRemovesVendoredWheel", not (project / ".socket/vendor/pypi" / (uuid or "x")).exists()) + info["rollbackEnvelope"] = {k: erb.get(k) for k in ("status", "rolledBack", "failed", "vendoredReverted") if k in erb} + if erb.get("hosted"): + info["rollbackEnvelope"]["hosted"] = {k: erb["hosted"].get(k) for k in ("reverted", "failed", "unsupported", "editedFiles")} + return finish("PASS" if all(checks.values()) else "FAIL") + + # --------------------------------------------------------- execution + tool_environments = {} + with concurrent.futures.ThreadPoolExecutor(max_workers=args.jobs) as pool: + futs = {pool.submit(bootstrap, v): v for v in args.versions} + for f in concurrent.futures.as_completed(futs): + v = futs[f] + try: + rec = f.result() + except Exception as e: + rec = {"version": v, "error": "bootstrap raised: " + str(e)[-800:]} + tool_environments[v] = rec + say("tool", v, "ok" if rec.get("ok") else "FAILED: " + rec.get("error", "?")[-300:].replace("\n", " ")) + jobs = [(v, s, m) for v in args.versions for s in args.shapes for m in args.modes if wanted(v, s, m)] + say(f"{len(jobs)} cases across {len(args.versions)} PDM releases") + results, errors = [], [] + for v in args.versions: + if not tool_environments.get(v, {}).get("ok"): + for s in args.shapes: + for m in args.modes: + if wanted(v, s, m): + results.append({"pdm": v, "python": python_for(v), "shape": s, "mode": m, "outcome": "SKIP", "passed": None, "checks": {}, "info": {"skip": "tool bootstrap failed: " + tool_environments.get(v, {}).get("error", "?")[-300:]}}) + jobs = [j for j in jobs if tool_environments.get(j[0], {}).get("ok")] + + def persist(): + save(root / "summary.json", { + "provenance": provenance, + "toolEnvironments": tool_environments, + "results": sorted(results, key=lambda r: (vtuple(r["pdm"]), r["shape"], r["mode"])), + "errors": errors, + }) + + persist() + with concurrent.futures.ThreadPoolExecutor(max_workers=args.jobs) as pool: + pending = {pool.submit(backtest, job): job for job in jobs} + for fut in concurrent.futures.as_completed(pending): + job = pending[fut] + try: + row = fut.result() + results.append(row) + failed = [k for k, ok in row["checks"].items() if not ok] + say(*job, row["outcome"], ",".join(failed), f"{row.get('durationSeconds', '?')}s") + except Exception as e: + err = {"pdm": job[0], "shape": job[1], "mode": job[2], "outcome": "ERROR", "error": str(e)[-3000:], "trace": traceback.format_exc()[-2000:]} + errors.append(err) + results.append({"pdm": job[0], "python": python_for(job[0]), "shape": job[1], "mode": job[2], "outcome": "ERROR", "passed": False, "checks": {}, "info": {"error": str(e)[-600:]}}) + say(*job, "ERROR", str(e)[-300:].replace("\n", " ")) + persist() + summary = json.loads((root / "summary.json").read_text(encoding="utf-8")) + (root / "summary.md").write_text(render_matrix(summary) + "\n\n" + render_details(summary) + "\n", encoding="utf-8") + say(render_matrix(summary)) + bad = [r for r in summary["results"] if r["outcome"] in ("FAIL", "ERROR")] + say(f"{len(summary['results'])} rows: " + ", ".join(f"{o} {sum(1 for r in summary['results'] if r['outcome'] == o)}" for o in ("PASS", "REFUSED-EXPECTED", "UNSUPPORTED", "SKIP", "FAIL", "ERROR"))) + if bad or errors: + sys.exit(1) + + +# -------------------------------------------------------------- rendering +CODES = {"PASS": "PASS", "FAIL": "FAIL", "REFUSED-EXPECTED": "REF", "UNSUPPORTED": "UNS", "SKIP": "SKIP", "ERROR": "ERR"} + + +def render_matrix(summary): + rows = summary["results"] + versions = sorted({r["pdm"] for r in rows}, key=vtuple) + shapes = [s for s in SHAPES if any(r["shape"] == s for r in rows)] + modes = [m for m in MODES if any(r["mode"] == m for r in rows)] + cols = [(s, m) for s in shapes for m in modes if any(r["shape"] == s and r["mode"] == m for r in rows)] + by = {(r["pdm"], r["shape"], r["mode"]): r for r in rows} + head = "| PDM | lock | " + " | ".join(f"{s}
{m}" for s, m in cols) + " |" + sep = "| --- | --- | " + " | ".join("---" for _ in cols) + " |" + lines = ["Cell legend: PASS, FAIL, REF = refused as expected (unsupported lock_version / expected no-op shape), UNS = layout the CLI cannot see (agent on `__pypackages__`), SKIP = shape not lockable on this release, ERR = harness error. Empty = not run.", "", head, sep] + for v in versions: + lock = next((r.get("lockVersion") for r in rows if r["pdm"] == v and r.get("lockVersion")), None) + cells = [] + for s, m in cols: + r = by.get((v, s, m)) + cells.append(CODES.get(r["outcome"], r["outcome"]) if r else "") + lines.append(f"| {v} | {lock or '—'} | " + " | ".join(cells) + " |") + return "\n".join(lines) + + +def render_details(summary): + rows = summary["results"] + lines = ["| PDM | shape | mode | outcome | failed checks | notes |", "| --- | --- | --- | --- | --- | --- |"] + for r in sorted(rows, key=lambda r: (vtuple(r["pdm"]), r["shape"], r["mode"])): + failed = ", ".join(k for k, ok in r.get("checks", {}).items() if not ok) + info = r.get("info", {}) + notes = [] + if r.get("expected"): + notes.append(r["expected"]) + if r.get("unexpected"): + notes.append("UNEXPECTED: " + r["unexpected"]) + if info.get("skip"): + notes.append(info["skip"][:160].replace("\n", " ")) + if info.get("error"): + notes.append("error: " + info["error"][-160:].replace("\n", " ")) + if "codes" in info and info["codes"]: + notes.append("codes=" + ",".join(str(c) for c in info["codes"])) + if "lockOnlyHosted" in info: + notes.append(f"lock-only hosted redirected={info['lockOnlyHosted'].get('redirected')}") + if "ordinaryInstall" in info: + o = info["ordinaryInstall"] + notes.append(f"pdm install exit {o.get('exit')} lockStable={o.get('lockStable')} baselineFresh={o.get('baselineFresh')} patched={info.get('ordinaryInstallPatched')}") + if info.get("manifestLeftover"): + notes.append(f"refusal left {len(info['manifestLeftover'])} manifest record(s); rollback exit {info.get('rollbackAfterRefusal', {}).get('exit')} cleared={info.get('rollbackAfterRefusal', {}).get('manifestCleared')}") + if "lockCheck" in info: + notes.append(f"lock --check exit {info['lockCheck'].get('exit')}") + if "tamper" in info: + notes.append(f"tamper install exit {info['tamper'].get('installExit')}") + if "relock" in info: + notes.append(f"relock exit {info['relock'].get('exit')} keepsPatch={info['relock'].get('keepsPatch')} rescanApplied={info.get('rescanAfterRelock', {}).get('applied')}") + rb1 = info.get("rollbackAfterRelockPristine") + if isinstance(rb1, dict) and rb1.get("failed"): + notes.append("rollback after relock: " + str(rb1["failed"][0].get("error", ""))[:140]) + if info.get("patchedOutsideProject"): + notes.append(f"agent patched the PATH interpreter instead ({','.join(info['patchedOutsideProject']['crawled'])}); rolled back exit {info.get('rollbackOutsideProject', {}).get('exit')}") + if "export" in info: + notes.append(f"export exit {info['export'].get('exit')} mentionsPatch={info['export'].get('mentionsPatchSource')}") + if "installedOrigin" in info and info["installedOrigin"]: + notes.append("installed in " + ("__pypackages__" if "__pypackages__" in info["installedOrigin"] else ".venv" if "/.venv/" in info["installedOrigin"] else info["installedOrigin"])) + lines.append(f"| {r['pdm']} | {r['shape']} | {r['mode']} | {r['outcome']} | {failed} | {'; '.join(notes)} |") + return "\n".join(lines) + + +def render_doc_table(summary): + """Per-PDM-version compatibility table for docs/testing/pdm-compatibility.md.""" + rows = summary["results"] + prov = summary.get("provenance", {}) + by = {} + for r in rows: + by.setdefault(r["pdm"], []).append(r) + lines = [] + if prov: + lines += [ + f"Run captured {prov.get('capturedAt', '?')[:10]} on {prov.get('platform', '?')} with socket-patch " + f"`{prov.get('cliVersion', '?')}` (source `{prov.get('cliRevision', '?')}`, binary sha256 `{prov.get('cliSha256', '?')}`), " + f"{len(by)} PDM releases, shapes: {', '.join(prov.get('shapes', []))}.", + "", + ] + lines += [ + "| PDM | Python | lock_version | hosted | vendored | agent | tamper rejected (H/V) | `pdm install` keeps lock (H/V) | relock keeps patch (H/V) | notes |", + "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |", + ] + + def cell(cases): + ran = [c for c in cases if c["outcome"] not in ("SKIP",)] + if not ran: + return "n/a" + refused = [c for c in ran if c["outcome"] == "REFUSED-EXPECTED" and c["shape"] not in EXPECTED_NOOP_SHAPES] + if refused and len(refused) == len([c for c in ran if c["shape"] not in EXPECTED_NOOP_SHAPES]): + return f"refused ({len(refused)} shapes)" + unsupported = [c for c in ran if c["outcome"] == "UNSUPPORTED"] + if unsupported and len(unsupported) == len(ran): + return f"unsupported layout ({len(ran)} shapes)" + ok = sum(1 for c in ran if c["outcome"] in ("PASS", "REFUSED-EXPECTED")) + return ("pass" if ok == len(ran) else f"{ok}/{len(ran)}") + f" ({len(ran)} shapes)" + + def flag(cases, key, sub): + vals = set() + for c in cases: + i = c.get("info", {}).get(key) + if isinstance(i, dict) and i.get(sub) is not None: + vals.add(i.get(sub)) + return "/".join(sorted(str(v).lower() for v in vals)) or "n/a" + + def tamper(cases): + vals = {("yes" if c["info"]["tamper"]["installExit"] != 0 else "no") for c in cases if "tamper" in c.get("info", {})} + return "/".join(sorted(vals)) or "n/a" + + def keeps_lock(cases): + vals = set() + for c in cases: + o = c.get("info", {}).get("ordinaryInstall") + if o: + vals.add("yes" if o.get("lockStable") else ("regenerated (stale by PDM's own check)" if o.get("baselineFresh") is False else "NO")) + return "/".join(sorted(vals)) or "n/a" + + for version in sorted(by, key=vtuple): + cs = by[version] + m = lambda mode: [c for c in cs if c["mode"] == mode] + hosted, vendored, agent = m("hosted"), m("vendored"), m("agent") + lock = next((c.get("lockVersion") for c in cs if c.get("lockVersion")), None) + py = next((c.get("python") for c in cs if c.get("python")), "") + notes = [] + if lock not in SUPPORTED_LOCK_VERSIONS: + notes.append(f"lock_version {lock or 'absent'} unsupported: refused before any write, native install intact" if any(c["outcome"] == "REFUSED-EXPECTED" for c in hosted + vendored) else f"lock_version {lock or 'absent'}") + if any(c["outcome"] == "UNSUPPORTED" for c in hosted + vendored + agent): + notes.append("`__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter)") + if any(c.get("info", {}).get("patchedOutsideProject") for c in agent): + notes.append("agent mode on a `__pypackages__` project patched the PATH interpreter's site-packages") + drift = [c for c in hosted + vendored if isinstance(c.get("info", {}).get("rollbackAfterRelockPristine"), dict) and c["info"]["rollbackAfterRelockPristine"].get("failed") and c["info"].get("rescanAfterRelock", {}).get("patchInLock")] + if drift: + notes.append("rollback after relock+re-scan fails (`" + ",".join(sorted({c["shape"] for c in drift})) + "`): the re-scan rewrote the lock but left the old ledger fragments, rollback reports drift") + dropped = [c for c in hosted + vendored if c.get("info", {}).get("relock", {}).get("targetKept") is False] + if dropped: + notes.append("relock dropped urllib3 1.26.18 (`" + ",".join(sorted({c["shape"] for c in dropped})) + "`: pinned resolution, no overrides on this release); re-scan then has nothing to redirect and rollback of the stale ledger exits " + "/".join(sorted({str(c["info"].get("rollbackAfterRelock", {}).get("exit")) for c in dropped}))) + if any(c.get("info", {}).get("manifestLeftover") for c in vendored): + notes.append("refused vendored scan still writes a `.socket/manifest.json` record") + relocked = [c for c in hosted + vendored if c.get("info", {}).get("ordinaryInstall", {}).get("lockStable") is False] + if relocked: + shapes_ = ",".join(sorted({c["shape"] for c in relocked})) + kept = sorted({str(c["info"].get("ordinaryInstallPatched")).lower() for c in relocked}) + stale = any(c.get("baselineFresh") is False for c in relocked) + notes.append( + f"`pdm install` re-locked ({shapes_}): " + + ("PDM's own freshness check flags its freshly generated lock as stale; " if stale else "") + + f"patched install afterwards={'/'.join(kept)}; use `pdm sync`" + ) + for c in hosted + vendored: + lo = c.get("info", {}).get("lockOnlyHosted") + if lo and lo.get("redirected") == 0 and c["shape"] == "direct" and c["mode"] == "hosted": + notes.append("lock-only checkout (nothing installed) is not redirected") + break + for c in hosted + vendored + agent: + if c["outcome"] in ("FAIL", "ERROR"): + failed = ", ".join(k for k, ok in c.get("checks", {}).items() if not ok) or c.get("info", {}).get("error", "")[-80:] + notes.append(f"{c['mode']}/{c['shape']} {c['outcome']}: {failed}") + if any(c.get("unexpected") for c in cs): + notes.append("UNEXPECTED: " + "; ".join(sorted({c["unexpected"] for c in cs if c.get("unexpected")}))) + def representative(cases): + direct = [c for c in cases if c["shape"] == "direct"] + return direct or [c for c in cases if "tamper" in c.get("info", {})] + + direct_h, direct_v = representative(hosted), representative(vendored) + lines.append( + f"| {version} | {py} | {lock or '—'} | {cell(hosted)} | {cell(vendored)} | {cell(agent)} | " + f"{tamper(direct_h)} / {tamper(direct_v)} | {keeps_lock(direct_h)} / {keeps_lock(direct_v)} | " + f"{flag(direct_h, 'relock', 'keepsPatch')} / {flag(direct_v, 'relock', 'keepsPatch')} | {'; '.join(dict.fromkeys(notes))} |" + ) + return "\n".join(lines) + + +if __name__ == "__main__": + main() From b9408d910bd2ed0aac36a7b48a36b822af0bcf11 Mon Sep 17 00:00:00 2001 From: Mikola Lysenko Date: Thu, 17 Sep 2026 20:29:41 -0400 Subject: [PATCH 3/3] Harden PDM patches: 14 correctness fixes from an adversarial review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A 12-finder review (42 confirmed findings) plus a real-PDM verification pass surfaced correctness gaps beyond the initial three. Fixes, each verified against real PDM binaries: Confirmation / attestation (false-success class): - Refuse a lock whose `strategy` lacks `inherit_metadata` (lock_version 4.4.1/4.5.x) — PDM 2.12-2.23 re-resolves such a lock and cannot match a rewritten `url`/`path` source (CandidateNotFound); read the 4.3 boolean strategy spelling (`cross_platform`/`static_urls`) that PDM 2.8-2.9 write. - A `pdm.lock` refusal now vetoes the sibling pypi rewriters only for a package the lock CONTAINS but refuses, never one it simply lacks (which a `requirements.txt`/pylock legitimately installs) — the old veto silently dropped those redirects. - An inactive `pdm.lock` (a `uv.lock`/`poetry.lock` drives) no longer feeds the substring confirmation probe, so an untouched uv/poetry project cannot report a bogus `redirected: 1`. - Emit `redirect_pdm_stale_install_risk` for PDM < 2.11 locks (2/4.3/4.4), which do not reinstall over an already-installed same-version package. - A marker/multi-target lock holding one package at several versions is refused with an accurate, ordering-independent message (hosted and vendored). Vendored integrity: - Refuse a symlinked `pdm.lock` before wire/revert (the rename-over would replace the link and strand its target) — mirrors the uv/hosted guards. - Require a real sha256 in the pre-flight hash guard so a non-sha256 lock is refused before the wheel is built. - Refuse a `pdm add`/partial-relock unit that kept the patched hash but lost the vendored `path`, so a stale patched hash is never recorded as the registry original. - Supersede a prior Socket-hosted `url` (rotated token / new uuid, same origin and wheel leaf) in place instead of refusing it as foreign. - Fix the version-mismatch refusal to print the plain version, not `Some("…")`. Fragments / keys: - Give the recorded package fragment a trailing boundary so a lock_version-2 pristine fragment is not a prefix of the rewritten one (replay convergence). - Key legacy `[metadata.files]` by PDM's `safe_name().lower()` (dots preserved), so dotted-name packages in format-2 locks are found. Docs: PDM 2.8.0 writes an indistinguishable `4.3` lock but shares the identity-loss bug, so the supported floor is 2.8.1; the docker vendored e2e awk counter now matches the inline `files` shape. Adds unit tests for the strategy gate, multi-version fork, URL supersede, dotted-name key, absent-package veto skip, stale advisory, symlink guard and the non-sha256 pre-flight refusal. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/pdm-compatibility.yml | 2 +- CHANGELOG.md | 4 +- .../src/commands/scan/hosted.rs | 12 + .../tests/docker_e2e_vendor_pypi_pm.rs | 2 +- .../src/patch/redirect/pdm.rs | 128 ++- .../socket-patch-core/src/utils/pdm_lock.rs | 242 +++++- .../socket-patch-core/src/vendor/pypi_pdm.rs | 194 ++++- docs/ecosystems.md | 2 +- docs/testing/pdm-compatibility.md | 10 +- docs/testing/pdm-compatibility/results.json | 732 +++++++++++++----- scripts/backtest-pdm.py | 27 +- 11 files changed, 1106 insertions(+), 249 deletions(-) diff --git a/.github/workflows/pdm-compatibility.yml b/.github/workflows/pdm-compatibility.yml index cdc38ef6..3732873e 100644 --- a/.github/workflows/pdm-compatibility.yml +++ b/.github/workflows/pdm-compatibility.yml @@ -61,7 +61,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 with: key: pdm-compat - run: cargo build --locked -p socket-patch-cli diff --git a/CHANGELOG.md b/CHANGELOG.md index c51af03a..ad24f5d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,7 +96,9 @@ into the new version's section — see docs/releasing.md. (`utils/pdm_lock.rs`). Both preserve line endings and non-canonical spacing, support the legacy `[metadata.files]` table and separate `extras` entries, are idempotent, and leave `pyproject.toml` and `content_hash` untouched. - Supported lock formats are `2` (PDM 0.12–1.4) and `4.3`–`4.5.1` (PDM 2.8+); + Supported lock formats are `2` (PDM 0.12–1.4) and `4.3`–`4.5.1` (PDM 2.8.1+; + PDM 2.8.0 writes the same `4.3` lock but still loses candidate identity, so + upgrade to ≥ 2.8.1); the identity-losing `3.1` / `4.0`–`4.2` formats (PDM 1.8–2.7) and unknown future formats are refused before any write (`redirect_pdm_refused` / `pypi_pdm_lock_version_unsupported`), leaving the registry lock installable. diff --git a/crates/socket-patch-cli/src/commands/scan/hosted.rs b/crates/socket-patch-cli/src/commands/scan/hosted.rs index 0b0e036b..03d6b768 100644 --- a/crates/socket-patch-cli/src/commands/scan/hosted.rs +++ b/crates/socket-patch-cli/src/commands/scan/hosted.rs @@ -1699,8 +1699,20 @@ pub(crate) async fn run_redirect_selected( // files — either written by this run or already present from an earlier // one. A granted reference whose rewriter found nothing to edit (e.g. no // lockfile) must NOT be recorded or attested: nothing pins the patch. + // A `pdm.lock` that is NOT the PyPI install driver (a `uv.lock` or + // `poetry.lock` sits beside it) is never rewritten this run, yet it can + // still carry a Socket artifact URL from an earlier run when pdm drove. + // That stale text pins nothing now, so it must not feed the substring + // confirmation probe below — otherwise an untouched uv/poetry project whose + // real lock was never redirected would report a bogus `redirected: 1` and + // persist a ledger record. When pdm DOES drive, pypi confirmation keys off + // `confirmed_pdm_uuids` and never consults this probe, so dropping the file + // here is always safe; `pdm.lock` only ever carries pypi URLs. + let pdm_inactive = files.contains_key("pdm.lock") + && (files.contains_key("uv.lock") || files.contains_key("poetry.lock")); let final_texts: Vec<&String> = files .iter() + .filter(|(name, _)| !(pdm_inactive && name.as_str() == "pdm.lock")) .map(|(name, content)| rewrite.files.get(name).unwrap_or(content)) .chain( rewrite diff --git a/crates/socket-patch-cli/tests/docker_e2e_vendor_pypi_pm.rs b/crates/socket-patch-cli/tests/docker_e2e_vendor_pypi_pm.rs index ef54f157..679901a0 100644 --- a/crates/socket-patch-cli/tests/docker_e2e_vendor_pypi_pm.rs +++ b/crates/socket-patch-cli/tests/docker_e2e_vendor_pypi_pm.rs @@ -278,7 +278,7 @@ grep -qF "path = \"./.socket/vendor/pypi/__UUID__/$WHEEL_NAME\"" pdm.lock \ || { cat pdm.lock >&2; fail "pdm.lock six entry has no relative path= to the vendored wheel"; } grep -qF "hash = \"sha256:$WHEEL_SHA\"" pdm.lock \ || { cat pdm.lock >&2; fail "pdm.lock files[] hash != vendored wheel sha256"; } -N=$(awk '/^name = "six"$/{f=1} f&&/^files = \[/{infiles=1;next} infiles&&/^\]/{infiles=0;f=0} infiles&&/file = /{c++} END{print c+0}' pdm.lock) +N=$(awk '/^name = "six"$/{f=1} f&&/files = \[/{infiles=1} infiles{c+=gsub(/file = /,"&")} infiles&&/\]/{infiles=0;f=0} END{print c+0}' pdm.lock) [ "$N" = "1" ] || { cat pdm.lock >&2; fail "six files[] has $N entries, expected exactly 1"; } # pyproject + content_hash are NEVER touched by the pdm lock-only splice. cmp -s pyproject.toml /workspace/snap/pyproject.prevendor \ diff --git a/crates/socket-patch-core/src/patch/redirect/pdm.rs b/crates/socket-patch-core/src/patch/redirect/pdm.rs index ffccc456..f8870bdc 100644 --- a/crates/socket-patch-core/src/patch/redirect/pdm.rs +++ b/crates/socket-patch-core/src/patch/redirect/pdm.rs @@ -3,6 +3,7 @@ use std::collections::BTreeMap; use serde_json::json; use super::{DepOverride, FileEdit, RewriteResult, RewriteWarning}; +use crate::crawlers::python_crawler::canonicalize_pypi_name; use crate::utils::pdm_lock::{pdm_lock_edits, rewrite_pdm_lock}; pub(super) fn rewrite( @@ -14,18 +15,56 @@ pub(super) fn rewrite( return; }; let mut text = original.clone(); + let mut stale_warned = false; for dep in overrides.iter().filter(|dep| dep.ecosystem == "pypi") { + // A package `pdm.lock` simply does not contain is not installed by pdm — + // a sibling `requirements.txt`/pylock may legitimately carry it — so we + // neither redirect it here nor veto the other pypi rewriters. Only a + // package the lock DOES contain but the plan refuses (source conflict, + // unsupported format, forked variants, bad hashes) withholds siblings. + if !lock_contains(&text, &dep.name) { + continue; + } match plan(&text, dep) { Ok((rewritten, edits)) => { result.confirmed_pdm_uuids.insert(dep.patch_uuid.clone()); - let lock = rewritten.parse::().ok(); - if lock - .as_ref() - .and_then(|lock| crate::utils::pdm_lock::lock_version(lock).ok()) - == Some("2") - { + let lock_ver: Option = rewritten + .parse::() + .ok() + .and_then(|lock| { + crate::utils::pdm_lock::lock_version(&lock) + .ok() + .map(str::to_string) + }); + if lock_ver.as_deref() == Some("2") { result.warnings.push(RewriteWarning { code: "redirect_pdm_legacy_sync_required".into(), detail: "PDM 0.x may regenerate freshly generated locks during install; use `pdm sync` to preserve this patch, or upgrade PDM".into() }); } + // PDM < 2.11 (lock_version "2"/"4.3"/"4.4") does not replace an + // already-installed package at the same version, so a warm + // `pdm sync`/`pdm install` leaves the upstream bytes live + // (measured: 1.4.5/2.9.3/2.10.4 keep them; 2.11+ reinstall). The + // installed-byte probe only fires for a discoverable venv, so a + // PEP 582 `__pypackages__` or a lock-only/CI scan gets no + // warning: warn proactively once per lock, mirroring poetry's + // `redirect_poetry_stale_install_risk`. + if !stale_warned + && matches!(lock_ver.as_deref(), Some("2") | Some("4.3") | Some("4.4")) + { + stale_warned = true; + result.warnings.push(RewriteWarning { + code: "redirect_pdm_stale_install_risk".into(), + detail: format!( + "pdm.lock (lock_version {}) was written by PDM < 2.11, which does \ + not replace an already-installed package at the same version: an \ + existing environment keeps the upstream {} until it is reinstalled \ + \u{2014} recreate the environment (or uninstall the package) before \ + `pdm sync`/`pdm install`; a fresh install picks up the patched \ + wheel. The installed files were left unchanged.", + lock_ver.as_deref().unwrap_or_default(), + dep.name + ), + }); + } text = rewritten; result.edits.extend(edits); } @@ -43,6 +82,30 @@ pub(super) fn rewrite( } } +/// Whether `pdm.lock` carries a `[[package]]` entry for `name`. When it does +/// not, pdm does not install this package, so the caller leaves it to the +/// sibling rewriters rather than vetoing them. A malformed lock, or one with no +/// package array, returns `true` so the genuine refusal still surfaces from +/// `rewrite_pdm_lock` (and, when pdm drives, withholds the siblings). +fn lock_contains(text: &str, name: &str) -> bool { + let Ok(lock) = text.parse::() else { + return true; + }; + let canon = canonicalize_pypi_name(name); + match lock + .get("package") + .and_then(toml_edit::Item::as_array_of_tables) + { + None => true, + Some(packages) => packages.iter().any(|package| { + package + .get("name") + .and_then(toml_edit::Item::as_str) + .is_some_and(|candidate| canonicalize_pypi_name(candidate) == canon) + }), + } +} + fn plan(text: &str, dep: &DepOverride) -> Result<(String, Vec), String> { let sha256 = dep .integrity @@ -126,4 +189,57 @@ mod tests { assert!(result.refused_pdm_uuids.contains(&dep().patch_uuid)); } } + + /// A package `pdm.lock` simply LACKS (a different dep is granted, or the + /// package installs via a sibling requirements.txt) is neither redirected + /// nor vetoed — the veto is reserved for packages the lock CONTAINS but + /// refuses, so a sibling rewriter can still land the patch. + #[test] + fn absent_package_is_skipped_not_vetoed() { + let original = include_str!("../../../tests/fixtures/pdm-native/2.29.2.lock"); + let other = DepOverride { + name: "left-pad".into(), + version: "1.3.0".into(), + patch_uuid: "11111111-1111-4111-8111-111111111111".into(), + ..dep() + }; + let mut result = RewriteResult::default(); + rewrite( + &BTreeMap::from([("pdm.lock".into(), original.to_string())]), + &[other.clone()], + &mut result, + ); + assert!( + result.refused_pdm_uuids.is_empty(), + "a package pdm.lock lacks must not veto the siblings" + ); + assert!(result.confirmed_pdm_uuids.is_empty()); + assert!(result.files.is_empty()); + } + + /// A lock_version 2 / 4.3 / 4.4 lock (PDM < 2.11) raises a proactive + /// stale-install advisory once, since those releases don't reinstall over + /// an already-installed same-version package. + #[test] + fn legacy_formats_warn_stale_install_risk_once() { + for (fixture, warns) in [ + (include_str!("../../../tests/fixtures/pdm-native/0.12.3.lock"), true), + (include_str!("../../../tests/fixtures/pdm-native/2.8.2.lock"), true), + (include_str!("../../../tests/fixtures/pdm-native/2.29.2.lock"), false), + ] { + let mut result = RewriteResult::default(); + rewrite( + &BTreeMap::from([("pdm.lock".into(), fixture.to_string())]), + &[dep()], + &mut result, + ); + assert!(result.confirmed_pdm_uuids.contains(&dep().patch_uuid)); + let n = result + .warnings + .iter() + .filter(|w| w.code == "redirect_pdm_stale_install_risk") + .count(); + assert_eq!(n, usize::from(warns), "stale advisory once for < 2.11 only"); + } + } } diff --git a/crates/socket-patch-core/src/utils/pdm_lock.rs b/crates/socket-patch-core/src/utils/pdm_lock.rs index a0cc2459..d2418909 100644 --- a/crates/socket-patch-core/src/utils/pdm_lock.rs +++ b/crates/socket-patch-core/src/utils/pdm_lock.rs @@ -18,10 +18,11 @@ pub fn lock_version(lock: &DocumentMut) -> Result<&str, String> { pub fn validate_strategy(lock: &DocumentMut) -> Result, String> { let mut result = Vec::new(); - if let Some(strategy) = lock - .get("metadata") - .and_then(|metadata| metadata.get("strategy")) - { + let Some(metadata) = lock.get("metadata") else { + return Ok(result); + }; + if let Some(strategy) = metadata.get("strategy") { + // lock_version >= 4.4: the strategy is an array of flag strings. for item in strategy.as_array().ok_or("invalid PDM strategy")? { let value = item.as_str().ok_or("invalid PDM strategy flag")?; if !matches!( @@ -32,12 +33,58 @@ pub fn validate_strategy(lock: &DocumentMut) -> Result, String> { } result.push(value.to_string()); } + } else { + // lock_version 4.3 (PDM 2.8-2.9) spells the strategy as `[metadata]` + // booleans instead of an array. Mirror PDM's own normalization so the + // flag set is recorded (and gated) identically to the array spelling. + for flag in ["cross_platform", "static_urls"] { + if let Some(item) = metadata.get(flag) { + if item.as_bool().ok_or("invalid PDM strategy flag")? { + result.push(flag.to_string()); + } + } + } + } + // A lock_version >= 4.4.1 without `inherit_metadata` (what `pdm lock + // --strategy no_inherit_metadata` writes) stores no per-package group or + // candidate metadata, so PDM ~2.12-2.23 re-resolves the lock at sync time + // and cannot match a package we rewrote to a `url`/`path` source + // (CandidateNotFound). Refuse rather than emit a lock that installs only on + // the exact PDM that wrote it. lock_version "4.4"/"4.3"/"2" predate the + // requirement (their default locks omit it) and stay allowed. + if matches!(lock_version(lock), Ok("4.4.1" | "4.5.0" | "4.5.1")) + && !result.iter().any(|flag| flag == "inherit_metadata") + { + return Err("PDM lock strategy lacks inherit_metadata; re-lock without \ + `--strategy no_inherit_metadata`" + .into()); } Ok(result) } +/// Mirror PDM's `safe_name(name).lower()`, which derives the legacy +/// `[metadata.files]` keys (lock_version "2", PDM 0.12-1.5). `safe_name` +/// collapses runs of characters outside `[A-Za-z0-9.]` to a single `-` but +/// PRESERVES dots — unlike PEP 503 canonicalization, which folds `.` into `-`. +/// So a dotted-name package such as `zope.interface` is keyed +/// `"zope.interface "`, not `"zope-interface "`. +fn pdm_files_key_name(name: &str) -> String { + let mut result = String::with_capacity(name.len()); + let mut in_separator_run = false; + for ch in name.chars() { + if ch.is_ascii_alphanumeric() || ch == '.' { + in_separator_run = false; + result.push(ch.to_ascii_lowercase()); + } else if !in_separator_run { + result.push('-'); + in_separator_run = true; + } + } + result +} + pub fn legacy_files_key(package: &Table) -> Option { - let name = canonicalize_pypi_name(package.get("name")?.as_str()?); + let name = pdm_files_key_name(package.get("name")?.as_str()?); let version = package.get("version")?.as_str()?; let mut extras: Vec<&str> = package .get("extras") @@ -71,6 +118,32 @@ pub fn wheel_matches(filename: &str, name: &str, version: &str) -> bool { && parts[1] == version } +/// Whether `existing` is an earlier hosted redirect of the SAME artifact: +/// same origin (`scheme://host[:port]`) and same trailing wheel filename as the +/// current artifact URL, fragments ignored. Grant tokens and patch uuids live +/// in the path between them, so a rotated token or a superseded patch (new +/// uuid) takes over the stale pin in place instead of being refused as a +/// foreign source (the poetry / bun rewriters make the same call). +fn is_prior_hosted_url(existing: &str, current: &str) -> bool { + fn origin_and_leaf(url: &str) -> Option<(&str, &str)> { + if !url.starts_with("https://") && !url.starts_with("http://") { + return None; + } + let url = url.split('#').next()?; + let scheme_end = url.find("://")? + 3; + let path_start = url[scheme_end..].find('/')? + scheme_end; + let leaf = url[path_start..] + .rsplit('/') + .next() + .filter(|leaf| !leaf.is_empty())?; + Some((&url[..path_start], leaf)) + } + match (origin_and_leaf(existing), origin_and_leaf(current)) { + (Some(old), Some(new)) => old == new, + _ => false, + } +} + pub fn rewrite_pdm_lock( text: &str, name: &str, @@ -112,6 +185,21 @@ pub fn rewrite_pdm_lock( if indices.is_empty() { return Err("missing PDM package".into()); } + // A marker/multi-target lock (PDM >= 2.17 `pdm lock --append`) can carry the + // same package at several versions, one per resolution fork. A single + // surgical rewrite would patch one fork and leave the others pinned to the + // registry, so refuse the whole lock ahead of the per-unit version check — + // the target version IS present, so the plain "version differs" below would + // misdirect the user to re-lock. + let locked_versions: std::collections::BTreeSet<&str> = indices + .iter() + .filter_map(|&index| packages.get(index)?.get("version").and_then(Item::as_str)) + .collect(); + if locked_versions.len() > 1 { + return Err("PDM lock resolves this package at multiple versions (a marker or \ + multi-target fork); patching one fork would leave the others unpatched" + .into()); + } let mut variants = std::collections::BTreeSet::new(); let mut edits = Vec::new(); for index in indices { @@ -133,7 +221,16 @@ pub fn rewrite_pdm_lock( "url", "path", "git", "hg", "svn", "bzr", "editable", "source", ] { if let Some(existing) = package.get(field) { - if field != kind || existing.as_str() != Some(location) { + let same_target = field == kind && existing.as_str() == Some(location); + // A prior socket-hosted `url` (rotated grant token or a + // superseded patch uuid — same origin and wheel leaf) is taken + // over in place; foreign urls and every other source refuse. + let prior_hosted = field == kind + && kind == "url" + && existing + .as_str() + .is_some_and(|existing| is_prior_hosted_url(existing, location)); + if !same_target && !prior_hosted { return Err(format!("refusing existing PDM {field} source")); } } @@ -191,6 +288,27 @@ pub fn rewrite_pdm_lock( Ok(result) } +/// End (exclusive, before its line break) of the first top-level TOML header +/// line at or after `from`, skipping blank/comment lines; `text.len()` at EOF; +/// `from` itself when the next non-blank line is not a header (a shape PDM never +/// writes — the fragment then ends where it used to). Kept local, like this +/// module's own `extend_span`. +fn next_header_end(text: &str, from: usize) -> usize { + let mut pos = from; + for line in text[from..].split_inclusive('\n') { + let content = line.trim_end_matches(['\r', '\n']); + if content.trim().is_empty() || content.trim_start().starts_with('#') { + pos += line.len(); + continue; + } + if content.starts_with('[') { + return pos + content.len(); + } + return from; + } + text.len() +} + pub fn pdm_lock_edits( original: &str, rewritten: &str, @@ -228,6 +346,14 @@ pub fn pdm_lock_edits( span.end += text[span.end..] .find(['\r', '\n']) .unwrap_or(text.len() - span.end); + // Carry the unit's BOUNDARY (blank line(s) after it plus the next + // top-level header, or EOF): the rewrite APPENDS `url` to the unit, + // so for a lock_version-2 unit — whose body carries no inline + // `files` to diverge — the pristine fragment would otherwise be a + // strict prefix of the rewritten one, and replay's "already + // converged" guard (`!new.contains(original)`) could never fire for + // a relocked lock. + span.end = next_header_end(text, span.end); result.push(text[span].to_string()); if !package.contains_key("files") { let key = legacy_files_key(package).ok_or("missing PDM files key")?; @@ -423,4 +549,108 @@ mod tests { ) .is_err()); } + + fn doc(text: &str) -> DocumentMut { + text.parse().unwrap() + } + + #[test] + fn strategy_boolean_spelling_and_inherit_metadata_gate() { + // lock_version 4.3 (PDM 2.8-2.9) spells strategy as [metadata] booleans. + assert_eq!( + validate_strategy(&doc(&fixture("2.8.2"))).unwrap(), + vec!["cross_platform".to_string()], + "4.3 booleans are read (static_urls=false is not recorded)" + ); + // 4.4 (2.10.4) default lock has no inherit_metadata and is still allowed. + assert!(validate_strategy(&doc(&fixture("2.10.4"))).is_ok()); + // A 4.5.0 lock whose strategy drops inherit_metadata (what + // `pdm lock --strategy no_inherit_metadata` writes) is refused — PDM + // re-resolves such a lock and cannot round-trip our url/path source. + let stripped = fixture("2.17.3").replace("[\"inherit_metadata\"]", "[\"cross_platform\"]"); + let err = validate_strategy(&doc(&stripped)).unwrap_err(); + assert!(err.contains("inherit_metadata"), "{err}"); + // The default 4.4.1/4.5.x locks keep inherit_metadata → allowed. + for v in ["2.11.2", "2.29.2"] { + assert!(validate_strategy(&doc(&fixture(v))).is_ok(), "{v}"); + } + } + + #[test] + fn multiple_locked_versions_refuse_as_a_fork() { + // A marker/multi-target lock holding urllib3 at two versions is refused + // ahead of the per-unit version check, with an accurate message. + let forked = format!( + "{}\n[[package]]\nname = \"urllib3\"\nversion = \"2.2.3\"\ngroups = [\"default\"]\nfiles = [\n {{file = \"urllib3-2.2.3-py3-none-any.whl\", hash = \"sha256:{}\"}},\n]\n", + fixture("2.29.2").trim_end(), + "b".repeat(64) + ); + let err = rewrite_pdm_lock( + &forked, + "urllib3", + "1.26.18", + ("path", PATH), + WHEEL, + &"a".repeat(64), + ) + .unwrap_err(); + assert!(err.contains("multiple versions"), "{err}"); + } + + #[test] + fn supersedes_a_prior_socket_hosted_url_in_place() { + let base = "https://patch.socket.dev/patch/pypi/urllib3/1.26.18"; + let stale = format!("{base}/OLDTOKEN/OLDUUID/{WHEEL}"); + let fresh = format!("{base}/NEWTOKEN/NEWUUID/{WHEEL}"); + // A lock already routing through an earlier Socket url (rotated token / + // new uuid, same origin + wheel leaf) is superseded, not refused. + let wired = rewrite_pdm_lock( + &fixture("2.29.2"), + "urllib3", + "1.26.18", + ("url", &stale), + WHEEL, + &"a".repeat(64), + ) + .unwrap(); + let rewired = rewrite_pdm_lock( + &wired, + "urllib3", + "1.26.18", + ("url", &fresh), + WHEEL, + &"a".repeat(64), + ) + .unwrap(); + assert!(rewired.contains(&fresh) && !rewired.contains(&stale), "{rewired}"); + // A foreign (non-Socket) existing url is still refused. + let foreign = fixture("2.29.2").replace( + "name = \"urllib3\"", + "name = \"urllib3\"\nurl = \"https://example.com/urllib3-1.26.18-py2.py3-none-any.whl\"", + ); + assert!(rewrite_pdm_lock( + &foreign, + "urllib3", + "1.26.18", + ("url", &fresh), + WHEEL, + &"a".repeat(64) + ) + .is_err()); + } + + #[test] + fn legacy_files_key_preserves_dotted_names() { + // PDM 0.12-1.5 key [metadata.files] with safe_name(name).lower(), which + // keeps dots — unlike PEP 503 canonicalization. + let table: Table = "name = \"Zope.Interface\"\nversion = \"6.0\"\n" + .parse::() + .unwrap() + .as_table() + .clone(); + assert_eq!( + legacy_files_key(&table).as_deref(), + Some("zope.interface 6.0") + ); + } } diff --git a/crates/socket-patch-core/src/vendor/pypi_pdm.rs b/crates/socket-patch-core/src/vendor/pypi_pdm.rs index 1355ce85..b3d89b28 100644 --- a/crates/socket-patch-core/src/vendor/pypi_pdm.rs +++ b/crates/socket-patch-core/src/vendor/pypi_pdm.rs @@ -21,6 +21,27 @@ const LOCK_FILE: &str = "pdm.lock"; /// The `WiringRecord.kind` discriminator this backend owns. const KIND_LOCK_PACKAGE: &str = "pdm_lock_package"; +/// Refuse when `pdm.lock` is itself a symlink. Every writer here stages a +/// replacement next to the path and renames over it, which REPLACES the link +/// with a detached regular file: the shared target the link points at stays +/// unpatched (git shows a 120000→100644 typechange), and `revert` restores +/// bytes but never the link. Both wire and revert check before any write — +/// mirroring the uv/pypi_lock vendored siblings and the hosted `first_symlink` +/// guard (pdm itself relocks THROUGH a linked pdm.lock). +async fn refuse_symlinked_lock(root: &Path) -> Result<(), (&'static str, String)> { + if crate::utils::fs::is_symlink(&root.join(LOCK_FILE)).await { + return Err(( + "pypi_pdm_symlink_unsupported", + format!( + "{LOCK_FILE} is a symbolic link; the atomic rewrite would replace the link with \ + a regular file and leave its target stale — vendor the real file's directory \ + instead" + ), + )); + } + Ok(()) +} + /// Guarded read shared in shape with the sibling backend twins: /// `open_regular_file` opens with `O_NONBLOCK` and rejects non-regular /// files, so a FIFO planted as `pdm.lock` (or the diagnostics-only @@ -201,6 +222,23 @@ pub(super) fn check_target_guards( format!("{LOCK_FILE} has no [[package]] entry for {canon_name}; run `pdm lock` first"), )); } + // A marker/multi-target lock (PDM >= 2.17 `pdm lock --append`) can resolve + // one package to several versions, one per fork. Detect it ahead of the + // per-unit version check so the refusal is accurate (the target version IS + // present) and ordering-independent. + let locked_versions: std::collections::BTreeSet<&str> = units + .iter() + .filter_map(|unit| unit.get("version").and_then(Item::as_str)) + .collect(); + if locked_versions.len() > 1 { + return Err(( + "pypi_pdm_lock_forked_package", + format!( + "{LOCK_FILE} resolves {canon_name} at multiple versions (a marker or \ + multi-target fork); vendoring one fork would leave the others unpatched" + ), + )); + } let mut variants = std::collections::BTreeSet::new(); let mut fresh = false; let mut in_sync = false; @@ -240,13 +278,11 @@ fn check_target_unit( version: &str, record_uuid: &str, ) -> Result { - if unit.get("version").and_then(Item::as_str) != Some(version) { + let locked_version = unit.get("version").and_then(Item::as_str).unwrap_or(""); + if locked_version != version { return Err(( "pypi_pdm_lock_package_missing", - format!( - "PDM locked version {:?} differs from installed {version}", - unit.get("version").and_then(Item::as_str) - ), + format!("PDM locked version {locked_version} differs from installed {version}"), )); } if ["url", "git", "hg", "svn", "bzr", "editable", "source"] @@ -297,9 +333,16 @@ fn check_target_unit( let hashed_entries = crate::utils::pdm_lock::files_for(&p.lock, unit) .map(|arr| { !arr.is_empty() - && arr - .iter() - .all(|v| v.as_inline_table().is_some_and(|t| t.contains_key("hash"))) + && arr.iter().all(|v| { + v.as_inline_table() + .and_then(|t| t.get("hash")) + .and_then(Value::as_str) + .is_some_and(|hash| { + hash.strip_prefix("sha256:").is_some_and(|hex| { + hex.len() == 64 && hex.bytes().all(|byte| byte.is_ascii_hexdigit()) + }) + }) + }) }) .unwrap_or(false); if !hashed_entries { @@ -315,6 +358,40 @@ fn check_target_unit( Ok(PdmTarget::Fresh) } +/// `true` when the target `[[package]]` unit's `files` already list THIS run's +/// patched wheel sha256. +/// +/// A `pdm add ` / partial relock on an already-vendored lock reuses the +/// stale `files` entry — which still carries our PATCHED wheel hash — while +/// dropping the vendored `path` source (measured on PDM 2.8–2.15, lock_version +/// 4.3/4.4/4.4.1: `pdm add` reuses pinned units verbatim, unlike a full +/// `pdm lock` which re-resolves the registry hashes). Sourceless and hashed, +/// that unit reads as [`PdmTarget::Fresh`], so a re-scan would rewrite it AND +/// record it as the pre-vendor `original`, baking the patched hash into the +/// ledger as the "registry" state — a later rollback then restores an +/// uninstallable lock and the true registry original is lost. A pristine +/// registry unit lists the REGISTRY hashes, never our patch's, so this cannot +/// false-positive on a genuinely fresh target. +fn target_carries_patched_wheel_hash( + lock: &DocumentMut, + canon_name: &str, + wheel_sha256_hex: &str, +) -> bool { + let needle = format!("sha256:{}", wheel_sha256_hex.to_ascii_lowercase()); + lock_units_named(lock, canon_name).into_iter().any(|unit| { + crate::utils::pdm_lock::files_for(lock, unit) + .map(|files| { + files.iter().any(|file| { + file.as_inline_table() + .and_then(|table| table.get("hash")) + .and_then(Value::as_str) + == Some(needle.as_str()) + }) + }) + .unwrap_or(false) + }) +} + /// Wire pdm.lock for the vendored wheel: rewrite ONLY the target /// `[[package]]` unit (the new text is fully computed before any write, then /// committed atomically). `rel_wheel` is the project-relative wheel path @@ -331,6 +408,8 @@ pub async fn wire_pdm( wheel_sha256_hex: &str, record_uuid: &str, ) -> Result<(Vec, PdmMeta), (&'static str, String)> { + // Before ANY write: a symlinked lock would be replaced by the rename-over. + refuse_symlinked_lock(root).await?; match check_target_guards(p, canon_name, version, record_uuid)? { // Defensive: the orchestrator short-circuits in-sync pre-flight and // never calls wire on it (we must never re-record our own edit as an @@ -347,6 +426,26 @@ pub async fn wire_pdm( PdmTarget::Fresh => {} } + // A `pdm add ` / partial relock drops our vendored `path` but reuses + // the stale `files` entry that still carries the patched wheel sha256 (PDM + // 2.8–2.15, lock_version 4.3/4.4/4.4.1). Sourceless + hashed, that unit + // reads as `Fresh`; rewriting it here would ALSO record it as the pre-vendor + // `original`, baking our patched hash into the ledger as the "registry" + // state — a later rollback would then restore an uninstallable lock and the + // true registry original would be lost. Refuse with the repair path (a full + // `pdm lock` re-resolves the registry hashes) so the ledger's real original + // survives untouched. + if target_carries_patched_wheel_hash(&p.lock, canon_name, wheel_sha256_hex) { + return Err(( + "pypi_pdm_source_already_exists", + format!( + "{LOCK_FILE}'s {canon_name} entry still carries this patch's wheel hash while PDM \ + dropped the vendored `path` (a `pdm add`/partial relock left an uninstallable \ + lock); run `pdm lock` to restore the registry hashes, then re-run vendor" + ), + )); + } + let new_lock = crate::utils::pdm_lock::rewrite_pdm_lock( &p.lock_text, canon_name, @@ -395,6 +494,18 @@ pub async fn wire_pdm( /// the shared fragment-splice revert (drift-tolerant, pdm.lock-only /// allowlist). pub async fn revert_pdm(entry: &VendorEntry, root: &Path, dry_run: bool) -> RevertOutcome { + // A symlinked lock would be replaced by the atomic rewrite-over, leaving + // its target stale and never restoring the link. Keep the artifact (the + // wiring still routes through the linked file) and fail — the guard lives + // here, not in the poetry-shared splice helper, so poetry is untouched. + if let Err((code, detail)) = refuse_symlinked_lock(root).await { + return RevertOutcome { + kept_artifact: true, + success: false, + warnings: Vec::new(), + error: Some(format!("{code}: {detail}")), + }; + } revert_lock_fragment_splice(entry, root, dry_run, LOCK_FILE, KIND_LOCK_PACKAGE, "pdm").await } @@ -1339,4 +1450,71 @@ distribution = false "drifted lock left alone" ); } + + /// A symlinked pdm.lock must be refused BEFORE any write: the atomic + /// rename-over would replace the link with a regular file and leave its + /// target stale, and revert would never restore the link. + #[cfg(unix)] + #[tokio::test] + async fn symlinked_lock_refuses_wire_and_revert_without_writing() { + let outer = tempfile::tempdir().unwrap(); + let real = outer.path().join("real.lock"); + tokio::fs::write(&real, LOCK_DIRECT_REGISTRY).await.unwrap(); + let root = outer.path().join("proj"); + tokio::fs::create_dir_all(&root).await.unwrap(); + tokio::fs::write(root.join("pyproject.toml"), PYPROJECT_DIRECT) + .await + .unwrap(); + std::os::unix::fs::symlink(&real, root.join("pdm.lock")).unwrap(); + + let p = load_pdm_project(&root).await.unwrap(); + let err = wire_pdm(&p, &root, "six", "1.16.0", REL_WHEEL, WHEEL_NAME, WHEEL_SHA, UUID) + .await + .unwrap_err(); + assert_eq!(err.0, "pypi_pdm_symlink_unsupported"); + // The link is intact and its target is byte-unchanged. + assert!(std::fs::symlink_metadata(root.join("pdm.lock")) + .unwrap() + .file_type() + .is_symlink()); + assert_eq!(read_lock(&root).await, LOCK_DIRECT_REGISTRY); + + // revert refuses the same way and keeps the artifact. + let meta = PdmMeta { + dep_class: "direct".into(), + lock_version: "4.5.0".into(), + strategy: vec!["inherit_metadata".into()], + }; + let wiring = vec![record( + LOCK_FILE, + KIND_LOCK_PACKAGE, + WiringAction::Rewritten, + "six", + Some("a".into()), + "b".into(), + )]; + let outcome = revert_pdm(&entry_for(wiring, meta), &root, false).await; + assert!(!outcome.success); + assert!(outcome.kept_artifact); + assert!( + outcome + .error + .as_deref() + .is_some_and(|e| e.contains("pypi_pdm_symlink_unsupported")), + "{:?}", + outcome.error + ); + } + + /// A pre-flight `files` entry whose hash is present but NOT a 64-hex + /// sha256 must be refused by the guard (before the wheel is built), not + /// only later by the rewriter. + #[tokio::test] + async fn non_sha256_hash_refused_by_preflight_guard() { + let lock = LOCK_DIRECT_REGISTRY.replace("sha256:", "md5:"); + let tmp = write_project(&lock, PYPROJECT_DIRECT).await; + let p = load_pdm_project(tmp.path()).await.unwrap(); + let err = check_target_guards(&p, "six", "1.16.0", UUID).unwrap_err(); + assert_eq!(err.0, "pypi_pdm_lock_no_hashes"); + } } diff --git a/docs/ecosystems.md b/docs/ecosystems.md index a30984d3..25a577b1 100644 --- a/docs/ecosystems.md +++ b/docs/ecosystems.md @@ -15,7 +15,7 @@ The backticked slug in each row is the value `-e`/`--ecosystems` accepts (e.g. | Ecosystem | agent (`--mode agent`) | vendored (`--mode vendored`) | hosted (`--mode hosted`) | |-----------|------------------------|------------------------------|--------------------------| | npm (`npm`) — pnpm / yarn / berry / bun | ✅ any install layout; `setup` postinstall hook | ✅ six lockfile flavors: package-lock, yarn classic, yarn berry (node-modules linker; PnP refused), pnpm v9, pnpm legacy v5.4/v6.0 (`pnpm 7/8` — frozen installs are path-bound because those majors absolutize `file:` override specifiers; moved checkouts run one `pnpm install --offline --no-frozen-lockfile`, surfaced as `vendor_pnpm_legacy_absolute_specifier`), bun `bun.lock` (binary `bun.lockb` refused with a `--save-text-lockfile` pointer). Rush monorepos refused (`vendor_rush_unsupported`) — see [Rush notes](#npm-rush-monorepos) | ✅ package-lock / npm-shrinkwrap, pnpm-lock.yaml and legacy shrinkwrap.yaml (pnpm majors 1–12; block and flow resolutions), yarn classic, yarn berry, bun — pnpm, berry, and bun carry constraints, see [npm hosted-mode notes](#npm-hosted-mode-notes) | -| PyPI (`pypi`) — uv / poetry / pdm / pipenv / pip | ✅ `.pth` startup hook via `setup` | ✅ uv project/script locks, PEP 751 `pylock.toml` / `pylock..toml`, poetry, pdm, pipenv (Pipenv 2018 or later — every `Pipfile.lock` category is rewired, lock-only checkouts included; Pipenv 2023+ does not hash-check local wheels — `vendor_integrity_unverified`; a venv still holding the upstream release is reported as `pypi_pipenv_stale_install`; see [Pipenv compatibility](testing/pipenv-compatibility.md)), and requirements.txt. Native uv vendoring requires uv ≥ 0.2.35 (the `[[package]]` lock grammar); hosted mode covers native `uv.lock` from uv 0.1.45 (the first release whose `uv lock` writes one) and requirements from uv 0.0.5; see [uv compatibility](testing/uv-compatibility.md). | ✅ requirements.txt including hash continuations, uv project/script locks, and PEP 751 locks. Version/source ambiguity is refused; see [uv compatibility](testing/uv-compatibility.md). Poetry 1.x and 2.x locks are supported; Poetry 0.x ignores URL sources and is refused. See [Poetry compatibility](testing/poetry-compatibility.md). Pipenv `Pipfile.lock` (pipfile-spec 6 — Pipenv 7 and later; `path` references for 7–11, `file` from 2018; lock-only checkouts and Pipenv's out-of-tree venv are discovered; a warm venv that Pipenv will not reinstall over warns `redirect_pypi_stale_install`; see [Pipenv compatibility](testing/pipenv-compatibility.md)). `pdm.lock` is supported for the lock formats PDM 0.12–1.4 and 2.8+ write (`lock_version` 2 / 4.3–4.5.1); the identity-losing 3.1 / 4.0–4.2 formats (PDM 1.8–2.7) are refused. See [PDM compatibility](testing/pdm-compatibility.md). | +| PyPI (`pypi`) — uv / poetry / pdm / pipenv / pip | ✅ `.pth` startup hook via `setup` | ✅ uv project/script locks, PEP 751 `pylock.toml` / `pylock..toml`, poetry, pdm, pipenv (Pipenv 2018 or later — every `Pipfile.lock` category is rewired, lock-only checkouts included; Pipenv 2023+ does not hash-check local wheels — `vendor_integrity_unverified`; a venv still holding the upstream release is reported as `pypi_pipenv_stale_install`; see [Pipenv compatibility](testing/pipenv-compatibility.md)), and requirements.txt. Native uv vendoring requires uv ≥ 0.2.35 (the `[[package]]` lock grammar); hosted mode covers native `uv.lock` from uv 0.1.45 (the first release whose `uv lock` writes one) and requirements from uv 0.0.5; see [uv compatibility](testing/uv-compatibility.md). | ✅ requirements.txt including hash continuations, uv project/script locks, and PEP 751 locks. Version/source ambiguity is refused; see [uv compatibility](testing/uv-compatibility.md). Poetry 1.x and 2.x locks are supported; Poetry 0.x ignores URL sources and is refused. See [Poetry compatibility](testing/poetry-compatibility.md). Pipenv `Pipfile.lock` (pipfile-spec 6 — Pipenv 7 and later; `path` references for 7–11, `file` from 2018; lock-only checkouts and Pipenv's out-of-tree venv are discovered; a warm venv that Pipenv will not reinstall over warns `redirect_pypi_stale_install`; see [Pipenv compatibility](testing/pipenv-compatibility.md)). `pdm.lock` is supported for the lock formats PDM 0.12–1.4 and 2.8.1+ write (`lock_version` 2 / 4.3–4.5.1); the identity-losing 3.1 / 4.0–4.2 formats (PDM 1.8–2.7) are refused. PDM 2.8.0 writes an indistinguishable `4.3` lock but shares that identity-loss bug, so a rewritten 2.8.0 lock crashes `pdm sync` — upgrade to ≥ 2.8.1. See [PDM compatibility](testing/pdm-compatibility.md). | | Cargo (`cargo`) | ✅ in-place + `.cargo-checksum.json` rewrite (shared registry-cache caveat — see [Cargo: shared registry cache](#cargo-shared-registry-cache)) | ✅ `[patch.crates-io]` path entry | ✅ per-patch sparse registry (`[registries.socket-patch-]` + Cargo.lock source/checksum) | | RubyGems (`gem`) | ✅ Bundler plugin via `setup` — needs bundler ≥ 2.2 (1.x cannot load `plugin ... path:` directives; `setup` refuses below the floor and `setup --check` red-flags a wired 1.x project) | ✅ Gemfile + Gemfile.lock path pair (`Gemfile` spelling only — a `gems.rb` project cannot vendor yet) | ✅ per-dep `source` block — edits `gems.rb` + `gems.locked` when present (bundler prefers them over `Gemfile`; spellings that diverge beyond Socket's own edits fail closed with `redirect_gem_gemfile_spellings_diverge`); the `CHECKSUMS` pin needs bundler ≥ 2.6 (older locks get a `redirect_gem_no_checksums_section` warning); a stale pre-redirect materialization that `bundle install` would reuse instead of refetching is flagged `redirect_gem_stale_install` with a prescriptive remedy (see CLI_CONTRACT.md's "Gem stale-install guard") | | Go (`golang`) | ✅ `go.mod` `replace` → `.socket/go-patches/` — see [Go: directory replaces and go.sum](#go-directory-replaces-and-gosum) | ✅ `replace` → the committed vendor tree | ✅ (free tier) fork-style `replace` → `patch.socket.dev/gopatch/` + committed `go.sum` pin; see [golang-hosted.md](design/golang-hosted.md). Paid tier stays ❌ ([golang-hosted-no-go.md](design/golang-hosted-no-go.md)); `redirect_golang_unsupported` names the vendored remedy | diff --git a/docs/testing/pdm-compatibility.md b/docs/testing/pdm-compatibility.md index 4bfd971b..8211792a 100644 --- a/docs/testing/pdm-compatibility.md +++ b/docs/testing/pdm-compatibility.md @@ -30,7 +30,8 @@ span-based edits, and produces byte-exact fragments for replay. The | PDM 0.12 – 1.4 | `2` | `url` + `files = [{file, hash}]` (or the legacy `[metadata.files]` entry). PDM 0.x/1.x has an upstream freshness bug — a freshly generated lock can fail its own hash check, so ordinary `pdm install` may regenerate it and discard the redirect. The CLI warns `redirect_pdm_legacy_sync_required`; use `pdm sync`. | Local-file `path` + `files` hash; same freshness advisory (`pypi_pdm_legacy_sync_required`). | | PDM 1.8 – 1.15 | `3.1` | **Refused** (`unsupported PDM lock_version`): native dependency lookup loses URL/path candidate identity before install, so a rewrite would not resolve. The original registry lock still installs. | Refused for the same reason. | | PDM 2.0 – 2.7 | `4.0` / `4.1` / `4.2` | **Refused** (same identity loss). | Refused. | -| PDM 2.8 – current | `4.3` / `4.4` / `4.4.1` / `4.5.0` / `4.5.1` | `url` + single `{file, hash}`; `static_urls` locks keep their `{url, hash}` file shape. | Local-file `path` + `{file, hash}`. | +| PDM 2.8.0 | `4.3` | **Accepted but not installable.** 2.8.0 writes the `4.3` grammar yet still loses `url`/`path` candidate identity (fixed in 2.8.1), so `pdm sync` on the rewritten lock crashes with `KeyError`. A 2.8.0 lock is byte-identical to a 2.8.1 lock and records no PDM version, so the rewriter cannot refuse it by format — upgrade to ≥ 2.8.1. | Same crash. | +| PDM 2.8.1 – current | `4.3` / `4.4` / `4.4.1` / `4.5.0` / `4.5.1` | `url` + single `{file, hash}`; `static_urls` locks keep their `{url, hash}` file shape. | Local-file `path` + `{file, hash}`. | | Any future `lock_version` | unknown | **Refused** until the format is tested (fail-closed). | Refused. | Both modes retain the package version, extras, groups, markers and the @@ -51,7 +52,8 @@ whose filename does not match the locked package. | 1.0 – 1.4 | 2 | supported | supported | supported | yes | as 0.12; 1.0 cannot self-install a dev-group project natively. | | 1.8 – 1.15 | 3.1 | refused | refused | supported | — | native install of the original registry lock is unaffected. | | 2.0 – 2.7 | 4.0–4.2 | refused | refused | supported | — | same identity-loss boundary. | -| 2.8 – current | 4.3–4.5.1 | supported | supported | supported | yes | `pdm sync` + `pdm install --check`; static_urls, extras, markers, multi-target and PEP 735 dependency-groups all pass. | +| 2.8.0 | 4.3 | crashes | crashes | supported | — | rewrite accepted but `pdm sync`/`pdm install` raise `KeyError` (identity loss, fixed in 2.8.1); agent mode is unaffected. Upgrade to ≥ 2.8.1. | +| 2.8.1 – current | 4.3–4.5.1 | supported | supported | supported | yes | `pdm sync` + `pdm install --check`; static_urls, extras, markers, multi-target and PEP 735 dependency-groups all pass. | Measured details: @@ -109,7 +111,7 @@ needs no Socket API token (the `urllib3@1.26.18` patch is a free tier). -Run captured 2026-09-17 on macOS-26.6.2-arm64-arm-64bit-Mach-O with socket-patch `socket-patch 4.0.0` (source `fixed`, binary sha256 `99a0977e83aad0d01371b41147104a123f7eaa8bfb3f85ac1b2dc64a5b6f093d`), 25 PDM releases, shapes: direct, transitive, dev, optional, extras, marker, marker-excluded, platform-linux, platform-windows, crlf, static-urls, space-unicode, dependency-groups, multi-target, two-versions, custom-lockfile, pep582. +Run captured 2026-09-18 on macOS-26.6.2-arm64-arm-64bit-Mach-O with socket-patch `socket-patch 4.0.0` (source `fixed2`, binary sha256 `b7ac2064ae2a466ab2d2bd74447ba1ae1f47b94943eab9a4310012fc253cac38`), 25 PDM releases, shapes: direct, transitive, dev, optional, extras, marker, marker-excluded, platform-linux, platform-windows, crlf, static-urls, space-unicode, dependency-groups, multi-target, two-versions, custom-lockfile, pep582. | PDM | Python | lock_version | hosted | vendored | agent | tamper rejected (H/V) | `pdm install` keeps lock (H/V) | relock keeps patch (H/V) | notes | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -127,7 +129,7 @@ Run captured 2026-09-17 on macOS-26.6.2-arm64-arm-64bit-Mach-O with socket-patch | 2.6.1 | 3.11 | 4.2 | refused (12 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version 4.2 unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | | 2.7.4 | 3.11 | 4.2 | refused (12 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | n/a / n/a | n/a / n/a | n/a / n/a | lock_version 4.2 unsupported: refused before any write, native install intact; `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record; lock-only checkout (nothing installed) is not redirected | | 2.8.2 | 3.11 | 4.3 | pass (13 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | -| 2.9.3 | 3.11 | 4.3 | pass (13 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | +| 2.9.3 | 3.11 | 4.3 | pass (13 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); agent mode on a `__pypackages__` project patched the PATH interpreter's site-packages; refused vendored scan still writes a `.socket/manifest.json` record | | 2.10.4 | 3.11 | 4.4 | pass (13 shapes) | 12/13 (13 shapes) | 8/9 (9 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | | 2.11.2 | 3.11 | 4.4.1 | pass (14 shapes) | 13/14 (14 shapes) | 9/10 (10 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | | 2.12.4 | 3.11 | 4.4.1 | pass (14 shapes) | 13/14 (14 shapes) | 9/10 (10 shapes) | yes / yes | yes / yes | false / false | `__pypackages__` layout: crawler does not see it (falls through to the PATH interpreter); refused vendored scan still writes a `.socket/manifest.json` record | diff --git a/docs/testing/pdm-compatibility/results.json b/docs/testing/pdm-compatibility/results.json index cd588ee9..e6a84ee2 100644 --- a/docs/testing/pdm-compatibility/results.json +++ b/docs/testing/pdm-compatibility/results.json @@ -1,9 +1,9 @@ { "provenance": { - "capturedAt": "2026-09-17T23:40:37.750526+00:00", - "cliPath": "/private/tmp/claude-501/-Users-mikolalysenko-Projects-socket-patch/9840a7e8-5cf9-4f42-8960-54a9c23b7cd7/scratchpad/socket-patch-fixed", - "cliRevision": "fixed", - "cliSha256": "99a0977e83aad0d01371b41147104a123f7eaa8bfb3f85ac1b2dc64a5b6f093d", + "capturedAt": "2026-09-18T00:43:22.692909+00:00", + "cliPath": "/private/tmp/claude-501/-Users-mikolalysenko-Projects-socket-patch/9840a7e8-5cf9-4f42-8960-54a9c23b7cd7/scratchpad/socket-patch-fixed2", + "cliRevision": "fixed2", + "cliSha256": "b7ac2064ae2a466ab2d2bd74447ba1ae1f47b94943eab9a4310012fc253cac38", "cliVersion": "socket-patch 4.0.0", "hostPython": "3.14.3", "modes": [ @@ -501,7 +501,7 @@ "mode": "agent", "outcome": "UNSUPPORTED", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "patchedOutsideProject": { @@ -517,7 +517,7 @@ ], "rollbackOutsideProject": { "exit": 0, - "rolledBack": 1 + "restored": true } } }, @@ -543,7 +543,7 @@ "mode": "vendored", "outcome": "UNSUPPORTED", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -815,7 +815,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -832,7 +833,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -846,6 +848,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -948,7 +951,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -965,7 +969,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -979,6 +984,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -1081,7 +1087,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -1098,7 +1105,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -1112,6 +1120,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -1214,7 +1223,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -1231,7 +1241,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -1245,6 +1256,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -1347,7 +1359,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -1364,7 +1377,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -1378,6 +1392,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -1458,6 +1473,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -1475,7 +1491,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -1489,6 +1506,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -1586,7 +1604,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -1603,7 +1622,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -1617,6 +1637,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -1679,7 +1700,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "2", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "patchedOutsideProject": { @@ -1695,7 +1716,7 @@ ], "rollbackOutsideProject": { "exit": 0, - "rolledBack": 1 + "restored": true } } }, @@ -1729,7 +1750,8 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -1746,7 +1768,8 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ] } }, @@ -1757,7 +1780,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "2", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -1793,6 +1816,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -1810,7 +1834,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -1824,6 +1849,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -1899,6 +1925,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -1916,7 +1943,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -1930,6 +1958,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -2027,7 +2056,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -2044,7 +2074,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -2058,6 +2089,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -2155,7 +2187,8 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -2173,7 +2206,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -2187,6 +2221,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "rollbackAfterRelock": { @@ -2297,7 +2332,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -2314,7 +2350,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -2328,6 +2365,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -2430,7 +2468,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -2447,7 +2486,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -2461,6 +2501,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -2563,7 +2604,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -2580,7 +2622,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -2594,6 +2637,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -2696,7 +2740,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -2713,7 +2758,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -2727,6 +2773,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -2829,7 +2876,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -2846,7 +2894,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -2860,6 +2909,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -2940,6 +2990,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -2957,7 +3008,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -2971,6 +3023,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -3068,7 +3121,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -3085,7 +3139,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -3099,6 +3154,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -3161,7 +3217,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "2", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "patchedOutsideProject": { @@ -3177,7 +3233,7 @@ ], "rollbackOutsideProject": { "exit": 0, - "rolledBack": 1 + "restored": true } } }, @@ -3211,7 +3267,8 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -3228,7 +3285,8 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ] } }, @@ -3239,7 +3297,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "2", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -3275,6 +3333,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -3292,7 +3351,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -3306,6 +3366,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -3381,6 +3442,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -3398,7 +3460,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -3412,6 +3475,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -3509,7 +3573,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -3526,7 +3591,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -3540,6 +3606,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -3637,7 +3704,8 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -3655,7 +3723,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -3669,6 +3738,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "rollbackAfterRelock": { @@ -3779,7 +3849,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -3796,7 +3867,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -3810,6 +3882,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -3912,7 +3985,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -3929,7 +4003,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -3943,6 +4018,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -4045,7 +4121,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -4062,7 +4139,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -4076,6 +4154,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -4178,7 +4257,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -4195,7 +4275,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -4209,6 +4290,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -4311,7 +4393,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -4328,7 +4411,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -4342,6 +4426,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -4422,6 +4507,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -4439,7 +4525,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -4453,6 +4540,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -4550,7 +4638,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -4567,7 +4656,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -4581,6 +4671,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -4643,7 +4734,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "2", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "patchedOutsideProject": { @@ -4660,7 +4751,7 @@ ], "rollbackOutsideProject": { "exit": 0, - "rolledBack": 2 + "restored": true } } }, @@ -4694,7 +4785,8 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -4711,7 +4803,8 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ] } }, @@ -4722,7 +4815,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "2", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -4758,6 +4851,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -4775,7 +4869,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -4789,6 +4884,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -4864,6 +4960,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -4881,7 +4978,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -4895,6 +4993,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -4992,7 +5091,8 @@ "rescanAfterRelock": { "applied": 1, "codes": [ - "redirect_pdm_legacy_sync_required" + "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -5009,7 +5109,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -5023,6 +5124,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -5120,7 +5222,8 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "exit": 0, "patchInLock": true @@ -5138,7 +5241,8 @@ "lockOnlyHosted": { "codes": [ "redirect_pdm_legacy_sync_required", - "redirect_pdm_refused" + "redirect_pdm_refused", + "redirect_pdm_stale_install_risk" ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18", @@ -5152,6 +5256,7 @@ "applied": 1, "codes": [ "redirect_pdm_legacy_sync_required", + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "rollbackAfterRelock": { @@ -5681,7 +5786,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "3.1", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "patchedOutsideProject": { @@ -5697,7 +5802,7 @@ ], "rollbackOutsideProject": { "exit": 0, - "rolledBack": 1 + "restored": true } } }, @@ -5725,7 +5830,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "3.1", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -6442,7 +6547,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "3.1", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "patchedOutsideProject": { @@ -6458,7 +6563,7 @@ ], "rollbackOutsideProject": { "exit": 0, - "rolledBack": 1 + "restored": true } } }, @@ -6486,7 +6591,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "3.1", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -7222,7 +7327,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "3.1", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -7255,7 +7360,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "3.1", "python": "3.8", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -7986,7 +8091,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.0", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -8019,7 +8124,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.0", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -8750,7 +8855,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.0", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -8783,7 +8888,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.0", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -9514,7 +9619,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.0", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -9547,7 +9652,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.0", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -10278,7 +10383,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.1", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -10311,7 +10416,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.1", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -11042,7 +11147,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.2", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -11075,7 +11180,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.2", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -11806,7 +11911,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.2", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -11839,7 +11944,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.2", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -12123,7 +12228,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -12137,7 +12244,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -12148,6 +12257,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -12289,7 +12399,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -12303,7 +12415,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -12314,6 +12428,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -12413,7 +12528,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -12427,7 +12544,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -12438,6 +12557,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -12537,7 +12657,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -12551,7 +12673,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -12562,6 +12686,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -12661,7 +12786,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -12675,7 +12802,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -12686,6 +12815,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -12763,6 +12893,7 @@ "rescanAfterRelock": { "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -12778,7 +12909,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -12789,6 +12922,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -12883,7 +13017,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -12897,7 +13033,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -12908,6 +13046,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -12968,7 +13107,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.3", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -13005,7 +13144,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -13019,7 +13160,9 @@ "targetKept": true }, "applied": 1, - "codes": [] + "codes": [ + "redirect_pdm_stale_install_risk" + ] } }, { @@ -13029,7 +13172,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.3", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -13063,6 +13206,7 @@ "rescanAfterRelock": { "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -13078,7 +13222,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -13089,6 +13235,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -13161,6 +13308,7 @@ "rescanAfterRelock": { "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -13176,7 +13324,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -13187,6 +13337,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -13281,7 +13432,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -13295,7 +13448,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -13306,6 +13461,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -13405,7 +13561,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -13419,7 +13577,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -13430,6 +13590,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -13529,7 +13690,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -13543,17 +13706,21 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], "exit": 0, - "lockfileOnlyPackages": 1, + "lockfileOnlyPackages": 0, "redirected": 1, - "scannedPackages": 43 + "scannedPackages": 45 }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -13619,11 +13786,13 @@ "info": { "lockOnlyHosted": { "codes": [], - "crawledUrllib3": [], + "crawledUrllib3": [ + "pkg:pypi/urllib3@1.26.18" + ], "exit": 0, "lockfileOnlyPackages": 0, "redirected": 0, - "scannedPackages": 42 + "scannedPackages": 45 }, "manifestLeftover": [], "applied": 0, @@ -13695,7 +13864,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -13709,17 +13880,21 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], "exit": 0, - "lockfileOnlyPackages": 1, + "lockfileOnlyPackages": 0, "redirected": 1, - "scannedPackages": 43 + "scannedPackages": 45 }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -13819,7 +13994,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -13833,17 +14010,21 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], "exit": 0, - "lockfileOnlyPackages": 1, + "lockfileOnlyPackages": 0, "redirected": 1, - "scannedPackages": 43 + "scannedPackages": 45 }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -13943,7 +14124,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -13957,17 +14140,21 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], "exit": 0, - "lockfileOnlyPackages": 2, + "lockfileOnlyPackages": 1, "redirected": 1, - "scannedPackages": 44 + "scannedPackages": 46 }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -14067,7 +14254,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -14081,17 +14270,21 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], "exit": 0, - "lockfileOnlyPackages": 1, + "lockfileOnlyPackages": 0, "redirected": 1, - "scannedPackages": 43 + "scannedPackages": 45 }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -14169,6 +14362,7 @@ "rescanAfterRelock": { "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -14184,17 +14378,21 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], "exit": 0, - "lockfileOnlyPackages": 1, + "lockfileOnlyPackages": 0, "redirected": 1, - "scannedPackages": 43 + "scannedPackages": 45 }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -14289,7 +14487,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -14303,17 +14503,21 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], "exit": 0, - "lockfileOnlyPackages": 1, + "lockfileOnlyPackages": 0, "redirected": 1, - "scannedPackages": 43 + "scannedPackages": 45 }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -14374,13 +14578,21 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.3", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { - "applied": 0, - "codes": [ - "package_not_installed" - ] + "patchedOutsideProject": { + "applied": 1, + "crawled": [ + "pkg:pypi/urllib3@1.26.18" + ] + }, + "applied": 1, + "codes": [], + "rollbackOutsideProject": { + "exit": 0, + "restored": true + } } }, { @@ -14411,7 +14623,10 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "exit": 0, "patchInLock": true }, @@ -14425,7 +14640,9 @@ "targetKept": true }, "applied": 1, - "codes": [] + "codes": [ + "redirect_pdm_stale_install_risk" + ] } }, { @@ -14435,14 +14652,23 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.3", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { - "applied": 0, + "patchedOutsideProject": { + "applied": 1, + "crawled": [ + "pkg:pypi/urllib3@1.26.18" + ] + }, + "applied": 1, "codes": [ - "package_not_installed", - "vendor_fetch_unverifiable" - ] + "vendor_prebuilt_downloaded" + ], + "rollbackOutsideProject": { + "exit": 0, + "restored": true + } } }, { @@ -14469,6 +14695,7 @@ "rescanAfterRelock": { "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -14484,17 +14711,21 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], "exit": 0, - "lockfileOnlyPackages": 1, + "lockfileOnlyPackages": 0, "redirected": 1, - "scannedPackages": 43 + "scannedPackages": 45 }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -14567,6 +14798,7 @@ "rescanAfterRelock": { "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -14582,17 +14814,21 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], "exit": 0, - "lockfileOnlyPackages": 1, + "lockfileOnlyPackages": 0, "redirected": 1, - "scannedPackages": 43 + "scannedPackages": 45 }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -14687,7 +14923,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -14701,17 +14939,21 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], "exit": 0, - "lockfileOnlyPackages": 1, + "lockfileOnlyPackages": 0, "redirected": 1, - "scannedPackages": 43 + "scannedPackages": 45 }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -14811,7 +15053,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -14825,17 +15069,21 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk", + "redirect_pypi_stale_install" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], "exit": 0, - "lockfileOnlyPackages": 5, + "lockfileOnlyPackages": 4, "redirected": 1, - "scannedPackages": 47 + "scannedPackages": 49 }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -14935,7 +15183,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -14949,7 +15199,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -14960,6 +15212,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -15101,7 +15354,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -15115,7 +15370,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -15126,6 +15383,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -15225,7 +15483,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -15239,7 +15499,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -15250,6 +15512,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -15349,7 +15612,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -15363,7 +15628,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -15374,6 +15641,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -15473,7 +15741,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -15487,7 +15757,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -15498,6 +15770,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -15575,6 +15848,7 @@ "rescanAfterRelock": { "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -15590,7 +15864,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -15601,6 +15877,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -15695,7 +15972,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -15709,7 +15988,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -15720,6 +16001,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -15780,7 +16062,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.4", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -15817,7 +16099,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -15831,7 +16115,9 @@ "targetKept": true }, "applied": 1, - "codes": [] + "codes": [ + "redirect_pdm_stale_install_risk" + ] } }, { @@ -15841,7 +16127,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.4", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -15875,6 +16161,7 @@ "rescanAfterRelock": { "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -15890,7 +16177,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -15901,6 +16190,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -15973,6 +16263,7 @@ "rescanAfterRelock": { "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ], "exit": 0, @@ -15988,7 +16279,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -15999,6 +16292,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -16093,7 +16387,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -16107,7 +16403,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -16118,6 +16416,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -16217,7 +16516,9 @@ }, "rescanAfterRelock": { "applied": 1, - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "exit": 0, "patchInLock": true }, @@ -16231,7 +16532,9 @@ "targetKept": true }, "lockOnlyHosted": { - "codes": [], + "codes": [ + "redirect_pdm_stale_install_risk" + ], "crawledUrllib3": [ "pkg:pypi/urllib3@1.26.18" ], @@ -16242,6 +16545,7 @@ }, "applied": 1, "codes": [ + "redirect_pdm_stale_install_risk", "redirect_pypi_stale_install" ] } @@ -17186,7 +17490,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.4.1", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -17247,7 +17551,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.4.1", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -18716,7 +19020,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.4.1", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -18777,7 +19081,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.4.1", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -20246,7 +20550,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.4.1", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -20307,7 +20611,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.4.1", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -21900,7 +22204,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.5.0", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -21961,7 +22265,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.5.0", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -23730,7 +24034,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.5.0", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -23791,7 +24095,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.5.0", "python": "3.11", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -26294,7 +26598,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.5.0", "python": "3.13", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -26355,7 +26659,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.5.0", "python": "3.13", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -28124,7 +28428,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.5.1", "python": "3.13", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, @@ -28185,7 +28489,7 @@ "outcome": "UNSUPPORTED", "lockVersion": "4.5.1", "python": "3.13", - "expected": "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)", + "expected": "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)", "baselineFresh": true, "info": { "applied": 0, diff --git a/scripts/backtest-pdm.py b/scripts/backtest-pdm.py index 42a62694..11181479 100644 --- a/scripts/backtest-pdm.py +++ b/scripts/backtest-pdm.py @@ -926,13 +926,26 @@ def uninstall(log): # the install) cannot serve this layout — with no venv the crawler # falls through to the `python` on PATH, which is NOT this # project's install. Documented `__pypackages__` limitation. - row["expected"] = "PDM `__pypackages__` layout: agent/vendored need a crawlable install (use hosted, or set `python.use_venv`)" - check("lockUnchanged", lock_after == pristine_lock) - if applied: - info["patchedOutsideProject"] = {"applied": applied, "crawled": crawled} - rb = Run(cli_cmd(project, "rollback"), project, cenv, case / "rollback.log", timeout=900) - info["rollbackOutsideProject"] = {"exit": rb.rc, "rolledBack": rb.json_or_empty().get("rolledBack")} - return finish("UNSUPPORTED" if checks["lockUnchanged"] else "FAIL") + row["expected"] = "PDM `__pypackages__` layout: agent/vendored cannot verify the install (use hosted, or set `python.use_venv`)" + if not applied: + # Refused / no-op (the common case): nothing was written. + check("lockUnchanged", lock_after == pristine_lock) + return finish("UNSUPPORTED" if checks["lockUnchanged"] else "FAIL") + # The CLI still wired/patched something despite the invisible + # `__pypackages__` layout — vendored via a prebuilt-wheel download, + # or agent patching the PATH interpreter. The install itself is + # unverifiable here, but whatever changed MUST be cleanly reversible + # and must not strand the project. + info["patchedOutsideProject"] = {"applied": applied, "crawled": crawled} + rb = Run(cli_cmd(project, "rollback"), project, cenv, case / "rollback.log", timeout=900) + restored = ( + rb.ok() + and (project / lockname).read_bytes() == pristine_lock + and (project / "pyproject.toml").read_bytes() == pristine_pyproject + ) + info["rollbackOutsideProject"] = {"exit": rb.rc, "restored": restored} + check("rollbackRestoresUnverifiableWrite", restored) + return finish("UNSUPPORTED" if restored else "FAIL") expected_refusal = mode != "agent" and (row["lockVersion"] not in SUPPORTED_LOCK_VERSIONS or shape in EXPECTED_NOOP_SHAPES) if expected_refusal: