diff --git a/pep-0492.txt b/pep-0492.txt index 2bf52d6e0..a7c9c718e 100644 --- a/pep-0492.txt +++ b/pep-0492.txt @@ -701,6 +701,9 @@ New Standard Library Functions * ``inspect.iscoroutinefunction(obj)`` returns ``True`` if ``obj`` is a *native coroutine function*. +* ``inspect.isawaitable(obj)`` returns ``True`` if ``obj`` is an + *awaitable*. + * ``inspect.getcoroutinestate(coro)`` returns the current state of a *native coroutine object* (mirrors ``inspect.getfgeneratorstate(gen)``). @@ -735,6 +738,20 @@ Abstract Base Classes (ABC) are added: implement ``send(value)``, ``throw(type, exc, tb)``, ``close()`` and ``__await__()`` methods. + Note that generator-based coroutines with ``CO_ITERABLE_COROUTINE`` + flag do not implement ``__await__`` method, and therefore are not + instances of ``collections.abc.Coroutine`` and + ``collections.abc.Awaitable`` ABCs:: + + @types.coroutine + def gencoro(): + yield + + assert not isinstance(gencoro(), collections.abc.Coroutine) + + # however: + assert inspect.isawaitable(gencoro()) + To allow easy testing if objects support asynchronous iteration, two more ABCs are added: @@ -837,8 +854,6 @@ it: * recognizes ``async def`` ``NAME`` tokens combination; -* keeps track of regular ``def`` and ``async def`` indented blocks; - * while tokenizing ``async def`` block, it replaces ``'async'`` ``NAME`` token with ``ASYNC``, and ``'await'`` ``NAME`` token with ``AWAIT``; @@ -931,41 +946,6 @@ Grammar changes are fairly minimal:: atom_expr: [AWAIT] atom trailer* -Transition Period Shortcomings ------------------------------- - -There is just one. - -Until ``async`` and ``await`` are not proper keywords, it is not -possible (or at least very hard) to fix ``tokenizer.c`` to recognize -them on the **same line** with ``def`` keyword:: - - # async and await will always be parsed as variables - - async def outer(): # 1 - def nested(a=(await fut)): - pass - - async def foo(): return (await fut) # 2 - -Since ``await`` and ``async`` in such cases are parsed as ``NAME`` -tokens, a ``SyntaxError`` will be raised. - -To workaround these issues, the above examples can be easily rewritten -to a more readable form:: - - async def outer(): # 1 - a_default = await fut - def nested(a=a_default): - pass - - async def foo(): # 2 - return (await fut) - -This limitation will go away as soon as ``async`` and ``await`` are -proper keywords. - - Deprecation Plans ----------------- @@ -1365,8 +1345,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)``, - ``inspect.getcoroutinestate(coro)``, and - ``inspect.getcoroutinelocals(coro)``. + ``inspect.isawaitable(obj)``, ``inspect.getcoroutinestate(coro)``, + and ``inspect.getcoroutinelocals(coro)``. 7. New ``CO_COROUTINE`` and ``CO_ITERABLE_COROUTINE`` bit flags for code objects.