diff --git a/pep-0492.txt b/pep-0492.txt index 90e6a535d..6847cafad 100644 --- a/pep-0492.txt +++ b/pep-0492.txt @@ -117,8 +117,6 @@ Key properties of *coroutines*: coroutines* compatible with *native coroutines* (set by `types.coroutine()`_ function). - All coroutines have ``CO_GENERATOR`` flag set. - * Regular generators, when called, return a *generator object*; similarly, coroutines return a *coroutine* object. @@ -135,7 +133,7 @@ Key properties of *coroutines*: types.coroutine() ----------------- -A new function ``coroutine(gen)`` is added to the ``types`` module. It +A new function ``coroutine(fn)`` is added to the ``types`` module. It allows interoperability between existing *generator-based coroutines* in asyncio and *native coroutines* introduced by this PEP:: @@ -147,8 +145,9 @@ in asyncio and *native coroutines* introduced by this PEP:: The function applies ``CO_ITERABLE_COROUTINE`` flag to generator- function's code object, making it return a *coroutine* object. -The function can be used as a decorator, since it modifies generator- -functions in-place and returns them. +If ``fn`` is not a *generator function*, it is wrapped. If it returns +a *generator*, it will be wrapped in an *awaitable* proxy object +(see below the definition of awaitable objects). Note, that the ``CO_COROUTINE`` flag is not applied by ``types.coroutine()`` to make it possible to separate *native @@ -176,8 +175,8 @@ can be one of: * A *native coroutine* object returned from a *native coroutine function*. -* A *generator-based coroutine* object returned from a *generator - function* decorated with ``types.coroutine()``. +* A *generator-based coroutine* object returned from a function + decorated with ``types.coroutine()``. * An object with an ``__await__`` method returning an iterator. @@ -204,7 +203,7 @@ can be one of: It is a ``TypeError`` if ``__await__`` returns anything but an iterator. -* Objects defined with CPython C API with a ``tp_as_async->am_await`` +* Objects defined with CPython C API with a ``tp_as_async.am_await`` function, returning an *iterator* (similar to ``__await__`` method). It is a ``SyntaxError`` to use ``await`` outside of an ``async def`` @@ -413,11 +412,13 @@ An *asynchronous iterable* is able to call asynchronous code in its asynchronous code in its *next* method. To support asynchronous iteration: -1. An object must implement an ``__aiter__`` method returning an +1. An object must implement an ``__aiter__`` method (or, if defined + with CPython C API, ``tp_as_async.am_aiter`` slot) returning an *awaitable* resulting in an *asynchronous iterator object*. 2. An *asynchronous iterator object* must implement an ``__anext__`` - method returning an *awaitable*. + method (or, if defined with CPython C API, ``tp_as_async.am_anext`` + slot) returning an *awaitable*. 3. To stop iteration ``__anext__`` must raise a ``StopAsyncIteration`` exception. @@ -681,16 +682,24 @@ New Standard Library Functions details. * ``inspect.iscoroutine(obj)`` returns ``True`` if ``obj`` is a - *coroutine* object. + *native coroutine* object. * ``inspect.iscoroutinefunction(obj)`` returns ``True`` if ``obj`` is a - *coroutine function*. + *native coroutine function*. * ``inspect.isawaitable(obj)`` returns ``True`` if ``obj`` can be used in ``await`` expression. See `Await Expression`_ for details. +* ``inspect.getcoroutinestate(coro)`` returns the current state of + a *native coroutine object* (mirrors + ``inspect.getfgeneratorstate(gen)``). + +* ``inspect.getcoroutinelocals(coro)`` returns the mapping of a + *native coroutine object's* local variables to their values + (mirrors ``inspect.getgeneratorlocals(gen)``). + * ``sys.set_coroutine_wrapper(wrapper)`` allows to intercept creation of - *coroutine* objects. ``wrapper`` must be either a callable that + *native coroutine* objects. ``wrapper`` must be either a callable that accepts one argument (a *coroutine* object), or ``None``. ``None`` resets the wrapper. If called twice, the new wrapper replaces the previous one. The function is thread-specific. See `Debugging @@ -1321,15 +1330,15 @@ List of high-level changes and new protocols keyword. 2. New ``__await__`` method for Future-like objects, and new - ``tp_as_async->am_await`` slot in ``PyTypeObject``. + ``tp_as_async.am_await`` slot in ``PyTypeObject``. 3. New syntax for asynchronous context managers: ``async with``. And associated protocol with ``__aenter__`` and ``__aexit__`` methods. 4. New syntax for asynchronous iteration: ``async for``. And associated protocol with ``__aiter__``, ``__aexit__`` and new built- - in exception ``StopAsyncIteration``. New ``tp_as_async->am_aiter`` - and ``tp_as_async->am_anext`` slots in ``PyTypeObject``. + in exception ``StopAsyncIteration``. New ``tp_as_async.am_aiter`` + and ``tp_as_async.am_anext`` slots in ``PyTypeObject``. 5. New AST nodes: ``AsyncFunctionDef``, ``AsyncFor``, ``AsyncWith``, ``Await``. @@ -1337,7 +1346,8 @@ List of high-level changes and new protocols 6. New functions: ``sys.set_coroutine_wrapper(callback)``, ``sys.get_coroutine_wrapper()``, ``types.coroutine(gen)``, ``inspect.iscoroutinefunction(func)``, ``inspect.iscoroutine(obj)``, - and ``inspect.isawaitable(obj)``. + ``inspect.isawaitable(obj)``, ``inspect.getcoroutinestate(coro)``, + and ``inspect.getcoroutinelocals(coro)``. 7. New ``CO_COROUTINE`` and ``CO_ITERABLE_COROUTINE`` bit flags for code objects. @@ -1346,6 +1356,11 @@ List of high-level changes and new protocols ``collections.abc.Coroutine``, ``collections.abc.AsyncIterable``, and ``collections.abc.AsyncIterator``. +9. C API changes: new ``PyCoro_Type`` (exposed to Python as + ``types.CoroutineType``) and ``PyCoroObject``. + ``PyCoro_CheckExact(*o)`` to test if ``o`` is a *native coroutine*. + + While the list of changes and new things is not short, it is important to understand, that most users will not use these features directly. It is intended to be used in frameworks and libraries to provide users