If you enforce them then you can't do duck typing, this means adding lots of boilerplate code to your code base, increasing the amount of bugs, since bugs are proportional to the total number of lines of code in the project.
Typing related bugs that aren't caught in unit testing are very rare.
Any additional bugs per lines of code, which would be less in a strictly typed language anyway, is worth the structure you get from a typed language.
I disliked JavaScript and love python. Typescript has replaced python as my labor of love language for now but a typed python in a similar manner would be great
> If you enforce them then you can't do duck typing, this means adding lots of boilerplate code to your code base, increasing the amount of bugs, since bugs are proportional to the total number of lines of code in the project.
You can still do duck typing. Python's Protocol and TypedDict do that for objects and dicts, respectively. Python also has sum types. I've added type annotations to thousands of lines of legacy code and rarely have I had to change any logic to accommodate.
> Typing related bugs that aren't caught in unit testing are very rare.
Not true at all. Unless you're writing unit tests that cover every possible code path, your unit tests will miss stuff. And I'd argue that 100% test coverage is a Herculean effort to write and maintain, and isn't worth it. Static analysis gives you tons of checking for free. The biggest benefit is forcing you to properly handle function arguments that could be None. Are you always checking that values aren't None before using them?
It absolutely is a code correctness tool. If I have a function that should only accept a string then static analysis will error in all the places that pass anything else. As long as you validate your inputs (i.e. request validation) then the type annotations are representative of the runtime types