The biggest issue with Python type hints for me isn't the hints themselves, it's that they encourage people to write overly complex, verbose code just to satisfy the type checker. Code like this [0] could simply be 3 functions. Instead it's 3 classes, plus a base class `AstNode`, just so the author can appease the type checker by writing `body: List[AstNode]` instead of the dynamically-typed `body = []`. [0] https://…
Writing `body: list[AstNode]` lets you statically know what elements you'll get when you do `body[i]` or iterate over it. If you don't specify the type, you don't know what you're getting, and you have to rely on always passing the correct objects around. I'm sure you've faced bugs where you expected something from a list and got something else. Note that you only need `body: list[AstNode] = []` if you declare an emp…
Don't get me wrong, I understand the benefit of the type hint - and if typing `: list[AstNode]` was all it took to get that benefit it would be a no-brainer. But that's not all it took - instead, to pass the type checker the entire script has become twice as long as it needs to be. The actual logic is hidden among multiple class definitions which are all unnecessary except to satisfy the type checker.
I agree with Armin Ronacher [0]: "types add value and they add cost". Perhaps the cost is worth paying for most programs - but there are plenty of other languages that support that way of working. For those programs where the cost might outweigh the benefits, I used to love writing Python as a more concise alternative to those languages - but instead nowadays it has become a poor attempt at mimicking them.