cpython: 5a11263bb612 (original) (raw)

Mercurial > cpython

changeset 105661:5a11263bb612 3.6

Yury Selivanov yury@magic.io
date Thu, 15 Dec 2016 17:36:05 -0500
parents b70b2d3f3167
children c4d6ef15bb7c
files Doc/glossary.rst Doc/library/asyncio-eventloop.rst Doc/library/inspect.rst Doc/library/sys.rst Doc/library/types.rst Doc/reference/compound_stmts.rst Doc/reference/datamodel.rst Doc/reference/expressions.rst Doc/reference/simple_stmts.rst
diffstat 9 files changed, 298 insertions(+), 4 deletions(-)[+] [-] Doc/glossary.rst 28 Doc/library/asyncio-eventloop.rst 18 Doc/library/inspect.rst 21 Doc/library/sys.rst 36 Doc/library/types.rst 8 Doc/reference/compound_stmts.rst 2 Doc/reference/datamodel.rst 19 Doc/reference/expressions.rst 166 Doc/reference/simple_stmts.rst 4

line wrap: on

line diff

--- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -74,6 +74,34 @@ Glossary :keyword:async with statement by defining :meth:__aenter__ and :meth:__aexit__ methods. Introduced by :pep:492.

+

+

+

+

+

+ asynchronous iterable An object, that can be used in an :keyword:async for statement. Must return an :term:asynchronous iterator from its

--- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -88,6 +88,24 @@ Run an event loop This is idempotent and irreversible. No other methods should be called after this one. + +.. coroutinemethod:: AbstractEventLoop.shutdown_asyncgens() +

+

+ .. _asyncio-pass-keywords: Calls

--- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -318,6 +318,27 @@ attributes: .. versionadded:: 3.5 +.. function:: isasyncgenfunction(object) +

+

+ +.. function:: isasyncgen(object) +

.. function:: istraceback(object) Return true if the object is a traceback.

--- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -594,6 +594,24 @@ always available. .. versionchanged:: 3.6 Added platform_version + +.. function:: get_asyncgen_hooks() +

+

+ + .. function:: get_coroutine_wrapper() Returns None, or a wrapper set by :func:set_coroutine_wrapper. @@ -1098,6 +1116,24 @@ always available. implementation platform, rather than part of the language definition, and thus may not be available in all Python implementations. +.. function:: set_asyncgen_hooks(firstiter, finalizer) +

+

+ .. function:: set_coroutine_wrapper(wrapper)

--- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -104,6 +104,14 @@ Standard names are defined for the follo .. versionadded:: 3.5 +.. data:: AsyncGeneratorType +

+ .. data:: CodeType .. index:: builtin: compile

--- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -697,7 +697,7 @@ coroutine bodies. Functions defined with async def syntax are always coroutine functions, even if they do not contain await or async keywords. -It is a :exc:SyntaxError to use :keyword:yield expressions in +It is a :exc:SyntaxError to use yield from expressions in async def coroutines. An example of a coroutine function::

--- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -627,6 +627,25 @@ Callable types as well as :keyword:async with and :keyword:async for statements. See also the :ref:coroutine-objects section.

+

+

+ Built-in functions .. index:: object: built-in function

--- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -172,7 +172,7 @@ Common syntax elements for comprehension .. productionlist:: comprehension: expression comp_for

@@ -186,6 +186,17 @@ each time the innermost block is reached Note that the comprehension is executed in a separate scope, so names assigned to in the target list don't "leak" into the enclosing scope. +Since Python 3.6, in an :keyword:async def function, an :keyword:async for +clause may be used to iterate over a :term:asynchronous iterator. +A comprehension in an :keyword:async def function may consist of either a +:keyword:for or :keyword:async for clause following the leading +expression, may contan additonal :keyword:for or :keyword:async for +clauses, and may also use :keyword:await expressions. +If a comprehension contains either :keyword:async for clauses +or :keyword:await expressions it is called an +:dfn:asynchronous comprehension. An asynchronous comprehension may +suspend the execution of the coroutine function in which it appears. +See also :pep:530. .. _lists: @@ -315,6 +326,14 @@ range(10) for y in bar(x))``. The parentheses can be omitted on calls with only one argument. See section :ref:calls for details. +Since Python 3.6, if the generator appears in an :keyword:async def function, +then :keyword:async for clauses and :keyword:await expressions are permitted +as with an asynchronous comprehension. If a generator expression +contains either :keyword:async for clauses or :keyword:await expressions +it is called an :dfn:asynchronous generator expression. +An asynchronous generator expression yields a new asynchronous +generator object, which is an asynchronous iterator +(see :ref:async-iterators). .. _yieldexpr: @@ -330,9 +349,22 @@ Yield expressions yield_atom: "(" yield_expression ")" yield_expression: "yield" [expression_list | "from" expression] -The yield expression is only used when defining a :term:generator function and +The yield expression is used when defining a :term:generator function +or an :term:asynchronous generator function and thus can only be used in the body of a function definition. Using a yield -expression in a function's body causes that function to be a generator. +expression in a function's body causes that function to be a generator, +and using it in an :keyword:async def function's body causes that +coroutine function to be an asynchronous generator. For example:: +

+

+ +Generator functions are described below, while asynchronous generator +functions are described separately in section +:ref:asynchronous-generator-functions. When a generator function is called, it returns an iterator known as a generator. That generator then controls the execution of the generator function. @@ -496,6 +528,134 @@ generator functions:: For examples using yield from, see :ref:pep-380 in "What's New in Python." +.. _asynchronous-generator-functions: + +Asynchronous generator functions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The presence of a yield expression in a function or method defined using +:keyword:async def further defines the function as a +:term:asynchronous generator function. + +When an asynchronous generator function is called, it returns an +asynchronous iterator known as an asynchronous generator object. +That object then controls the execution of the generator function. +An asynchronous generator object is typically used in an +:keyword:async for statement in a coroutine function analogously to +how a generator object would be used in a :keyword:for statement. + +Calling one of the asynchronous generator's methods returns an +:term:awaitable object, and the execution starts when this object +is awaited on. At that time, the execution proceeds to the first yield +expression, where it is suspended again, returning the value of +:token:expression_list to the awaiting coroutine. As with a generator, +suspension means that all local state is retained, including the +current bindings of local variables, the instruction pointer, the internal +evaluation stack, and the state of any exception handling. When the execution +is resumed by awaiting on the next object returned by the asynchronous +generator's methods, the function can proceed exactly as if the yield +expression were just another external call. The value of the yield expression +after resuming depends on the method which resumed the execution. If +:meth:~agen.__anext__ is used then the result is :const:None. Otherwise, if +:meth:~agen.asend is used, then the result will be the value passed in to +that method. + +In an asynchronous generator function, yield expressions are allowed anywhere +in a :keyword:try construct. However, if an asynchronous generator is not +resumed before it is finalized (by reaching a zero reference count or by +being garbage collected), then a yield expression within a :keyword:try +construct could result in a failure to execute pending :keyword:finally +clauses. In this case, it is the responsibility of the event loop or +scheduler running the asynchronous generator to call the asynchronous +generator-iterator's :meth:~agen.aclose method and run the resulting +coroutine object, thus allowing any pending :keyword:finally clauses +to execute. + +To take care of finalization, an event loop should define +a finalizer function which takes an asynchronous generator-iterator +and presumably calls :meth:~agen.aclose and executes the coroutine. +This finalizer may be registered by calling :func:sys.set_asyncgen_hooks. +When first iterated over, an asynchronous generator-iterator will store the +registered finalizer to be called upon finalization. For a reference example +of a finalizer method see the implementation of +asyncio.Loop.shutdown_asyncgens in :source:Lib/asyncio/base_events.py. + +The expression yield from <expr> is a syntax error when used in an +asynchronous generator function. + +.. index:: object: asynchronous-generator +.. _asynchronous-generator-methods: + +Asynchronous generator-iterator methods +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This subsection describes the methods of an asynchronous generator iterator, +which are used to control the execution of a generator function. + + +.. index:: exception: StopAsyncIteration + +.. coroutinemethod:: agen.anext() +

+ +.. coroutinemethod:: agen.asend(value) +

+ +.. coroutinemethod:: agen.athrow(type[, value[, traceback]]) +

+.. index:: exception: GeneratorExit + + +.. coroutinemethod:: agen.aclose() +

.. _primaries:

--- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -492,6 +492,10 @@ generator is done and will cause :exc:S[](#l9.3) value (if any) is used as an argument to construct :exc:StopIteration and[](#l9.4) becomes the :attr:StopIteration.value attribute.[](#l9.5) [](#l9.6) +In an asynchronous generator function, an empty :keyword:return statement[](#l9.7) +indicates that the asynchronous generator is done and will cause[](#l9.8) +:exc:StopAsyncIteration to be raised. A non-empty :keyword:return` +statement is a syntax error in an asynchronous generator function. .. _yield: