Add a typechecker

How to add a new typechecker to the typecheck goal.

Adding a typechecker is almost identical to adding a linter, except for these differences:

  1. Subclass TypecheckRequest from pants.core.goals.typecheck, rather than LintRequest. Register a UnionRule(TypecheckRequest, CustomTypecheckerRequest).
  2. Return TypecheckResults in your rule—which is a collection of TypecheckResult objects—rather than returning LintResults. Both types are defined in pants.core.goals.typecheck.

The rule will look like this:

from dataclasses import dataclass

from pants.core.goals.typecheck import TypecheckRequest, TypecheckResult, TypecheckResults
from pants.engine.target import FieldSet
from pants.engine.rules import collect_rules, rule
from pants.engine.unions import UnionRule
from pants.util.logging import LogLevel


@dataclass(frozen=True)
class MyPyFieldSet(FieldSet):
    required_fields = (PythonSources,)

    sources: PythonSources


class MyPyRequest(TypecheckRequest):
    field_set_type = MyPyFieldSet


@rule(desc="Typecheck using MyPy", level=LogLevel.DEBUG)
async def mypy_typecheck(request: MyPyRequest, mypy: MyPy) -> TypecheckResults:
    if mypy.skip:
        return TypecheckResults([], typechecker_name="MyPy")
    ...
    return TypecheckResults(
        [TypecheckResult.from_fallible_process_result(result)], typechecker_name="MyPy"
    )

def rules():
    return [*collect_rules(), UnionRule(TypecheckRequest, MyPyRequest)]

Refer to Add a linter. See pants/backend/python/typecheck/mypy/rules.py for an example of MyPy.


Did this page help you?