Search code examples
pythongeneratorcoroutineyield

Python coroutine can one `send` without first doing `next`?


When sending a value to a generator/coroutine, is there a way to avoid that initial next(g)?

def gen(n):
    m = (yield) or "did not send m to gen"
    print(n, m)

g = gen(10)
next(g)
g.send("sent m to g") # prints "10 sent m to g"

Without next(g), we get

TypeError: can't send non-None value to a just-started generator

Solution

  • The error stems from this bit of code in CPython's gen_send_ex2, i.e. it occurs if gi_frame_state is FRAME_CREATED.

    The only place that matters for this discussion that sets gi_frame_state is here in gen_send_ex2, after a (possibly None) value has been sent and a frame is about to be evaluated.

    Based on that, I'd say no, there's no way to send a non-None value to a just-started generator.