I think that you have a few (pretty common, I would say) misconceptions about what type hints in Python are.
> I want to argue the same, obvious stuff don't need to be annotated
The first misconception is that type hints are something optional: they are not. Every single Python variable, function argument and return are annotated - it's only that, if there is no explicit annotation, it is assumed to be `Any`.
As we know, Python is strongly-typed: every object has a clearly defined type, even if it's the default `object`. However it is also dynamically-typed, meaning that variables do not constrain which types they can contain; so every variable can contain anything.
> Python type serve as extra documentation
The second misconception is that the annotations are there to document which types a variable is supposed to contain. I mean yes, that is definitely a welcome effect, but their primary purpose is to enable static analysis, i.e. to validate that there are no unexpected collisions between types when executing a program.
The main difference between Python and statically-typed languages like C++ or Java is that, in Python, the static analysis step is optional - if you don't run `mypy` or another type checker before deploying, your program will still happily execute as if there were no annotations at all.
> balance between clarity and verbosity
Another misconception is that type annotations inevitably make your code more verbose. In fact, you can have all the benefits of the typing annotations without having a single type hint in your code.
Python typing specifications allow you to expunge all your typing annotations into separate files, and keep the main code clean of them. For example imagine a source file, let's call it `foo.py`, which looks like this:
def foo(bar, baz):
return f"result: {bar + baz}"
class Bla:
def lalala(self):
return 42
Now you can have a separate file, named `foo.pyi`, which looks like this:
def foo(bar: int, baz: int) -> str: ...
class Bla:
def lalala(self) -> int: ...
Now, when you run `mypy`, it will use that second file to validate the typing information. This is called a "stub file", and you can read more about them in PEP 484 [0].
A few more misconceptions:
> - args and kwargs: We all know that these are lists and dictionaries respectively.However, I've seen code where they are annotated still.
Annotating args and kwargs are not about annotating those variables themselves, they are about marking their contents*. So if you annotate `kwargs` with `dict`, you're telling `mypy` that you expect the value of each keyword argument to be a dictionary, which is probably not what you wanted.
> When a function doesn't return anything, should we still annotate it with None, or we are kinda stating the obvious here.
Yes, because without an explicit annotation the default is `Any`, which is different from `None`. Specifically, as explained in the `mypy` documentation [1], an unannotated function is considered to be "dynamically typed", and some internal typing errors might go unchecked.
Again, for the purposes of static analysis nothing is "obvious".
> When the variable name is obvious. Do I still need to tell the type if the variable is called timestamp
Even if we look at annotation as simply documentation - does your variable contain a datetime object, a numeric timestamp (e.g. Linux epoch), or maybe an ISO 8601 formatted string?
> I feel like type checking is a way to hack a dynamic language like Python to become Java
As described above, the only difference between Python and Java (when it comes to typing) is that the latter enforces static analysis at compile time. Python, being dynamically interpreted, would require this analysis to happen on every run, which would make most programs completely unusable, so this analysis is completely optional. Yes, at runtime a Python function can be passed a type it does not know how to handle; but this is also perfectly possible even in statically typed languages.
Static analysis is a powerful tool, and many static language proponents insists that they give you enough correctness validation that you don't need unit tests. But it is only a tool, and it is a great benefit to have an option of having it when desired and ignoring it when practical; most languages don't have that luxury.
[0] https://www.python.org/dev/peps/pep-0484/#stub-files
[1] https://mypy.readthedocs.io/en/stable/getting_started.html?h...