website/blog/2026-08-05-v1.2.md
Pyrefly v1.2 is now available 🎉 This release adds support for Bazel and attrs, along with improvements to type checking, the language server, and the CLI.
<!--truncate-->This release includes 901 commits from 59 contributors. To get started, run:
pip install --upgrade pyrefly==1.2.0
Pyrefly now type-checks attrs classes with no plugin or configuration required. It recognizes the modern API (@define, @frozen, @mutable, attrs.field) and the classic API (@attr.s, @attr.ib, @attr.dataclass) in the attr. and attrs. namespaces. Pyrefly synthesizes __init__ signatures, including converter input types, and catches misconfigurations that cause errors when the class is created.
from attrs import define, field
def to_bpm(s: str) -> int:
return int(s.removesuffix(" bpm"))
@define
class Chart:
title: str
tempo: int = field(converter=to_bpm)
Chart("Blue Bossa", "120 bpm") # OK: converter accepts str
Chart("Blue Bossa", 120) # Error: expected str, got int
See the attrs documentation and dedicated blog post for details.
Before v1.2, teams using Pyrefly with Bazel had to write custom build logic to collect sources, dependencies, import paths, and generated files for each target. Pyrefly v1.2 provides a standard integration through the new pyrefly bazel-check command and rules_pyrefly.
rules_pyrefly uses an aspect to apply Pyrefly across existing py_library, py_binary, and py_test targets. It follows the Bazel target graph, reading the Python version from the rules_python toolchain and the platform from Bazel platform constraints. Projects do not need wrapper rules or Pyrefly declarations in each BUILD file.
Once configured, run Pyrefly for any target or target pattern:
bazel build --config=pyrefly //path/to/package:target
rules_pyrefly 0.1.0 is available via the Bazel Central Registry. The integration is still at an early stage. Some import layouts are not yet supported, and the rules_pyrefly and bazel-check interfaces may change as we expand coverage. If you build Python with Bazel, please try the integration and let us know how it works for you. Bug reports and PRs are always welcome!
pyrefly coverage is now stable and ready for production use. It provides two subcommands:
pyrefly coverage report writes a JSON report with project, module, and per-symbol coverage data, including the locations of missing annotations.pyrefly coverage check reports incomplete coverage and can enforce a minimum coverage threshold in CI.Projects including NumPy, Narwhals, sh, and scipy-stubs already use Pyrefly to track their type coverage.
Our collaborator Joren Hammudoglu (@jorenham) has led the development of the coverage feature. We will publish a dedicated post about this topic soon.
Tensor shape checking remains early alpha. This release adds a NumPy stubs package that covers array construction, broadcasting, ufuncs, reductions, and parts of linalg and random. Arithmetic and broadcasting have moved from the type checker's Rust internals into the editable shape DSL. The shape primitives are now named Int, IntVar, and IntTuple. Dim has been removed.
The API will continue to change as this work develops. The tensor shapes documentation tracks the current API.
Other type-checking improvements in v1.2 include:
functools.partial support: bound arguments are validated at the partial(...) call, and Pyrefly synthesizes a signature for the remaining parameters. This catches errors when the partial is created and when it is called.functools.singledispatch support: calls are checked against the signature of the function you decorated, and each registered implementation is checked against that function's first parameter.populate_by_name and built-in alias_generator functions. Django ForeignKey string references such as "app_label.Model" now resolve with the correct relation and <field>_id types.TypedDict methods and attributes: classes synthesize __required_keys__ and __optional_keys__, allowing them to satisfy protocols that require these attributes, including protocols used by LangGraph. Calls to .get() and .pop() with literal defaults also preserve the field type..value types: .value on an enum type is inferred as the union of its member literal values, preserving the type of each value.The Pyrefly documentation and release notes cover the full set of changes.
Language server improvements in v1.2 cover hover information, imports, rename, and editor compatibility:
__call__ signature, overload docstrings remain available at call sites, and enum fields are shown. Nested callable and Concatenate[...] signatures also wrap for readability.SymbolInformation for clients such as Helix, cross-file diagnostics refresh on save in clients such as Zed, and lspArguments defaults to ["lsp"], preventing startup failures in dev containers and remote environments.v1.2 also includes updates to the CLI, configuration, import resolution, and stub generation:
pyrefly infer --dry-run previews inferred annotations without touching your files and exits unsuccessfully if changes would be made, so CI can fail when a file is missing annotations Pyrefly could have inferred.implicit-bool, invalid-cast, unused-call-result, empty-body, missing-super-call, implicit-reexport, no-any-return, and a family of unknown-*-type checks for finding sources of Any.# pyrefly: ignore-errors[code] suppresses a specific diagnostic throughout a file.partial marker from py.typed and merges the stubs with the runtime package, deferring to the runtime package for omitted modules.python-platform accepts multiple platforms or all platforms. Platform guards are folded only when every configured platform agrees.TypeAlias right-hand sides and static __all__ literals are preserved so re-exports remain in generated stubs. Implicit class variables are wrapped in ClassVar[...], and multi-line parenthesized expressions keep their parentheses, preventing an IndentationError in the generated file.Pyrefly gets faster with every release. In our benchmarks across eight projects from Astral's ty_benchmark suite, v1.2 was about 8% faster than v1.1. We also measured 2% to 4% lower memory use on tested repositories.
Between v1.1 and v1.2, we closed 137 bug issues. The fixes cover false positives, crashes, stack overflows, narrowing, and library support. You can browse the full list on GitHub.
Our priorities for v1.3 include reducing false positives, improving performance, and expanding library support. Follow development or get involved through these resources:
Thank you to the 59 contributors who made v1.2 possible, and to everyone who filed an issue or joined a discussion. We look forward to building v1.3 together.