This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: PEP 492 - example benchmark doesn't work (TypeError)
Type: behavior Stage: resolved
Components: asyncio, Documentation Versions: Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: docs@python, ezio.melotti, gvanrossum, scoder, terry.reedy, vstinner, wodny, yselivanov
Priority: normal Keywords:

Created on 2015-07-17 14:47 by wodny, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg246856 - (view) Author: Marcin Szewczyk (wodny) Date: 2015-07-17 14:47
Using benchmark from the section https://www.python.org/dev/peps/pep-0492/#async-await raises:
Traceback (most recent call last):
  File "./bench.py", line 28, in <module>
    timeit(abinary, 19, 30)
  File "./bench.py", line 23, in timeit
    list(gen(depth))
TypeError: 'coroutine' object is not iterable

Am I missing something or is a correction needed in code or documentation?

BTW, PEP 492 uses the term "plain generator", but unlike "generator-based coroutine" or "native coroutine" it's not defined in section https://www.python.org/dev/peps/pep-0492/#glossary. I think adding a definition would be beneficial.
msg246863 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2015-07-17 18:20
timeit(binary, 5, 3)
timeit(abinary, 5, 3)
gives me the same error running on Win 7 from Idle
msg246887 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2015-07-18 06:39
Fixed in https://hg.python.org/peps/rev/7ad183c1d9be

I'll quote the commit message here:

    pep-492: Update benchmark code

    Since coroutines now have a distinct type, they do not support
    iteration. Instead of doing 'list(o)', we now do 'o.send(None)'
    until StopIteration.

    Note, that the updated timings are due to the difference of
    doing a loop in Python vs doing it in C ('list()' vs 'while True').

Marcin and Terry, thanks for reporting this!
msg246891 - (view) Author: Stefan Behnel (scoder) * (Python committer) Date: 2015-07-18 08:57
Thanks for updating the micro-benchmark. Just FYI (and sorry for hijacking this ticket), I ran it through Cython. Here are the numbers:

Cython 0.23 (latest master)
binary(21) * 3: total 1.609s
abinary(21) * 3: total 1.514s

CPython 3.5 (latest branch)
binary(21) * 3: total 4.653s
abinary(21) * 3: total 4.750s

The low factor between the two shows (IMO) that using a type slot function for await was a very good idea. Streamlining FetchStopIteration might bring another bit.

I also tried the same thing with alternating recursively between the Python and Cython implementation by changing it to

    l = await cy_abinary(n - 1)
    r = await py_abinary(n - 1)

binary(21) * 3: total 3.835s
abinary(21) * 3: total 3.952s

So even the slow fallback paths seem pretty efficient on both sides.
msg246948 - (view) Author: Marcin Szewczyk (wodny) Date: 2015-07-19 19:28
Thanks for the update.

Regarding the "plain generator" part -- am I right thinking it's simply a generator not decorated with @asyncio.coroutine?
History
Date User Action Args
2022-04-11 14:58:18adminsetgithub: 68842
2015-07-19 19:28:16wodnysetmessages: + msg246948
2015-07-18 08:57:27scodersetnosy: + scoder
messages: + msg246891
2015-07-18 06:39:53yselivanovsetstatus: open -> closed
resolution: fixed
messages: + msg246887

stage: needs patch -> resolved
2015-07-17 18:43:08ezio.melottisetnosy: + ezio.melotti
2015-07-17 18:20:16terry.reedysetnosy: + terry.reedy
messages: + msg246863

type: enhancement -> behavior
stage: needs patch
2015-07-17 14:47:12wodnycreate