7 ms·
So three years passed and static checkers have gotten even more traction. What's the best option for Python so far for small projects today? I tried mypy [1] b
by flakiness 5y ago
So three years passed and static checkers have gotten even more traction. What's the best option for Python so far for small projects today?
I tried mypy [1] before but it was a bit cumbersome to keep it checking my code. At work I use pytype [2]. It's good enough but that's only because someone else made a build system integration for me. Pyre's scan-all-the-files approach seems easier to get started. Is there any catch? Which one are you using and what's your impression?
[1] https://mypy.readthedocs.io/en/stable/
[2] https://github.com/google/pytype
- hiq 5y agoAs someone who hasn't started using types in Python seriously yet, it's a bit discouraging to see that there are already so many competing type checkers with different approaches and no clear winner. I understand that the problem is a bit harder than `{go, cargo} fmt`, but I feel we'd be better off with one type checker to rule them all. Or does it mean that we should check types using all type-checkers available to have the most compliant code possible?
- Mehdi2277 5y agoIn practice they are quite similar in errors reported. There are differences that pop up but most of the time either it is bug to report or one has implemented a certain pep faster than another. A few rare things are extra type checking support entirely like pyright supports recursive types but mypy does not (or pyre has best tensor related support but those are future peps). Mypy's biggest unique thing is plugin support and some very dynamic libraries use plugins for better coverage. The differences should become peps if important enough and then eventually be supported by all 4. I think for most people any of the 4 big ones is fine. Most of the common type errors will look identical regardless of which you pick. Configuring multiple in CI is pretty straightforward if you want to go full. My current codebase has mypy + pyright configured. Pyright was a mix of fast response time on github issues + I use vscode and was the one that added type checks to CI. If you want a deep dive pycon is this week I think and there's a day for type checking related talks including one talk comparing the 4. I think type checking day is thursday.
- flakiness 5y agoThanks for the tip! Posting link here for the reference: https://us.pycon.org/2021/summits/typing/ https://us.pycon.org/2021/summits/typing/ Hope they post the recordings somewhere later.
- ben509 5y agoNo, multiple checkers will drive you crazy because one type checker will support one feature while another will report errors for it.
- pl-94 5y agoI personally use neovim with coc-pyright plugin. It integrates remarkably well mypy. It has saved me so many hours of development, I just can't dev without it nowadays.
- MapleWalnut 5y agoI've used mypy and pyright. Mypy generally "just works" for all the Python idioms I use, while pyright is less reliable. Pyright's VSCode integration, Pylance, provides a great auto complete experience. So I use Pyright for autocomplete in VSCode and mypy for type checking.
- throwaway894345 5y agoLast I checked, mypy struggled to represent recursive types. Think `JSON = Union[None, bool, str, float, int, List['JSON'], Dict[str, 'JSON']`. That's a bummer because recursive data types are darn handy. Worse, importing third party packages often fails silently and when you can get error messages they tend to be completely inactionable (I recall one error message which linked to a web page that had lots of details and workarounds for fixing other problems, but none of which solved the error itself). Figuring out how to distribute my own type annotations was similarly painful. IIRC, you have to drop a specially-named file into a particular directory and this is all undocumented save for a dense PEP and the error messages are unsurprisingly terrible. All of these things are actionable, but the progress seems slow (these have been among my top grievances since the project debuted, so the maintainers and I have different priorities, clearly). The problems for which I'm less optimistic tend to revolve around shoehorning typing into existing Python syntax--e.g., to get a callback that takes kwargs you have to define a protocol with a `__call__` method that takes kwargs because you can't express it with `typing.Callable`. Similarly where a language with first-class support for types might have `type Foo<T>`, Python makes you write `T = TypeVar("T"); class Foo(Generic[T])` or something like that, and it gets more confusing when you only want one of the methods to be generic and I can never remember whether that `T` takes on a single type across all uses or which scope I need to define it in, etc. This is largely an ergonomic nightmare and I don't have lots of optimism for this stuff to improve unless the Python community really comes to embrace typing as the default way to use Python (but I suspect most people who care a lot about this kind of stuff will leave for Go or other languages where these things just work out of the box).
- codethief 5y ago> Similarly where a language with first-class support for types might have `type Foo<T>`, Python makes you write `T = TypeVar("T"); class Foo(Generic[T])` or something like that, and it gets more confusing when you only want one of the methods to be generic and I can never remember whether that `T` takes on a single type across all uses or which scope I need to define it in, etc. I don't know about you but I find PEP 484 very clear here: https://www.python.org/dev/peps/pep-0484/#scoping-rules-for-type-variables https://www.python.org/dev/peps/pep-0484/#scoping-rules-for-...
- zem 5y agohave you had any problems using the open source version of pytype? we've tried to make it easy to just drop in to your setup.cfg and automatically analyse an entire project; if there are things that don't work we'd love bug reports for them!
- flakiness 5y agoNo. I didn't expect it to be non-blaze/bazel tool friendly, but sounds like it is (aims to be at lest)? It does seems to support the entire-directory parsing as well. That's nice! Let me give it a try next time. Thanks for the tip! As a reminder to myself, here is the link to the doc: https://google.github.io/pytype/ https://google.github.io/pytype/
- tomwojcik 5y agoI'd advise to give mypy yet another try but disable in config file error codes that are painful and # noqa or # type: ignore lines that can't be understood well by mypy.
- nickm12 5y agoI'm not sure what you mean by "cannot be understood well". Either the type annotation is correct or not. If there is a genuine bug in mypy, the recommended convention is to use "type: ignore" (ideally with a reference to a bug tracking id). If you are genuinely subverting the typesystem, then use a cast(). If the code is too complex to type correctly or the type cannot be expressed in the typesystem (e.g. recursive types) then use type Any.
- 6gvONxR4sf7o 5y agoWhichever option you take, stick it into pre-commit. A good pre-commit-config.yaml is quality-of-life changing.
- jchonphoenix 5y agoMypy and Pyre appear to be the only two that work really well and can solve type-checking issues at scale.