What are variable annotations?
Variable annotations are just the next step from # type
comments, as they were defined in PEP 484
; the rationale behind this change is highlighted in the respective section of PEP 526.
So, instead of hinting the type with:
primes = [] # type: List[int]
New syntax was introduced to allow for directly annotating the type with an assignment of the form:
primes: List[int] = []
which, as @Martijn pointed out, denotes a list of integers by using types available in typing
and initializing it to an empty list.
What changes does it bring?
The first change introduced was new syntax that allows you to annotate a name with a type, either standalone after the :
character or optionally annotate while also assigning a value to it:
annotated_assignment_stmt ::= augtarget ":" expression ["=" expression]
So the example in question:
primes: List[int] = [ ]
# ^ ^ ^
# augtarget | |
# expression |
# expression (optionally initialize to empty list)
Additional changes were also introduced along with the new syntax; modules and classes now have an __annotations__
attribute (as functions have had since PEP 3107 -- Function Annotations) in which the type metadata is attached:
from typing import get_type_hints # grabs __annotations__
Now __main__.__annotations__
holds the declared types:
>>> from typing import List, get_type_hints
>>> primes: List[int] = []
>>> captain: str
>>> import __main__
>>> get_type_hints(__main__)
{'primes': typing.List<~T>[int]}
captain
won't currently show up through get_type_hints
because get_type_hints
only returns types that can also be accessed on a module; i.e., it needs a value first:
>>> captain = "Picard"
>>> get_type_hints(__main__)
{'primes': typing.List<~T>[int], 'captain': <class 'str'>}
Using print(__annotations__)
will show 'captain': <class 'str'>
but you really shouldn't be accessing __annotations__
directly.
Similarly, for classes:
>>> get_type_hints(Starship)
ChainMap({'stats': typing.Dict<~KT, ~VT>[str, int]}, {})
Where a ChainMap
is used to grab the annotations for a given class (located in the first mapping) and all annotations defined in the base classes found in its mro
(consequent mappings, {}
for object).
Along with the new syntax, a new ClassVar
type has been added to denote class variables. Yup, stats
in your example is actually an instance variable, not a ClassVar
.
Will I be forced to use it?
As with type hints from PEP 484
, these are completely optional and are of main use for type checking tools (and whatever else you can build based on this information). It is to be provisional when the stable version of Python 3.6 is released so small tweaks might be added in the future.
primes: List[int] = []
is just an empty list asprimes = []
. The difference is that you are claiming thatprimes
is meant to contain onlyint
s and 3rd party applications might type check your program to verify this claim, but when you run the code in any python interpreter that's just the same as writingprimes = []
, and thus doingprimes: List[int] = []; primes.append("string")
is still valid. – Precede