diff --git a/pep-0492.txt b/pep-0492.txt index e02f3e67c..84afd9517 100644 --- a/pep-0492.txt +++ b/pep-0492.txt @@ -61,7 +61,7 @@ are still based on generators. It is strongly suggested that the reader understands how coroutines are implemented in Python (PEP 342 and PEP 380). It is also recommended to read -PEP 3156 (asyncio framework). +PEP 3156 (asyncio framework) and PEP 3152 (Cofunctions). From this point in this document we use the word *coroutine* to refer to functions declared using the new syntax. *generator-based coroutine* is used @@ -659,6 +659,56 @@ The required changes are mainly: Design Considerations ===================== +PEP 3152 +-------- + +PEP 3152 by Gregory Ewing proposes a different mechanism for coroutines +(called "cofunctions"). Some key points: + +1. A new keyword ``codef`` to declare a *cofunction*. *Cofunction* is always a + generator, even if there is no ``cocall`` expressions inside it. Maps to + ``async def`` in this proposal. + +2. A new keyword ``cocall`` to call a *cofunction*. Can only be used inside a + *cofunction*. Maps to ``await`` in this proposal (with some differences, + see below.) + +3. It is not possible to call a *cofunction* without a ``cocall`` keyword. + +4. ``cocall`` grammatically requires parentheses after it:: + + atom: cocall | + cocall: 'cocall' atom cotrailer* '(' [arglist] ')' + cotrailer: '[' subscriptlist ']' | '.' NAME + +5. ``cocall f(*args, **kwds)`` is semantically equivalent to + ``yield from f.__cocall__(*args, **kwds)``. + +Differences from this proposal: + +1. There is no equivalent of ``__cocall__`` in this PEP, which is called and + its result is passed to ``yield from`` in the ``cocall`` expression. + ``await`` keyword expects an *awaitable* object, validates the type, and + executes ``yield from`` on it. Although, ``__await__`` method is similar to + ``__cocall__``, but is only used to define *Future-like* objects. + +2. ``await`` is defined in the same way as ``yield`` in the grammar (it is + later enforced that ``await`` can only be inside ``async def``). + +3. To make asyncio work with PEP 3152 it would be required to modify + ``@asyncio.coroutine`` decorator to wrap all functions in an object with a + ``__cocall__`` method. To call *cofunctions* from existing generator-based + coroutines it would be required to use ``costart`` built-in. In this + proposal ``@asyncio.coroutine`` simply sets ``CO_ASYNC`` on the wrapped + function's code object and everything works automatically. + +4. Since it is impossible to call a *cofunction* without a ``cocall`` keyword, + it automatically prevents the common mistake of forgetting to use + ``yield from`` on generator-based coroutines. + +5. There are no equivalents of ``async for`` and ``async with`` in PEP 3152. + + No implicit wrapping in Futures -------------------------------