I am using Python 3.6.1, and I have come across something very strange. I had a simple dictionary assignment typo that took me a long time to find.
context = {}
context["a"]: 2
print(context)
Output
{}
What is the code context["a"]: 2 doing? It doesn’t raise a SyntaxError when it should IMO. At first I thought it was creating a slice. However, typing repr(context["a"]: 2) raises a SyntaxError. I also typed context["a"]: 2 in the console and the console didn’t print anything. I thought maybe it returned None, but I’m not so sure.
I’ve also thought it could be a single line if statement, but that shouldn’t be the right syntax either.
Additionally, context["a"] should raise a KeyError.
I am perplexed. What is going on?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You have accidentally written a syntactically correct variable annotation. That feature was introduced in Python 3.6 (see PEP 526).
Although a variable annotation is parsed as part of an annotated assignment, the assignment statement is optional:
annotated_assignment_stmt ::= augtarget ":" expression ["=" expression]
Thus, in context["a"]: 2
context["a"]is the annotation target2is the annotation itselfcontext["a"]is left uninitialised
The PEP states that “the target of the annotation can be any valid single assignment target, at least syntactically (it is up to the type checker what to do with this)”, which means that the key doesn’t need to exist to be annotated (hence no KeyError). Here’s an example from the original PEP:
d = {}
d['a']: int = 0 # Annotates d['a'] with int.
d['b']: int # Annotates d['b'] with int.
Normally, the annotation expression should evaluate to a Python type —
after all the main use of annotations is type hinting, but it is not enforced. The annotation can be any valid Python expression, regardless of the type or value of the result.
As you can see, at this time type hints are very permissive and rarely useful, unless you have a static type checker such as mypy.
Method 2
The annotations are automatically stored in __annotations__ which is a dict. For x: y. y must be a valid expression, i.e. y, or whatever is on the right side of the :, has to evaluate. On the other hand x ,must, at a minimum be able to be a key, thus hashable.
In addition, the LHS cannot be a set, because sets are unhashable,
>>> {2}: 8
SyntaxError: illegal target for annotation
nor a list:
>>> [2]: 8
[2]: 8 SyntaxError: only single target (not list) can be annotated
nor a tuple:
>>> (2,3): 8
(2,3): 8 SyntaxError: only single target (not tuple) can be annotated
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0