On 19/01/18 22:50, Léo El Amri wrote: > Hello list, > > I am currently trying to learn co-routine/asynchronous mechanisms in > Python. I read the PEP 342, but I stumble on the fourth example. > I don't understand what the lines "data = yield nonblocking_read(sock)" > in echo_handler() and "connected_socket = yield > nonblocking_accept(sock)" in listen_on() are trying to do. > > For example, can someone explain me how the returned value in the line > "connected_socket = yield nonblocking_accept(sock)" can be used on the > next line ("trampoline.add(handler(connected_socket))") ? To me, it > looks like the returned value is lost in the Trampoline, when resume() > gets the returned value of the yield expression. > > Léo >
Let's see. Upon the line connected_socket = yield nonblocking_accept(sock) control is returned to t.resume. nonblocking_accept is supposed to be a coroutine, so t.resume does this: if isinstance(value, types.GeneratorType): # Yielded to a specific coroutine, push the # current one on the stack, and call the new # one with no args self.schedule(value, (coroutine,stack)) Ergo, it schedules the nonblocking_accept coroutine (‘value’) to be called on the next iteration, and keeps the running listen_on coroutine (‘coroutine’) on the stack for safekeeping. On a subsequent iteration (jump?) of the trampoline, nonblocking_accept will yield a socket. Then, resume will elif stack: # Yielded a result, pop the stack and send the # value to the caller self.schedule(stack[0], stack[1], value) plan to return control to listen_on (‘stack[0]’), and (the next time around) send the value back in. if exc: value = coroutine.throw(value,*exc) else: value = coroutine.send(value) Now, listen on is running again and has the value yielded by nonblocking_accept. I wish I knew how exactly nonblocking_accept was supposed to work here, but that's beside the point as the world of Python coroutines and async I/O has moved on since 2005. Hope this helps Thomas -- https://mail.python.org/mailman/listinfo/python-list