Skip to content

Enable mypy type checking for pipenv's own code - #6745

Merged
matteius merged 1 commit into
mainfrom
mypy-type-checking
Oct 18, 2026
Merged

matteius merged 1 commit into
mainfrom
mypy-type-checking

Conversation

@matteius

Copy link
Copy Markdown
Member

Closes #5335.

What

  • Adds a mirrors-mypy (v2.4.0) pre-commit hook. CI's lint job already runs pre-commit run --all-files, so mypy now gates CI without a workflow change.
  • Updates the stale [tool.mypy] config. It was targeting Python 3.7, pointing at a typeshed/ dir that doesn't exist and generating an HTML report that needs lxml. It now targets 3.10, checks pipenv/, excludes pipenv/vendor/ and pipenv/patched/, and uses follow_imports = "skip" so imports into them aren't followed.
  • Vendored and patched packages are untouched.
  • Fixes all 201 existing errors across pipenv's 77 modules. Most fixes correct annotations or convert legacy # type: comments to inline annotations. Ruff doesn't count type comments as using an import, so they caused unused-import errors once the typing names were imported. # type: ignore is limited to code that's genuinely dynamic, such as the private _normalized_name/_path attributes on importlib.metadata distributions and the latest_version attribute set on them at runtime.

Small real fixes mypy surfaced

  • get_pip_args passed a bare src_dir string to list.extend, which would add one argument per character. It now produces ["--src", src_dir]. No caller passes it today.
  • Lockfile.from_data built a ProjectFile with a str location, which would break ProjectFile.write() (str has no .open). It now passes a Path.
  • Environment.is_satisfied and safe_import used pkg_resources APIs (.location, .has_metadata, .project_name, .activate) on stdlib distributions. Neither path can actually run, so this isn't a user-facing fix. In is_satisfied, the earlier req.specifier check always returns first. The safe_import fallback runs only when _modules[name] is falsy, which never happens. I switched the first to the importlib equivalents and removed the second.

Follow-ups (not in this PR)

Mypy still skips the bodies of functions with no annotations. Turning on check_untyped_defs to check them is the natural next step, best done one module at a time.

Testing

  • mypy: no issues in 77 source files
  • pre-commit run --all-files: all hooks pass
  • Unit: 1760 passed, 10 skipped
  • Integration: 250 passed. 15 failed locally, and the same 15 fail on main in this environment (local mirror/index fixtures), so this branch doesn't cause them.

🤖 Generated with Claude Code

Add a mirrors-mypy pre-commit hook (which also gates CI via the lint
job) and modernize the [tool.mypy] config: target Python 3.10, check
pipenv/, exclude pipenv/vendor and pipenv/patched, and skip following
imports into them.

Fix the 201 existing errors, mostly by correcting annotations and
converting legacy "# type:" comments to inline annotations. A few real
issues surfaced along the way:

- get_pip_args extended the arg list with a bare src_dir string (one
  arg per character); it now emits ["--src", src_dir]. No caller passes
  it today.
- Lockfile.from_data built ProjectFile with a str location, which
  would break ProjectFile.write(); it now passes a Path.
- Environment.is_satisfied and safe_import used pkg_resources APIs on
  importlib.metadata distributions in unreachable branches; switched to
  the importlib equivalents / removed the dead fallback.

Vendored and patched packages are untouched.

Closes #5335

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>


@overload
def add_ssh_scheme_to_git_uri(uri: str) -> str: ...
@overload
def add_ssh_scheme_to_git_uri(uri: str) -> str: ...
@overload
def add_ssh_scheme_to_git_uri(uri: bytes) -> bytes: ...
@overload
def add_ssh_scheme_to_git_uri(uri: bytes) -> bytes: ...
@overload
def add_ssh_scheme_to_git_uri(uri: None) -> None: ...
@matteius
matteius merged commit a0fdd62 into main Oct 18, 2026
28 checks passed
@matteius
matteius deleted the mypy-type-checking branch October 18, 2026 20:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Get mypy type checking enabled in pipenv

1 participant