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

Phillip J. Eby pje at telecommunity.com
Tue May 10 17:49:17 CEST 2005


At 07:57 AM 5/10/2005 -0700, Alex Martelli wrote:
>On May 9, 2005, at 21:58, Guido van Rossum wrote:
> > 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
>
>I like this.  The only aspect of other proposals that I would sorely
>miss here, would be the inability for abc.__exit__ to deal with
>exceptions raised in BLOCK (or, even better, a separate specialmethod
>on abc called in lieu of __exit__ upon exceptions).  Or am I missing
>something, and would this give a way within abc.__exit__ to examine
>and possibly ``unraise'' such an exception...?

Yeah, I'd ideally like to see __try__, __except__, __else__, and 
__finally__ methods, matching the respective semantics of those clauses in 
a try/except/finally block.


> > 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 must be thick this morning, because this relatively straightforward
>decorator isn't immediately obvious to me -- care to show me how
>with_template gets coded?

Something like this, I guess:

     def with_template(f):
         class controller(object):
             def __init__(self,*args,**kw):
                 self.iter = f(*args,**kw)

             def __enter__(self):
                 return self.iter.next()

             def __exit__(self):
                 self.iter.next()
         return controller

But I'd rather see it with __try__/__except__ and passing exceptions into 
the generator so that the generator can use try/except/finally blocks to 
act on the control flow.



More information about the Python-Dev mailing list