HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
python
mypy
Python2013–2026
python / mypy

mypy

Optional static typing for Python

81Distinct people
96Mentions
1Explicit recommenders
20.7KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Optional static typing for Python

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

PEP 695 is great. I've been using mypy every day at work in last couple years or so with very strict parameters (no any type etc) and I have experience writing real life…

gnulinux used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 6:01:08 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year96 dated mentions

Observed mentions: 2013-07-08 20:54:16 UTC to 2026-03-17 14:56:14 UTC.

0510152013-01-01 00:00:00 UTC to 2014-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments20132014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 2 mentions; 2 submissions, 0 comments2015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 5 mentions; 2 submissions, 3 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 6 mentions; 0 submissions, 6 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 15 mentions; 0 submissions, 15 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 17 mentions; 1 submissions, 16 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 10 mentions; 1 submissions, 9 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 9 mentions; 0 submissions, 9 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 11 mentions; 0 submissions, 11 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 8 mentions; 1 submissions, 7 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20132013-01-01 00:00:00 UTC2014-01-01 00:00:00 UTC110
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC220
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC101
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC523
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC606
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC202
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC15015
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC17116
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC1019
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC909
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC11011
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC817
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC707
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC202

What Hacker News says

11 sources
It's funny you should say this. Reading this article prompted me to future-proof a program I maintain for fun that deals with time; it had one use of utcnow, which I fixed. And then I tripped over a runtime type problem in an unrelated area of the code, despite the code being green under "mypy --strict". (and "100% coverage" from tests, except this particular exception only occured in a "# pragma: no-cover" codepath so it wasn't actually covered) It turns out that because of some core decisions about how datetime objects work, `datetime.date.today() < datetime.datetime.now()` type-checks but gives a TypeError at runtime. Oops. (cause discussed at length in https://github.com/python/mypy/issues/9015 but without action for 3 years) One solution is apparently to use `datetype` for type annotations (while continuing to use `datetime` objects
Read the rest
In datetime.utcnow() is now deprecated
gnulinux·Oct 18, 2023Recommendation phrase
PEP 695 is great. I've been using mypy every day at work in last couple years or so with very strict parameters (no any type etc) and I have experience writing real life programs with Rust, Agda, and some Haskell before, so I'm familiar with strict type systems. I'm sure many will disagree with me but these are my very honest opinions as a professional who uses Python types every day: * Some types are better than no types. I love Python types, and I consider them required. Even if they're not type-checked they're better than no types. If they're type-checked it's even better. If things are typed properly (no any etc) and type-checked that's even better. And so on... * Having said this, Python's type system as checked by mypy feels like a toy type system. It's very easy to fool it, and you need to be careful so that type-checking actually
Read the rest
fails badly formed programs. * The biggest issue I face are exceptions. Community discussed this many times [1] [2] and the overall consensus is to not check exceptions. I personally disagree as if you have a Python program that's meticulously typed and type-checked exceptions still cause bad states and since Python code uses exceptions liberally, it's pretty easy to accidentally go to a bad state. E.g. in the linked github issue JukkaL (developer) claims checking things like "KeyError" will create too many false positives, I strongly disagree. If a function can realistically raise a "KeyError" the program should be properly written to accept this at some level otherwise something that returns type T but 0.01% of the time raises "KeyError" should actually be typed "Raises[T, KeyError]". * PEP 695 will help because typing things particularly is very helpful. Often you want to pass bunch of Ts around but since this is impractical some devs resort to passing "dict[str, Any]"s around and thus things type-check but you still get "KeyError" left and right. It's better to have "SomeStructure[T]" types with "T" as your custom data type (whether dataclass, or pydantic, or traditional class) so that type system has more opportunities to reject bad programs. * Overall, I'm personally very optimistic about the future of types in Python! [1] https://github.com/python/mypy/issues/1773 [2] https://discuss.python.org/t/extend-type-hints-to-cover-exce...
In What's New in Python 3.12
It's quite useful on ci, and as a `make mypy` can run before pushing up your code, but for interactive errors we all use pyright, which is a bit of a letdown because you don't get autocomplete for fields and models accessed through reverse relation managers etc, pyright doesn't know about them. Many packages ship types nowadays, so the type coverage isn't too bad for us right now. Here's our plugin setup in mypy.ini in case this helps (Django 4.2 + drf 3.14) [mypy] plugins = mypy_django_plugin.main, mypy_drf_plugin.main ignore_missing_imports = True follow_imports = silent no_implicit_optional = True warn_unused_ignores = True check_untyped_defs = True disallow_untyped_defs = True disallow_untyped_calls = True warn_unreachable = True strict_equality = True allow_redefinition = True show_error_codes =
Read the rest
True mypy_path = stubs [mypy.plugins.django-stubs] django_settings_module = 'mycompany.settings' with packages: mypy==1.6.0 django-stubs==4.2.4 django-stubs-ext==4.2.2 djangorestframework-stubs==3.14.3 with this horror of a regex in make (because you'll get drowned in wrong type errors in all of the untype files, and errors get shown from imports even if you don't care about that imported file), add more file targets as necessary: FILES_TO_MYPY = $(shell ls mycompany/\*/validators.py mycompany/\*/services.py mycompany/\*/selectors.py mycompany/\*/managers.py | sort | uniq) # 1)We have to grep out django-manager-missing like this until the following bug # is fixed: https://github.com/python/mypy/issues/12987. # 2) We grep out the line of `Found 95 errors in 16 files (checked 83 source # files)` that now appears as we use follow-imports: silent, because there's a # bug where errors from imported modules are counted against the total even # though they aren't emitted. If any real errors appear we get them as a # separate line anyways. .PHONY: mypy mypy: @{ MYPY_FORCE_COLOR=${NOT_CI} $(VENV)/bin/mypy --config-file mypy.ini $(FILES_TO_MYPY) 2>&3 | grep -v 'django-manager-missing\|errors in'; } 3>&1 | tee $(HYRE_TESTS_OUTPUT_PATH)/mypy.stdout.txt This allows you to get proper errors for things like model = MyModel.objects.get() othermodel = model.othermodel_set.first() reveal_type(othermodel) # correctly revealed to note: Revealed type is "Union[mycompany.importpath.models.OtherModel None]" and even errors on typos like model = MyModel.objects.get() othermodel = model.ooooothermodel_set.first() # revealed as MyModel has no attribute ooooothermodel_set, perhaps you ment othermodel_set .
In Mypy 1.6
You probably already know but you can add type hints and then check for consistency with https://github.com/python/mypy in python. Modern Python with things like https://learnpython.com/blog/python-match-case-statement/ + mypy + Ruff for linting https://github.com/astral-sh/ruff can get pretty good results. I found typed dataclasses (https://docs.python.org/3/library/dataclasses.html) in python using mypy to give me really high confidence when building data representations. And there's https://pypi.org/project/django-stubs/ for working with Django.
In Ask HN: Why are all of the best back end web frameworks dynamically typed?
>Ah OK, so this is where I think that we're talking past each other. When I say "testing", and the reason I focus on making them automated is that when I sit down to write tests, if I'm really up to it I get myself in a mood where I'm thinking of what can go wrong. >Doing that is what I'm suggesting might have made the difference. What? I get myself in the mood for manual tests too. We're not talking past each other. You can't just quote "testing" and embed extra meaning into that after the fact. There's no way I would know what you're talking about. >I'm not a python + mypy regular user though, so I don't know where it's limits are, but particularly with the haskell comparison, it does not support GADTs (https://github.com/python/mypy/issues/8252). Also, I know it doesn't support Rust's affine type system (ownership/borrows). Nah when it
Read the rest
comes to the lang extensions almost nothing comes close. I'm just talking about regular haskell ADTs. The affine stuff isn't relevant as python uses a GC. What does it even mean to do borrow checking when nothing owns a variable in python? It's quite obvious I'm just referring to the ADTs here. Python supports regular ADTs better than typescript. So it's better imo. But that's just my initial opinion, I don't use ts extensively so it might be better. >I personally believe NodeJS is the best of the "scripting" languages, but that's a whole 'nother discussion. If You mean JS. then no, JS is horrible. Typescript has an argument here, I think that's what you mean. >I agree on being flexible, I like using Haskell/Rust because of this as well. I certainly disagree that python matches any of those others in type level power though. It matches it in terms of ADTs and where relevant. >Theorem proving != engineering, and this is why Haskell/Idris/ML languages at large never hit mainstream properly. If you try to write the kind of types that could even attempt to get correctness absolutely right, less than 0.1% of programmers would be able to use or work on your codebase. So? I never made this claim. I just said there are other methodologies to employ other then strict fanatical loyalty to testing. I simply used Idris as an example of an alternate path. In fact I specifically STATED that it would be hard to use proofs with Idris. >I don't think TLA+ is relevant here because it's mostly used for testing distributed/concurrent systems in practice, and is not a PL so-to-speak. The point was using proof to write correct programs. So it's completely relevant as TLA+ is used for that. >Naturals (& peano numbers) are the categorical example of dependent types that are useful -- in Haskell, natural numbers are the set of positive integers including zero. It makes the -1 case impossible (i.e. fail to parse @ the program boundary), which is the point. ah my mistake I had a brain fart and thought you were referring to Haskells Num or something along those lines. Yes if by Nat you mean Haskell Nat or unsigned int, then that makes sense. >I think we're agreeing, but you just said two very different things -- most things (especially important ones) cannot be easily solved at the type level. I never said two different things. I think you just made some assumptions and responded to some paragraphs without reading far enough. Like your "Theorem proving != engineering," comment. If you read further you'd realize I already know about what you're saying. My overall point on this front is aspects of proving can help type checking and FP and other techniques reduce error rate by a large margin. >How do you type-check a redis connection at compile time? or a database like postgres at runtime? You can't, really -- because they are inherently dynamic things. I'm not sure why you're telling me this. Did I make a claim that type checking can work on a redis connection? Do you remember when I said integration tests are more important then unit tests? And unit tests are mostly practically trivial? Well type checking is sort of involved with that. I mean these are points I've been making throughout our conversation suddenly your like "How do you type check a redis connection?" as if I haven't made any of those points. I made a point and you made the same point. Anyway we agree here. >Yeah this is where we disagree -- I think this case called for it, you disagree. Yes. To get into more detail here. The point is the infra cost of integration tests we disagree on that, I don't think it's worth it all the time I think you believe it's worth it in more cases. For the take home project I still don't think it's worth it. But I concede I'm wrong because the Reviewer is looking for tests and I need to cater to what the reviewer is looking for. >We agree that sometimes tests are not necessary or warranted. Well you told me you have testing enshrined. So I was disagreeing with that. I think you were just making a statement about the importance of testing. In actuality we're more in agreement about the nuance of testing. >No problem, always glad to have a debate, and being able to have them on HN is why I still come to this site! Sometimes these conversations generate some heat on HN. I actually don't mind the heat, keeps people brutally honest. Great talking to you as well!
In Ask HN: I have 10 yrs of Exp. Failed 4 takehome projects. What am I doing wrong?
> No this bug wouldn't have been caught. I'd have to write the test for it. ... Ah OK, so this is where I think that we're talking past each other. When I say "testing", and the reason I focus on making them automated is that when I sit down to write tests, if I'm really up to it I get myself in a mood where I'm thinking of what can go wrong. Doing that is what I'm suggesting might have made the difference. > This is where you are wrong. Python has what I call an opt-in type system meaning it's optional and it can be as strong as you want it to be. You choose the external type checker like mypy and those type checkers can be as powerful as you want. ... > > The python type system can even do Haskell/Rust level exhaustive matching on sum types: https://tech.preferred.jp/en/blog/python-exhaustive-union-ma... > So this comes back to me not w
Read the rest
riting much python -- but I have used typing + mypy briefly a while ago, but I'd need to see some claims it is nowhere near as powerful as Typescript/Rust/Haskell. I'm not a python + mypy regular user though, so I don't know where it's limits are, but particularly with the haskell comparison, it does not support GADTs (https://github.com/python/mypy/issues/8252). Also, I know it doesn't support Rust's affine type system (ownership/borrows). It's true that mypy could in theory do this, but it does not, and I do not expect it to anytime soon (backing for the other projects is more sound anyway). I personally believe NodeJS is the best of the "scripting" languages, but that's a whole 'nother discussion. > So modern python matches these language in type level power, it's just optional so it's not as pervasive as typescript but the option is there and when utilized it's equal if not better in power. But proof based coding isn't solely just on using types to prove out your code. I just used idris as an example of an alternative path. The reality is Idris is a bit too extreme because coding those types takes too much effort. > > Basically i change my coding style to both minimize errors and allow me to build a minimal proof in my head. I use coding style, proofs in my head, and a strong/versatile type system all in conjunction to minimize error rate to low enough levels that tests are less important. I agree on being flexible, I like using Haskell/Rust because of this as well. I certainly disagree that python matches any of those others in type level power though. > You can't do integration tests without using infrastructure and spinning up processes. Let me put it to you plainly. It's not ME who thinks it's difficult. It's the majority of the developer population knows it's much more difficult then unit tests. That's why such a segregation even exists. The fact that we categorize the tests into integration tests and unit tests speaks to huge differences between the two in difficulty. > > You may think integration tests are easy, but that's just your own opinion. This is different from the overall general opinion which is more inline with what I'm saying. Regardless of what other devs thing of it, it's worth doing IMO. Here's the project I linked before https://testcontainers-python.readthedocs.io/en/latest/READM... > Dependent types are enough to prove a program is correct given a set of specifications. Of course not everything can be proven. But most things can. Disagree with this. For example, memory leaks. If I define "correct" to be "doesn't leak memory", Haskell (for example -- don't know what the memory is like in Idris) is going to have a hard time. There are things that are hard/impossible to encode into dependent types. > Theorem proving is the title. or aka proving anything mathematical or aka proving mathematical programs meet mathematical specs. Dependent typing is one way to go about this. There are other ways. The intended design of idris is similar to TLA+ the intention is to allow the user to prove the program correct to a spec and avoid unit tests via proof. Theorem proving != engineering, and this is why Haskell/Idris/ML languages at large never hit mainstream properly. If you try to write the kind of types that could even attempt to get correctness absolutely right, less than 0.1% of programmers would be able to use or work on your codebase. I don't think TLA+ is relevant here because it's mostly used for testing distributed/concurrent systems in practice, and is not a PL so-to-speak. > How is using a nat more safe than an int? A nat just makes it more general. https://hackage.haskell.org/package/natural-numbers-0.1.2.0/... Naturals (& peano numbers) are the categorical example of dependent types that are useful -- in Haskell, natural numbers are the set of positive integers including zero. It makes the -1 case impossible (i.e. fail to parse @ the program boundary), which is the point. > With something like idris you can, technically speaking, eliminate the need for unit tests all together. But this is a technical thing. In practice it's really hard to achieve this due to how hard it is to write these proofs. But the technical level of safety is operating at the highest level here. I think we're agreeing, but you just said two very different things -- most things (especially important ones) cannot be easily solved at the type level. How do you type-check a redis connection at compile time? or a database like postgres at runtime? You can't, really -- because they are inherently dynamic things. Now in the case of unit tests, I'd argue that a good type system is one of the only things that can prevent you from having to write lots of unit tests. I'm pretty sure we agree on this! > I'll tell you this: I don't enshrine the concept of testing. It's always a case by case basis. Yeah this is where we disagree -- I think this case called for it, you disagree. We agree that sometimes tests are not necessary or warranted. > Hey I know this thread got a little heated. I want you know that I appreciate your viewpoints even though I disagree with a lot of points. I think heated but respectful debates are healthy and I definitely learned something here. Conversations where people are overly polite I feel like I learn nothing because people rather be polite then honest. So appreciate all the time you took to reply. I may be clashing hard against your points but there's nothing but respect here. You are clearly experienced. No problem, always glad to have a debate, and being able to have them on HN is why I still come to this site! We can disagree, and I benefit from learning where your disagreements are (I don't there are actually many, I think our stances on testing and types are very similar outside of me just not liking in python in any meaningful way).
In Ask HN: I have 10 yrs of Exp. Failed 4 takehome projects. What am I doing wrong?
I'm also 100% convinced most people who use mypy don't realize the myriad ways it just silently stopps typing things or just silently crashes with a 0 exit code. Even if you configure it to warn untyped functions etc. It will still just not work properly in some of circumstances and you will literally never know until you debug a bug that just happened to trigger it. There are over 1.4k open bug tickets it's such a broken piece of software: https://github.com/python/mypy/issues?q=is%3Aissue+is%3Aopen... The involvement of Guido in mypy is such a tragedy.
In Writing Python like it's Rust
Function annotations were added as part of Python 3.0, with PEP 3107, proposed in 2006 [0]. The first public mypy commit was in 2012 [1], and originally it was using C++-style syntax (`list<Token> lex(str s):`). The `typing` module and the official use of function annotation for type hints came in 2014 with PEP 484 [2], inspired by mypy. The first pyright commit was in 2019 (with a lot of code in the third commit [3], possibly moved from the VSCode extension). [0] https://peps.python.org/pep-3107/ [1] https://github.com/python/mypy/commit/6f0826a9c169c4f05bb893... [2] https://peps.python.org/pep-0484/ [3] https://github.com/microsoft/pyright/commit/1d91744b1f268fd0...
In The different uses of Python type hints
Python now has an optional type system and if you add one of them such as mypy or pyre to your CI process and you can configure GitHub to refuse the pull request until types are added you can make it somewhat strongly typed. If you have a preexisting codebase I believe the way you can convert it is to add the types that you know on commits and eventually you will have enough types that adding the missing ones should be easy. For the missing ones Any is a good choice. https://pyre-check.org and https://github.com/python/mypy are popular.
In Ruby 3.2’s YJIT is Production-Ready

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.