diff options
author | Yury Selivanov <yury@magic.io> | 2016-06-09 19:08:31 (GMT) |
---|---|---|
committer | Yury Selivanov <yury@magic.io> | 2016-06-09 19:08:31 (GMT) |
commit | a6f6edbda8648698289a8ee7abef6a35c924151b (patch) | |
tree | 9eb77fd4f552bcabfb46a3938d0ded084e7709f9 /Doc/reference | |
parent | ebe95fdabb42b02ff7eecab6bc9637cf5ccf1d2c (diff) | |
download | cpython-a6f6edbda8648698289a8ee7abef6a35c924151b.zip cpython-a6f6edbda8648698289a8ee7abef6a35c924151b.tar.gz cpython-a6f6edbda8648698289a8ee7abef6a35c924151b.tar.bz2 |
Issue #27243: Fix __aiter__ protocol
Diffstat (limited to 'Doc/reference')
-rw-r--r-- | Doc/reference/compound_stmts.rst | 2 | ||||
-rw-r--r-- | Doc/reference/datamodel.rst | 48 |
2 files changed, 47 insertions, 3 deletions
diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 8047673..2469422 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -726,7 +726,7 @@ The following code:: Is semantically equivalent to:: iter = (ITER) - iter = await type(iter).__aiter__(iter) + iter = type(iter).__aiter__(iter) running = True while running: try: diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 3ddbd62..493acaa 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2359,6 +2359,7 @@ generators, coroutines do not directly support iteration. Coroutine objects are automatically closed using the above process when they are about to be destroyed. +.. _async-iterators: Asynchronous Iterators ---------------------- @@ -2371,7 +2372,7 @@ Asynchronous iterators can be used in an :keyword:`async for` statement. .. method:: object.__aiter__(self) - Must return an *awaitable* resulting in an *asynchronous iterator* object. + Must return an *asynchronous iterator* object. .. method:: object.__anext__(self) @@ -2384,7 +2385,7 @@ An example of an asynchronous iterable object:: async def readline(self): ... - async def __aiter__(self): + def __aiter__(self): return self async def __anext__(self): @@ -2395,6 +2396,49 @@ An example of an asynchronous iterable object:: .. versionadded:: 3.5 +.. note:: + + .. versionchanged:: 3.5.2 + Starting with CPython 3.5.2, ``__aiter__`` can directly return + :term:`asynchronous iterators <asynchronous iterator>`. Returning + an :term:`awaitable` object will result in a + :exc:`PendingDeprecationWarning`. + + The recommended way of writing backwards compatible code in + CPython 3.5.x is to continue returning awaitables from + ``__aiter__``. If you want to avoid the PendingDeprecationWarning + and keep the code backwards compatible, the following decorator + can be used:: + + import functools + import sys + + if sys.version_info < (3, 5, 2): + def aiter_compat(func): + @functools.wraps(func) + async def wrapper(self): + return func(self) + return wrapper + else: + def aiter_compat(func): + return func + + Example:: + + class AsyncIterator: + + @aiter_compat + def __aiter__(self): + return self + + async def __anext__(self): + ... + + Starting with CPython 3.6, the :exc:`PendingDeprecationWarning` + will be replaced with the :exc:`DeprecationWarning`. + In CPython 3.7, returning an awaitable from ``__aiter__`` will + result in a :exc:`RuntimeError`. + Asynchronous Context Managers ----------------------------- |