They all lack certain features vs basedpyright (what I was using) such as auto imports (Ty has experimental support), showing signature/doc when selecting autocomplete options (I think Ty does have this one) and some other features that I can't remember.
One feature that always existed in Jedi (and now also Zuban) is "goto declaration" in Python. It allowed me to goto the "import" instead of the original definition of a function/class which I'm surprised either isn't supported at all (pyright?) or would just do the same thing as "goto definition" (Ty), seems like an obvious oversight imho.
Edit: Also, I wish all these new tools give more importance to such IDE features as much as they do for type checking.
We're dedicated to providing a great IDE experience, though it does take some time. Please bother us on github / our discord if you have features you want - bug reports / community asks are our biggest priority.
- auto import is implemented in Pyrefly: it uses your pyrefly.toml project structure or falls back to your VSCode workspace (up to the first 2500 files). we're happy to fix it for your situation if you want to provide a reproduction
- signature/doc when selecting autocomplete options is a known bug [here](https://github.com/facebook/pyrefly/issues/1090)
- go to declaration: I've created an issue for that [here](https://github.com/facebook/pyrefly/issues/1291), it should be quick.
- speed: by far the biggest issue. your problem is likely related to [this](https://github.com/facebook/pyrefly/issues/360) but we need more information to speed it up. we're happy to work with you to to improve this if you're willing to provide a project structure
New typecheckers don't need to be perfect. They need to be good enough, easy to integrate and have low false positives. Sure, they will improve with time, but if feels like a pain then no one will pick it up. Python users are famously averse to tools that slow down their dev cycles, even if it means better long term stability
BasedPyright is popular because it comes built-in with Cursor and disappears into the background. I have a positive bias towards Astral figuring it out given their track record. But, none of these tools have reached the point of effortlessness just yet.
I really don't agree. Sure, they don't need to be perfect but also keep in mind many codebases have already standardized on something like (based)pyright or mypy. So there's a migration cost. If your analysis has a lot of false positives or misses a lot of what those type checkers miss then there's little incentive to migrate. Sure, ty and pyrefly are much faster, but at the end of the day speed is only one consideration for a type checker.
HN discussion of above: https://news.ycombinator.com/item?id=44107655
How Well Do New Python Type Checkers Conform? A Deep Dive into Ty, Pyrefly, and Zuban (2025-08-29) https://sinon.github.io/future-python-type-checkers/
I used to find this kind of tooling explosion exhausting (and back then with JS it truly was), but generally speaking it's a good sign that the community is hungry to push things forward. Choice is good, as long as we keep the Unix spirit alive: small, composable tools that play nicely together and can be interchanged.
Anything whatever the FE team feels like using, and the less I know about it, the better.
* uv: project management, formatting
* Pyright: type checking
* Pylint: linting (this is probably optional though I would strongly recommend it). Ruff is an option but I don't think it is quite as comprehensive yet.
There are alternatives for those tools but they are pretty clearly the best options at the moment. There's nothing in uv's league, and the only alternatives in Pyright's league is BasedPyright. Hopefully Ty and Pyrefly will be good options in future but I don't think they're ready for production use just yet.
So which is it that you want, to just reach for one tool or have tools that have specific design goals and then have to reach for many tools in a full workflow?
FWIW Astral's long term goal appears to be to just reach for one tool, hence why you can now do "uv format".
The problem with the python tooling is no one can get it right. There aren't clear winners for a lot of the tooling.
Yes there are alternatives to CPython, unfortunely they aren't adopted as much as they should.
There is a reason us old timers mostly wait on the sidelines until the dust settles.
We have seen this movie already too many times.
> pyrefly, ty, pyright, and basedpyright
All of them will complain 2-4x more about your code than PyCharm. I had more than 300 typing errors when I first opened my 20k LOC project in pyright that I wrote in Pycharm.
PyCharm works great when your code is not annotated. It infers types very well. But it won't complain in a lot of cases when your code is annotated.
Related reddit post https://old.reddit.com/r/Python/comments/1ajnikt/to_pycharm_...
They are designed for code which are more or less fully typed, as opposed to PyCharm which cobbles together a bunch of heuristics to try to make sense out of untyped code. An admirable quest, but not one I'm personally interested in.
And their insistence on only supporting this approach drove my entire team away from using PyCharm.
(From shallowly observing notifications on the 20+ typehint related issues I'm subscribed to, they seem to have kinda turned around and working toward fully supporting the python type system finally - possibly by integrating with one of the third-party type-checkers)
Nowadays I'm finding myself using Zed a lot more, so maybe the story will be that all these nice Rust based tools become baked in giving it super powers for Python.
def fn(x: str):
if x is None:
x = "123" # pyright flags that as unreachable code, pyrefly does not
Autocomplete for modules also doesn't work for me yet: import os
os. # I'll get `ABC, `Any`, `AnyStr`, `AnyStr_co`, `BinaryIO`, ...
Looking forward to have a fast language server for python though, pyright is way too slow for large projects.We're planning on adding unreachable code diagnostics soon (github issue [here](https://github.com/facebook/pyrefly/issues/1292)). These come for free with Pyright so we don't want to regress features.
I'm happy to help diagnose/fix your autocomplete issue: it should work on modules. If you want to provide details here, on [discord](https://discord.gg/Cf7mFQtW7W), or as a Github issue (github/discord preferred) we'll fix it for you + anyone else with the problem.
There's no way to get an actual null reference, afaik. Variables always have some value, possibly None.
(not sure what happens if you set a reference to null from C - a crash, probably?)
Looks like none of these new type checkers are ready yet.
You can take a look yourself if you think some of them are wrong: https://github.com/python/typeshed/tree/main/stdlib/asyncio
The advantage is type hints can be fixed without needing to release a new version of Python. The disadvantage is there's a lot of code in the standard library that doesn't really consider how to represent it with type hints, and it can be really tricky and not always possible.
I'm surprised to see so many people moving to pyrefly, ty, and zuban so quickly. I was going to wait until some time in 2026 to see which has matured to the point I find useful, I guess some users really find existing solutions actually unworkable.
Hmm. Presumably mypy and pyrefly use the same ones, but then I don't understand why pyrefly is complaining and mypy isn't:
ERROR Argument `Future[list[BaseException | Any]]` is not assignable to parameter `future` with type `Awaitable[tuple[Any]]` in function `asyncio.events.AbstractEventLoop.run_until_complete` [bad-argument-type]
--> xxx/xxx.py:513:33
|
513 | loop.run_until_complete(tasks.gather(*x, return_exceptions=True))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The definition in typeshed is this: def run_until_complete(self, future: _AwaitableLike[_T]) -> _T: ...
…where is it even puling "tuple[Any]" from…(tbh this is rather insignificant compared to the noise from external packages without type annotations, or with incomplete ones… pyrefly's inferences at the existence of attributes and their types are extremely conservative…)
It has some things it can’t pick up on - no return after a catch block when all code paths are covered for example - but it’s speedy and the error messages are good enough for Claude to understand and ignore or resolve.
Recommended!
I've been leaning on pyright + django-stubs, but wondering if I'm missing something better with fewer gaps and pain points.
We've seen a lot of people have success with the mypy plugin + django-stubs.
Full out-of-the-box support is being actively worked on in Pyrefly: we will have specialized django enum support in the next release and we expect real experimental support by the end of the year. At that time we'll likely post a blog post to announce it [here](https://pyrefly.org/blog/).
- zuban
- ty (from ruff team)
- pyrefly
One year ago, we had none of them, only slow options.
It is interesting that nobody was writing these tools in C or in C++. There are obvious ergonomic reasons, but perhaps also it matters that Rust cares a lot more about types than either of those languages.
Pydantic is probably the problem here, but it is what it is.
foo = eval(result)
It can’t know what you’re going to load until it actually does it.Things which lean heavily into metaprogramming, typically ORMs or things like Pydantic, fall into that category. I can’t hold that against the type system.
Already there is some support in Pydantic for native dataclasses: https://docs.pydantic.dev/latest/concepts/dataclasses/