Are these even supposed to work?
Yes
Is this an oversight?
No
Is this an implementation detail of CPython that PyPy happens to also
implement?
No
If you can assign to it, you can use it as the free variable in the for loop.
For questions like this, it's worth going straight to the grammar:
for_stmt ::= "for" target_list "in" expression_list ":" suite
["else" ":" suite]
A target_list
is just a bunch of target
:
target_list ::= target ("," target)* [","]
target ::= identifier
| "(" target_list ")"
| "[" [target_list] "]"
| attributeref
| subscription
| slicing
| "*" target
If you look at that closely, you'll see that none of the working examples you've given is a counter-example. Mind you, bugs in the parser are not unheard of (even I found one once), so if you find a legitimate syntax anomaly then by means submit a ticket - these tend to get fixed quickly.
The most interesting pair you gave is (True and obj.d)
and (True and obj).d
, which seem to be the same logically but are parsed differently:
>>> ast.dump(ast.parse('(True and obj.d)'), annotate_fields=False)
"Module([Expr(BoolOp(And(), [Name('True', Load()), Attribute(Name('obj', Load()), 'd', Load())]))])"
>>> ast.dump(ast.parse('(True and obj).d'), annotate_fields=False)
"Module([Expr(Attribute(BoolOp(And(), [Name('True', Load()), Name('obj', Load())]), 'd', Load()))])"
Note: (True and obj).d
is an attributeref
in the grammar.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…