[Python-ideas] Propagating StopIteration value

Jan Kaliszewski zuo at chopin.edu.pl
Thu Oct 11 01:29:32 CEST 2012


> The goal described by the OP could be reached with a wrapper
> generator -- something like this:
[snip]

PS. A more convenient version (you don't need to repeat yourself):

     import collections

     def genfrom(iter_factory, *args):
         final_value = None
         def catching(iterable):
             subiter = iter(iterable)
             nonlocal final_value
             try:
                 while True:
                     yield next(subiter)
             except StopIteration as exc:
                 if exc.args:
                     final_value = exc.args[0]
                 raise
         args = [catching(arg.iterable) if isinstance(arg, genfrom.this) 
else arg
                 for arg in args]
         yield from iter_factory(*args)
         return final_value

     genfrom.this = collections.namedtuple('propagate_from_this', 
'iterable')

Some examples:

     >>> import itertools
     >>> def f():
     ...     yield 'g'
     ...     return 10000000
    ...
     >>> my_chain = genfrom(itertools.chain, 'abc', 'def', 
genfrom.this(f()))
     >>> while True:
     ...     print(next(my_chain))
     ...
     a
     b
     c
     d
     e
     f
     g
     Traceback (most recent call last):
       File "<stdin>", line 2, in <module>
     StopIteration: 10000000
     >>> my_filter = genfrom(filter, lambda x: True, genfrom.this(f()))
     >>> next(my_filter)
     'g'
     >>> next(my_filter)
     Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
     StopIteration: 10000000




More information about the Python-ideas mailing list