Comment by Pay08
7 hours ago
I still can't get over the utter idiocy in Python's type hints being decorative. In what world does x: int = "thing" not give someone in the standardisation process pause?
7 hours ago
I still can't get over the utter idiocy in Python's type hints being decorative. In what world does x: int = "thing" not give someone in the standardisation process pause?
Can you elaborate what you mean by decorative?
If you run a type checker like ty or pyright they're not decorative — you'll get clear diagnostics for that particular example [1], and any other type errors you might have. You can set up CI so that e.g. blocks PRs from being merged, just like any other test failure.
If you mean types not being checked at runtime, the consensus is that most users don't want to pay the cost of the checks every time the program is run. It's more cost-effective to do those checks at development/test/CI time using a type checker, as described above. But if you _do_ want that, you can opt in to that using something like beartype [2].
[1] https://play.ty.dev/905db656-e271-4a3a-b27d-18a4dd45f5da
[2] https://github.com/beartype/beartype/
Exactly my point. If I need to run 300 external tools for a language feature to be worth a damn, why is it a language feature?
‘uvx ty check’ or ‘uvx pyrefly check’. That’s hardly 300 external tools.
It's a community that delayed progress for a decade while they waited for everyone to put parenthesis on the print statement. Give 'em enough time and they'll figure out best practices.
In C-ish languages the statement
is perfectly valid. It means reserve a spot for a 32 bit int and then shove the pointer to the string "thing" at the address of x. It will do the wrong thing and also overflow memory but you could generate code for it. The type checker is what stops you. It's the same in Python, if you make type checking a build breaker then the annotations mean something. Types aren't checked at runtime but C doesn't check them either.
It's valid in C, due to semantics around pointers. Try that in Java and you'll quickly find that it's not valid in "C-ish languages". C absolutely checks types, it's just weakly typed. Python doesn't check types at all, which I wouldn't have a problem with, if the language didn't have type annotations that sure look like they'll do something.
In C, int may be as small as 16 bits You may get 32 bits (or more) but it's not guaranteed. I don't see how you get a memory overflow though?
I'd be surprised if a compiler with -Wall -Werror accepts to compile this.
Trying to cast back the int to a char* might work if the pointers are the same size as int on the target platform, but it's actually Undefined Behaviour IIRC.
I guess an overflow would be possible if the size of a point and int differs.
It's the complete opposite. The objective of type hints is that they're optional precisely because type hints narrow the functionality of the language. And evidenced by the fact that different type checks have different heuristics for determining what is a valid typed program and what isn't, it seems that the decision is correct.
No type system will allow for the dynamism that Python supports. It's not a question of how you annotate types, it's about how you resolve types.
Nobody is saying they are mandatory, and I'm actually a big fan of gradual typing. My point is that they do nothing.
However, type hints reducing the functionality of the language isn't true either.
Optional on paper, sure. Once you publish shared libs or keep a nontrivial repo usable across teams, type hints stop feeling optional fast, because the minute mypy, pyright, and Pyre disagree on metaprogramming or runtime patching you get three incompatible stories about the same program and a pile of contraditions instead of signal. Python can stay dynamic, yet this setup mostly buys busywork for CI and false confidence for humans.