Note that if you split the variables into lines, prior to Python 3.10 you must use backslashes to wrap the newlines.
with A() as a, \
B() as b, \
C() as c:
doSomething(a,b,c)
Parentheses don't work, since Python creates a tuple instead.
with (A(),
B(),
C()):
doSomething(a,b,c)
Since tuples lack a __enter__
attribute, you get an error (undescriptive and does not identify class type):
AttributeError: __enter__
If you try to use as
within parentheses, Python catches the mistake at parse time:
with (A() as a,
B() as b,
C() as c):
doSomething(a,b,c)
SyntaxError: invalid syntax
When will this be fixed?
This issue is tracked in https://bugs.python.org/issue12782.
Python announced in PEP 617 that they would replace the original parser with a new one. Because Python's original parser is LL(1), it cannot distinguish between "multiple context managers" with (A(), B()):
and "tuple of values" with (A(), B())[0]:
.
The new parser can properly parse multiple context managers surrounded by parentheses. The new parser has been enabled in 3.9. It was reported that this syntax will still be rejected until the old parser is removed in Python 3.10, and this syntax change was reported in the 3.10 release notes. But in my testing, it works in trinket.io's Python 3.9.6 as well.
with open('./file') as arg.x = file:
? – Eberhardtcontextlib.ExitStack
. – Elegancy