[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