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