Pyrefly v1.4: Fewer false positives

Pyrefly v1.4

Pyrefly v1.4 is out. Highlights:

  • Fewer false positives, from fixes to import resolution, gradual types, and overloads.
  • Tensor shapes for libraries: a new compatibility syntax, and JAX shape stubs on PyPI.
  • The VS Code extension uses the Pyrefly in your environment, so your editor and CLI run the same version.
  • uv workspace members are now type checked.
  • Layered configuration and BasedPyright migration.

This release includes 1,191 commits from 66 contributors. To get started, run:

pip install --upgrade pyrefly==1.4.0

For the full list of changes, see the v1.4.0 release notes.


Fewer false positives

A false positive is an error reported on code that is correct. Each one forces you to stop, investigate, and suppress it. False positives were the most common category of feedback after v1.3, so they were the focus of this release. They can be hard to track down because they often depend on a specific project layout or library. Many of the fixes below started as a bug report with a small reproduction.

Thank you to everyone in the community who filed an issue, trimmed a failing project down to a few lines, tested a pre-release, or sent a pull request. You made this release possible, so please keep the reports coming!

We test each change against a corpus of open-source projects with mypy_primer, so we can confirm that a fix removes the errors it targets without introducing new ones.

Import resolution

An unresolved import leaves every name it provides untyped, which causes follow-on errors.

  • Test packages in src/ layouts. When Pyrefly infers a src/ layout, it also searches the project root at a lower priority, so tests.helpers and conftest resolve.
  • sys.path ordering. Pyrefly follows Python's first-match rule: an earlier .py file wins over a package from a later search root.
  • Re-export cycles. Pyrefly falls back to stubs when source files re-export from each other in a cycle.

Unknown base classes

A base class from a conditional import can have a union type such as Loader | Unknown. Pyrefly used to reject it with invalid-inheritance. It now uses the known class and records that the class has a dynamic base.

try:
from yaml import CLoader as Loader
except ImportError:
from yaml import Loader

class MyLoader(Loader): # v1.3: Invalid base class: `Loader | Unknown`
... # v1.4: OK

Gradual types and overloads

  • no-any-return no longer reports a function whose declared return type already contains Any.
  • Methods whose type is a union with Any, or whose decorator returns T | Any, bind self correctly.
  • Assignments to an overloaded type are accepted when the value fits any branch, and overloaded tuples unpack position by position.
  • Overloaded arguments to generic functions use a new overload table. incompatible-overload-residual is renamed to incompatible-overload-argument; the old name remains as a deprecated alias.

Tensor shapes

  • Compatibility syntax. shape_extensions.Shaped and shape_extensions.shape_vars let a library annotate with shape types without requiring its users to run Pyrefly.
  • JAX shape stubs on PyPI as jax-pyrefly-stubs, the first stable release to include them.
  • Experimental jaxtyping support, behind an opt-in configuration option.
  • Broader coverage across Torch, NumPy, and JAX, including jax.lax.scan, Tensor.T, and torch.is_tensor narrowing.

Tensor shape support remains experimental. See the tensor shapes documentation for current APIs and examples.


Editor and project setup

  • VS Code uses your environment's Pyrefly. The extension launches the Pyrefly installed in your active environment and falls back to its bundled binary if there isn't one. Set pyrefly.pyreflyExecutable to bundled to keep the old behavior.
  • uv workspace members are type checked. Pyrefly previously treated editable workspace sources as installed packages and skipped them. Errors in those packages can now appear.
  • Layered configuration. extends lets a config file build on another, so a monorepo can share one base config.
  • BasedPyright migration. Pyrefly reads [tool.basedpyright] in pyproject.toml and applies the matching preset.
  • Shell completion. pyrefly completion generates scripts for bash, zsh, and fish.

New checks

  • method-assign reports assignment to a method on an instance.
  • Unreachable code after an if/else where every branch returns or raises.
  • Opt-in Any checks, such as unknown-member-type, unknown-return-type, and untyped-function-decorator, help you find where Any enters your code.

Library support

  • Polars: select and with_columns preserve schemas, column names are validated in filter, sort, unique, and drop_nulls, and pl.col. completes columns.
  • Django: QuerySet.annotate() keeps keyword annotations on result rows, and ForeignKey(to=...) resolves correctly.

Upgrading

Some changes in this release can surface new errors or change your editor setup. The release notes list the behavior changes and explain how to suppress new errors while you upgrade.


We're not done

v1.4 fixes the false positives we could reproduce, but it doesn't fix all of them, and reducing false positives remains a priority for upcoming releases. If Pyrefly reports an error on code that you think is correct, or anything else looks wrong, please open an issue. A small code sample that reproduces the problem is the fastest way for us to fix it.

Thank you to the 66 contributors to v1.4, and to everyone who has filed a bug report.

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论