Skip to content

Enforce type checking in CI: py.typed is shipped but never verified #16

Description

@Panadestein

What is going on

Three things are inconsistent, which is why this looks confusing:

  1. The package advertises inline type information. src/src_method/py.typed
    exists and pyproject.toml declares the Typing :: Typed classifier. Both
    are a promise to downstream users that they can type-check their code
    against our annotations (PEP 561).

  2. Nothing verifies that promise. No type checker runs in CI, in
    pre-commit, or anywhere else.

  3. There is a leftover config for a checker that is never invoked.
    pyproject.toml contains a 20-line [tool.pyright] block — inherited from
    the project template — but pyright is not in any dependency group and is
    never executed. It is dead configuration that makes it look like type
    checking is covered when it is not.

So we ship a typing guarantee we do not test. If an annotation drifts out of
sync with the implementation, nobody finds out; the downstream user does.

Good news

I ran a checker against the package as it stands and it is essentially already
clean:

$ uvx ty check src/
error[unresolved-import]: Cannot resolve imported module `cupy`
  --> src/src_method/utils/_backend.py:37
Found 1 diagnostic

The single diagnostic is the deliberately lazy, optional cupy import. So
enforcing this is cheap — it is a matter of wiring, not of fixing a backlog.

Proposed fix

Use the modern Astral toolchain, consistent with the uv + ruff setup
already in place:

  • Adopt ty as the type checker and add it
    to the dev dependency group.
  • Replace the dead [tool.pyright] block with a [tool.ty] section:
    target Python 3.11, check src/, and silence the optional cupy import
    (via an ignore rule or a TYPE_CHECKING stub) rather than leaving a real
    error in the baseline.
  • Add a ty check step to the lint workflow and to .pre-commit-config.yaml
    so it gates pull requests.
  • Tighten the annotations that are currently loose while we are here:
    dtype: type should be numpy.typing.DTypeLike, and the bare NDArray in
    utils/linalg.py should carry its generic parameter.

One caveat worth stating openly: ty is pre-1.0 and still moving. If we would
rather have stability than novelty, mypy is the conservative choice and the
rest of this issue is unchanged. Either is better than the current situation.

Acceptance criteria

  • A type checker runs in CI and fails the build on new type errors.
  • The dead [tool.pyright] block is gone.
  • The optional cupy import is handled without leaving an error in the baseline.
  • dtype and NDArray annotations are precise.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions