Possibly Pythonic Tail Call Optimization (TCO/TRE)

Terry Reedy tjreedy at udel.edu
Fri Jul 17 22:27:49 CEST 2015

On 7/17/2015 7:43 AM, Antoon Pardon wrote:
> On 07/17/2015 01:05 PM, Chris Angelico wrote:

>> def gen():
>>      yield stuff
>>      yield more stuff
>> for stuff in gen():
>>      bomb with exception
>> The error didn't happen in the generator, so I wouldn't expect to see
>> it in the traceback.
> Yes something like that. And I wouldn't expect it either but if it
> is not present, is it because nobody thought about it or because it
> is a bad idea or an idea difficult to implement?
>> There's still room for the cause of an error to
>> not be in the traceback; imagine, for instance, a function that
>> populates a concrete list, and then you iterate over the list. If that
>> function sticks a None into the list and the subsequent processing is
>> expecting all strings, that's going to bomb, but then you have to
>> figure out where the None came from. If the traceback could include
>> that, it'd be great, but some things aren't possible.
> Sure, but in this case, the generator is still active.

No more than any other object sitting around inactive. Calling a 
generator function like gen above returns a generator with the generator 
function, in a suspended inactive state, attached as an attribute.  When 
the generator.__next__ function is called, it activates its instance of 
the generator function, which suspends itself again after yielding 
something.  At the point of the exception above, the generator next 
function has returned.  There could be multiple generators with 
suspended generator functions sitting around.  For instance:

def f():
     for tup in zip(gf0, gf1, gf2, gf3, gf4, gf5):
         a = tup[6]  # whoops, IndexError
         <unreachable code meant to do something>

Terry Jan Reedy

More information about the Python-list mailing list