Pyright: Static Type Checker for Python
github.com
github.com
tldr; mostly about performance improvements but there's also semantic differences. The latter sounds like it means a split between the community who decides to do mypy vs pyright. But maybe pyright only differs with mypy in terms of things that are considered bugs in mypy, and things that are optional in mypy (via flags).
https://github.com/microsoft/pyright/blob/main/docs/mypy-com....
The semantic differences are mainly in areas where type system is not specific enough on exact behavior expected. As an example if you have a function that has overloads how do you decide which overload to pick? Sometimes that can become ambiguous especially when type variables are involved or multiple overloads match. Cases like that are where you see most intentional differences and as a user of both type checkers I consider depending on specific behavior there to be like using c++ compiler’s undefined behavior.
The bigger area I see differences is feature development/bug fix velocity. Mypy is maintained well. Pyright is maintained magically and I’ve reported bugs that maintainer fixes the same day. Most bug reports to pyright get fixed in a week. Only a couple tend to stay open for a while. New type system features (peps) get implemented really fast in pyright and usually if you try to use very recent features you will need to wait a while for mypy to catch up. A good example is release time for paramspecs or typevartuple. Most of the time new type system peps are added in pyright while still in draft stage.
https://github.com/microsoft/pyright/issues/607
E.g. https://github.com/Shoobx/mypy-zope can't work with pyright
Here's an official bit about the new types: https://docs.sqlalchemy.org/en/20/changelog/whatsnew_20.html...
that said, the codebase primarily targets mypy for internal type checking; we tried targeting both tools simultaneously but there were great differences between both tools, which tended towards doubling our workload in getting everything to pass typing fully. In more than one case there were areas where the two tools would mutually disagree with each other, making "correct" typing impossible. This was some iterations back and mypy has had a lot of good releases since then (pyright has had many more, obviously).
when typing a large codebase, there are invariably lots of areas where you just need to "type: ignore" or otherwise do some non-ideal workarounds. it's in that area that trying to target more than one type checker at once gets to be really difficult.
This means being able to incrementally type check incomplete code blocks and to also infer & suggest types, where mypy is too slow and/or just doesn’t support those features.
[1] https://github.com/microsoft/pylance-release/issues/4
[2] https://github.com/microsoft/pylance-release/issues/746
[3] https://parsiya.net/blog/2021-12-20-rce-in-visual-studio-cod...
On the other hand, when Microsoft creates an interoperability standard to solve the proliferation of wheel-inventing in IDEs, actively promotes it as such, creates and supports an open-source implementation of it for Python as part of said promotion, then abandons[1] said implementation in favour of a proprietary one that deliberately speaks the interoperability protocol in a slightly non-interoperable way, then yes, I do feel like I’ve been conned, and maybe I should stop treating Microsoft’s open-source efforts seriously even if they’re good software at the present moment. (Whether my level of cynicism regarding Microsoft should have been high enough that I wouldn’t have been surprised, I’m not sure.)
[1] https://github.com/microsoft/python-language-server/issues/2...
Authors of other language servers deliberately chose to put up with Microsoft’s legacy-induced craziness in the protocol (positions in UTF-8-encoded strings specified as UTF-16 code unit counts, etc.) due to Microsoft’s promise of an interoperable ecosystem; then Microsoft reneged on that.
I’d have much less of a problem, for example, if I could use a proprietary Pylance with VS Codium or Neovim or whatever else I want; I’d have almost no problem if Microsoft also hadn’t published then abandoned an open-source Python language server first. But I can’t, and they did.
I just had a quick check and can't obviously see if that has been fixed/worked around in pylsp-mypy, on the off-chance that you might know :)
You also have a lot more control with pyright over where unknown types are permitted or what other checks should be performed. Also, it can scan library source code to infer types which I don't think mypy supports.
The lack of plug-in support might feel like a hang-up, for instance if you’re using Django. FWIW, I like the “no plug-in” philosophy. I’ve discovered that explicitly adding annotations that a MyPy plug-in would have surmised feels cleaner. (Example: an annotation for a reverse collection on a Model referenced by a foreign key.) Even better: I don’t need to suffer the (in my experience) frequent bugs of the plugins themselves.
def foo(data: list[str]):
r = [] # error: Need type annotation
for key in data:
r.append(key if len(r) > 0 else '')
return rIs there a reason not to go with Pyright and stick with MyPy?
I think the major reasons for mypy is if you are working on a library to be shared with many others (especially open source one) you'd like library to be compatible with mypy as your users are likely to use mypy as it's still most popular type checker. So for open source libraries it makes sense to use both mypy/pyright. For projects that you do not expect main users (company internal one you define standards) it's more fine to pick type checker you prefer. The other main place mypy can be helpful is plugins if you need some behavior outside of type system for a library you work with a lot.
Also pyright is implemented in typescript which does mean you'll need to have a CI dependency on javascript environment that python project's often don't need. Lastly for typical python developer it's a bit easier to make pull request to mypy vs pyright just as they normally have more python knowledge then javascript knowledge. This is pretty minor given most people don't debug there own type checker and pyright's bug list is very short.
In my experience, mypy tends to be more correct and correctly understands more python code.
For example, the following won't type check in pyright (it doesn't infer the type of out):
out = []
for x in bar:
out.append(x \* 2)
return out
Edit: also pyright's vendoring of type stubs is annoying as they take precedence over downloaded type stubs.Edit2: also lack of plugins, makes using things like Pydantic less type safe compared to mypy
Narrowing on object truthiness unsure what you mean. That's intended to be supported. The out example is real difference where mypy does do better. It should at least type check on basic pyright but won't type check on strict without doing out: list[int]. That one comes from mypy has special handling for lists to allow inferring type of elements later, while pyright always infers type of a variable only based on it's declarations and never it's method calls like append.
Which isn’t very pythonic imho
Also I’m pretty sure ‘if res.ok is True’ doesn’t work
If that's not working for you you should open an issue at https://github.com/microsoft/pylance-release.
Besides the bug count, it's kind of weird to see the "reference" type checker for Python constantly lagging behind in terms of features, experimental ones but also ones that have already been accepted PEPs for a while. Meanwhile pyre and pyright both have usually had features for _months_ before mypy has even started implementing them.
As a side question, does anyone know how I can easily interface with an LSP client from Python? I'm itching to build something that gives me some custom typing insight as I write code, and it's probably more robust to consult LSP than to parse CLI output.
At same time this only affects a subset of Django behavior and I have used pyright with a Django codebase and it mostly worked well. The more you use very dynamic features of Django the more this matters.
One note for both is you do want to tune configuration settings. Pyright basic is fairly easy to satisfy, pyright strict is too hard for most codebases. Similarly mypy defaults are too lenient, but mypy strict is pretty hard (even mypy doesn't use strict to check itself). I roughly go for strict for both and then remove ~5 hardest rules and call that good enough. Strictest rules pretty much require all of your dependencies to be well typed/stubbed.
In general, we were very happy with the result and never looked back. Correctness and perf were both notably improved. (That pyright is also part of pylance, Microsoft’s proprietary LSP implementation for Python that plays well with VSCode, was an advantage for this particular team.)
This was about a year and a half ago so the experience may differ; both pyright and mypy + its plugins have gotten more capable and mature over time.
When the pain of maintaining larger codebases resulted in attempts to add static type checking (ultimately successful), it was, and still is, impossible to produce a solution that would work equally well for all kinds of codebases. Stricter tools show too many "false positives", laxer tools miss too many cases that a real static type checker would flag. Say, things that Django does (not to mention Zope) can only be described well by special-casing them. Hence different tools which strike different kinds of compromises.
Is it? Mypy is semi-official and has Guido as a contributor. It also predates both pyright and pyre by many years.
Honestly I find it somewhat sad that huge tech companies create their own instead of contributing to an existing and popular implementation. But perhaps the internal versions predated Mypy by a lot.
Pyre's reason is interesting, https://github.com/facebook/pyre-check/issues/38. Pyre is based off of Hack, facebook's php compiler. Facebook made pyre to re-use tooling/techniques from Hack on python. Secondary reason is performance. Pyre is done in OCaml and having same performance in type checker implemented within python is hard.
I usually pair it with pyre, another great tool
FB people have great experience with introducing typing into weakly typed languages (e.g. PHP vs Hack). So I actually started using pyre-check in place of mypy. The tool is really great and fast. I also like pysa quite a lot.
Pyright only came into focus because it was best Python LSP implementation for NeoVim, and it is also the default for helix-editor which I play with. It's also nice that I could suggest pyright for some younger colleagues using VisualStudio Code (with strict mode enabled of course).
P.S. I'm also using other interesting tools and libraries from FB (Instagram) like libcst [1] or fixit [2]
[1] https://github.com/Instagram/LibCST/ [2] https://github.com/Instagram/Fixit
Why both? I just have more confidence in getting feedback from both of the tools.
Pyright: Static type checker for Python - https://news.ycombinator.com/item?id=19473631 - March 2019 (87 comments)
Also:
Using Mypy in Production - https://news.ycombinator.com/item?id=32556816 - Aug 2022 (129 comments)
Exhaustiveness Checking with Mypy - https://news.ycombinator.com/item?id=25428583 - Dec 2020 (19 comments)
Applying Mypy to real-world projects - https://news.ycombinator.com/item?id=22302789 - Feb 2020 (23 comments)
Statically-typed error handling in Python using Mypy - https://news.ycombinator.com/item?id=21736620 - Dec 2019 (126 comments)
Pytype – A static type analyzer for Python code - https://news.ycombinator.com/item?id=19476605 - March 2019 (29 comments)
Pyre: Facebook's static type checker for Python - https://news.ycombinator.com/item?id=19476286 - March 2019 (2 comments)
Type hints cheat sheet (Python 3) - https://news.ycombinator.com/item?id=18660309 - Dec 2018 (18 comments)
PyAnnotate – Auto-generate type annotations for mypy - https://news.ycombinator.com/item?id=15707877 - Nov 2017 (33 comments)
Static types in Python - https://news.ycombinator.com/item?id=12703008 - Oct 2016 (221 comments)
Typed Python: new Mypy release - https://news.ycombinator.com/item?id=11641245 - May 2016 (46 comments)
Mypy 0.3 Released – optional static type checker for Python - https://news.ycombinator.com/item?id=11134647 - Feb 2016 (19 comments)
Mypy – static type checking for Python 3 - https://news.ycombinator.com/item?id=8191916 - Aug 2014 (29 comments)
Mypy - An experimental Python variant with dynamic and static typing - https://news.ycombinator.com/item?id=4561973 - Sept 2012 (39 comments)
https://github.com/microbit-foundation/pyright (and more specifically https://github.com/microbit-foundation/pyright/blob/microbit... )