[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