A Pants plugin that runs the Pyrefly type checker in the `check` goal.
Project description
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.12, with nopantsbuild.pantsdependency (Pants provides itself at runtime) — so it installs into any Pants whose runtime is CPython 3.12+ (e.g. 2.32 → CPython 3.14). Pants 2.27 runs on CPython 3.11, below the floor — install from source there (see Installation); the plugin code still supports it.
Installation
Add the plugin and enable its backend in pants.toml:
[GLOBAL]
plugins = ["pants-pyrefly==0.1.0"]
backend_packages.add = [
"pants.backend.python",
"pants_pyrefly",
]
From source (in-repo)
Prefer to vendor the plugin — for rapid iteration, to pin to an exact source state, or to run on
Pants 2.27 (its CPython 3.11 runtime is below the published wheel's floor)? 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).
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 ofMYPYPATH/sys.path). - Third-party deps: Pants materializes the target's resolved requirements into a venv and points
Pyrefly's
--python-interpreter-pathat it, so Pyrefly discoverssite-packagesand the target Python version exactly asimportwould at runtime.
Pants compatibility
| Plugin version | Pants | Pyrefly (default) |
|---|---|---|
0.1.0 |
2.27–2.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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pants_pyrefly-0.1.0.tar.gz.
File metadata
- Download URL: pants_pyrefly-0.1.0.tar.gz
- Upload date:
- Size: 16.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b5451d301d7b6b939a1f35f06efe3c07530eb6cfe028ba35c75e443529ee88a
|
|
| MD5 |
16dfa419172256392f6c0099fb74fa12
|
|
| BLAKE2b-256 |
154ea1ddf274e95a341327bfefd3bf02552691724367ed8b4d446393403e6567
|
Provenance
The following attestation bundles were made for pants_pyrefly-0.1.0.tar.gz:
Publisher:
release.yml on tague/pants-pyrefly
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pants_pyrefly-0.1.0.tar.gz -
Subject digest:
6b5451d301d7b6b939a1f35f06efe3c07530eb6cfe028ba35c75e443529ee88a - Sigstore transparency entry: 1934879587
- Sigstore integration time:
-
Permalink:
tague/pants-pyrefly@a3bbd909417e24a7d362e7428074dc86192bd6b1 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/tague
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a3bbd909417e24a7d362e7428074dc86192bd6b1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pants_pyrefly-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pants_pyrefly-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0372473a2046a854f19fbe98a476c48e9c9fbbcb5193aa660c89a9f36b1d20b2
|
|
| MD5 |
da4c6b90a737441d164cc01523a6c231
|
|
| BLAKE2b-256 |
cba2932a36c693f3b62b0e6b19aa298dabb175ac714cb9ded3f03c959acc8816
|
Provenance
The following attestation bundles were made for pants_pyrefly-0.1.0-py3-none-any.whl:
Publisher:
release.yml on tague/pants-pyrefly
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pants_pyrefly-0.1.0-py3-none-any.whl -
Subject digest:
0372473a2046a854f19fbe98a476c48e9c9fbbcb5193aa660c89a9f36b1d20b2 - Sigstore transparency entry: 1934879635
- Sigstore integration time:
-
Permalink:
tague/pants-pyrefly@a3bbd909417e24a7d362e7428074dc86192bd6b1 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/tague
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a3bbd909417e24a7d362e7428074dc86192bd6b1 -
Trigger Event:
push
-
Statement type: