Skip to content

Consider switching to Pyrefly for typechecking #4200

Description

@javabster

I'd like to propose adding Pyrefly for typechecking - it could either be added alongside mypy or migrated entirely. Happy to open the PR, just checking here first to see if there's interest. For transparency I work on the Pyrefly team, I came across this project while investigating the performance of mypy vs Pyrefly on real repos and it looked like it could be a good fit :)

I did some initial investigation, running locally mypy 2.3.0 vs Pyrefly 1.1.1, Pyrefly is ~11x faster:

Checker Run
mypy 2.4 s
Pyrefly 0.2 s

How to make the switch:

  1. Add the dependency to [tool.poetry.group.dev.dependencies]: pyrefly = ">=1.1.1".
  2. Add [tool.pyrefly] config mirroring the existing [tool.mypy] config:
    [tool.pyrefly]
    project-includes = ["rich"]
    search-path = ["."]                 # lets Pyrefly resolve the `rich` package at the repo root
    errors = {redundant-cast = "warn", redundant-condition = "error"}   # mirrors your enable_error_code
    preset = "legacy"                   # matches mypy's non-strict defaults
    ignore-missing-imports = ["pygments.*", "ipython.*", "ipywidgets.*", "IPython.*"]  # mirrors ignore_missing_imports
    (preset = "legacy" keeps Pyrefly aligned with how mypy is configured here — it won't
    type-check unannotated function bodies, same as mypy's default, so the two are comparable.)
  3. There are some differences between the errors pyrefly catches and what mypy does (14 new errors from what I can see running locally, details below), so we could either ignore them (# pyrefly: ignore [code]) for now or see if there are genuine issues to address. If we opt for removing mypy we could also remove ~4 out of 22 mypy ignores that pyrefly doesn't complain about, so the total ignores would stay roughly the same.
  4. Wire into CI in .github/workflows/pythonpackage.yml, mirroring the mypy job
    (make typecheck) with a run pyrefly check step. Suggest starting non-blocking, then
    flipping to required once you're comfortable.

Error differences - Mypy vs Pyrefly

When I compared pyrefly and mypy output, I found 14 new errors from Pyrefly that aren't flagged by Mypy:

Error code Count Reason for difference Suggested approach
bad-argument-type 11 Mostly container-invariance + Self-typing patterns (list.append, object.__new__); a couple in console.py building renderable lists look like they could be genuine Mostly suppress — review console.py:2004/2017
missing-attribute 1 sys.getwindowsversion in _windows.py — Windows-only stdlib checked on non-Windows (pyrefly doesn't narrow sys.platform) Suppress
missing-module-attribute 1 Deferred/lazy import of Live from rich.live Suppress
invalid-yield 1 Generator in pretty.py yields a tuple narrower than the declared yield type Review
Total 14 ~12 suppress · ~2 review

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions