Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python grammar: with_stmt

In the full python grammar specification with statement is defined as:

with_stmt: 'with' with_item (',' with_item)*  ':' suite
with_item: test ['as' expr]

Where expr is:

expr: xor_expr ('|' xor_expr)*
xor_expr: and_expr ('^' and_expr)*
and_expr: shift_expr ('&' shift_expr)*

Why does with_item contains expr rule instead of plain name?

This is valid python code:

with open('/dev/null') as f:
    pass

According to the grammar this code is also valid?

with open('/dev/null') as x^y|z:
    pass
like image 823
Andreo Avatar asked Oct 16 '14 21:10

Andreo


1 Answers

with open('/dev/null') as x^y|z:
    pass

Yes, this code is valid according to the grammar! Otherwise you'd get a parse error ("invalid syntax"). The parser proper is fine with this syntax, it's another part of the compiler that checks that such expression is not allowed on the left side (because as is semantically equivalent to the assignment). The reason why the grammar allows expr here, and not just NAME is that you can have any lvalue after as:

with open('/dev/null') as some.thing
with open('/dev/null') as some[thing] 

but there's no separate rule for lvalues, e.g. assignments use testlist on the left, which is even wider than expr.

like image 163
georg Avatar answered Sep 17 '22 20:09

georg