Pyrefly v1.3: More configurability and composable tensor shapes

We've just released Pyrefly v1.3, which adds flexible tools for configuring, suppressing, and baselining errors. Also included: a composable tensor shape DSL that expands experimental tensor shape support for JAX and NumPy, improved DataFrame schema checking for Polars, and a battery of new type checking diagnostics.
Try out the new version with:
pip install --upgrade pyrefly==1.3.0
Configuration & CLI Improvements
Pyrefly now supports pyrefly-specific tags in # type: ignore directives:
value: str = 0 # type: ignore[pyrefly:bad-assignment]
This suppresses only the named Pyrefly diagnostic without hiding unrelated errors on the same line. A new type-ignore-unknown-tag-behavior option controls how tags belonging to other type checkers affect Pyrefly diagnostics.
Baseline files — a way to centrally suppress existing type errors in a codebase — are easier to maintain and review, thanks to new options:
baseline-matching-modelets you choose whether to match diagnostics by column or concise description.baseline-formatwrites either full diagnostic metadata or a compact representation containing only the fields needed for matching.baseline-error-levelkeeps matched diagnostics visible at a specified severity instead of hiding them.--prune-baselineremoves stale entries without recording newly introduced errors.--error-stale-baselinelets CI reject baseline files that contain obsolete entries.
The new replace-untyped-imports-with-any option lets projects choose which installed third-party packages should be treated as Any when they provide neither stubs nor a py.typed marker. When migrating from mypy, pyrefly init translates follow_untyped_imports settings automatically.
Tensor Shapes
Tensor shape checking remains experimental, but its foundations have changed substantially in v1.3. A composable, type-level DSL now lets JAX, NumPy, and PyTorch stubs express shape transformations directly in type signatures. The previous @shaped_array API has been removed.
New shape-aware JAX stubs cover array creation, manipulation, and linear algebra. The new pyrefly-numpy-stubs package brings the same style of shape-aware checking to NumPy alongside the existing PyTorch support.
The API remains experimental and may continue to evolve as we expand coverage and learn from real-world use. The tensor shapes documentation tracks the current API.
DataFrame Schema Checking
Pyrefly can now track Polars schemas through common DataFrame transformations and enforce schema contracts expressed via Annotated metadata:
from typing import Annotated
import polars as pl
class ReportSchema:
name: pl.String
score: pl.Int64
Report = Annotated[pl.DataFrame, ReportSchema]
def publish(report: Report) -> None: ...
publish(pl.DataFrame({"name": ["Ada"], "score": [98]})) # OK
publish(pl.DataFrame({"name": ["Ada"]})) # Error: missing `score`
DataFrame schema checking is also experimental, and we welcome feedback as support grows across more operations and libraries.
Other Type Checking Improvements
v1.3 adds new diagnostics for mistakes that can otherwise survive until runtime:
- Invalid regular expressions: the new
regexdiagnostic checks literal patterns for syntax errors and unintended capturing groups. - Invalid patch targets:
missing-attribute-patch-targetwarns when a string passed tounittest.mock.patchnames an attribute that does not exist. - Dataclass problems: Pyrefly reports unsupported
dataclass_transformarguments and emits a newbad-dataclass-descriptordiagnostic when a descriptor-backed field has incompatible read and write types. - Invalid protocol implementations: incompatible
Protocol.__call__overrides are now detected. - Non-exhaustive matches: a new
non-exhaustive-match-open-typeerror kind lets projects opt into exhaustiveness checks for all types, not just the limited set that Pyrefly checks by default.
But Wait, There's More!
The release also includes improved workspace symbol search, performance improvements, 88 bug fixes, and more. You can browse the details in the v1.3 release notes.
What's Next & How To Get Involved
v1.3 reflects the work of 71 contributors, plus everyone who filed an issue or joined a discussion. Thank you to everyone who helped shape this release.
Looking ahead to v1.4, we'll keep pushing on the fundamentals: reducing false positives, improving performance, and broadening library support. We'll also continue developing tensor shape and DataFrame schema checking as we learn from early adopters.
You can follow along or contribute through these resources:
- GitHub milestones: see what's planned for upcoming releases
- Join our Discord: chat with the team and community
- Open an issue: suggest features and report bugs