
On Jul 9, 2019, at 13:09, Shay Cohen shayco@gmail.com wrote:
a: 3
The reason this isn’t a syntax error is that Python allows any valid expression as an annotation. And “3” is just as valid an expression as “int”.
More generally, annotations don’t actually do anything at runtime, except get stored in an annotation dictionary. If you want to get errors related to type annotations, you need a separate tool, like mypy (or a library that processes the annotations dictionary for some special use, as dataclasses does). And of course mypy will give you an error for using 3 as a type.
Since this is python-ideas, not python-list, maybe you’re suggesting that Python _should_ require a type at runtime? If so, there are multiple reasons that won’t work:
* “Forward references”, like a Node class with a next element of type Node, work by putting the type name in a string, which only works because as far as Python is concerned the string “Node” is a perfectly valid value.
* Shortcuts like using None to mean NoneType again only work because Python only cares that None is a valid value.
* Annotations have been part of the language since 3.0, and it’s only since 3.5 that it’s recommended to only use them for types. Changing that now could break working code, preventing people from upgrading to 3.8.
* If the compiler and interpreter aren’t going to check the types (which would require major changes to everything about the way Python works), all it would do is mislead people into thinking they’re getting static type checking when they aren’t.
type(a: 3)
File "<stdin>", line 1 type(a: 3) ^ SyntaxError: invalid syntax
This is invalid because annotations can only appear in a few specific places, like assignment statements, function parameters, and useless expression statements, not in the middle of an arbitrary expression.
a: 3 type(a)
Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined
The reason you get a NameError is that you haven’t actually created a variable named a. All you’ve done is said “if I create a variable named a later (or have already done so earlier), annotate it with int”. To create the variable, assign it a value.
But also, the annotation has nothing to do with the actual runtime type (the thing the type function returns). As far as Python is concerned, variables don’t have types, values do. Since you haven’t given a a value, there is nothing to ask for the type of (hence the NameError). But it may be more useful to look at this example:
>>> a: str = 5 >>> type(a) int
If the value of a is 5, then the type of a is the type of 5, which is int. If you run this through the mypy checker, it will reject that assignment, because you’re trying to store an int value in a str-annotated variable. But as far as Python is concerned, that annotation means nothing, so the assignment is fine. And then, the type of a is the type of that value, 5, which is int.