[Python-ideas] Yield-From: Finalization guarantees

Nick Coghlan ncoghlan at gmail.com
Mon Mar 30 00:43:12 CEST 2009


Jacob Holm wrote:
> Nick Coghlan wrote:
>> Jacob Holm wrote:
>>  
>>> The problem is that any exception thrown into inner is converted to a
>>> GeneratorReturn, which is then swallowed by the yield-from instead of
>>> being reraised.
>>>     
>>
>> That actually only happens if inner *catches and suppresses* the thrown
>> in exception. 
> Having a return in the finally clause like in my example is sufficient
> to suppress the exception.

Ah, I did miss that - I think it just means the code has been refactored
incorrectly though.

>> Otherwise throw() will reraise the original exception
>> automatically:
>>   
> I am not sure what your point is.  Yes, this is a corner case.  I am
> trying to make sure we have the corner cases working as well.

I think the refactoring is buggy, because it has changed the code from
leaving exceptions alone to suppressing them. Consider what it would
mean to do the same refactoring with normal functions:

def inner():
   try:
       perform_operation()
   finally:
       return 'VALUE'

def outer():
   val = inner()
   print val

That code does NOT do the same thing as:

def outer():
   try:
       perform_operation()
   finally:
       val = 'VALUE'
   print val

A better refactoring would keep the return outside the finally clause in
the inner generator:

Either:

def inner():
   try:
       yield 1
       yield 2
       yield 3
   finally:
       val = 'VALUE'
   return val

Or else:

def inner():
   try:
       yield 1
       yield 2
       yield 3
   finally:
       pass
   return 'VALUE'

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------



More information about the Python-ideas mailing list