But, because type hints are just window dressing in Python, you still have to write those tests. So now when you make a change, you not only have to update your tests but also update your type hints everywhere. As far as I can tell, type hints just double the work for little to no benefit. If they actually removed a need for unit testing, that would be a different story, but then it wouldn't be Python anymore.
If I want to use types to enforce things, I'd prefer to use a language designed for that. But I choose Python because it lets me get things done quickly. Despite helping you out in some cases, overall maintaining type hints are a drag on that feeling of getting things done quickly. The last thing I want to do when writing Python is spend an afternoon composing a complicated TypeVar arrangement to express the full range of inputs my function can handle.
What this article talks about (Protocol) seems to be at least an improvement in that regard, as you can worry about what your function does instead of what your types do.
Type annotations are not window dressing in a Python workflow using typechecking tools over the final code base, unless you explicitly tell the typechecker to ignore a detected error.
It's true that a type annotated library can't necessarily rely on downstream clients to have type discipline, and some library packages may not be fully annotated, which may create gaps to address.
> If I want to use types to enforce things, I'd prefer to use a language designed for that.
Python's type annotations were designed largely to make Python compatible with a separate existing language designed for that purpose; there's a reason mypy’s domain is mypy-lang.org
> What this article talks about (Protocol) seems to be at least an improvement in that regard, as you can worry about what your function does instead of what your types do.
Protocols are types; specifically, they are structural types.
To me even though the type annotations don't provide the same kind of guarantees that the type system of say Haskell does, they do increase the readability of the source code.
Finally (and this is more of my workflow), I utilize a build tool that has a mypy --strict call that will check my type annotations and alert me when things don't match up.
If you are using a static analyzer before deploying, type annotations are just as enforced in Python as in Haskell; that is, they are enforced by a process that happens before and detached from run time.