I can confirm Guido's words, now parentheses for continuation across lines are already supported.
Even without parentheses, multiline with items can be supported. I just implemented it here: https://github.com/thautwarm/cpython/blob/bpo-12782/Grammar/python.gram#L180-L187
from contextlib import contextmanager
@contextmanager
def f(x):
try:
yield x
finally:
pass
# Ok
with f('c') as a,
f('a') as b:
pass
# Ok
with f('c') as a,
f('a') as b,
f('a') as c:
pass
# ERROR
with f('c') as a,
f('a') as b,
f('a') as c:
x = 1 + 1
# message:
File "/home/thaut/github/cpython/../a.py", line 49
x = 1 + 1
^
IndentationError: unindent does not match any outer indentation
level
# ERROR
with f('c') as a,
f('a') as b,
f('a') as c:
x = 1 + 1
File "/home/thaut/github/cpython/../a.py", line 49
x = 1 + 1
IndentationError: unexpected indent
The grammar is:
with_stmt[stmt_ty]:
| ...
| 'with' a=(',' [NEWLINE ~ INDENT?]).with_item+ ':' tc=[TYPE_COMMENT] NEWLINE b=statements DEDENT {
_Py_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
| ...
The restriction here is, since the second 'with_item', until the end of 'statements', the expression and statements have to keep the same indentation.
with item1,
item2,
...:
block
The indentation of 'item2', ..., 'block' should be the same.
This implementation leverages the new PEG and how the lexer deals with indent/dedent. |