10 ms·
Pyrefly: Python type checker and language server in Rust
- zelphirkalt 1y agoAnother one I recently discovered and that has a very active maintainer is "zuban" or zuban-ls. It has replaced jedi-language-server for me, and aims to replace mypy as well.
- f311a 1y agoYeah, there are now 3 competitors and they all written in Rust: - zuban - ty (from ruff team) - pyrefly One year ago, we had none of them, only slow options.
- jerrygenser 1y agoBasedpyright is not rust but it's a fork of pyright with added features that are otherwise locked in vscode
- f311a 1y agoIt's written in Typescript, which is a super weird choice.
- huflungdung 1y ago[dead]
- wiseowise 1y agoWasn’t pyright made specifically for VSCode? That would explain TS.
- f311a 1y agoYes, but why they did not write it in a compiled language? Pyright is pretty slow in large code bases and takes a lot of RAM. Javascript can be faster than python in some cases, but Python is so easily extendable with C,C++, Cython, Rust. They could use Python with one of the compiled language.
- IshKebab 1y agoBecause they wanted it to be usable on the web, and I guess WASM wasn't where it is right now when they started.
- drcongo 1y agoIt's also horrible for fasle positives unless your project happens to be the exact same setup as the maintainers' - I had to turn off the actual type checking on it. I've since moved wholesale to the Ty alpha and it feels a hell of a lot smarter.
- JimDabell 1y agoIt also inherits the unfortunate attitude of Pyright that it will warn against idiomatic Python (EAFP) in favour of non-idiomatic Python (LBYL): https://github.com/microsoft/pyright/issues/1739 https://github.com/microsoft/pyright/issues/1739 https://docs.python.org/3/glossary.html#term-EAFP https://docs.python.org/3/glossary.html#term-EAFP https://docs.python.org/3/glossary.html#term-LBYL https://docs.python.org/3/glossary.html#term-LBYL
- kstrauser 1y agoEww, what? I hadn’t seen that before. Yikes, I hope the situation’s improved. I’d be butting into that continually.
- deleted 1y ago[deleted]
- maleldil 1y agoSometimes dynamic Python idioms are incompatible with typed Python. I personally think that's fine, since I consider static typing a significant improvement overall.
- JimDabell 1y agoThis isn’t. They actually fixed that bug. Then they changed their minds and backed the fix back out again because they don’t think you should write Python that way: > I think EAFP is a very unfortunate and ill-advised practice. They want you to not write the idiomatic Python: try: foo = bar["baz"]["qux"] ... except KeyError: ... …and instead write the non-idiomatic version: if "baz" in bar and "qux" in bar["baz"]: foo = bar["baz"]["qux"] ... else: ... If this were a linter then I would accept that it is going to be opinionated. But this is not a linter, it’s a type checker. Their opinions about EAFP are irrelevant. That’s idiomatic Python.
- jon-wood 1y agoI'm sorry, I can't take seriously any piece of software which decided to prefix the previous version's name with "based". I'm aware this is a me problem.
- cruffle_duffle 1y agoHah. I love the name. It implies that whatever the original “pyright” was doing wasn’t keepin’ it real. This new version, it’s “based” so it must be somehow more “real” and “grounded” and “legit”. All I know is it is much more strict about stuff than pylance was. Also a me problem!
- wiseowise 1y agoDefinitely this. I commend author of BPyright, but clown (?) avatar, unknown identity of maintainer, and name of the fork rub me off wrong way.
- arccy 1y agoit'll be like python package managers and js web frameworks.... a new one every quarter
- vovavili 1y agouv works so well for the vast majority of scenarios that I don't really see a demand for further innovation in the Python package manager domain.
- insane_dreamer 1y agoit still needs to add handling for binaries (the one thing conda can do that uv can't)
- arccy 1y agoyeah we all heard that story every 3 months with all the previous package managers. until there's adoption by an overwhelming majority of projects, it isn't really settled yet.
- wiseowise 1y agoI’ve literally never heard that much buzz and excitement about Python tool before. And I’ve seen them all. All of them had some big issue that prevented it from getting mainstream. Either it was slow, or didn’t work with existing workflow, or had complex configuration, or something that prevented gradual adoption. uv is universally praised as the second coming Christ in Python world (and for a good reason). So no, I doubt there will be something else. Not only you need to be better than uv, you also need to have community momentum.
- pjmlp 1y agoUsing Python in one form or the other since Python 1.6, there is always some buzz for whatever tool now and then.
- tialaramex 1y agoSpeed is one of those "Quantity has a quality all its own" things. We use very fast tools in a qualitatively different way, even though all that changed was how long it takes in seconds. 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.
- f311a 1y agoIt's just very hard to write such systems in C/C++. Even all these Rust versions are segfaulting and panicking quite a lot. So many corner and edge cases that can be found in Python code, and the memory handling is also hard. The author of Zuban started writing it back in 2020 or 2021, so it took him more than 4 years to complete it. And he is the author of Jedi, so he had prior experience already.
- tialaramex 1y agoI get why they'd panic, but why have enough segfaults that you noticed? So, I went and read the code. Zuban seems to have a bunch of scary "I'm not sure if this is correct" unsafe blocks, which to me would be a red flag. I mean, it's better that there's a comment expressing the doubt, but my experience is that if you're not sure whether it's correct, it's probably not correct.
- estebank 1y agoWhile acknowledging the risk of causing a pile-on (which I don't want!), would it be possible to have a link to them or a description of what the unsafe blocks accomplish? I'm intrigued if they are for performance or API ergonomics, if they are due to limitations of the borrow checker, the stdlib or crate dependencies. For anyone reaching for unsafe, there are in many cases either an existing API (split_at_mut comes to mind). For others, using zero-copy or bytemuck instead of unsafe is a good idea too. None of that is to say "never write unsafe", unsafe existing is pretty much one of the reasons for Rust to be :)
- rana762 1y ago[dead]
- scosman 1y agoAnyone know how this compares to 'ty': a new typechecker from Astral (uv/ruff team), also written in Rust and super fast. I had been waiting on it to reach beta, but would love to move to something faster than pyright sooner if possible.
- emddudley 1y agoPyrefly vs. ty: Comparing Python’s Two New Rust-Based Type Checkers (2025-05-27) https://blog.edward-li.com/tech/comparing-pyrefly-vs-ty/ https://blog.edward-li.com/tech/comparing-pyrefly-vs-ty/ HN discussion of above: https://news.ycombinator.com/item?id=44107655 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/ https://sinon.github.io/future-python-type-checkers/
- scosman 1y agoamazing reply. Thanks!
- underdeserver 1y agoA note - the second link talks mostly about conformance with a standard suite of tests, only briefly touching on real-world use. I would very much like to understand how good Zuban is today compared to the competition.
- pawelkobojek 1y agoI love the speed advantage of pyrefly over (based)pyright but so far it doesn't seem to highlight as much as pyright does, for example it doesn't catch unreachable code like this: 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.
- veber-alex 1y agoYeah I have a similar experience with ty. Looks like none of these new type checkers are ready yet.
- f311a 1y agoTy has autocomplete for imports, but it's hidden behind a toggle right now. They are still working on it. They index all the modules and functions, so you can just type the function name and it will suggest the correct import and insert it.
- parhamn 1y agoWhats the expected error in the example you gave? That x can't be none because it was received as a str?
- boxed 1y agoOr that x is unused?
- pawelkobojek 1y agoExactly - something along the lines of "Statement is unreachable".
- robertlagrant 1y agoYes, exactly. x would have to be str | None to be reachable.
- whalesalad 1y agoPython is starting to feel a bit like JavaScript circa 2014. Remember grunt, gulp, webpack, coffeescript, babel? Now we've got pyright, mypy, pyrefly, black, ruff, ty, flake8, poetry, uv... 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.
- strangescript 1y ago"grunt, gulp, webpack, coffeescript, babel" --- except no one uses these anymore and they are dead outside of legacy software. The problem with the python tooling is no one can get it right. There aren't clear winners for a lot of the tooling.
- jon-wood 1y agoI think that's the point. Every now and then a language will have a small explosion of new tooling, and all you can really do is wait for it to blow over and see what tools people adopted afterwards, it feels like Python is going through a period like that at the moment.
- parhamn 1y agoInterestingly besides typescript, javascript in 2025 is still super fragmeneted but by a bunch of well-polished tools that all do approximately the same thing. esbuild/vite(rollup)/trubopack(swc), prettier/biome/oxc, npm/bun/pnpm/yarn, bun/node/deno/worker-runtimes
- WesolyKubeczek 1y agoThe fact that you even didn't mention webpack, once a champion, is especially sad.
- koakuma-chan 1y ago
- bobajeff 1y agoThough, I'm happy with basedpyright and usually disable type checking. It's great to have so many options in language servers for Python now that pylance is locked to vscode.
- brianzelip 1y agoSee the recent Talk Python podcast featuring some Pyrefly team members, https://talkpython.fm/episodes/show/523/pyrefly-fast-ide-friendly-typing-for-python https://talkpython.fm/episodes/show/523/pyrefly-fast-ide-fri...
- insane_dreamer 1y agoI've tried pyrefly, ty, pyright, and basedpyright, with a large complex code base written using PyCharm, and _none_ of them do as good a job as PyCharm, particularly in discovering more complex type inheritances. It's a pity because in other respects Zed (which relies on these) is a worthy competitor to PyCharm (and much faster!) -- but the endless squiggly lines because pyrefly can't figure out the type, is annoying (and turning off the warnings is unhelpful). Hopefully one of these will get up to PyCharm's level (my money would be on ty as Astral is kicking a* these days).
- giancarlostoro 1y agoI think the 2nd best IDE for Python for me is Visual Studio proper, not Code. I know it sounds crazy, but Microsoft actually put some effort into their Python integration. Again, its a 2nd best, but that still says a lot about everyone else's editors. 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.
- f311a 1y agoPyCharm has very basic type checking, though. It's not strict. > 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_users_how_are_you_type_checking_your/ https://old.reddit.com/r/Python/comments/1ajnikt/to_pycharm_...
- olejorgenb 1y agoI don't think these are designed to "discovering" complex type inheritances. 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)
- rasulkireev 1y agoThis looks interesting. But I decided to go with ty in my projects, for the incremental approach.
- codethief 1y agoHow well does ty work these days? Last time I checked it still produced a lot of false positives and false negatives. (Which was very much expected, given its alpha/WIP status.)
- rasulkireev 1y agoHonestly i barely use it, just started to give it a try by adding types where it makes most sense and running with pre-commit. No issues so far. But, again, I'm a very light user.
- flanked-evergl 1y agoSadly, the question with both this and ty is: Does it support pydantic? If not, then it's not really helpful for many people, and right now AFAIK neither supports pydantic. Pydantic is probably the problem here, but it is what it is.
- phailhaus 1y agoPython's type system is the problem here, which cannot support even the native dataclass pattern and needs custom plugins written for each type checker.
- kstrauser 1y agoThe type system’s alright. It just gets especially tricky when you’re trying to check code which won’t exist until you run it. For instance, suppose you wanted to load your own module from a database with something like 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.
- phailhaus 1y ago> I can’t hold that against the type system. I think we should. Dataclasses have existed in Python for an extremely long time, and yet the type system doesn't support defining your own similar classes. Kwargs have also existed forever, but they forgot to support that and had to add TypedDict's much later. And it still doesn't properly support optional fields. There's a lot of stuff like this in the language which are unbelievably frustrating, because for some reason they implemented the syntax before implementing a typechecker. Everything has been hacked in ever since. I consider python's type system to be a lost cause, just hoping for someone to make the Typescript equivalent for Python.
- flanked-evergl 1y agoDataclasses support optional fields and kwargs perfectly. Not sure what you are talking about. I don't think you understand what Pydantic brings to the table or why people use it. It has lots more to do with serialization, complex validation and data mapping.
- sirfz 1y agoI've decided to to try out Pyrefly, Ty and Zuban for their language server features (type checking disabled where possible) last week and found that Zuban is the fastest (but unfortunately doesn't currently have the option to disable type checking). Ty comes next and Pyrefly was surprisingly slow to load (have to wait a few seconds before I can goto definition for example). 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.
- jswny 1y agoAt least for Ty, not sure about the others, it is explicitly for type checking, exposed as an LSP. It’s not trying to compete with full LSP implementations. Most modern editors let you combine multiple LSPs, you shouldn’t think of them as using only one at a time
- ehsanu1 1y agoDo you assign different responsibilities to different LSP servers when there multiple I suppose?
- charliermarsh 1y agoWe actually do want ty to be a first-class LSP (i.e., a complete alternative to Pylance and others), and it already supports nearly all of the features you'd expect. I use it as my primary LSP today in lieu of Pylance!
- jswny 1y agoGood to know, I had no idea!
- sheepscreek 1y agoI much prefer the rigidity of pyrefly. It enforces a standard expectation across the code base, which will lead to less surprises IMO.
- whilenot-dev 1y agoThe weird Literal promotion makes pyrefly unusable for me, except if I'd avoid Literal types: https://github.com/facebook/pyrefly/issues/742 https://github.com/facebook/pyrefly/issues/742
- eqvinox 1y agoHm, it doesn't seem to be dealing particularly well with imported packages that don't have type annotations. Seeing a bunch of "has no attribute" warnings. Some of the "substitute" annotations also seem to be wrong (e.g. asyncio in CPython has no annotations [in my installed version], but it's pulling some in from somewhere and they're not quite right…) It's also getting confused about lists and tuples in __slots__.
- notatallshaw 1y agoThe standard library does not directly include type hints, they are stored in typeshed: https://github.com/python/typeshed https://github.com/python/typeshed You can take a look yourself if you think some of them are wrong: https://github.com/python/typeshed/tree/main/stdlib/asyncio 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.
- eqvinox 1y ago> You can take a look yourself if you think some of them are wrong: https://github.com/python/typeshed/tree/main/stdlib/asyncio https://github.com/python/typeshed/tree/main/stdlib/asyncio 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…)
- Too 1y agoAnyone struggling with slow mypy should really update to latest version. This years releases has focused on performance and it has payed off. Add the boost from latest Python versions to that and you can see 50% type checking improvements. Still far from a rust based tool, always something, all without changing your tool chain.
- natdempk 1y agoAnyone here know what the ideal/best setup is for typechecking + LSPing Django these days? I've been leaning on pyright + django-stubs, but wondering if I'm missing something better with fewer gaps and pain points.
- kinto 1y ago(Pyrefly dev here) 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/ https://pyrefly.org/blog/).
- nprateem 1y agoJust started trying ty with django-types. I got the models typed in a day or so. Still wading through the other 200+ errors in my codebase. But it's fast at least.
- deleted 1y ago[deleted]
- cadamsdotcom 1y agoBeen using pyrefly since July on a big python build. 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!