[Python-Dev] Merging PEP 310 and PEP 340-redux?

Phillip J. Eby pje at telecommunity.com
Fri May 13 16:50:02 CEST 2005


At 03:05 AM 5/13/2005 -0700, Guido van Rossum wrote:
>So then the all-important question I want to pose is: do we like the
>idea of using a (degenerate, decorated) generator as a "template" for
>the do-statement enough to accept the slightly increased complexity?

Since the "do protocol" is now distinct from the iterator protocol, I don't 
believe a decorator is still required.  The purpose of the decorator was to 
help reduce confusion between the block statement and a "for" loop.  Since 
you can no longer swallow exceptions, there is no downside to using an 
existing generator as the target of a "do" statement.  That is, the concern 
about generators catching StopIteration from a "yield" doesn't matter, as 
they will simply step through to their next yield statement, and then the 
original exception will propagate.


>The added complexity is caused by the need to separate VAR from EXPR
>so that a generator can be used. I personally like this separation; I
>actually like that the "anonymous block controller" is logically
>separate from the variable bound by the construct. From Greg Ewing's
>response to the proposal to endow file objects with __enter__ and
>__exit__ methods, I believe he thinks so too.
>
>Straight up-or-down votes in the full senate are appreciated at this point.

+1.


>On to the secondary questions:
>
>- Today I like the 'do' keyword better; 'with' might confuse folks
>coming from Pascal or VB

+1 on "do EXPR as VAR", where VAR may be any valid LHS of an assignment.


>This means that __exit__ can be called with the following arguments:
>
>abc.__exit__(True) - normal completion of BLOCK
>
>abc.__exit__(False) - BLOCK was left by a non-local goto 
>(break/continue/return)
>
>abc.__exit__(False, t, v, tb) - BLOCK was left by an exception
>
>(An alternative would be to always call it with 4 arguments, the last
>three being None in the first two cases.)

I'm not sure the extra argument is a good idea; doesn't this introduce the 
same sort of invisible control flow as swallowing exceptions?  Also, since 
the block controller can't actually change the control flow, I'm having a 
hard time thinking of any actual use cases for this information.


>If we adopt PEP 340 redux, it's up to the decorator for degenerate
>generators to decide how to pass this information into the generator;
>if we adopt PEP 342 ("continue EXPR") at the same time, we can let the
>yield-expression return a 4-tuple (oke, t, v, tb). Most templates can
>ignore this information (so they can just use a yield-statement).

I was going to propose having a generator-iterator's __exit__() raise the 
triple inside the generator, or raise StopIteration inside the generator if 
there is no triple.  I'd ideally also like close() as a synonym for 
__exit__() with no arguments.  Although these are properly the subject of 
PEPs 288 and 325 respectively, I felt this would elegantly bring them both 
to closure.

However, after thinking it through, I realized that I don't see any obvious 
way to make __exit__ reusable for PEPs 288 and 325, because for 288 at 
least, I'd want __exit__ to either return the next yielded value or raise 
StopIteration.  But, this isn't compatible with the "do protocol"'s needs, 
unless the "do protocol" suppressed StopIteration, and that doesn't seem 
like such a good idea.

It seems to me that passing exceptions into a generator does in fact 
require a distinct method.  But, I still do believe that 
generator-iterators can have predefined __enter__ and __exit__ methods 
without the need for a decorator.


>PS. I've come up with another interesting use case: block signals for
>the duration of a block. This could be a function in the signal
>module, e.g. signal.blocking([ist of signals to block]). The list
>would default to all signals. Similar signal.ignoring().

Sweet.  You could also use it for temporary signal handling, i.e. "set this 
signal handler for the duration of the block".  Sort of the same class of 
"make sure I restore a global I'm tampering with" use case as redirecting 
stdout, and Tim Peters' Decimal context use cases.



More information about the Python-Dev mailing list