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:
- Add the dependency to
[tool.poetry.group.dev.dependencies]: pyrefly = ">=1.1.1".
- 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.)
- 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.
- 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 |
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:
How to make the switch:
[tool.poetry.group.dev.dependencies]:pyrefly = ">=1.1.1".[tool.pyrefly]config mirroring the existing[tool.mypy]config:preset = "legacy"keeps Pyrefly aligned with how mypy is configured here — it won'ttype-check unannotated function bodies, same as mypy's default, so the two are comparable.)
# 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.(
make typecheck) with a run pyrefly check step. Suggest starting non-blocking, thenflipping 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:
bad-argument-typeSelf-typing patterns (list.append,object.__new__); a couple inconsole.pybuilding renderable lists look like they could be genuineconsole.py:2004/2017missing-attributesys.getwindowsversionin_windows.py— Windows-only stdlib checked on non-Windows (pyrefly doesn't narrowsys.platform)missing-module-attributeLivefromrich.liveinvalid-yieldpretty.pyyields a tuple narrower than the declared yield type