diff --git a/Makefile b/Makefile index 0f4cccd..a927b27 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ lint: $(VENV)/pyvenv.cfg . $(VENV_BIN)/activate && \ ruff format --check $(ALL_PY_SRCS) && \ ruff check $(ALL_PY_SRCS) && \ - mypy + mypy src/ test/ . $(VENV_BIN)/activate && \ interrogate -c pyproject.toml . diff --git a/pyproject.toml b/pyproject.toml index e0bdaee..84f23d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,8 +34,10 @@ lint = [ "types-requests", "types-toml", "interrogate", + # linting relies on test deps, since we also typecheck our test suite + "pypi-attestations[test]", ] -dev = ["pypi-attestations[doc,test,lint]", "twine", "wheel", "build"] +dev = ["pypi-attestations[doc,test,lint]", "build"] [project.urls] @@ -54,6 +56,7 @@ omit = ["src/pypi_attestations/_cli.py", "src/pypi_attestations/__main__.py"] [tool.mypy] mypy_path = "src" packages = "pypi_attestations" +plugins = ["pydantic.mypy"] allow_redefinition = true check_untyped_defs = true disallow_incomplete_defs = true @@ -88,6 +91,7 @@ ignore = ["ANN101", "ANN102", "D203", "D213", "COM812", "ISC001"] "D", # no docstrings in tests "S101", # asserts are expected in tests "SLF001", # private APIs are expected in tests + "ANN401", # dynamic types are OK in tests ] [tool.interrogate] diff --git a/test/test_impl.py b/test/test_impl.py index 538df1c..5afe8f5 100644 --- a/test/test_impl.py +++ b/test/test_impl.py @@ -4,6 +4,7 @@ import os from hashlib import sha256 from pathlib import Path +from typing import Any import pretend import pypi_attestations._impl as impl @@ -75,7 +76,7 @@ def test_roundtrip(self, id_token: IdentityToken) -> None: def test_wrong_predicate_raises_exception(self, monkeypatch: pytest.MonkeyPatch) -> None: def dummy_predicate(self_: StatementBuilder, _: str) -> StatementBuilder: # wrong type here to have a validation error - self_._predicate_type = False + self_._predicate_type = False # type: ignore[assignment] return self_ monkeypatch.setattr(sigstore.dsse.StatementBuilder, "predicate_type", dummy_predicate) @@ -100,7 +101,7 @@ def in_validity_period(_: IdentityToken) -> bool: def test_multiple_signatures( self, id_token: IdentityToken, monkeypatch: pytest.MonkeyPatch ) -> None: - def get_bundle(*_) -> Bundle: # noqa: ANN002 + def get_bundle(*_: Any) -> Bundle: # Duplicate the signature to trigger a Conversion error bundle = Bundle.from_json(gh_signed_dist_bundle_path.read_bytes()) bundle._inner.dsse_envelope.signatures.append(bundle._inner.dsse_envelope.signatures[0]) @@ -468,7 +469,7 @@ def test_ultranormalize_dist_filename_invalid(input: str) -> None: class TestPublisher: def test_discriminator(self) -> None: gh_raw = {"kind": "GitHub", "repository": "foo/bar", "workflow": "publish.yml"} - gh = TypeAdapter(impl.Publisher).validate_python(gh_raw) + gh: impl.Publisher = TypeAdapter(impl.Publisher).validate_python(gh_raw) assert isinstance(gh, impl.GitHubPublisher) assert gh.repository == "foo/bar" @@ -476,7 +477,7 @@ def test_discriminator(self) -> None: assert TypeAdapter(impl.Publisher).validate_json(json.dumps(gh_raw)) == gh gl_raw = {"kind": "GitLab", "repository": "foo/bar/baz", "environment": "publish"} - gl = TypeAdapter(impl.Publisher).validate_python(gl_raw) + gl: impl.Publisher = TypeAdapter(impl.Publisher).validate_python(gl_raw) assert isinstance(gl, impl.GitLabPublisher) assert gl.repository == "foo/bar/baz" assert gl.environment == "publish" @@ -499,7 +500,7 @@ def test_claims(self) -> None: "this-too": 123, }, } - pub = TypeAdapter(impl.Publisher).validate_python(raw) + pub: impl.Publisher = TypeAdapter(impl.Publisher).validate_python(raw) assert pub.claims == { "this": "is-preserved",