I disagree that type errors "aren't practically a problem". NoneType errors and AttributeErrors turn up all the time in Python.
I disagree that type errors "aren't practically a problem". NoneType errors and AttributeErrors turn up all the time in Python.
I've also written about this publicly before, e.g. https://mail.python.org/archives/list/typing-sig@python.org/..., where I found a number of errors by tweaking pytype in a way to make it stronger. It's difficult to quantify what percentage of bugs would have been found anyway, but pretty much any time the type systems I work with improve, it uncovers new bugs.
The result might be surprising, but those are the most interesting results! I note that, so far, nobody has countered this with any evidence, only anecdotes and "surely not!"
I'm not a fan of this kind of methodology, because there are so many different use cases for github issue tracker (including feature requests, documentation requests, etc.) that I think the denominator here is overestimated. I'd rather have a study that looked at 1000 issues in depth with a rigorous rubric than one that grepped through millions of issues.
Also, looking only at the issues doesn't count the ones that were caught in development or testing. I like the notion of "moving your bugs to the left"[1] and would much rather find these type errors at build time than later.
Finally as I said in my other comment, avoiding type errors is not the only benefit of type checking. Making code easier to understand and refactor (including programmatic refactoring) are other benefits that are not captured only by counting bugs.
Aside: It's worth commenting more on "code readability" because it cuts both ways. It can absolutely be the case that a complex, manifest type system can be a hindrance to understandably and productivity due to the "noise" of all the types that need to be written. I think struggling with C++ and (to a lesser extent) Java typing is part of the reason the industry really embraced dynamic languages in the 2000s. Python and Ruby were like a breath of fresh air. But eventually we built large systems with these languages and discovered the pain that comes from having no type-safety.
The trend I've seen in the last decade is to embrace type inference, with explicit type declarations on function signatures and otherwise only when needed for disambiguation. To me, this is the sweet spot, giving the benefits of static typing with much of the cleanliness and concision of dynamic languages.