[Python-ideas] with-statement syntactic quirk

MRAB python at mrabarnett.plus.com
Wed Oct 31 18:25:26 CET 2012


On 2012-10-31 13:22, Nick Coghlan wrote:
> On Wed, Oct 31, 2012 at 10:52 PM, Eli Bendersky <eliben at gmail.com> wrote:
>> On Wed, Oct 31, 2012 at 5:45 AM, Devin Jeanpierre <jeanpierreda at gmail.com>
>> wrote:
>>> Anyway, it looks like this isn't how the tokenizer treats
>>> braces/brackets (it ignores indent/dedent, but not newlines (I guess
>>> the grammar handles those)). What I meant to suggest was, treat "with
>>> ... :" similarly to how the OP suggests treating "with (...) :".
>>
>> If this gets accepted, then, is there a reason to stop at "with"? Why not
>> ignore newlines between "if" and its trailing ":" as well? [playing devil's
>> advocate here]
>
> Note that I agreed with Barry that we probably *should* change it from
> a principle-of-least-surprise point of view. I just called "not it" on
> actually figuring out how to make it work given the current Grammar
> definition as a starting point :)
>
> Between expression precedence control, singleton tuples, generator
> expressions, function calls, function parameter declarations, base
> class declarations, import statement grouping and probably a couple of
> other cases that have slipped my mind, parentheses already have plenty
> of different meanings in Python, and we also have plenty of places
> where the syntactical rules aren't quite the same as those in an
> ordinary expression.
>
> The thing that makes Python's parser simple is the fact that we have
> *prefixes* in the Grammar that make it clear when the parsing rules
> should change, so you don't need much lookahead at parsing time (it's
> deliberately limited to only 1 token, in fact). The challenge in this
> particular case is to avoid a Grammar ambiguity relative to ordinary
> expression syntax without duplicating large sections of the grammar
> file.
>
Another possibility could be to allow a tuple of context managers and a
tuple of names:

with (open('/etc/passwd'), open('/etc/passwd')) as (p1, p2):
     pass

meaning:

with open('/etc/passwd') as p1:
     with open('/etc/passwd')) as p2:
         pass

or perhaps more correctly:

with open('/etc/passwd') as temp_1:
     with open('/etc/passwd')) as temp_2:
         p1, p2 = temp_1, temp_2
         pass

It would also allow:

with (cmA, cmB):
     pass

meaning:

with cmA:
     with cmB:
         pass




More information about the Python-ideas mailing list