Are for-loop name list expressions legal?
<p>In CPython 2.7.10 and 3.4.3, and PyPy 2.6.0 (Python 2.7.9), it is apparently legal to use expressions (or some subset of them) for the name list in a for-loop. Here's a typical for-loop:</p>

<pre><code>&gt;&gt;&gt; for a in [1]: pass
...
&gt;&gt;&gt; a
1
</code></pre>

<p>But you can also use attributes from objects:</p>

<pre><code>&gt;&gt;&gt; class Obj(object): pass
...
&gt;&gt;&gt; obj = Obj()
&gt;&gt;&gt; for obj.b in [1]: pass
...
&gt;&gt;&gt; obj.b
1
</code></pre>

<p>And you can even use attributes from expressions:</p>

<pre><code>&gt;&gt;&gt; for Obj().c in [1]: pass
...
</code></pre>

<p>But not all expressions appear to work:</p>

<pre><code>&gt;&gt;&gt; for (True and obj.d) in [1]: pass
...
  File "&lt;stdin&gt;", line 1
SyntaxError: can't assign to operator
</code></pre>

<p>But they do so long as the attribute is on the outside?</p>

<pre><code>&gt;&gt;&gt; for (True and obj).e in [1]: pass
...
&gt;&gt;&gt; obj.e
1
</code></pre>

<p>Or something is assignable?</p>

<pre><code>&gt;&gt;&gt; for {}['f'] in [1]: pass
...
</code></pre>

<p>I'm surprised any of these are legal syntax in Python. I expected only names to be allowed.  Are these even supposed to work? Is this an oversight? Is this an implementation detail of CPython that PyPy happens to also implement?</p>

<blockquote>
  <p>Are these even supposed to work? </p>
</blockquote>

<p>Yes</p>

<blockquote>
  <p>Is this an oversight? </p>
</blockquote>

<p>No</p>

<blockquote>
  <p>Is this an implementation detail of CPython that PyPy happens to also
  implement?</p>
</blockquote>

<p>No</p>

<hr>

<p>If you can assign to it, you can use it as the free variable in the for loop.</p>

<p>For questions like this, it's worth going straight to the <a href="https://docs.python.org/3/reference/compound_stmts.html#the-for-statement" rel="nofollow">grammar</a>:</p>

<pre><code>for_stmt ::=  "for" target_list "in" expression_list ":" suite
              ["else" ":" suite]
</code></pre>

<p>A <code>target_list</code> is just a bunch of <code>target</code>:</p>

<pre><code>target_list     ::=  target ("," target)* [","]
target          ::=  identifier
                     | "(" target_list ")"
                     | "[" [target_list] "]"
                     | attributeref
                     | subscription
                     | slicing
                     | "*" target
</code></pre>

<p>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 (<a href="http://stackoverflow.com/questions/23998026/why-isnt-this-a-syntax-error-in-python#comment36983617_23998128">even I found one once</a>), so if you find a legitimate syntax anomaly then by means submit a ticket - these tend to get fixed quickly.  </p>

<p>The most interesting pair you gave is <code>(True and obj.d)</code> and <code>(True and obj).d</code>, which seem to be the same logically but are parsed differently:</p>

<pre><code>&gt;&gt;&gt; ast.dump(ast.parse('(True and obj.d)'), annotate_fields=False)
"Module([Expr(BoolOp(And(), [Name('True', Load()), Attribute(Name('obj', Load()), 'd', Load())]))])"
&gt;&gt;&gt; ast.dump(ast.parse('(True and obj).d'), annotate_fields=False)
"Module([Expr(Attribute(BoolOp(And(), [Name('True', Load()), Name('obj', Load())]), 'd', Load()))])"
</code></pre>

<p><em>Note:</em> <code>(True and obj).d</code> is an <a href="https://docs.python.org/3/reference/expressions.html#attribute-references" rel="nofollow"><code>attributeref</code></a> in the grammar.  </p>

python language-lawyer