Comment by viccis

1 day ago

Yeah I think, given its gradual typing approach, that any discussion about the quality and utility of Python's type system assumes that one is using one of the best in class type checkers right now.

I didn't really use it much until the last few years. It was limited and annoyiongly verbose. Now it's great, you don't even have to do things like explicitly notate covariant/contravariant types, and a lot of what used to be clumsy annotation with imports from typing is now just specified with normal Python.

And best of all, more and more libraries are viewing type support as a huge priority, so there's usually no more having to download type mocks and annotation packages and worry about keeping them in sync. There are some libraries that do annoying things like adding " | None" after all their return types to allow themselves to be sloppy, but at least they are sort of calling out to you that they could be sloppy instead of letting it surprise you.

It's now good and easy enough that it saves me time to use type annotations even for small scripts, as the time it saves from quickly catching typos or messing up a return type.

Like you said, Pydantic is often the magic that makes it really useful. It is just easy enough and adds enough value that it's worth not lugging around data in dicts or tuples.

My main gripe with Go's typing has always been that I think the structural typing of its interfaces is convenient but really it's convenient in the same way that duck typing is. In the same way that a hunter with a duck call is the same as a duck with duck typing, a F16 and a VCR are both things that have an ejection feature.