Maintenance/code cleanup 2026-05 Phase II (venv locator)#6665
Open
matteius wants to merge 18 commits into
Open
Maintenance/code cleanup 2026-05 Phase II (venv locator)#6665matteius wants to merge 18 commits into
matteius wants to merge 18 commits into
Conversation
…ocol Initiative F task T_F.2 (design): produces docs/dev/initiative-f-typed-design.md, a 719-line proposal for a versioned dataclass-based ResolverRequest / ResolverResponse pair that replaces the current ad-hoc argv + tempfile + env-var cocktail catalogued in T_F.1. Covers: envelope with schema_version, discriminated success / resolution- error / internal-error result, a single canonical LockedRequirement formatter that folds Entry.get_cleaned_dict and format_requirement_for_lockfile, migration strategy (one-shot rewrite, no backwards-compat shim per T_C.3 §9 / T_E.1 §6 sign-offs), test plan, and 10 numbered open questions for maintainer sign-off. Design only. No production code touched. Awaits maintainer sign-off before T_F.3 execution. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
T_F.2 (Initiative F typed-schema design) committed at 921212e. Status set to Completed; awaits maintainer sign-off before T_F.3 execution. Wave seed table gains a "4-design" row for T_F.2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s.py
T_E.3: Per the T_E.1 design + sign-off, move four single-line/short
helpers from pipenv/utils/requirementslib.py to pipenv/utils/dependencies.py
(the canonical home). merge_items brings its two private helpers
(_merge_into, _new_container_like) with it.
Moved:
is_vcs (~14 lines)
add_ssh_scheme_to_git_uri (~14 lines)
merge_items (~33 lines, + 2 private helpers)
get_pip_command (~9 lines)
Caller imports migrated in the same PR per T_C.3 sec.9 / T_E.1
sign-off -- no backwards-compat shim. Five caller files updated:
pipenv/utils/{locking,pipfile}.py (folded into the existing
dependencies-import block), pipenv/project.py (one-line late-import
in _get_vcs_packages, narrow-scoped), tests/unit/test_requirementslib.py
(docstring + import re-target), tests/unit/test_utils.py (the
test_is_vcs late import).
requirementslib.py shrank from 275 to 144 lines (-131). After T_E.3
only one in-tree importer of requirementslib remains
(dependencies.py for unpack_url); T_E.4 will close that out by
relocating the unpack_url/get_http_url fork pair to a new
pipenv/utils/unpack.py and deleting requirementslib.py.
Validation:
- tests/unit/test_dependencies_bridges.py: 31 tests pass (21 from
T_E.2 + 10 new for T_E.3: 4 import-shape pins, 1 source-cleared
sanity check, 5 light behaviour pins).
- All four moved symbols importable from pipenv.utils.dependencies;
no longer exist on pipenv.utils.requirementslib.
- The pipenv/project.py one-line import-line edit is intentionally
not staged in this commit; T_D.4 is concurrently rewriting that
file and will sweep up the import-line change as part of its
larger commit (same pattern as T_D.3 sweeping up T_E.2's
routines/install.py changes).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the full T_E.3 entry to docs/dev/modernization-plan.md following the T_E.2 format: status Completed, log of moved symbols + caller-migration summary, files-edited list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ema design Maintainer agreement on the proposed design plus an additional design constraint: the typed schema should not foreclose future pluggable resolver backends (uv being the obvious candidate) even though Initiative F itself stays pip-only. The change adds: - A new "out of scope" bullet in §2 calling out pluggable backends explicitly, with a pointer to the new §6a. - §6a "Future: pluggable resolver backends (informational; not in F)" documenting which design choices preserve the option (wire-type cleanliness, backend-neutral ResolverResult, package-layout reservation for pipenv/resolver/backends/) and which questions are intentionally left for a successor initiative (Pipfile opt-in shape, multi-backend selection, lockfile compatibility signalling, vendored-uv posture). - An anchor in §8 Q1 (schema home) to §6a, making the package-layout decision a load-bearing prerequisite for future pluggability. No code change. T_F.3 execution still gated on the maintainer answering the 10 sign-off questions in §8. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
T_D.4: Third extraction in Initiative D (after T_D.2 Sources and
T_D.3 Settings). The 13 VenvLocator-classified methods on
pipenv.project.Project move into a new pipenv.utils.venv_locator.VenvLocator
class accessed via the @cached_property on Project. Every internal
caller migrated to the new access path in the same PR (per T_D.1
§8.4 sign-off: no holding-pattern wrappers, no DeprecationWarning).
API rename (matches T_D.2 Sources pattern): the ``virtualenv_``
prefix drops because the subsystem itself is named ``venv_locator``:
project.virtualenv_location -> project.venv_locator.location
project.virtualenv_exists -> project.venv_locator.exists
project.virtualenv_name -> project.venv_locator.name
project.virtualenv_src_loc... -> project.venv_locator.src_location
project.virtualenv_scripts... -> project.venv_locator.scripts_location
project.download_location -> project.venv_locator.download_location
project.proper_names_db_path -> project.venv_locator.proper_names_db_path
project.is_venv_in_project() -> project.venv_locator.is_venv_in_project()
project.get_location_for_... -> project.venv_locator.get_location()
project.finders / .finder -> project.venv_locator.finders / .finder
project.which / .python -> project.venv_locator.which / .python
project._which -> project.venv_locator._which
The three __init__-set cache attrs (_virtualenv_location,
_download_location, _proper_names_db_path) moved to VenvLocator
instance state per the task spec. The private helpers _sanitize,
_get_virtualenv_hash, _pipfile_venv_in_project, _which moved with
their public counterparts. proper_names and register_proper_name
stayed on Project (Pipfile-bucket per T_D.1) but now read the
proper-names-db path through self.venv_locator.
Per T_D.1 §6.1 maintainer sign-off VenvLocator is read-only against
the venv (creation happens in pipenv/utils/virtualenv.py); no
Locator/Bootstrap split was needed.
pipenv/project.py shrinks by 245 net lines (1526 -> 1281). The
extracted methods + their docstrings live in pipenv/utils/venv_locator.py
(431 lines). Unused module-level imports purged from project.py:
base64, fnmatch, operator, re, find_windows_executable,
get_workon_home, is_virtual_environment, looks_like_dir,
system_which, virtualenv_scripts_dir.
Caller-site migration covers ~38 sites across pipenv/ and tests/:
pipenv/cli/command.py (6), pipenv/routines/{graph,install,lock,
shell,uninstall,update}.py (10), pipenv/utils/{pip,pipfile,project,
resolver,shell,virtualenv}.py (15), tests/integration/test_project.py
(1), tests/unit/{test_credential_safety,test_install_error_context,
test_utils}.py (mock-side migrations).
Behaviour-preserving: every VenvLocator method's logic is a
relocation. Same env-var precedence, same Pipfile reads, same
mkdir-on-access semantics, same finders caching shape (a per-
instance attribute on VenvLocator with the cached_property
on Project keeping VenvLocator alive for the process).
Tests: 17 new in tests/unit/test_venv_locator.py covering the
constructor, the @cached_property accessor, the env-var-vs-Pipfile
precedence for is_venv_in_project, the VIRTUAL_ENV short-circuit
in .location, location caching, mkdir-on-access for src/download/
proper-names-db, the PIPENV_CUSTOM_VENV_NAME and PIPENV_PYTHON
hooks in .name, and the which/_which fallback paths.
Full unit suite green: 677 passed, 9 skipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
T_D.4 (VenvLocator subsystem extraction) landed in commit cb34945. Updated the plan entry with status, the Option B naming-collision rationale (matches T_D.2 Sources pattern), the API-rename table, caller-migration summary, and the files-edited list. Initiative D progress: three of five subsystem extractions now complete (Sources T_D.2, Settings T_D.3, VenvLocator T_D.4). Remaining: Lockfile (T_D.5, blocked-on T_D.4 — now unblocked) and Pipfile (T_D.6, blocked-on T_D.5). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dependency-aware execution plan for the typed-schema migration designed
in docs/dev/initiative-f-typed-design.md. Single atomic PR target on
maintenance/code-cleanup-phase2-2026-05 (per maintainer 2026-05-12).
Plan organization:
Wave A (strict serial — A1 must commit golden JSON snapshots BEFORE
A2 moves pipenv/resolver.py; the snapshots are generated against
today's Entry.get_cleaned_dict + format_requirement_for_lockfile):
A1 — schema dataclasses + canonical formatter + golden snapshots
A2 — pipenv/resolver.py → pipenv/resolver/ package restructure
Wave B (3-way parallel on disjoint files):
B1 — subprocess entry rewrite; deletes Entry/process_resolver_results;
migrates the three test files that imported those symbols
B2 — parent-side rewrite, including the PIPENV_RESOLVER_PARENT_PYTHON
in-process branch (type migration, NOT fold — fold is T_F.4)
B3 — lockfile writer consumes LockedRequirement; deletes
format_requirement_for_lockfile; ports the 17
tests/unit/test_utils.py:1323-1538 pinning cases to the new API
(coverage count must not drop)
Wave C (4-way parallel test/doc):
C1 — schema-dataclass unit tests
C2 — JSON wire-shape integration test (incl. PIPENV_REGEN_PROTOCOL_FIXTURES branch)
C3 — comma-in-marker regression fixture
C4 — news/T_F.3.behavior.rst fragment
Wave D:
D1 — mark T_F.3 complete in modernization-plan.md
Plan reviewed by a subagent; 8 substantive gaps surfaced and resolved
in-place: stale test imports (test_dependencies, test_resolver_regressions,
test_locking_no_mutation), test_utils.py coverage port assignment,
in-process branch ownership disambiguation between B1/B2, golden-fixture
generation timing (A1 before A2), atomic-PR intermediate-commit caveat,
console-script reinstall note, fixture-regen mechanism, modernization-plan
single-writer guarantee.
T_F.3 execution remains gated on maintainer sign-off of the 10
§8 questions in initiative-f-typed-design.md. The plan assumes the
documented recommendations are accepted; any override revises specific
tasks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… and news fragment Three Copilot review findings on PR #6663: 1. **Sources.all could return None.** When a lockfile exists but ``_meta.sources`` is missing/empty, the if/else fell through with no explicit return — the implicit ``None`` would break callers (``default``, ``index_urls``, ``get_source``, ``find_source``) that expect a list. Inherited behaviour from the original ``Project.sources`` property, surfaced by Copilot now that the shape is documented as a List accessor. Always fall back to ``pipfile_sources()`` after the lockfile path declines to provide anything. 2. **Stale Python 3.7 reference in find_source.** Inline comment claimed the explicit iteration was needed "to stay compatible with Python 3.7" — pipenv has required ≥ 3.10 for some time. The short-circuit concern the comment described is also moot after #1 (``self.all`` no longer returns None), so the explicit-iteration pattern stands on its own without the misleading version note — dropped. 3. **News fragment mismatched reality.** The fragment described a deprecation-with-future-removal, but T_A.4 in this same PR removed the alias outright (commit 8554651). Rewrote the fragment to describe the actual change and the underlying "CLI is the stable API" rationale; also covers the parallel SourceNotFound re-export removal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ma module Add §3.6 to the typed-schema design and a Risk #9 to the execution plan: pipenv/resolver/schema.py runs inside the *target* venv's Python, not the parent pipenv's Python. The target Python is whatever the user's project virtualenv has — typically pipenv's minimum (currently CPython 3.10) through the latest. This drives several load-bearing discipline points that look like footnotes: - Stdlib idioms back to the minimum target: @DataClass(frozen=True) ✓, Optional/Sequence/Mapping from typing ✓; disallowed at module top: typing.Self (3.11+), tomllib (3.11+), 3.11+ match patterns, ANY new vendored dep, ANY pipenv.patched.pip._internal import. - The "no new vendor deps" rule is doubly load-bearing here: anything the schema imports at top level must be installable into every supported target venv. - Diagnostics.pip_version reports pipenv's vendored pip (pipenv.patched.pip._vendor.pip.__version__), not the user's pip. Document explicitly so future readers don't misread. - schema_version mismatch can fire in the legitimate-installs case where parent and subprocess come from different pipenv installs (e.g. global vs venv). - pip-internal types are accepted ONLY inside the body of LockedRequirement.from_install_requirement, never at module top. A1's validation step picks up an explicit "schema imports cleanly on the minimum target Python" check plus a grep gate for top-level pip-internal imports. CI's 3.10–3.14 matrix is the integration gate. This constraint was implicit in F.1's §3.2 invocation-path notes; T_F.2 makes it explicit because the typed-schema module is a new artifact that must survive the same execution environment. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR continues the “maintenance/code cleanup 2026-05 Phase II” work by extracting virtualenv discovery/path logic from Project into a dedicated VenvLocator subsystem, migrating call sites/tests to the new API surface, and relocating several dependency helper utilities from requirementslib.py into dependencies.py. It also updates internal dev documentation for Initiative D/E/F work.
Changes:
- Introduce
pipenv.utils.venv_locator.VenvLocatorand addProject.venv_locator(@cached_property), migrating call sites fromProject.virtualenv_*/Project._which()toproject.venv_locator.*. - Move
is_vcs,add_ssh_scheme_to_git_uri,merge_items, andget_pip_commandfrompipenv.utils.requirementslibintopipenv.utils.dependencies, updating imports and adding tests to pin the new import surface/behavior. - Add/adjust unit + integration tests and update modernization/typed-resolver design docs.
Reviewed changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_venv_locator.py | New unit tests pinning VenvLocator behavior and precedence/caching semantics. |
| tests/unit/test_utils.py | Update unit tests/mocks to use project.venv_locator.* and new helper import paths. |
| tests/unit/test_requirementslib.py | Retarget merge_items tests to pipenv.utils.dependencies. |
| tests/unit/test_install_error_context.py | Update test stubs to use project.venv_locator.src_location. |
| tests/unit/test_dependencies_bridges.py | Extend pinning tests for symbols moved into pipenv.utils.dependencies and removal from requirementslib. |
| tests/unit/test_credential_safety.py | Update fake project to expose venv_locator.src_location. |
| tests/integration/test_project.py | Update integration test assertion to use project.venv_locator.location. |
| pipenv/utils/virtualenv.py | Migrate venv path/existence calls to project.venv_locator.*. |
| pipenv/utils/venv_locator.py | New VenvLocator subsystem implementing venv resolution, naming, and executable lookup. |
| pipenv/utils/sources.py | Ensure Sources.all falls back to Pipfile sources when lockfile meta is empty/missing. |
| pipenv/utils/shell.py | Switch project_python() to call project.venv_locator._which("python"). |
| pipenv/utils/resolver.py | Migrate to project.venv_locator.src_location and project.venv_locator.python(...). |
| pipenv/utils/requirementslib.py | Remove moved helpers, leaving only the unpack_url/get_http_url fork and VCS_SCHEMES. |
| pipenv/utils/project.py | Migrate venv existence + python path resolution to project.venv_locator.*. |
| pipenv/utils/pipfile.py | Migrate venv checks and imports of is_vcs/merge_items to dependencies. |
| pipenv/utils/pip.py | Update default PIP_SRC fallback to project.venv_locator.src_location. |
| pipenv/utils/locking.py | Move is_vcs/merge_items imports to dependencies. |
| pipenv/utils/dependencies.py | Add moved helper functions and supporting imports (InstallCommand, is_valid_url). |
| pipenv/routines/update.py | Use project.venv_locator.python() and pass which=project.venv_locator._which. |
| pipenv/routines/uninstall.py | Use project.venv_locator._which and project.venv_locator.download_location. |
| pipenv/routines/shell.py | Use project.venv_locator.location for shell/run path wiring. |
| pipenv/routines/lock.py | Pass which=project.venv_locator._which to resolver. |
| pipenv/routines/install.py | Use project.venv_locator.exists and project.venv_locator._which. |
| pipenv/routines/graph.py | Use project.venv_locator.python() and project.venv_locator.exists. |
| pipenv/project.py | Remove venv-related methods/properties and add Project.venv_locator; route proper-names DB path via venv_locator. |
| pipenv/cli/command.py | Migrate --py, --rm, --venv, activation paths to project.venv_locator.*. |
| news/+initiative-a-is-valid-url.removal.rst | Update news fragment about removal of internal-only import alias(es). |
| docs/dev/modernization-plan.md | Mark T_D.4 as completed; document T_E.3 completion and add T_F.2 entry. |
| docs/dev/initiative-f-typed-design.md | New typed resolver subprocess protocol design document (T_F.2). |
| docs/dev/initiative-f-execution-plan.md | New execution plan document for implementing the typed resolver schema (T_F.3). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…Scripts Windows / Python 3.10 CI run 25744107117 on PR #6665 reproducibly fails test_multiple_editable_packages_should_not_race with: FileNotFoundError: [WinError 3] The system cannot find the path specified: 'C:\\Users\\runneradmin\\.virtualenvs\\pipenv-...\\Scripts' The traceback runs through `VenvLocator._get_virtualenv_hash`, which iterates `WORKON_HOME` and calls `is_virtual_environment(path)` on every child to detect case-collision conflicts. When a parallel test leaves a partially torn-down venv directory under WORKON_HOME — root exists, but `Scripts` (or `bin`) has been removed — `Path.glob` behaves differently per platform: - Unix: returns an empty iterator (the loop body simply doesn't run). - Windows: `scandir` is strict, so `Path.joinpath("Scripts").glob("python*")` raises `FileNotFoundError`, which bubbles all the way up and crashes `pipenv install` before resolution can start. Fix is a single `bindir.is_dir()` guard before iterating its glob. Resilient on both platforms; preserves existing semantics for real venvs (test added). Two new unit tests pin the behaviour: - `test_is_virtual_environment_returns_false_for_directory_without_bindir` — the bug repro: empty dir is not a venv, must not crash. - `test_is_virtual_environment_returns_true_for_real_venv_layout` — sanity: a bin/python layout still resolves to True. No skip marker added; the proper fix replaces the platform-specific workaround. 679 unit tests pass (was 677 baseline + 2 new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Agent-Logs-Url: https://github.com/pypa/pipenv/sessions/18303346-406f-45d2-bff4-984f606f3020 Co-authored-by: matteius <479892+matteius@users.noreply.github.com>
Agent-Logs-Url: https://github.com/pypa/pipenv/sessions/18303346-406f-45d2-bff4-984f606f3020 Co-authored-by: matteius <479892+matteius@users.noreply.github.com>
Agent-Logs-Url: https://github.com/pypa/pipenv/sessions/18303346-406f-45d2-bff4-984f606f3020 Co-authored-by: matteius <479892+matteius@users.noreply.github.com>
Agent-Logs-Url: https://github.com/pypa/pipenv/sessions/18303346-406f-45d2-bff4-984f606f3020 Co-authored-by: matteius <479892+matteius@users.noreply.github.com>
6 tasks
…-cleanup-phase2-2026-05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 2 of the pipenv maintenance-mode modernization stack. Bases on top of PR #6663 (Phase 1). Phase 3 and Phase 4 land as their own follow-up PRs (links below).
14 commits, +2602 / −514 across
pipenv/andtests/, plus three new design docs underdocs/dev/. Touches zero vendored or patched files. 679 unit tests pass (was 651 baseline at start of Phase 2 = +28 new).In this PR
T_D.4 —
VenvLocatorsubsystem extraction (Initiative D, continued)pipenv/utils/venv_locator.py(431 lines) holds the 13 venv-classified methods/properties extracted fromProject.pipenv/project.py: 1526 → 1281 lines (-245 net).Project.venv_locatoris a@cached_propertyreturning aVenvLocator(self)instance.virtualenv_prefix:project.virtualenv_location→project.venv_locator.location,project.virtualenv_name→project.venv_locator.name, etc. (same Sources/Settings cascade pattern as T_D.2 / T_D.3 in PR Maintenance/code cleanup 2026-05 Phase I (general base) #6663).tests/unit/test_venv_locator.py.T_E.3 — Continued requirement-model consolidation (Initiative E)
Four helpers moved from
pipenv/utils/requirementslib.py(the legacy-vendored module) topipenv/utils/dependencies.py(the canonical home):is_vcsadd_ssh_scheme_to_git_urimerge_items(+ private helpers_merge_into/_new_container_like)get_pip_commandrequirementslib.pyshrinks 275 → 144 lines (-131). After this PR it holds only theunpack_url/get_http_urlfork pair +VCS_SCHEMES, which T_E.4 (queued) will move next.T_F.2 — Typed resolver subprocess protocol DESIGN (Initiative F design phase)
Three new design docs (no code changes for the resolver itself yet — execution is on the phase-3 branch, see below):
docs/dev/initiative-f-typed-design.md(886 lines) — proposes the typedResolverRequest/ResolverResponseenvelope, the discriminatedResolverResultunion, the canonicalLockedRequirement.from_install_requirementformatter that will replace bothEntry.get_cleaned_dictandformat_requirement_for_lockfile, the §6a "future pluggable resolver backends" addendum, and the §3.6 target-Python execution constraint (the schema module must work under the target venv's Python, not the parent pipenv's). Resolves the 11 deferred decisions from F.1 and surfaces 10 sign-off questions for the maintainer.docs/dev/initiative-f-execution-plan.md(359 lines) — the swarm-ready dependency-aware execution plan for T_F.3 (reviewed by a subagent before publication; 8 substantive gaps resolved in-place).docs/dev/initiative-f-protocol.md(the current ad-hoc protocol catalogue) was added in PR Maintenance/code cleanup 2026-05 Phase I (general base) #6663.Standalone fixes (regressions surfaced during Phase 2)
d771de96—Sources.allcould returnNonewhen a lockfile existed but_meta.sourceswas missing/empty (fell through if/else with no explicit return). Inherited from the originalProject.sourcesproperty; surfaced by Copilot once the shape was documented as a list accessor. Always falls back topipfile_sources()now.6da42d9b—is_virtual_environment(path)was failing on Windows / Python 3.10 CI runs consistently. WhenWORKON_HOMEcontained a partially torn-down sibling venv directory — root exists butScripts/had been removed —Path.joinpath("Scripts").glob("python*")returned an empty iterator on Unix but raisedFileNotFoundErroron Windows (scandiris strict).VenvLocator._get_virtualenv_hashiteratesWORKON_HOMEand callsis_virtual_environmenton every child to detect case-collision conflicts, so a half-cleaned-up parallel-test artifact crashedpipenv installbefore resolution could start. Fixed with a one-linebindir.is_dir()guard before the glob; two pinning unit tests added.Sources.find_sourceremoved (pipenv requires ≥ 3.10).is_valid_urlremoval rather than a hypothetical deprecation.Stacked follow-up PRs (work already done; landing separately)
The remaining Initiative F work was completed but lives on sibling branches so each PR stays reviewable independently:
maintenance/code-cleanup-phase3-resolver-typed-schema-2026-05pipenv/resolver/package, deletesEntry.get_cleaned_dict+format_requirement_for_lockfile, drops 3 env-var hops + 5 dead argv flags, ports 17 test-coverage cases to typed equivalents, adds JSON wire-shape integration test withPIPENV_REGEN_PROTOCOL_FIXTURESregen branch, addsnews/T_F.3.behavior.rst. 17 commits, 758 unit tests pass.maintenance/code-cleanup-phase4-resolver-followups-2026-05resolve_for_pipenv(request)driver in newpipenv/resolver/core.py. T_F.5a — pluggable-backends design doc (948 lines, 10 sign-off questions queued including Pipfile opt-in shape, vendored-uv-vs-system, lockfile compatibility). T_F.6 — wall-clock timeout enforcement viarequest.metadata.deadline_seconds(subprocess:subprocess.run(timeout=...); in-process:signal.SIGALRMon Unix, no-op on Windows). T_F.7 — populateDiagnostics.resolver_logwith structured resolve records, surfaced in--verbosemode. 10 commits, 780 unit tests pass.Still-queued work (not started)
Lockfilesubsystem fromProject.Pipfilesubsystem fromProject(largest; most coupled).unpack_url/get_http_url; delete the (then-empty)requirementslib.py.docs/dev/initiative-f-backends-design.md(lives on phase-4 branch).Test plan
pytest tests/unit/)test_venv_locator.py(13),test_dependencies_bridges.py(4 for T_E.3),test_utils.py(2 for the Windows fix), and othersis_virtual_environmentFileNotFoundErrorfixed (was the only consistent CI failure on the prior runruns/25744107117)pipenv install,pipenv lock,pipenv updateon a representative fixture Pipfile🤖 Generated with Claude Code