[Python-Dev] Enhancing PEP 310 (or conflating, your decision :-)

Holger Krekel pyth at devel.trillke.net
Sun Jan 4 06:43:19 EST 2004

hello python-dev, and hello Michael and Paul, 

here are, eventually, some remarks, ideas and food for thought 
regarding PEP 310. 

++ with with yield 

The 'with' as proposed by PEP 310 implements semantics that you can
today implement with a try-finally construct.  (see the PEP for
explanation).  But I think that we can make PEP 310 do better than
try-finally in that we can allow yield inside with-blocks. 

Let's recap PEP 310 quickly:

    __enter__ is called upon entering a with code block 
    __exit__  is called upon leaving a with code block
              (should be renamed '__leave__' which i do subsequently :-)

Compared to the try-finally statement we explicitely have some crucial 
information: the __enter__ method which encapsulates the prepare/acquire 
code for the block. Thus we could specifically allow:

    with handler():
        for x in someiter:
            yield x

and define the semantics so that handler.__enter__ is called every time 
the generator frame resumes execution and handler.__leave_ when it is
suspended/destroyed [*].  (It *may* also be feasible to indicate 
the specific reason for leaving the code block (suspend/finish) 
to the __leave__ method or probably better to call another method). 

PEP325 proposes a coarser-grained "close" method on generators that is
triggered when the generator has finished work.  In constract, the above
semantic extension of PEP 310 allows finer-grained locking as seen when
using locks/critical regions as it directly allows yield within 
try-finally-alike semantics.

++ with and exceptions

In an independent consideration, it would be useful if we had a way to
react on exceptions from the with-object, say with an __except__ method
that retrieves exceptions from 'its' code block. I am not sure, however,
that this can be implemented in a straight forward way (Michael 
commented on this earlier with a similar sentiment IIRC).  But it does 
seem to be a nice abstraction that you can provide an object that 
encapsulates how you deal with exceptions because you can change 
exception-handling code in *one* place instead of possibly many 
scattered try-finally/except-locations. 

++ with loops 

In another independent consideration, we could extend PEP 310 to enable 
loop-constructs: the __leave__ method returns True if it wants
the interpreter to revisit the code-block.  Well this one is really more 
food for thought more than anything else but ... taking and combinining 
the above ideas we might be able to make

  with line in file(somefn):
      # work with line (probably even yield it ...) 
  # the file is guaranteed to be closed here!

work with clean semantics.  Hmmm, IIRC Armin Rigo had a similar suggestion to
reuse the 'for' statement instead of introducing a new with-keyword alltogether. 
This doesn't sound too far away now, anymore :-) 


cheers and a happy new year,


[*] disclaimer: I am not entirely sure if this can be implemented in a 
    straight forward way but it shouldn't be too hard :-) 

More information about the Python-Dev mailing list