Skip to main content

pants-pyrefly

A Pants plugin that runs Pyrefly — Meta's fast, Rust-based Python type checker — as part of the Pants check goal.

Pants downloads the official prebuilt Pyrefly binary (pinned by SHA256) and runs it hermetically in a sandbox, wiring up your first-party source roots and the resolved third-party dependencies so that imports resolve correctly.

Requirements

  • Pants 2.27–2.32. A single codebase supports both the legacy (Get/MultiGet-era) and modern (call-by-name) rules APIs via a small version-conditional import; verified on 2.27 and 2.32.
  • The published wheel is pure-Python — Requires-Python: >=3.11, with no pantsbuild.pants dependency (Pants provides itself at runtime) — so a single release installs into any supported Pants, from 2.27 (CPython 3.11) through 2.32 (CPython 3.14).

Installation

Add the plugin and enable its backend in pants.toml:

[GLOBAL]
plugins = ["pants-pyrefly==0.2.0"]
backend_packages.add = [
    "pants.backend.python",
    "pants_pyrefly",
]

From source (in-repo)

Prefer to vendor the plugin — for rapid iteration, or to pin to an exact source state? Consume it the way in-repo plugins are normally loaded: copy pants-plugins/pants_pyrefly/ into your repo and:

[GLOBAL]
pythonpath = ["%(buildroot)s/pants-plugins"]
backend_packages.add = ["pants.backend.python", "pants_pyrefly"]

If you keep plugin code in a dedicated pants-plugins resolve, add it there and run pants generate-lockfiles.

Usage

pants check ::                 # type-check everything
pants check path/to/dir::      # type-check a subtree

Configuration

[pyrefly] subsystem options:

Option Env / flag Description
skip --pyrefly-skip / PANTS_PYREFLY_SKIP Don't run Pyrefly during check.
args --pyrefly-args Extra args passed to Pyrefly, e.g. --pyrefly-args='--python-version 3.12'.
extra_type_stubs --pyrefly-extra-type-stubs Stub-only packages to add to the type-check environment without making them runtime deps, e.g. types-requests, sqlalchemy2-stubs==0.0.2a38. Resolved directly, so pin versions for reproducibility.
output_format --pyrefly-output-format Override Pyrefly's output format: min-text, full-text, json, github, junit-xml, omit-errors.
min_severity --pyrefly-min-severity Only show errors at/above this severity (ignore/info/warn/error).
only --pyrefly-only Only report these error kinds (e.g. bad-assignment); handy for triage.
config --pyrefly-config Path to a pyrefly.toml / pyproject.toml (disables discovery).
config_discovery --[no-]pyrefly-config-discovery Auto-discover pyrefly.toml / [tool.pyrefly].
baseline --pyrefly-baseline Path to a Pyrefly baseline JSON; check then reports only errors new since the baseline. Generate it with pants pyrefly-update-baseline.
version / known_versions / url_template (advanced) Pin or override the downloaded Pyrefly binary.

Opt a target out of Pyrefly:

python_sources(skip_pyrefly=True)

Incremental adoption (baseline)

Adopting Pyrefly on a codebase that already has type errors? Record them in a baseline so check only fails on new errors:

pants pyrefly-update-baseline ::   # writes the file named by [pyrefly].baseline
pants check ::                     # now reports only errors introduced since the baseline

Configure the path (and commit the baseline file):

[pyrefly]
baseline = "build-support/pyrefly-baseline.json"

Re-run pants pyrefly-update-baseline after fixing errors, or to refresh it. Baseline matching is Pyrefly's own (lenient by design, so it survives code churn).

Prefer inline suppressions? pants pyrefly-suppress :: instead rewrites the targeted files in place, adding # pyrefly: ignore on each current error (Pyrefly's suppress); delete them as you fix, or run pants pyrefly-suppress --pyrefly-suppress-remove-unused :: to strip stale ones. An external baseline (JSON) and inline suppressions are two strategies for the same goal — pick one.

Migrating from MyPy

Moving a Pants repo off MyPy? See docs/migrating-from-mypy.md — config conversion (pyrefly init --migrate-from mypy), running both checkers during the transition, baseline-based incremental adoption, and the MyPy-plugin gap (SQLAlchemy et al.).

Editor / IDE (LSP)

Pyrefly ships an LSP server, but in a Pants repo your editor doesn't know the source roots. Generate a pyrefly.toml with them:

pants pyrefly-lsp-config        # writes search-path (= your source roots) + python-version

For third-party imports, point your editor's interpreter at a venv (e.g. pants export --resolve=python-default). If your Pyrefly config lives in pyproject.toml [tool.pyrefly], the goal prints the keys to add instead of writing a shadowing pyrefly.toml.

Type coverage

Track typing progress — useful as a migration ratchet:

pants pyrefly-coverage ::                                    # prints overall % typed
pants pyrefly-coverage --pyrefly-coverage-fail-under=80 ::   # also fails if below 80%

How import resolution works

  • First-party code: every source root is passed to Pyrefly via --search-path (the analogue of MYPYPATH / sys.path).
  • Third-party deps: Pants materializes the target's resolved requirements into a venv and points Pyrefly's --python-interpreter-path at it, so Pyrefly discovers site-packages and the target Python version exactly as import would at runtime.

Pants compatibility

Plugin version Pants Pyrefly (default)
0.2.0 2.272.32 1.1.1
0.1.0 2.272.32 1.1.1

The plugin supports both the legacy (Get/MultiGet) and modern (call-by-name) rules APIs through a small version-conditional import (the rules API changed at Pants 2.30, and again removed Get by 2.32). Verified on 2.27 and 2.32; in-between versions use the same modern API.

Development

This repo dogfoods its own tooling: ruff (lint + format) and Pyrefly itself (check) run on the plugin's sources.

pants generate-lockfiles          # pants-plugins + python-default resolves
pants fmt lint ::                 # ruff format + check
pants check ::                    # Pyrefly type-checks the plugin (dogfood) + testprojects/
pants test ::                     # run the integration tests
pants package pants-plugins/pants_pyrefly:dist   # build the wheel + sdist into dist/

Releasing

Push a vX.Y.Z tag. The release workflow builds the wheel and publishes it to PyPI using Trusted Publishing (OIDC, no API tokens). Configure a PyPI trusted publisher for this repo + the release.yml workflow first.

License

Apache-2.0.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pants_pyrefly-0.2.0.tar.gz (17.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pants_pyrefly-0.2.0-py3-none-any.whl (17.1 kB view details)

Uploaded Python 3

File details

Details for the file pants_pyrefly-0.2.0.tar.gz.

File metadata

  • Download URL: pants_pyrefly-0.2.0.tar.gz
  • Upload date:
  • Size: 17.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for pants_pyrefly-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e62ebdaabb189ea2f9c37e21a3ee9d44d9813edad01b0bab7df7de6037a39445
MD5 c52f955d9c8618e793936b64fc2458ec
BLAKE2b-256 bfcb528ed861361c3e884ab5fa5002f9a693bb2ae436a3d539db6df40b98e210

See more details on using hashes here.

Provenance

The following attestation bundles were made for pants_pyrefly-0.2.0.tar.gz:

Publisher: release.yml on tague/pants-pyrefly

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pants_pyrefly-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pants_pyrefly-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 17.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for pants_pyrefly-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1ca6ab93213b66e9b0fa4353a9d629ffbe0ff873578ada455eca56138421d1b5
MD5 5ce854f770f626cfb2cfd9b81f027778
BLAKE2b-256 1ae803da1e471934d5cf4ecd30b03e0547431f237a9a7cb8f66efd563dcfbd8a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pants_pyrefly-0.2.0-py3-none-any.whl:

Publisher: release.yml on tague/pants-pyrefly

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.0.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

This release

0.2.0 This release

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page