top | item 37914146

Mypy 1.6

167 points| hackandthink | 2 years ago |mypy-lang.blogspot.com | reply

110 comments

order
[+] _fdsfs12123|2 years ago|reply
Has anyone had to choose between Mypy and Pyright? Which is "better"?

A couple years ago I was in charge of choosing between the two, and I somewhat flippantly chose Pyright because it felt a lot faster (<5 second to do 30k lines) and had an easy integration with the editors people use at work (Pylance, coc-pyright).

Later, I realized that some popular libraries we use (django, numpy) have dedicated plugins for Mypy that you can't use with Pyright. So you have to look for Pyright-friendly type stubs or roll your own.

I've generally liked Pyright (as a side note, they have super responsive maintainers - ask a question on their GH, and they usually answer within a few hours), but I've been wondering if I am missing out with Mypy.

[+] davepeck|2 years ago|reply
At least today, my experience is that Pyright is faster, flags more issues, provides better error messages, and (alas for Mypy) has fewer bugs. I hope this will change over time as Mypy matures, but there you have it.

When using Pyright in large Django projects, it's helpful to add explicit type annotations in a number of places (like reverse relations in Models) but I've found this tends to improve the clarity of the resulting code anyway.

[+] strokirk|2 years ago|reply
Pyright doesn’t really support a lot of big libraries, like Django, so if you want to use them you’re out of luck.
[+] veber-alex|2 years ago|reply
pyright and ruff are my new go to python tools, replacing mypy, pylint, isort and black.

So far the only thing that bothers me about pyright is that it can't infer the type of collections based on later insertions.

So in something like:

  lst = []
  lst.append(1)
lst is of type list[Any]

I also program in Rust so I kinda expect this to work :P

I asked the maintainer about this and this is apparently by design, though mypy handles this correctly IIRC.

[+] rhaps0dy|2 years ago|reply
Pyright is great, and IME does more inference than Mypy and flags more errors.

Mypy is catching up on speed though! Can't say I've tried any plugins.

[+] IshKebab|2 years ago|reply
Pyright is much better.

It is much better written, much more correct, has fewer bugs, and it is the default in VSCode so less friction to set up.

In my experience it isn't hugely faster so I wouldn't say that is a big factor. The main benefit is that it is just very correct and has very few bugs (and when there are bugs they are fixed very quickly).

I would avoid Mypy if at all possible. I once tried to fix a bug in it and the codebase was very very hairy. Partly that's because it predates official type hinting support, and partly because it supports a load of hacks to allow incorrect types. Sometimes even the way you write the type affects how it is interpreted (e.g. `a # type: foo` is different to `a: foo`).

The only times I would choose Mypy is if you really need one of those plugins you mentioned, or if you are adding types to a legacy codebase and can't face seeing how bad it really is.

[+] gen220|2 years ago|reply
`mypy` originally had first-mover advantage, `pyright` has late-mover advantage.

Now that we're in the mid-to-late stage of Python typecheckers, `pyright` has a better intercept and slope than `mypy`.

I think there'll be one last typechecker to rule them all written in Rust – but we're not there yet, so use `pyright`.

[+] globular-toast|2 years ago|reply
For Django there is django-types, a fork of django-stubs that works without the mypy plugin. There might be similar for numpy.
[+] maximilianroos|2 years ago|reply
For those using mypy and wishing it were a bit faster — dmypy is really good.

I often leave this running, so I can see live errors on every save:

    watchexec -rc -e py -- dmypy run
[+] kps|2 years ago|reply
I don't touch Python much, so last time I wrote something, I used mypy and pyright and pylint and ruff.
[+] kelsolaar|2 years ago|reply
We started with Mypy for thr colour-science.org projects but Pyright is so much faster that it is hard to look back. We have no particular issue with Numpy. As you pointed out the devs, especially Eric Traut, are really responsive.
[+] guappa|2 years ago|reply
Last I tried it, pyright had several false positives that didn't affect mypy. So I remained with mypy.
[+] KolmogorovComp|2 years ago|reply
Is anyone still using mypy, and if so why? I have replaced it by pyright [0] for a while now, and not looking back. It’s been a faster, more powerful replacement with (in my case), zero downside.

[0]: https://github.com/microsoft/pyright

[+] aleksanb|2 years ago|reply
Pyright doesn't work with Django, as Django's so dynamic that it requires a plugin to infer all types correctly. Sadly, even mypy with plugins is a mess to get set up in vscode, especially if you want it to use the same config as you use for ci checks from the command line.

We use mypy + [django-stubs](https://github.com/typeddjango/django-stubs) (in a huge Django + drf project at day job) which includes a plugin for mypy allowing it to recognize all reverse relations and manager methods. Mypy is still really rough around the edges. The cli args are poorly documented, and how they correspond to declarations in a mypy.ini / pyproject.toml is mysterious. Match-statements still have bugs even a year after release. Exclusion of untyped / partially typed files and packages we've had to solve with grep filtering mypy's output for our whitelisted set of files, as it's been unable to separate properly between errors you care about (in your own codebase) and errors in others code (dependencies, untypable dynamic python packages etc).

The largest issue IMO is that mypy tried to adapt a java / OOP style way of type system onto python, instead of recognizing the language's real power within duck typing and passing structural types around. Typescript chose the right approach here, modelling javascript the way it is actually written, favoring structural over nominal typing, instead of the archaic and now left-behind way of Java-style OOP that has influenced mypy.

There was a recently accepted PEP which allowed for limited dataclass transforms, enough to cover the @attr.s usecase for both mypy and pyright, but nowhere near expressive enough to cover django's models and ORM sadly. It's probably impossible / undesirable to allow for such rich plugins, so i see the future for proper pluginless typing to be more akin to how pydantic / normal dataclasses solve typing, by starting with a specification of the types, deriving its runtime implementation, instead of plugins having to reverse the type representation of a custom DSL.

[+] keithasaurus|2 years ago|reply
mypy is essentially the reference implementation. pyright probably is better as a type checker, but, for the referential aspect alone, I suspect many libraries will continue targeting mypy.

One potential benefit of mypy is that it comes with mypyc, a compiler that leverages mypy's evaluation of types. Since pyright and mypyc are not exactly equal, it makes sense to use mypy if you want to use mypyc.

[+] ehsankia|2 years ago|reply
Is there any in depth comparison of mypy, pytype, pyright and pyre yet?

They all seem to have slightly different approaches and features, but it's hard to decide which is best for the job.

[+] diarrhea|2 years ago|reply
I had started using mypy a couple years ago and simply never looked back at the decision. I perceived pyright as a Microsoft-specific tool, and waved it off, as mypy seemed the blessed and eventually converged-upon target.

Turns out that’s wrong so far. Tons of people advocating for the latter.

I quickly looked at the two repos. Pyright has 30 open issues. Mypy is at 2200. That is a simplistic metric, but an immense difference in any case.

[+] guappa|2 years ago|reply

    apt install pyright
    E: Unable to locate package pyright

    apt install mypy
    mypy is already the newest version (1.6.0-1).
[+] syntaxing|2 years ago|reply
I work on a monorepo and MyPy and Flake8 was such a PITA at first but after you use it for a while, you really see the value of type checking. Makes unit testing better and the code more robust in general. MyPy is seriously a great tool, especially with pydoc enforcements.
[+] diarrhea|2 years ago|reply
It makes unit testing better in the sense that it can obsolete a good chunk of it, even.
[+] softirq|2 years ago|reply
At that point, why not just use Go? It's designed to feel dynamic, provides concurrency primitives out of the box, and it's orders of magnitude faster for most tasks.
[+] VeejayRampay|2 years ago|reply
I really wish we had a ruff equivalent for python type checking, mypy is OK but it's really slow
[+] networked|2 years ago|reply
Pyre, written in OCaml, is the closest thing that's stable. It has been discussed on HN a couple of times. Here is the 2021 discussion: https://news.ycombinator.com/item?id=27107647.

Note that Pyre does not support Windows (https://github.com/facebook/pyre-check/issues/554) and only provides wheels for x86_64 Linux and macOS (https://pypi.org/project/pyre-check/0.9.18/#files). While I don't use Windows, it makes me reluctant to adopt it. First, I want Windows users to be able to contribute to my projects that work on Windows. Mypy and (predictably) Pyright won't create an obstacle for Windows users. Second, the limited number of platforms makes Pyre seem a little internal-toolish.

It may still be worth it. As of today, actually, one of my projects has a Pyre branch. I want to see what it is like developing with it.

[+] tyingq|2 years ago|reply
I want to like type hinted python, but there's always some corner case. Which is fine if I'm writing the rules, but there are teams that force things like "no adding ignore/disable for things you can't figure out".
[+] bloopernova|2 years ago|reply
Somewhat offtopic, does anyone have a link to a page that describes which extensions/tools I should be using with VSCode to author Python code?

Edited to add: when you read various recommendations, they're all discrete and don't have the overall context. e.g. I installed the VSCode suggested extensions, but then read a comment that I should really be using Ruff. OK, that's good, but if I have extensions X, Y, and Z, should I add extensions A, B, and C?

[+] gen220|2 years ago|reply
These pages are naturally out of date from the moment they're written.

Caveats aside, I use pyright, ruff and black (although ruff will probably one day consume `black`, entirely) – that's it.

`ruff` centralizes a lot of the linter/fixer ecosystem (isort, autoflake, pylint and more). `pyright` is for GoToDefinition and type-checking. `black` is for sanity-checking what `ruff` spits out, and should hopefully not be necessary (for me) as a standalone package at some point in the near future.

Ruff is not 1.0 yet, so I wouldn't use it at work – but I use it in all my own things.

[+] jimmydoe|2 years ago|reply
the default extension is good enough to begin with. as you are adding more to your project (e.g. black/isort/django), you can naturally find more extensions.
[+] imjonse|2 years ago|reply
In the age of most projects having animated websites, videos on the homepages, ads for courses and maybe an online conference for launching a new version, I find this use of 2006-era blogspot strangely comforting.
[+] thejosh|2 years ago|reply
Also has what the product actually IS in the header and everything! "Updates about mypy, an optional static type checker for Python"
[+] kunley|2 years ago|reply
It is a pity I can't upvote you more than once ;)
[+] coding123|2 years ago|reply
no idea how blogspot has survived this long
[+] baq|2 years ago|reply
For the past year I've worked with a large JS/TS project undergoing a slow, gradual transformation into TS - before that, for the better part of past 10 years I worked on a Python 3 + some typing, lightly enforced by mypy.

I must say I don't like JS, never have, likely never won't, but Typescript is a really pleasant language, even if JS underneath is more visible than I'd like. The mix of static analysis possible with TS vs added overhead of having to specify types (which can get very complex!) is just right. I welcome any and all efforts to make Python go this way - I'd be perfectly fine with transplanting TS type system as is.

[+] networked|2 years ago|reply
Do you know about Pyright? It is a Python type checker implemented in, and apparently influenced by, TypeScript. It is from Microsoft, so the influence is not that surprising.

There was a recent HN submission about it: https://news.ycombinator.com/item?id=34222407.

I use Pyright as my primary type checker and mypy as a secondary. (For example, Pyright won't run in Termux on my phone. I could likely fix this, but mypy just installs with pipx.) There is a document comparing Pyright and mypy in the Pyright repository: https://github.com/microsoft/pyright/blob/b09f35889a9cc9b262....

[+] solarkraft|2 years ago|reply
I find "dynamic during runtime + static during development" to be a highly potent combination because it largely prevents dumb programming mistakes and enables rich IDE hints while still allowing for enough magic to build beautiful interfaces.

While they are usually a great benefit and easy enough to so, sometimes getting types just right can be more of an effort than it's worth - it's beautiful that in those cases you can still go "fuck it, I know what I'm doing".

Best of both worlds, really.

[+] mjr00|2 years ago|reply
Python's typing ecosystem has come leaps and bounds, quickly. About 5 years ago I had to do an evaluation of Python+mypy and found that while mypy was a great idea, support by major libraries was abysmal and mypy itself was immature, so it wasn't suitable for real use. 2 years later, I took another look and the ecosystem had evolved massively, most libraries I cared about had type annotations added, PyCharm/VSCode had added support for type checking in the IDE, etc.

These days all of my use of Python is with type annotations that are validated by mypy as part of CI. It's very rare that I run into a Python library that doesn't have type annotations available. It's massively improved the stability of the Python code I'm working on. One indirect side effect is that static typing actively discourages people from poor design patterns such as **kwargs or passing around dicts/dataframes of data, since there's an obvious downside to doing so now.

[+] pjmlp|2 years ago|reply
That is basically my sentiment towards C, while using C++. :)
[+] cbb330|2 years ago|reply
I have 90 PRs to Mypy configured repos this year, across 10+ python repos which are a mix of services and background jobs. All of them have some mix of pyright/jedi+ruff+black. I have implemented these tools either via CI or in my ide like experience in NVim.

TLDR; BE WARNED. this basket of bandaids is NOT a replacement for a strongly typed language. I would NOT recommend Python to teams or for services. No amount of mypy, pydantic, pyright, ruff, black, can convert python into a production language. This collection of bandaids is complex to maintain, upgrade, standardize, and has infinite edge cases where type annotation errors are just wrong.

The worst part about this basket is that you get all of the above features for free and are REQUIRED with go via gopls and gofmt. Gopls "is the official Go language server developed by the Go team." good luck achieving parity of this in python.

If you implement a service/app/anything production, use anything but a dynamically typed language like python.

[+] linkdd|2 years ago|reply
> No amount of mypy, pydantic, pyright, ruff, black, can convert python into a production language.

Ah yes, because Python was never used in production ever, not at Google, not at Dropbox, not ever.

The "static typing above all else" cargo cult is getting ridiculous.

[+] totoglazer|2 years ago|reply
The continued growth and maturity of typing and LLMs like GitHub copilot finally make IDEs powerful for python. Excited about the future of the language.