Add missing hashes for mypy dep (#103)

Not sure what happened here but I verified the download URL below was
not in the previous hashes. To fix this I had to delete the hashes and
rerun update_requirements

```
===== stdout start =====
Collecting mypy==1.16.1 (from -r /var/folders/zr/s5f2x9jn50qc68n6416fgxym0000gn/T/tmpufjbqktw (line 1))
  Using cached mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl (10.1 MB)
===== stdout end =====
===== stderr start =====
ERROR: THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
    mypy==1.16.1 from https://files.pythonhosted.org/packages/e6/e5/26c347890efc6b757f4d5bb83f4a0cf5958b8cf49c938ac99b8b72b420a6/mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl (from -r /var/folders/zr/s5f2x9jn50qc68n6416fgxym0000gn/T/tmpufjbqktw (line 1)):
        Expected sha256 0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f
        Expected     or 0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15
        Expected     or 1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6
        Expected     or 13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383
        Expected     or 22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca
        Expected     or 2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4
        Expected     or 472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc
        Expected     or 4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee
        Expected     or 58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40
        Expected     or 86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72
        Expected     or d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be
        Expected     or dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd
        Expected     or ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea
        Expected     or ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d
             Got        66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9
```
1 file changed
tree: 49a992556472da57f953d23c0fa2bb28bc63f458
  1. .bcr/
  2. .github/
  3. .vscode/
  4. examples/
  5. mypy/
  6. .bazelignore
  7. .bazelrc
  8. .bazelversion
  9. .gitattributes
  10. .gitignore
  11. BUILD.bazel
  12. LICENSE
  13. MODULE.bazel
  14. readme.md
  15. WORKSPACE.bazel
readme.md

rules_mypy

An aspect to instrument py_* targets with mypy type-checking.

Compared to bazel-mypy-integration, this ruleset aims to make a couple of improvements:

  • Propagation of the mypy cache between dependencies within a repository to avoid exponential type-checking work
  • Robust (and automated) support for including 3rd party types/stubs packages

[!WARNING]
rules_mypy's build actions produce mypy caches as outputs, and these may contain large file counts and that will only grow as a dependency chain grows. This may have an impact on the size and usage of build and/or remote caches.

Usage

This aspect will run over any py_binary, py_library or py_test.

Setup is significantly easier with bzlmod, we recommend and predominantly support bzlmod, though these rules should work without issue in non-bzlmod setups, albeit with more work to configure.

Bzlmod Setup

Add rules_mypy to your MODULE.bazel:

bazel_dep(name = "rules_mypy", version = "0.0.0")

Optionally, configure a types repository:

Many Python packages have separately published types/stubs packages. While mypy (and these rules) will work without including these types, this ruleset provides some utilities for leveraging these types to improve mypy's type checking.

types = use_extension("@rules_mypy//mypy:types.bzl", "types")
types.requirements(
    name = "pip_types",
    # `@pip` in the next line corresponds to the `hub_name` when using
    # rules_python's `pip.parse(...)`.
    pip_requirements = "@pip//:requirements.bzl",
    # also legal to pass a `requirements.in` here
    requirements_txt = "//:requirements.txt",
)
use_repo(types, "pip_types")

Configure mypy_aspect.

Define a new aspect in a .bzl file (such as ./tools/aspects.bzl):

load("@pip_types//:types.bzl", "types")
load("@rules_mypy//mypy:mypy.bzl", "mypy")

mypy_aspect = mypy(types = types)

Update your .bazelrc to include this new aspect:

# register mypy_aspect with Bazel
build --aspects //tools:aspects.bzl%mypy_aspect

# optionally, default enable the mypy checks
build --output_groups=+mypy

Customizing mypy

Configuring mypy with mypy.ini

mypy's behavior may be customized using a mypy config file file. To use a mypy config file, pass a label for a valid config file to the mypy aspect factory:

mypy_aspect = mypy(
    mypy_ini = "@@//:mypy.ini",
    types = types,
)

[!NOTE] The label passed to mypy_ini needs to be absolute (a prefix of @@ means the root repo).

[!NOTE] mypy.ini files should likely contain the following lines to suppress type-checking 3rd party modules.

follow_imports = silent
follow_imports_for_stubs = True

Changing the version of mypy and/or including plugins

To customize the version of mypy, use rules_python's requirements resolution and construct a custom mypy CLI:

# in a BUILD file
load("@pip//:requirements.bzl", "requirements") # '@pip' must match configured pip hub_name
load("@rules_mypy//mypy:mypy.bzl", "mypy", "mypy_cli")

mypy_cli(
    name = "mypy_cli",
    mypy_requirement = requirement("mypy"),
)

And in your aspects.bzl (or similar) file:

load("@rules_mypy//mypy:mypy.bzl", "mypy")

mypy_aspect = mypy(
    mypy_cli = ":mypy_cli",
    types = types,
)

Further, to use mypy plugins referenced in any config file, use the deps attribute of mypy_cli:

# in a BUILD file
load("@pip//:requirements.bzl", "requirement") # '@pip' must match configured pip hub_name
load("@rules_mypy//mypy:mypy.bzl", "mypy", "mypy_cli")

mypy_cli(
    name = "mypy_cli",
    mypy_requirement = requirement("mypy"),
    deps = [
        requirement("pydantic"),
    ],
)

Skipping Targets

Skip running mypy on targets by tagging with no-mypy, or customize the tags that will suppress mypy by providing a list to the suppression_tags argument of the mypy aspect initializer:

load("@rules_mypy//mypy:mypy.bzl", "mypy")

mypy_aspect = mypy(
    suppression_tags = ["no-mypy", "no-checks"],
    types = types,
)

Running in opt-in mode

To add type checking to a codebase incrementally, configure a list of opt-in tags that will suppress running mypy by default unless a target is tagged explicitly with one of the opt-in tags.

load("@rules_mypy//mypy:mypy.bzl", "mypy")

mypy_aspect = mypy(
    opt_in_tags = ["typecheck"],
    types = types,
)