Gregory Kuhn Gregory Kuhn - 4 months ago 28
Python Question

Asyncio coroutines

I thought I had grokked coroutines with David Beazley's very good presentation but I can't reconcile it fully with the new syntax described in PEP-492.

In the presentation, he explains how coroutines can be thought of as a pipeline that gets pushed to as opposed to pulled from like in generators.

For example:

# cofollow.py
#
# A simple example showing how to hook up a pipeline with
# coroutines. To run this, you will need a log file.
# Run the program logsim.py in the background to get a data
# source.

from coroutine import coroutine

# A data source. This is not a coroutine, but it sends
# data into one (target)

import time
def follow(thefile, target):
thefile.seek(0,2) # Go to the end of the file
while True:
line = thefile.readline()
if not line:
time.sleep(0.1) # Sleep briefly
continue
target.send(line)

# A sink. A coroutine that receives data

@coroutine
def printer():
while True:
line = (yield)
print line,

# Example use
if __name__ == '__main__':
f = open("access-log")
follow(f,printer())


How can one implement the
printer()
coroutine using this new syntax? I have not yet seen an example where the coroutine gets pushed to using this new syntax. Is it possible?

Answer

What you have there is not a coroutine in the sense of the asyncio module and/or PEP-492. As the PEP itself says:

[This PEP] is relevant only to the kind of coroutine that uses yield as a signal to the scheduler, indicating that the coroutine will be waiting until an event (such as IO) is completed.

  1. There's no scheduler (event loop) involved in your example, and
  2. the coroutine is not using yield only "as a signal to the scheduler"; it is really using it to read data.