[Python-ideas] Yield-From: Finalization guarantees
Jacob Holm
jh at improva.dk
Sat Mar 28 14:44:31 CET 2009
Hi Greg
There seems to be another issue with GeneratorExit in the latest
expansion (reproduced below). Based on the inlining/refactoring
principle, I would expect the following code:
def inner():
try:
yield 1
yield 2
yield 3
except GeneratorExit:
val = 'closed'
else:
val = 'exhausted'
return val.upper()
def outer():
val = yield from inner()
print val
To be equivalent to this:
def outer():
try:
yield 1
yield 2
yield 3
except GeneratorExit:
val = 'closed'
else:
val = 'exhausted'
val = val.upper()
print val
However, with the current expansion they are different. Only the
version not using "yield from" will print "CLOSED" in this case:
g = outer()
g.next() # prints 1
g.close() # should print "CLOSED", but doesn't because the GeneratorExit is reraised by yield-from
I currently don't think that a special case for GeneratorExit is
needed. Can you give me an example showing that it is?
- Jacob
------------------------------------------------------------------------
_i = iter(EXPR)
try:
_y = _i.next()
except StopIteration, _e:
_r = _e.value
else:
while 1:
try:
_s = yield _y
except:
_m = getattr(_i, 'throw', None)
if _m is not None:
_x = sys.exc_info()
try:
_y = _m(*_x)
except StopIteration, _e:
if _e is _x[1] or isinstance(_x[1], GeneratorExit):
raise
else:
_r = _e.value
break
else:
_m = getattr(_i, 'close', None)
if _m is not None:
_m()
raise
else:
try:
if _s is None:
_y = _i.next()
else:
_y = _i.send(_s)
except StopIteration, _e:
_r = _e.value
break
RESULT = _r
More information about the Python-ideas
mailing list