[Python-Dev] Merging PEP 310 and PEP 340-redux?
Guido van Rossum
gvanrossum at gmail.com
Tue May 10 06:58:14 CEST 2005
Apologies if this has been discovered and rejected already; I've had
to skip most of the discussions but this though won't leave my head...
So PEP 310 proposes this:
with VAR = EXPR:
BLOCK
translated to
VAR = EXPR\
if hasattr(VAR, "__enter__"):
VAR.__enter__()
try:
BLOCK
finally:
VAR.__exit__()
This equates VAR with the value of EXPR. It has a problem: what if
inside BLOCK an assignment to VAR is made -- does this affect the
finally clause or not? I think that the finally clause should use an
internal variable that isn't affected by assignments to VAR.
But what if we changed the translation slightly so that VAR gets
assigned to value of the __enter__() call:
abc = EXPR
VAR = abc.__enter__() # I don't see why it should be optional
try:
BLOCK
finally:
abc.__exit__()
Now it would make more sense to change the syntax to
with EXPR as VAR:
BLOCK
and we have Phillip Eby's proposal. The advantage of this is that you
can write a relatively straightforward decorator, call it
@with_template, that endows a generator with the __enter__ and
__exit__ methods, so you can write all the examples (except
auto_retry(), which was there mostly to make a point) from PEP 340
like this:
@with_template
def opening(filename, mode="r"):
f = open(filename, mode)
yield f
f.close()
and so on. (Note the absence of a try/finally block in the generator
-- the try/finally is guaranteed by the with-statement but not by the
generator framework.)
I used to dislike this, but the opposition and the proliferation of
alternative proposals have made me realize that I'd rather have this
(plus "continue EXPR" which will be moved to a separate PEP once I
have some extra time) than most of the other proposals.
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-Dev
mailing list