I suppose, if you're relying on type stubs. Ordinary in-line type hints won't lie or go out of sync without complaining somewhere though.
Defensive code is good, but I'm absolutely sick of writing code that has to be defensive about the type of absolutely every variable everywhere. It's ridiculous, verbose, and nearly impossible to do universally. THAT is the worst of both worlds. Having to manually fret about the types that every variable may hold. At the point that you're having to write defensive code due to dynamic types, you've already lost the advantages of dynamic types entirely.
I use type hints to say "use and expect these types or get Undefined Behavior", and that contract is good enough for me.
Thanks for the example. That's happening because the `main` function is an untyped function. You can fix that by changing `def main():` to `def main -> None:` You can also make it pick up with `--check-untyped-defs`. I always used mypy with --strict, so I forgot that it wasn't the default configuration.
I agree, though. Pyright has better defaults. It's not great that mypy just completely skips all functions without typing information given. It makes a lot more sense for it to just check everything and assume Any on all unspecified arguments and returns. It's still valuable to type-check the contents of functions with unspecified types.
Defensive code is good, but I'm absolutely sick of writing code that has to be defensive about the type of absolutely every variable everywhere. It's ridiculous, verbose, and nearly impossible to do universally. THAT is the worst of both worlds. Having to manually fret about the types that every variable may hold. At the point that you're having to write defensive code due to dynamic types, you've already lost the advantages of dynamic types entirely.
I use type hints to say "use and expect these types or get Undefined Behavior", and that contract is good enough for me.