I'm the author of Robust Python, and the first quarter of my book is all about type hinting, so suffice to say I've thought about it a lot. What follows is strictly my opinion on things.
I absolutely agree that there needs to be a balance between verbosity and clarity. Obvious things such as some variable names probably don't need to be annotated, but I think we disagree with what an obvious name is. When I see a variable named timestamp, is that an int, or a datetime? When I see days_since_creation, is that an int or a timedelta? When I see amount_paid, is that an int, float, decimal.Decimal or some custom type? The only way I can answer these questions is look at how it's used. For variables that may be clear, but for things like parameters in a function it's less clear. I have to look at calling code to see what people can pass in, and I have no guarantee that all the calling code is even visible to me. In these cases, I will happily trade off the verbosity of a type annotation so that I can have a better chance of correctness as more people work on the code over years. Now, if the project is small, maintained by a single developer or something like that, then I would say type hints can just be added noise. (but if at anytime you need to change the name of a variable to be more clear, such as "amount_paid" -> "amount_paid_decimal", I would encourage a type annotation instead).
I also think it's a mistake to treat type checking as a hack to feel more Java-like. I feel like the more appropriate counterpart is TypeScript (Guido has talked about it before: https://developers.slashdot.org/story/21/05/22/0348235/what-...). I believe type annotations (along with type checkers) was introduced to Python to solve an absolutely real problem with dealing with the robustness of codebase when you have multiple people working on it (across multiple years, even decades even).
All in all, yes, I do not think you should be type annotating everything, but I also am wary about type annotating too little. All of this advice is context-dependent; there is no one right answer depending on project size/value. But if you want to increase communication and lessen the amount of mistakes someone can make as they modify your code (especially if they never get the chance to talk to you), I whole-heartedly endorse type checking and type annotations. After all, your code is going to be read much more often than written, and I'd rather optimize for the unfortunate souls who have to read my code later on. I'll happily pay the penalty now for writing out a few more characters.
I just read your book this last week and loved it! I came here to recommend it.
One thing I still struggle with, though your book helped a lot, is when you start trying to get typing right with decorators and other types of misdirection. You pretty quickly start reading through PEPs and forums and using weird hacks that may or may not be a good idea.
For example, I’ve spent a fair amount of time trying to get PyCharm to understand a classmethod property to no avail. It’s hard to know if it’s a problem with my typing, a problem with PyCharm, or something else.
If it makes you feel better, I struggle with that too from time to time -> it happens to the best of us. It's a tricky thing to balance the use of more complicated features, because sometimes it clarifies things and sometimes it makes it more complicated (and often depends on the audience).
My main recommendation is to not get too hung up on fighting your tools, at some point, you run into a law of diminishing returns. I've run into bugs in tools and have sucked it up and put in a # type: ignore. But, and this is critical, I try to have a comment for future developers who might have a better way to do it, or even a link to a public bug. Remember, your main goal is communication to the future, not necessarily a strict dogmatic rigor of type adoption.
That being said, I always love a good programming puzzle, so if you get stuck on something like that, feel free to reach out to me on Twitter. No promises I have the answer, but I like learning just as much as the next person.
Relax. Per my understanding, you don't need to push yourself so hard. I come from C/C++/Java first. Then I use python. When I learn python, everyone said that the good part of python is its duck type and dynamic type. Now everyone talked about type hints. I can't express my feeling about it. Per my experience, type hints can improve your code quality if you are working with huge code base or some complex project. However, if you just write some scripts to auto some daily tasks, using type hints is a kind of over-skill.
Author of Robust Python here: I definitely recommend Fluent Python as well once the 2nd edition is available. I wrote Robust Python to focus very much on how to write Python in a long-lived codebase and how to do trade-offs for readability/maintainability/testability/etc. It also covers a lot of things outside of standard built-ins (such as acceptance testing, mutation testing, pydantic, type checkers, etc.). I find Fluent Python to be more focused on more of the built-ins, and I think it might cover some of the performance trade-offs you might be looking for.
Long story short : I think both have a lot of value (but beware I'm quite biased on Robust Python)
I'm the author of Robust Python, and the first quarter of my book is all about type hinting, so suffice to say I've thought about it a lot. What follows is strictly my opinion on things.
I absolutely agree that there needs to be a balance between verbosity and clarity. Obvious things such as some variable names probably don't need to be annotated, but I think we disagree with what an obvious name is. When I see a variable named timestamp, is that an int, or a datetime? When I see days_since_creation, is that an int or a timedelta? When I see amount_paid, is that an int, float, decimal.Decimal or some custom type? The only way I can answer these questions is look at how it's used. For variables that may be clear, but for things like parameters in a function it's less clear. I have to look at calling code to see what people can pass in, and I have no guarantee that all the calling code is even visible to me. In these cases, I will happily trade off the verbosity of a type annotation so that I can have a better chance of correctness as more people work on the code over years. Now, if the project is small, maintained by a single developer or something like that, then I would say type hints can just be added noise. (but if at anytime you need to change the name of a variable to be more clear, such as "amount_paid" -> "amount_paid_decimal", I would encourage a type annotation instead).
I also think it's a mistake to treat type checking as a hack to feel more Java-like. I feel like the more appropriate counterpart is TypeScript (Guido has talked about it before: https://developers.slashdot.org/story/21/05/22/0348235/what-...). I believe type annotations (along with type checkers) was introduced to Python to solve an absolutely real problem with dealing with the robustness of codebase when you have multiple people working on it (across multiple years, even decades even).
All in all, yes, I do not think you should be type annotating everything, but I also am wary about type annotating too little. All of this advice is context-dependent; there is no one right answer depending on project size/value. But if you want to increase communication and lessen the amount of mistakes someone can make as they modify your code (especially if they never get the chance to talk to you), I whole-heartedly endorse type checking and type annotations. After all, your code is going to be read much more often than written, and I'd rather optimize for the unfortunate souls who have to read my code later on. I'll happily pay the penalty now for writing out a few more characters.