PEP 380 - the 'yield from' proposal

Hallvard B Furuseth h.b.furuseth at
Fri Oct 15 23:05:12 CEST 2010

"Syntax for Delegating to a Subgenerator":

The first call can only be .next(), there's no way to provide an initial
value to .send().  That matches common use, but an initial .send() is
possible if .next() was called before "yield from".  So I suggest:

RESULT = yield from EXPR [with SEND_FIRST] # default SEND_FIRST=None

The code under Formal Semantics uses .throw and .close = None as
equivalent to absent attributes, which is not what the textual
description says.

I think the code should delete values when it no longer has use for
them, so they can be garbage-collected as quickly as possible.

So the formal semantics would be something like

i, snd, yld, throw = iter(EXPR), SEND_FIRST, None, None
res = absent = object()         # Internal marker, never exposed
    while res is absent:
            yld = ( if snd is None else i.send(snd))
        except StopIteration as e:
            res = e.value
            snd = absent  # 'del snd', but that could break 'finally:'
            while yld is not absent:
                    snd = yield yld
                    yld = absent
                    del yld
                    if throw is None: # optional statement
                        throw = getattr(i, 'throw', absent)
                        if throw is absent:
                            getattr(i, 'close', bool)() # bool()=dummy
                    x = sys.exc_info()
                        yld = throw(*x)
                    except StopIteration as e:
                        if e is x[1] or isinstance(x[1], GeneratorExit):
                        res = e.value
                        del x
    del i, snd, throw
RESULT = res
del res

Maybe it's excessive to specify all the 'del's, but I'm thinking the
'with' statement might have destroyed or set to None the 'as <foo>'
variable today if the spec had taken care to specify deletes.


More information about the Python-list mailing list