2124 lines
194 KiB
HTML
2124 lines
194 KiB
HTML
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="color-scheme" content="light dark">
|
||
<title>PEP 3156 – Asynchronous IO Support Rebooted: the “asyncio” Module | peps.python.org</title>
|
||
<link rel="shortcut icon" href="../_static/py.png">
|
||
<link rel="canonical" href="https://peps.python.org/pep-3156/">
|
||
<link rel="stylesheet" href="../_static/style.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
|
||
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
|
||
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
|
||
<meta property="og:title" content='PEP 3156 – Asynchronous IO Support Rebooted: the “asyncio” Module | peps.python.org'>
|
||
<meta property="og:description" content="This is a proposal for asynchronous I/O in Python 3, starting at Python 3.3. Consider this the concrete proposal that is missing from PEP 3153. The proposal includes a pluggable event loop, transport and protocol abstractions similar to those in Twist...">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:url" content="https://peps.python.org/pep-3156/">
|
||
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
|
||
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
|
||
<meta property="og:image:alt" content="Python PEPs">
|
||
<meta property="og:image:width" content="200">
|
||
<meta property="og:image:height" content="200">
|
||
<meta name="description" content="This is a proposal for asynchronous I/O in Python 3, starting at Python 3.3. Consider this the concrete proposal that is missing from PEP 3153. The proposal includes a pluggable event loop, transport and protocol abstractions similar to those in Twist...">
|
||
<meta name="theme-color" content="#3776ab">
|
||
</head>
|
||
<body>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Following system colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="9"></circle>
|
||
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected dark colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected light colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="5"></circle>
|
||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||
</svg>
|
||
</symbol>
|
||
</svg>
|
||
<script>
|
||
|
||
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
|
||
</script>
|
||
<section id="pep-page-section">
|
||
<header>
|
||
<h1>Python Enhancement Proposals</h1>
|
||
<ul class="breadcrumbs">
|
||
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> » </li>
|
||
<li><a href="../pep-0000/">PEP Index</a> » </li>
|
||
<li>PEP 3156</li>
|
||
</ul>
|
||
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
|
||
</button>
|
||
</header>
|
||
<article>
|
||
<section id="pep-content">
|
||
<h1 class="page-title">PEP 3156 – Asynchronous IO Support Rebooted: the “asyncio” Module</h1>
|
||
<dl class="rfc2822 field-list simple">
|
||
<dt class="field-odd">Author<span class="colon">:</span></dt>
|
||
<dd class="field-odd">Guido van Rossum <guido at python.org></dd>
|
||
<dt class="field-even">BDFL-Delegate<span class="colon">:</span></dt>
|
||
<dd class="field-even">Antoine Pitrou <antoine at python.org></dd>
|
||
<dt class="field-odd">Discussions-To<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><a class="reference external" href="https://groups.google.com/g/python-tulip">python-tulip@googlegroups.com</a></dd>
|
||
<dt class="field-even">Status<span class="colon">:</span></dt>
|
||
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
|
||
<dt class="field-odd">Type<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
|
||
<dt class="field-even">Created<span class="colon">:</span></dt>
|
||
<dd class="field-even">12-Dec-2012</dd>
|
||
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
|
||
<dd class="field-odd">3.3</dd>
|
||
<dt class="field-even">Post-History<span class="colon">:</span></dt>
|
||
<dd class="field-even">21-Dec-2012</dd>
|
||
<dt class="field-odd">Replaces<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><a class="reference external" href="../pep-3153/">3153</a></dd>
|
||
<dt class="field-even">Resolution<span class="colon">:</span></dt>
|
||
<dd class="field-even"><a class="reference external" href="https://mail.python.org/pipermail/python-dev/2013-November/130419.html">Python-Dev message</a></dd>
|
||
</dl>
|
||
<hr class="docutils" />
|
||
<section id="contents">
|
||
<details><summary>Table of Contents</summary><ul class="simple">
|
||
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
||
<li><a class="reference internal" href="#introduction">Introduction</a><ul>
|
||
<li><a class="reference internal" href="#status">Status</a></li>
|
||
<li><a class="reference internal" href="#dependencies">Dependencies</a></li>
|
||
<li><a class="reference internal" href="#module-namespace">Module Namespace</a></li>
|
||
<li><a class="reference internal" href="#interoperability">Interoperability</a></li>
|
||
<li><a class="reference internal" href="#transports-and-protocols">Transports and Protocols</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#event-loop-interface-specification">Event Loop Interface Specification</a><ul>
|
||
<li><a class="reference internal" href="#event-loop-policy-getting-and-setting-the-current-event-loop">Event Loop Policy: Getting and Setting the Current Event Loop</a><ul>
|
||
<li><a class="reference internal" href="#passing-an-event-loop-around-explicitly">Passing an Event Loop Around Explicitly</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#specifying-times">Specifying Times</a></li>
|
||
<li><a class="reference internal" href="#embedded-event-loops">Embedded Event Loops</a></li>
|
||
<li><a class="reference internal" href="#event-loop-classes">Event Loop Classes</a></li>
|
||
<li><a class="reference internal" href="#event-loop-methods-overview">Event Loop Methods Overview</a></li>
|
||
<li><a class="reference internal" href="#event-loop-methods">Event Loop Methods</a><ul>
|
||
<li><a class="reference internal" href="#starting-stopping-and-closing">Starting, Stopping and Closing</a></li>
|
||
<li><a class="reference internal" href="#basic-callbacks">Basic Callbacks</a></li>
|
||
<li><a class="reference internal" href="#thread-interaction">Thread interaction</a></li>
|
||
<li><a class="reference internal" href="#internet-name-lookups">Internet name lookups</a></li>
|
||
<li><a class="reference internal" href="#internet-connections">Internet connections</a></li>
|
||
<li><a class="reference internal" href="#wrapped-socket-methods">Wrapped Socket Methods</a></li>
|
||
<li><a class="reference internal" href="#i-o-callbacks">I/O Callbacks</a></li>
|
||
<li><a class="reference internal" href="#pipes-and-subprocesses">Pipes and Subprocesses</a></li>
|
||
<li><a class="reference internal" href="#signal-callbacks">Signal callbacks</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#mutual-exclusion-of-callbacks">Mutual Exclusion of Callbacks</a></li>
|
||
<li><a class="reference internal" href="#exceptions">Exceptions</a></li>
|
||
<li><a class="reference internal" href="#debug-mode">Debug Mode</a></li>
|
||
<li><a class="reference internal" href="#handles">Handles</a></li>
|
||
<li><a class="reference internal" href="#servers">Servers</a></li>
|
||
<li><a class="reference internal" href="#futures">Futures</a></li>
|
||
<li><a class="reference internal" href="#transports">Transports</a><ul>
|
||
<li><a class="reference internal" href="#methods-for-all-transports">Methods For All Transports</a></li>
|
||
<li><a class="reference internal" href="#bidirectional-stream-transports">Bidirectional Stream Transports</a></li>
|
||
<li><a class="reference internal" href="#unidirectional-stream-transports">Unidirectional Stream Transports</a></li>
|
||
<li><a class="reference internal" href="#datagram-transports">Datagram Transports</a></li>
|
||
<li><a class="reference internal" href="#subprocess-transports">Subprocess Transports</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#protocols">Protocols</a><ul>
|
||
<li><a class="reference internal" href="#stream-protocols">Stream Protocols</a></li>
|
||
<li><a class="reference internal" href="#datagram-protocols">Datagram Protocols</a></li>
|
||
<li><a class="reference internal" href="#subprocess-protocol">Subprocess Protocol</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#callback-style">Callback Style</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#coroutines-and-the-scheduler">Coroutines and the Scheduler</a><ul>
|
||
<li><a class="reference internal" href="#coroutines">Coroutines</a></li>
|
||
<li><a class="reference internal" href="#waiting-for-multiple-coroutines">Waiting for Multiple Coroutines</a></li>
|
||
<li><a class="reference internal" href="#sleeping">Sleeping</a></li>
|
||
<li><a class="reference internal" href="#tasks">Tasks</a></li>
|
||
<li><a class="reference internal" href="#the-scheduler">The Scheduler</a></li>
|
||
<li><a class="reference internal" href="#convenience-utilities">Convenience Utilities</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#synchronization">Synchronization</a><ul>
|
||
<li><a class="reference internal" href="#locks">Locks</a></li>
|
||
<li><a class="reference internal" href="#queues">Queues</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#miscellaneous">Miscellaneous</a><ul>
|
||
<li><a class="reference internal" href="#logging">Logging</a></li>
|
||
<li><a class="reference internal" href="#sigchld-handling-on-unix"><code class="docutils literal notranslate"><span class="pre">SIGCHLD</span></code> handling on UNIX</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#wish-list">Wish List</a></li>
|
||
<li><a class="reference internal" href="#open-issues">Open Issues</a></li>
|
||
<li><a class="reference internal" href="#references">References</a></li>
|
||
<li><a class="reference internal" href="#acknowledgments">Acknowledgments</a></li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
</ul>
|
||
</details></section>
|
||
<section id="abstract">
|
||
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
|
||
<p>This is a proposal for asynchronous I/O in Python 3, starting at
|
||
Python 3.3. Consider this the concrete proposal that is missing from
|
||
<a class="pep reference internal" href="../pep-3153/" title="PEP 3153 – Asynchronous IO support">PEP 3153</a>. The proposal includes a pluggable event loop, transport and
|
||
protocol abstractions similar to those in Twisted, and a higher-level
|
||
scheduler based on <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> (<a class="pep reference internal" href="../pep-0380/" title="PEP 380 – Syntax for Delegating to a Subgenerator">PEP 380</a>). The proposed package
|
||
name is <code class="docutils literal notranslate"><span class="pre">asyncio</span></code>.</p>
|
||
</section>
|
||
<section id="introduction">
|
||
<h2><a class="toc-backref" href="#introduction" role="doc-backlink">Introduction</a></h2>
|
||
<section id="status">
|
||
<h3><a class="toc-backref" href="#status" role="doc-backlink">Status</a></h3>
|
||
<p>A reference implementation exists under the code name Tulip. The
|
||
Tulip repo is linked from the References section at the end. Packages
|
||
based on this repo will be provided on PyPI (see References) to enable
|
||
using the <code class="docutils literal notranslate"><span class="pre">asyncio</span></code> package with Python 3.3 installations.</p>
|
||
<p>As of October 20th 2013, the <code class="docutils literal notranslate"><span class="pre">asyncio</span></code> package has been checked into
|
||
the Python 3.4 repository and released with Python 3.4-alpha-4, with
|
||
“provisional” API status. This is an expression of confidence and
|
||
intended to increase early feedback on the API, and not intended to
|
||
force acceptance of the PEP. The expectation is that the package will
|
||
keep provisional status in Python 3.4 and progress to final status in
|
||
Python 3.5. Development continues to occur primarily in the Tulip
|
||
repo, with changes occasionally merged into the CPython repo.</p>
|
||
</section>
|
||
<section id="dependencies">
|
||
<h3><a class="toc-backref" href="#dependencies" role="doc-backlink">Dependencies</a></h3>
|
||
<p>Python 3.3 is required for many of the proposed features. The
|
||
reference implementation (Tulip) requires no new language or standard
|
||
library features beyond Python 3.3, no third-party modules or
|
||
packages, and no C code, except for the (optional) IOCP support on
|
||
Windows.</p>
|
||
</section>
|
||
<section id="module-namespace">
|
||
<h3><a class="toc-backref" href="#module-namespace" role="doc-backlink">Module Namespace</a></h3>
|
||
<p>The specification here lives in a new top-level package, <code class="docutils literal notranslate"><span class="pre">asyncio</span></code>.
|
||
Different components live in separate submodules of the package. The
|
||
package will import common APIs from their respective submodules and
|
||
make them available as package attributes (similar to the way the
|
||
email package works). For such common APIs, the name of the submodule
|
||
that actually defines them is not part of the specification. Less
|
||
common APIs may have to explicitly be imported from their respective
|
||
submodule, and in this case the submodule name is part of the
|
||
specification.</p>
|
||
<p>Classes and functions defined without a submodule name are assumed to
|
||
live in the namespace of the top-level package. (But do not confuse
|
||
these with methods of various classes, which for brevity are also used
|
||
without a namespace prefix in certain contexts.)</p>
|
||
</section>
|
||
<section id="interoperability">
|
||
<h3><a class="toc-backref" href="#interoperability" role="doc-backlink">Interoperability</a></h3>
|
||
<p>The event loop is the place where most interoperability occurs. It
|
||
should be easy for (Python 3.3 ports of) frameworks like Twisted,
|
||
Tornado, or even gevents to either adapt the default event loop
|
||
implementation to their needs using a lightweight adapter or proxy, or
|
||
to replace the default event loop implementation with an adaptation of
|
||
their own event loop implementation. (Some frameworks, like Twisted,
|
||
have multiple event loop implementations. This should not be a
|
||
problem since these all have the same interface.)</p>
|
||
<p>In most cases it should be possible for two different third-party
|
||
frameworks to interoperate, either by sharing the default event loop
|
||
implementation (each using its own adapter), or by sharing the event
|
||
loop implementation of either framework. In the latter case two
|
||
levels of adaptation would occur (from framework A’s event loop to the
|
||
standard event loop interface, and from there to framework B’s event
|
||
loop). Which event loop implementation is used should be under
|
||
control of the main program (though a default policy for event loop
|
||
selection is provided).</p>
|
||
<p>For this interoperability to be effective, the preferred direction of
|
||
adaptation in third party frameworks is to keep the default event loop
|
||
and adapt it to the framework’s API. Ideally all third party
|
||
frameworks would give up their own event loop implementation in favor
|
||
of the standard implementation. But not all frameworks may be
|
||
satisfied with the functionality provided by the standard
|
||
implementation.</p>
|
||
<p>In order to support both directions of adaptation, two separate APIs
|
||
are specified:</p>
|
||
<ul class="simple">
|
||
<li>An interface for managing the current event loop</li>
|
||
<li>The interface of a conforming event loop</li>
|
||
</ul>
|
||
<p>An event loop implementation may provide additional methods and
|
||
guarantees, as long as these are called out in the documentation as
|
||
non-standard. An event loop implementation may also leave certain
|
||
methods unimplemented if they cannot be implemented in the given
|
||
environment; however, such deviations from the standard API should be
|
||
considered only as a last resort, and only if the platform or
|
||
environment forces the issue. (An example would be a platform where
|
||
there is a system event loop that cannot be started or stopped; see
|
||
“Embedded Event Loops” below.)</p>
|
||
<p>The event loop API does not depend on <code class="docutils literal notranslate"><span class="pre">await/yield</span> <span class="pre">from</span></code>. Rather, it uses
|
||
a combination of callbacks, additional interfaces (transports and
|
||
protocols), and Futures. The latter are similar to those defined in
|
||
<a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>, but have a different implementation and are not tied to
|
||
threads. In particular, the <code class="docutils literal notranslate"><span class="pre">result()</span></code> method raises an exception
|
||
instead of blocking when a result is not yet ready; the user is
|
||
expected to use callbacks (or <code class="docutils literal notranslate"><span class="pre">await/yield</span> <span class="pre">from</span></code>) to wait for the result.</p>
|
||
<p>All event loop methods specified as returning a coroutine are allowed
|
||
to return either a Future or a coroutine, at the implementation’s
|
||
choice (the standard implementation always returns coroutines). All
|
||
event loop methods documented as accepting coroutine arguments <em>must</em>
|
||
accept both Futures and coroutines for such arguments. (A convenience
|
||
function, <code class="docutils literal notranslate"><span class="pre">ensure_future()</span></code>, exists to convert an argument that is either a
|
||
coroutine or a Future into a Future.)</p>
|
||
<p>For users (like myself) who don’t like using callbacks, a scheduler is
|
||
provided for writing asynchronous I/O code as coroutines using the PEP
|
||
380 <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> or <a class="pep reference internal" href="../pep-0492/" title="PEP 492 – Coroutines with async and await syntax">PEP 492</a> <code class="docutils literal notranslate"><span class="pre">await</span></code> expressions.
|
||
The scheduler is not pluggable;
|
||
pluggability occurs at the event loop level, and the standard
|
||
scheduler implementation should work with any conforming event loop
|
||
implementation. (In fact this is an important litmus test for
|
||
conforming implementations.)</p>
|
||
<p>For interoperability between code written using coroutines and other
|
||
async frameworks, the scheduler defines a Task class that behaves like a
|
||
Future. A framework that interoperates at the event loop level can
|
||
wait for a Future to complete by adding a callback to the Future.
|
||
Likewise, the scheduler offers an operation to suspend a coroutine
|
||
until a callback is called.</p>
|
||
<p>If such a framework cannot use the Future and Task classes as-is, it
|
||
may reimplement the <code class="docutils literal notranslate"><span class="pre">loop.create_future()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">loop.create_task()</span></code> methods. These should return objects
|
||
implementing (a superset of) the Future/Task interfaces.</p>
|
||
<p>A less ambitious framework may just call the
|
||
<code class="docutils literal notranslate"><span class="pre">loop.set_task_factory()</span></code> to replace the Task class without
|
||
implementing its own event loop.</p>
|
||
<p>The event loop API provides limited interoperability with threads:
|
||
there is an API to submit a function to an executor (see <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>)
|
||
which returns a Future that is compatible with the event loop, and
|
||
there is a method to schedule a callback with an event loop from
|
||
another thread in a thread-safe manner.</p>
|
||
</section>
|
||
<section id="transports-and-protocols">
|
||
<h3><a class="toc-backref" href="#transports-and-protocols" role="doc-backlink">Transports and Protocols</a></h3>
|
||
<p>For those not familiar with Twisted, a quick explanation of the
|
||
relationship between transports and protocols is in order. At the
|
||
highest level, the transport is concerned with <em>how</em> bytes are
|
||
transmitted, while the protocol determines <em>which</em> bytes to transmit
|
||
(and to some extent when).</p>
|
||
<p>A different way of saying the same thing: a transport is an
|
||
abstraction for a socket (or similar I/O endpoint) while a protocol is
|
||
an abstraction for an application, from the transport’s point of view.</p>
|
||
<p>Yet another view is simply that the transport and protocol interfaces
|
||
<em>together</em> define an abstract interface for using network I/O and
|
||
interprocess I/O.</p>
|
||
<p>There is almost always a 1:1 relationship between transport and
|
||
protocol objects: the protocol calls transport methods to send data,
|
||
while the transport calls protocol methods to pass it data that has
|
||
been received. Neither transport nor protocol methods “block” – they
|
||
set events into motion and then return.</p>
|
||
<p>The most common type of transport is a bidirectional stream transport.
|
||
It represents a pair of buffered streams (one in each direction) that
|
||
each transmit a sequence of bytes. The most common example of a
|
||
bidirectional stream transport is probably a TCP connection. Another
|
||
common example is an SSL/TLS connection. But there are some other things
|
||
that can be viewed this way, for example an SSH session or a pair of
|
||
UNIX pipes. Typically there aren’t many different transport
|
||
implementations, and most of them come with the event loop
|
||
implementation. However, there is no requirement that all transports
|
||
must be created by calling an event loop method: a third party module
|
||
may well implement a new transport and provide a constructor or
|
||
factory function for it that simply takes an event loop as an argument
|
||
or calls <code class="docutils literal notranslate"><span class="pre">get_event_loop()</span></code>.</p>
|
||
<p>Note that transports don’t need to use sockets, not even if they use
|
||
TCP – sockets are a platform-specific implementation detail.</p>
|
||
<p>A bidirectional stream transport has two “ends”: one end talks to
|
||
the network (or another process, or whatever low-level interface it
|
||
wraps), and the other end talks to the protocol. The former uses
|
||
whatever API is necessary to implement the transport; but the
|
||
interface between transport and protocol is standardized by this PEP.</p>
|
||
<p>A protocol can represent some kind of “application-level” protocol
|
||
such as HTTP or SMTP; it can also implement an abstraction shared by
|
||
multiple protocols, or a whole application. A protocol’s primary
|
||
interface is with the transport. While some popular protocols (and
|
||
other abstractions) may have standard implementations, often
|
||
applications implement custom protocols. It also makes sense to have
|
||
libraries of useful third party protocol implementations that can be
|
||
downloaded and installed from PyPI.</p>
|
||
<p>There general notion of transport and protocol includes other
|
||
interfaces, where the transport wraps some other communication
|
||
abstraction. Examples include interfaces for sending and receiving
|
||
datagrams (e.g. UDP), or a subprocess manager. The separation of
|
||
concerns is the same as for bidirectional stream transports and
|
||
protocols, but the specific interface between transport and protocol
|
||
is different in each case.</p>
|
||
<p>Details of the interfaces defined by the various standard types of
|
||
transports and protocols are given later.</p>
|
||
</section>
|
||
</section>
|
||
<section id="event-loop-interface-specification">
|
||
<h2><a class="toc-backref" href="#event-loop-interface-specification" role="doc-backlink">Event Loop Interface Specification</a></h2>
|
||
<section id="event-loop-policy-getting-and-setting-the-current-event-loop">
|
||
<h3><a class="toc-backref" href="#event-loop-policy-getting-and-setting-the-current-event-loop" role="doc-backlink">Event Loop Policy: Getting and Setting the Current Event Loop</a></h3>
|
||
<p>Event loop management is controlled by an event loop policy, which is
|
||
a global (per-process) object. There is a default policy, and an API
|
||
to change the policy. A policy defines the notion of context; a
|
||
policy manages a separate event loop per context. The default
|
||
policy’s notion of context is defined as the current thread.</p>
|
||
<p>Certain platforms or programming frameworks may change the default
|
||
policy to something more suitable to the expectations of the users of
|
||
that platform or framework. Such platforms or frameworks must
|
||
document their policy and at what point during their initialization
|
||
sequence the policy is set, in order to avoid undefined behavior when
|
||
multiple active frameworks want to override the default policy.
|
||
(See also “Embedded Event Loops” below.)</p>
|
||
<p>To get the event loop for current context, use <code class="docutils literal notranslate"><span class="pre">get_event_loop()</span></code>.
|
||
This returns an event loop object implementing the interface specified
|
||
below, or raises an exception in case no event loop has been set for
|
||
the current context and the current policy does not specify to create
|
||
one. It should never return <code class="docutils literal notranslate"><span class="pre">None</span></code>.</p>
|
||
<p>To set the event loop for the current context, use
|
||
<code class="docutils literal notranslate"><span class="pre">set_event_loop(event_loop)</span></code>, where <code class="docutils literal notranslate"><span class="pre">event_loop</span></code> is an event loop
|
||
object, i.e. an instance of <code class="docutils literal notranslate"><span class="pre">AbstractEventLoop</span></code>, or <code class="docutils literal notranslate"><span class="pre">None</span></code>.
|
||
It is okay to set the current event loop to <code class="docutils literal notranslate"><span class="pre">None</span></code>, in
|
||
which case subsequent calls to <code class="docutils literal notranslate"><span class="pre">get_event_loop()</span></code> will raise an
|
||
exception. This is useful for testing code that should not depend on
|
||
the existence of a default event loop.</p>
|
||
<p>It is expected that <code class="docutils literal notranslate"><span class="pre">get_event_loop()</span></code> returns a different event
|
||
loop object depending on the context (in fact, this is the definition
|
||
of context). It may create a new event loop object if none is set and
|
||
creation is allowed by the policy. The default policy will create a
|
||
new event loop only in the main thread (as defined by threading.py,
|
||
which uses a special subclass for the main thread), and only if
|
||
<code class="docutils literal notranslate"><span class="pre">get_event_loop()</span></code> is called before <code class="docutils literal notranslate"><span class="pre">set_event_loop()</span></code> is ever
|
||
called. (To reset this state, reset the policy.) In other threads an
|
||
event loop must be explicitly set. Other policies may behave
|
||
differently. Event loop by the default policy creation is lazy;
|
||
i.e. the first call to <code class="docutils literal notranslate"><span class="pre">get_event_loop()</span></code> creates an event loop
|
||
instance if necessary and specified by the current policy.</p>
|
||
<p>For the benefit of unit tests and other special cases there’s a third
|
||
policy function: <code class="docutils literal notranslate"><span class="pre">new_event_loop()</span></code>, which creates and returns a new
|
||
event loop object according to the policy’s default rules. To make
|
||
this the current event loop, you must call <code class="docutils literal notranslate"><span class="pre">set_event_loop()</span></code> with
|
||
it.</p>
|
||
<p>To change the event loop policy, call
|
||
<code class="docutils literal notranslate"><span class="pre">set_event_loop_policy(policy)</span></code>, where <code class="docutils literal notranslate"><span class="pre">policy</span></code> is an event loop
|
||
policy object or <code class="docutils literal notranslate"><span class="pre">None</span></code>. If not <code class="docutils literal notranslate"><span class="pre">None</span></code>, the policy object must be
|
||
an instance of <code class="docutils literal notranslate"><span class="pre">AbstractEventLoopPolicy</span></code> that defines methods
|
||
<code class="docutils literal notranslate"><span class="pre">get_event_loop()</span></code>, <code class="docutils literal notranslate"><span class="pre">set_event_loop(loop)</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">new_event_loop()</span></code>, all behaving like the functions described above.</p>
|
||
<p>Passing a policy value of <code class="docutils literal notranslate"><span class="pre">None</span></code> restores the default event loop
|
||
policy (overriding the alternate default set by the platform or
|
||
framework). The default event loop policy is an instance of the class
|
||
<code class="docutils literal notranslate"><span class="pre">DefaultEventLoopPolicy</span></code>. The current event loop policy object can
|
||
be retrieved by calling <code class="docutils literal notranslate"><span class="pre">get_event_loop_policy()</span></code>.</p>
|
||
<p>TBD: describe child watchers and UNIX quirks for subprocess processing.</p>
|
||
<section id="passing-an-event-loop-around-explicitly">
|
||
<h4><a class="toc-backref" href="#passing-an-event-loop-around-explicitly" role="doc-backlink">Passing an Event Loop Around Explicitly</a></h4>
|
||
<p>It is possible to write code that uses an event loop without relying
|
||
on a global or per-thread default event loop. For this purpose, all
|
||
APIs that need access to the current event loop (and aren’t methods on
|
||
an event class) take an optional keyword argument named <code class="docutils literal notranslate"><span class="pre">loop</span></code>. If
|
||
this argument is <code class="docutils literal notranslate"><span class="pre">None</span></code> or unspecified, such APIs will call
|
||
<code class="docutils literal notranslate"><span class="pre">get_event_loop()</span></code> to get the default event loop, but if the
|
||
<code class="docutils literal notranslate"><span class="pre">loop</span></code> keyword argument is set to an event loop object, they will
|
||
use that event loop, and pass it along to any other such APIs they
|
||
call. For example, <code class="docutils literal notranslate"><span class="pre">Future(loop=my_loop)</span></code> will create a Future tied
|
||
to the event loop <code class="docutils literal notranslate"><span class="pre">my_loop</span></code>. When the default current event is
|
||
<code class="docutils literal notranslate"><span class="pre">None</span></code>, the <code class="docutils literal notranslate"><span class="pre">loop</span></code> keyword argument is effectively mandatory.</p>
|
||
<p>Note that an explicitly passed event loop must still belong to the
|
||
current thread; the <code class="docutils literal notranslate"><span class="pre">loop</span></code> keyword argument does not magically
|
||
change the constraints on how an event loop can be used.</p>
|
||
</section>
|
||
</section>
|
||
<section id="specifying-times">
|
||
<h3><a class="toc-backref" href="#specifying-times" role="doc-backlink">Specifying Times</a></h3>
|
||
<p>As usual in Python, all timeouts, intervals and delays are measured in
|
||
seconds, and may be ints or floats. However, absolute times are not
|
||
specified as POSIX timestamps. The accuracy, precision and epoch of
|
||
the clock are up to the implementation.</p>
|
||
<p>The default implementation uses <code class="docutils literal notranslate"><span class="pre">time.monotonic()</span></code>. Books could be
|
||
written about the implications of this choice. Better read the docs
|
||
for the standard library <code class="docutils literal notranslate"><span class="pre">time</span></code> module.</p>
|
||
</section>
|
||
<section id="embedded-event-loops">
|
||
<h3><a class="toc-backref" href="#embedded-event-loops" role="doc-backlink">Embedded Event Loops</a></h3>
|
||
<p>On some platforms an event loop is provided by the system. Such a
|
||
loop may already be running when the user code starts, and there may
|
||
be no way to stop or close it without exiting from the program. In
|
||
this case, the methods for starting, stopping and closing the event
|
||
loop may not be implementable, and <code class="docutils literal notranslate"><span class="pre">is_running()</span></code> may always return
|
||
<code class="docutils literal notranslate"><span class="pre">True</span></code>.</p>
|
||
</section>
|
||
<section id="event-loop-classes">
|
||
<h3><a class="toc-backref" href="#event-loop-classes" role="doc-backlink">Event Loop Classes</a></h3>
|
||
<p>There is no actual class named <code class="docutils literal notranslate"><span class="pre">EventLoop</span></code>. There is an
|
||
<code class="docutils literal notranslate"><span class="pre">AbstractEventLoop</span></code> class which defines all the methods without
|
||
implementations, and serves primarily as documentation. The following
|
||
concrete classes are defined:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">SelectorEventLoop</span></code> is a concrete implementation of the full API
|
||
based on the <code class="docutils literal notranslate"><span class="pre">selectors</span></code> module (new in Python 3.4). The
|
||
constructor takes one optional argument, a <code class="docutils literal notranslate"><span class="pre">selectors.Selector</span></code>
|
||
object. By default an instance of <code class="docutils literal notranslate"><span class="pre">selectors.DefaultSelector</span></code> is
|
||
created and used.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">ProactorEventLoop</span></code> is a concrete implementation of the API except
|
||
for the I/O event handling and signal handling methods. It is only
|
||
defined on Windows (or on other platforms which support a similar
|
||
API for “overlapped I/O”). The constructor takes one optional
|
||
argument, a <code class="docutils literal notranslate"><span class="pre">Proactor</span></code> object. By default an instance of
|
||
<code class="docutils literal notranslate"><span class="pre">IocpProactor</span></code> is created and used. (The <code class="docutils literal notranslate"><span class="pre">IocpProactor</span></code> class
|
||
is not specified by this PEP; it is just an implementation
|
||
detail of the <code class="docutils literal notranslate"><span class="pre">ProactorEventLoop</span></code> class.)</li>
|
||
</ul>
|
||
</section>
|
||
<section id="event-loop-methods-overview">
|
||
<h3><a class="toc-backref" href="#event-loop-methods-overview" role="doc-backlink">Event Loop Methods Overview</a></h3>
|
||
<p>The methods of a conforming event loop are grouped into several
|
||
categories. The first set of categories must be supported by all
|
||
conforming event loop implementations, with the exception that
|
||
embedded event loops may not implement the methods for starting,
|
||
stopping and closing. (However, a partially-conforming event loop is
|
||
still better than nothing. :-)</p>
|
||
<ul class="simple">
|
||
<li>Starting, stopping and closing: <code class="docutils literal notranslate"><span class="pre">run_forever()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">run_until_complete()</span></code>, <code class="docutils literal notranslate"><span class="pre">stop()</span></code>, <code class="docutils literal notranslate"><span class="pre">is_running()</span></code>, <code class="docutils literal notranslate"><span class="pre">close()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">is_closed()</span></code>.</li>
|
||
<li>Basic and timed callbacks: <code class="docutils literal notranslate"><span class="pre">call_soon()</span></code>, <code class="docutils literal notranslate"><span class="pre">call_later()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">call_at()</span></code>, <code class="docutils literal notranslate"><span class="pre">time()</span></code>.</li>
|
||
<li>Thread interaction: <code class="docutils literal notranslate"><span class="pre">call_soon_threadsafe()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">run_in_executor()</span></code>, <code class="docutils literal notranslate"><span class="pre">set_default_executor()</span></code>.</li>
|
||
<li>Internet name lookups: <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code>, <code class="docutils literal notranslate"><span class="pre">getnameinfo()</span></code>.</li>
|
||
<li>Internet connections: <code class="docutils literal notranslate"><span class="pre">create_connection()</span></code>, <code class="docutils literal notranslate"><span class="pre">create_server()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">create_datagram_endpoint()</span></code>.</li>
|
||
<li>Wrapped socket methods: <code class="docutils literal notranslate"><span class="pre">sock_recv()</span></code>, <code class="docutils literal notranslate"><span class="pre">sock_sendall()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">sock_connect()</span></code>, <code class="docutils literal notranslate"><span class="pre">sock_accept()</span></code>.</li>
|
||
<li>Tasks and futures support: <code class="docutils literal notranslate"><span class="pre">create_future()</span></code>, <code class="docutils literal notranslate"><span class="pre">create_task()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">set_task_factory()</span></code>, <code class="docutils literal notranslate"><span class="pre">get_task_factory()</span></code>.</li>
|
||
<li>Error handling: <code class="docutils literal notranslate"><span class="pre">get_exception_handler()</span></code>, <code class="docutils literal notranslate"><span class="pre">set_exception_handler()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">default_exception_handler()</span></code>, <code class="docutils literal notranslate"><span class="pre">call_exception_handler()</span></code>.</li>
|
||
<li>Debug mode: <code class="docutils literal notranslate"><span class="pre">get_debug()</span></code>, <code class="docutils literal notranslate"><span class="pre">set_debug()</span></code>.</li>
|
||
</ul>
|
||
<p>The second set of categories <em>may</em> be supported by conforming event
|
||
loop implementations. If not supported, they will raise
|
||
<code class="docutils literal notranslate"><span class="pre">NotImplementedError</span></code>. (In the default implementation,
|
||
<code class="docutils literal notranslate"><span class="pre">SelectorEventLoop</span></code> on UNIX systems supports all of these;
|
||
<code class="docutils literal notranslate"><span class="pre">SelectorEventLoop</span></code> on Windows supports the I/O event handling
|
||
category; <code class="docutils literal notranslate"><span class="pre">ProactorEventLoop</span></code> on Windows supports the pipes and
|
||
subprocess category.)</p>
|
||
<ul class="simple">
|
||
<li>I/O callbacks: <code class="docutils literal notranslate"><span class="pre">add_reader()</span></code>, <code class="docutils literal notranslate"><span class="pre">remove_reader()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">add_writer()</span></code>, <code class="docutils literal notranslate"><span class="pre">remove_writer()</span></code>.</li>
|
||
<li>Pipes and subprocesses: <code class="docutils literal notranslate"><span class="pre">connect_read_pipe()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">connect_write_pipe()</span></code>, <code class="docutils literal notranslate"><span class="pre">subprocess_shell()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">subprocess_exec()</span></code>.</li>
|
||
<li>Signal callbacks: <code class="docutils literal notranslate"><span class="pre">add_signal_handler()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">remove_signal_handler()</span></code>.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="event-loop-methods">
|
||
<h3><a class="toc-backref" href="#event-loop-methods" role="doc-backlink">Event Loop Methods</a></h3>
|
||
<section id="starting-stopping-and-closing">
|
||
<h4><a class="toc-backref" href="#starting-stopping-and-closing" role="doc-backlink">Starting, Stopping and Closing</a></h4>
|
||
<p>An (unclosed) event loop can be in one of two states: running or
|
||
stopped. These methods deal with starting and stopping an event loop:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">run_forever()</span></code>. Runs the event loop until <code class="docutils literal notranslate"><span class="pre">stop()</span></code> is called.
|
||
This cannot be called when the event loop is already running. (This
|
||
has a long name in part to avoid confusion with earlier versions of
|
||
this PEP, where <code class="docutils literal notranslate"><span class="pre">run()</span></code> had different behavior, in part because
|
||
there are already too many APIs that have a method named <code class="docutils literal notranslate"><span class="pre">run()</span></code>,
|
||
and in part because there shouldn’t be many places where this is
|
||
called anyway.)</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">run_until_complete(future)</span></code>. Runs the event loop until the
|
||
Future is done. If the Future is done, its result is returned, or
|
||
its exception is raised. This cannot be called when the event loop
|
||
is already running.
|
||
The method creates a new <code class="docutils literal notranslate"><span class="pre">Task</span></code> object if the
|
||
parameter is a coroutine.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">stop()</span></code>. Stops the event loop as soon as it is convenient. It
|
||
is fine to restart the loop with <code class="docutils literal notranslate"><span class="pre">run_forever()</span></code> or
|
||
<code class="docutils literal notranslate"><span class="pre">run_until_complete()</span></code> subsequently; no scheduled callbacks will
|
||
be lost if this is done. Note: <code class="docutils literal notranslate"><span class="pre">stop()</span></code> returns normally and the
|
||
current callback is allowed to continue. How soon after this point
|
||
the event loop stops is up to the implementation, but the intention
|
||
is to stop short of polling for I/O, and not to run any callbacks
|
||
scheduled in the future; the major freedom an implementation has is
|
||
how much of the “ready queue” (callbacks already scheduled with
|
||
<code class="docutils literal notranslate"><span class="pre">call_soon()</span></code>) it processes before stopping.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">is_running()</span></code>. Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the event loop is currently
|
||
running, <code class="docutils literal notranslate"><span class="pre">False</span></code> if it is stopped.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">close()</span></code>. Closes the event loop, releasing any resources it may
|
||
hold, such as the file descriptor used by <code class="docutils literal notranslate"><span class="pre">epoll()</span></code> or
|
||
<code class="docutils literal notranslate"><span class="pre">kqueue()</span></code>, and the default executor. This should not be called
|
||
while the event loop is running. After it has been called the event
|
||
loop should not be used again. It may be called multiple times;
|
||
subsequent calls are no-ops.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">is_closed()</span></code>. Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the event loop is closed,
|
||
<code class="docutils literal notranslate"><span class="pre">False</span></code> otherwise. (Primarily intended for error reporting;
|
||
please don’t implement functionality based on this method.)</li>
|
||
</ul>
|
||
</section>
|
||
<section id="basic-callbacks">
|
||
<h4><a class="toc-backref" href="#basic-callbacks" role="doc-backlink">Basic Callbacks</a></h4>
|
||
<p>Callbacks associated with the same event loop are strictly serialized:
|
||
one callback must finish before the next one will be called. This is
|
||
an important guarantee: when two or more callbacks use or modify
|
||
shared state, each callback is guaranteed that while it is running, the
|
||
shared state isn’t changed by another callback.</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">call_soon(callback,</span> <span class="pre">*args)</span></code>. This schedules a callback to be
|
||
called as soon as possible. Returns a <code class="docutils literal notranslate"><span class="pre">Handle</span></code> (see below)
|
||
representing the callback, whose <code class="docutils literal notranslate"><span class="pre">cancel()</span></code> method can be used to
|
||
cancel the callback. It guarantees that callbacks are called in the
|
||
order in which they were scheduled.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">call_later(delay,</span> <span class="pre">callback,</span> <span class="pre">*args)</span></code>. Arrange for
|
||
<code class="docutils literal notranslate"><span class="pre">callback(*args)</span></code> to be called approximately <code class="docutils literal notranslate"><span class="pre">delay</span></code> seconds in
|
||
the future, once, unless cancelled. Returns a <code class="docutils literal notranslate"><span class="pre">Handle</span></code> representing
|
||
the callback, whose <code class="docutils literal notranslate"><span class="pre">cancel()</span></code> method can be used to cancel the
|
||
callback. Callbacks scheduled in the past or at exactly the same
|
||
time will be called in an undefined order.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">call_at(when,</span> <span class="pre">callback,</span> <span class="pre">*args)</span></code>. This is like <code class="docutils literal notranslate"><span class="pre">call_later()</span></code>,
|
||
but the time is expressed as an absolute time. Returns a similar
|
||
<code class="docutils literal notranslate"><span class="pre">Handle</span></code>. There is a simple equivalency: <code class="docutils literal notranslate"><span class="pre">loop.call_later(delay,</span>
|
||
<span class="pre">callback,</span> <span class="pre">*args)</span></code> is the same as <code class="docutils literal notranslate"><span class="pre">loop.call_at(loop.time()</span> <span class="pre">+</span>
|
||
<span class="pre">delay,</span> <span class="pre">callback,</span> <span class="pre">*args)</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">time()</span></code>. Returns the current time according to the event loop’s
|
||
clock. This may be <code class="docutils literal notranslate"><span class="pre">time.time()</span></code> or <code class="docutils literal notranslate"><span class="pre">time.monotonic()</span></code> or some
|
||
other system-specific clock, but it must return a float expressing
|
||
the time in units of approximately one second since some epoch.
|
||
(No clock is perfect – see <a class="pep reference internal" href="../pep-0418/" title="PEP 418 – Add monotonic time, performance counter, and process time functions">PEP 418</a>.)</li>
|
||
</ul>
|
||
<p>Note: A previous version of this PEP defined a method named
|
||
<code class="docutils literal notranslate"><span class="pre">call_repeatedly()</span></code>, which promised to call a callback at regular
|
||
intervals. This has been withdrawn because the design of such a
|
||
function is overspecified. On the one hand, a simple timer loop can
|
||
easily be emulated using a callback that reschedules itself using
|
||
<code class="docutils literal notranslate"><span class="pre">call_later()</span></code>; it is also easy to write coroutine containing a loop
|
||
and a <code class="docutils literal notranslate"><span class="pre">sleep()</span></code> call (a toplevel function in the module, see below).
|
||
On the other hand, due to the complexities of accurate timekeeping
|
||
there are many traps and pitfalls here for the unaware (see <a class="pep reference internal" href="../pep-0418/" title="PEP 418 – Add monotonic time, performance counter, and process time functions">PEP 418</a>),
|
||
and different use cases require different behavior in edge cases. It
|
||
is impossible to offer an API for this purpose that is bullet-proof in
|
||
all cases, so it is deemed better to let application designers decide
|
||
for themselves what kind of timer loop to implement.</p>
|
||
</section>
|
||
<section id="thread-interaction">
|
||
<h4><a class="toc-backref" href="#thread-interaction" role="doc-backlink">Thread interaction</a></h4>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">call_soon_threadsafe(callback,</span> <span class="pre">*args)</span></code>. Like
|
||
<code class="docutils literal notranslate"><span class="pre">call_soon(callback,</span> <span class="pre">*args)</span></code>, but when called from another thread
|
||
while the event loop is blocked waiting for I/O, unblocks the event
|
||
loop. Returns a <code class="docutils literal notranslate"><span class="pre">Handle</span></code>. This is the <em>only</em> method that is safe
|
||
to call from another thread. (To schedule a callback for a later
|
||
time in a threadsafe manner, you can use
|
||
<code class="docutils literal notranslate"><span class="pre">loop.call_soon_threadsafe(loop.call_later,</span> <span class="pre">when,</span> <span class="pre">callback,</span>
|
||
<span class="pre">*args)</span></code>.) Note: this is not safe to call from a signal handler
|
||
(since it may use locks). In fact, no API is signal-safe; if you
|
||
want to handle signals, use <code class="docutils literal notranslate"><span class="pre">add_signal_handler()</span></code> described
|
||
below.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">run_in_executor(executor,</span> <span class="pre">callback,</span> <span class="pre">*args)</span></code>. Arrange to call
|
||
<code class="docutils literal notranslate"><span class="pre">callback(*args)</span></code> in an executor (see <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>). Returns an
|
||
<code class="docutils literal notranslate"><span class="pre">asyncio.Future</span></code> instance whose result on success is the return
|
||
value of that call. This is equivalent to
|
||
<code class="docutils literal notranslate"><span class="pre">wrap_future(executor.submit(callback,</span> <span class="pre">*args))</span></code>. If <code class="docutils literal notranslate"><span class="pre">executor</span></code>
|
||
is <code class="docutils literal notranslate"><span class="pre">None</span></code>, the default executor set by <code class="docutils literal notranslate"><span class="pre">set_default_executor()</span></code>
|
||
is used. If no default executor has been set yet, a
|
||
<code class="docutils literal notranslate"><span class="pre">ThreadPoolExecutor</span></code> with a default number of threads is created
|
||
and set as the default executor. (The default implementation uses
|
||
5 threads in this case.)</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">set_default_executor(executor)</span></code>. Set the default executor used
|
||
by <code class="docutils literal notranslate"><span class="pre">run_in_executor()</span></code>. The argument must be a <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>
|
||
<code class="docutils literal notranslate"><span class="pre">Executor</span></code> instance or <code class="docutils literal notranslate"><span class="pre">None</span></code>, in order to reset the default
|
||
executor.</li>
|
||
</ul>
|
||
<p>See also the <code class="docutils literal notranslate"><span class="pre">wrap_future()</span></code> function described in the section about
|
||
Futures.</p>
|
||
</section>
|
||
<section id="internet-name-lookups">
|
||
<h4><a class="toc-backref" href="#internet-name-lookups" role="doc-backlink">Internet name lookups</a></h4>
|
||
<p>These methods are useful if you want to connect or bind a socket to an
|
||
address without the risk of blocking for the name lookup. They are
|
||
usually called implicitly by <code class="docutils literal notranslate"><span class="pre">create_connection()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">create_server()</span></code> or <code class="docutils literal notranslate"><span class="pre">create_datagram_endpoint()</span></code>.</p>
|
||
<ul>
|
||
<li><code class="docutils literal notranslate"><span class="pre">getaddrinfo(host,</span> <span class="pre">port,</span> <span class="pre">family=0,</span> <span class="pre">type=0,</span> <span class="pre">proto=0,</span> <span class="pre">flags=0)</span></code>.
|
||
Similar to the <code class="docutils literal notranslate"><span class="pre">socket.getaddrinfo()</span></code> function but returns a
|
||
Future. The Future’s result on success will be a list of the same
|
||
format as returned by <code class="docutils literal notranslate"><span class="pre">socket.getaddrinfo()</span></code>, i.e. a list of
|
||
<code class="docutils literal notranslate"><span class="pre">(address_family,</span> <span class="pre">socket_type,</span> <span class="pre">socket_protocol,</span> <span class="pre">canonical_name,</span>
|
||
<span class="pre">address)</span></code> where <code class="docutils literal notranslate"><span class="pre">address</span></code> is a 2-tuple <code class="docutils literal notranslate"><span class="pre">(ipv4_address,</span> <span class="pre">port)</span></code>
|
||
for IPv4 addresses and a 4-tuple <code class="docutils literal notranslate"><span class="pre">(ipv6_address,</span> <span class="pre">port,</span> <span class="pre">flow_info,</span>
|
||
<span class="pre">scope_id)</span></code> for IPv6 addresses. If the <code class="docutils literal notranslate"><span class="pre">family</span></code> argument is zero
|
||
or unspecified, the list returned may contain a mixture of IPv4 and
|
||
IPv6 addresses; otherwise the addresses returned are constrained by
|
||
the <code class="docutils literal notranslate"><span class="pre">family</span></code> value (similar for <code class="docutils literal notranslate"><span class="pre">proto</span></code> and <code class="docutils literal notranslate"><span class="pre">flags</span></code>). The
|
||
default implementation calls <code class="docutils literal notranslate"><span class="pre">socket.getaddrinfo()</span></code> using
|
||
<code class="docutils literal notranslate"><span class="pre">run_in_executor()</span></code>, but other implementations may choose to
|
||
implement their own DNS lookup. The optional arguments <em>must</em> be
|
||
specified as keyword arguments.<p>Note: implementations are allowed to implement a subset of the full
|
||
socket.getaddrinfo() interface; e.g. they may not support symbolic
|
||
port names, or they may ignore or incompletely implement the
|
||
<code class="docutils literal notranslate"><span class="pre">type</span></code>, <code class="docutils literal notranslate"><span class="pre">proto</span></code> and <code class="docutils literal notranslate"><span class="pre">flags</span></code> arguments. However, if <code class="docutils literal notranslate"><span class="pre">type</span></code>
|
||
and <code class="docutils literal notranslate"><span class="pre">proto</span></code> are ignored, the argument values passed in should be
|
||
copied unchanged into the return tuples’ <code class="docutils literal notranslate"><span class="pre">socket_type</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">socket_protocol</span></code> elements. (You can’t ignore <code class="docutils literal notranslate"><span class="pre">family</span></code>, since
|
||
IPv4 and IPv6 addresses must be looked up differently. The only
|
||
permissible values for <code class="docutils literal notranslate"><span class="pre">family</span></code> are <code class="docutils literal notranslate"><span class="pre">socket.AF_UNSPEC</span></code> (<code class="docutils literal notranslate"><span class="pre">0</span></code>),
|
||
<code class="docutils literal notranslate"><span class="pre">socket.AF_INET</span></code> and <code class="docutils literal notranslate"><span class="pre">socket.AF_INET6</span></code>, and the latter only if
|
||
it is defined by the platform.)</p>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">getnameinfo(sockaddr,</span> <span class="pre">flags=0)</span></code>. Similar to
|
||
<code class="docutils literal notranslate"><span class="pre">socket.getnameinfo()</span></code> but returns a Future. The Future’s result
|
||
on success will be a tuple <code class="docutils literal notranslate"><span class="pre">(host,</span> <span class="pre">port)</span></code>. Same implementation
|
||
remarks as for <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code>.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="internet-connections">
|
||
<h4><a class="toc-backref" href="#internet-connections" role="doc-backlink">Internet connections</a></h4>
|
||
<p>These are the high-level interfaces for managing internet connections.
|
||
Their use is recommended over the corresponding lower-level interfaces
|
||
because they abstract away the differences between selector-based
|
||
and proactor-based event loops.</p>
|
||
<p>Note that the client and server side of stream connections use the
|
||
same transport and protocol interface. However, datagram endpoints
|
||
use a different transport and protocol interface.</p>
|
||
<ul>
|
||
<li><code class="docutils literal notranslate"><span class="pre">create_connection(protocol_factory,</span> <span class="pre">host,</span> <span class="pre">port,</span> <span class="pre"><options>)</span></code>.
|
||
Creates a stream connection to a given internet host and port. This
|
||
is a task that is typically called from the client side of the
|
||
connection. It creates an implementation-dependent bidirectional
|
||
stream Transport to represent the connection, then calls
|
||
<code class="docutils literal notranslate"><span class="pre">protocol_factory()</span></code> to instantiate (or retrieve) the user’s
|
||
Protocol implementation, and finally ties the two together. (See
|
||
below for the definitions of Transport and Protocol.) The user’s
|
||
Protocol implementation is created or retrieved by calling
|
||
<code class="docutils literal notranslate"><span class="pre">protocol_factory()</span></code> without arguments(*). The coroutine’s result
|
||
on success is the <code class="docutils literal notranslate"><span class="pre">(transport,</span> <span class="pre">protocol)</span></code> pair; if a failure
|
||
prevents the creation of a successful connection, an appropriate
|
||
exception will be raised. Note that when the coroutine completes,
|
||
the protocol’s <code class="docutils literal notranslate"><span class="pre">connection_made()</span></code> method has not yet been called;
|
||
that will happen when the connection handshake is complete.<p>(*) There is no requirement that <code class="docutils literal notranslate"><span class="pre">protocol_factory</span></code> is a class.
|
||
If your protocol class needs to have specific arguments passed to
|
||
its constructor, you can use <code class="docutils literal notranslate"><span class="pre">lambda</span></code>.
|
||
You can also pass a trivial <code class="docutils literal notranslate"><span class="pre">lambda</span></code> that returns a previously
|
||
constructed Protocol instance.</p>
|
||
<p>The <options> are all specified using optional keyword arguments:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">ssl</span></code>: Pass <code class="docutils literal notranslate"><span class="pre">True</span></code> to create an SSL/TLS transport (by default
|
||
a plain TCP transport is created). Or pass an <code class="docutils literal notranslate"><span class="pre">ssl.SSLContext</span></code>
|
||
object to override the default SSL context object to be used. If
|
||
a default context is created it is up to the implementation to
|
||
configure reasonable defaults. The reference implementation
|
||
currently uses <code class="docutils literal notranslate"><span class="pre">PROTOCOL_SSLv23</span></code> and sets the <code class="docutils literal notranslate"><span class="pre">OP_NO_SSLv2</span></code>
|
||
option, calls <code class="docutils literal notranslate"><span class="pre">set_default_verify_paths()</span></code> and sets <code class="docutils literal notranslate"><span class="pre">verify_mode</span></code>
|
||
to <code class="docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code>. In addition, whenever the context (default
|
||
or otherwise) specifies a <code class="docutils literal notranslate"><span class="pre">verify_mode</span></code> of <code class="docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code> or
|
||
<code class="docutils literal notranslate"><span class="pre">CERT_OPTIONAL</span></code>, if a hostname is given, immediately after a
|
||
successful handshake <code class="docutils literal notranslate"><span class="pre">ssl.match_hostname(peercert,</span> <span class="pre">hostname)</span></code> is
|
||
called, and if this raises an exception the connection is closed.
|
||
(To avoid this behavior, pass in an SSL context that has
|
||
<code class="docutils literal notranslate"><span class="pre">verify_mode</span></code> set to <code class="docutils literal notranslate"><span class="pre">CERT_NONE</span></code>. But this means you are not
|
||
secure, and vulnerable to for example man-in-the-middle attacks.)</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">family</span></code>, <code class="docutils literal notranslate"><span class="pre">proto</span></code>, <code class="docutils literal notranslate"><span class="pre">flags</span></code>: Address family, protocol and
|
||
flags to be passed through to <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code>. These all
|
||
default to <code class="docutils literal notranslate"><span class="pre">0</span></code>, which means “not specified”. (The socket type
|
||
is always <code class="docutils literal notranslate"><span class="pre">SOCK_STREAM</span></code>.) If any of these values are not
|
||
specified, the <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> method will choose appropriate
|
||
values. Note: <code class="docutils literal notranslate"><span class="pre">proto</span></code> has nothing to do with the high-level
|
||
Protocol concept or the <code class="docutils literal notranslate"><span class="pre">protocol_factory</span></code> argument.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">sock</span></code>: An optional socket to be used instead of using the
|
||
<code class="docutils literal notranslate"><span class="pre">host</span></code>, <code class="docutils literal notranslate"><span class="pre">port</span></code>, <code class="docutils literal notranslate"><span class="pre">family</span></code>, <code class="docutils literal notranslate"><span class="pre">proto</span></code> and <code class="docutils literal notranslate"><span class="pre">flags</span></code>
|
||
arguments. If this is given, <code class="docutils literal notranslate"><span class="pre">host</span></code> and <code class="docutils literal notranslate"><span class="pre">port</span></code> must be
|
||
explicitly set to <code class="docutils literal notranslate"><span class="pre">None</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">local_addr</span></code>: If given, a <code class="docutils literal notranslate"><span class="pre">(host,</span> <span class="pre">port)</span></code> tuple used to bind
|
||
the socket to locally. This is rarely needed but on multi-homed
|
||
servers you occasionally need to force a connection to come from a
|
||
specific address. This is how you would do that. The host and
|
||
port are looked up using <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">server_hostname</span></code>: This is only relevant when using SSL/TLS; it
|
||
should not be used when <code class="docutils literal notranslate"><span class="pre">ssl</span></code> is not set. When <code class="docutils literal notranslate"><span class="pre">ssl</span></code> is set,
|
||
this sets or overrides the hostname that will be verified. By
|
||
default the value of the <code class="docutils literal notranslate"><span class="pre">host</span></code> argument is used. If <code class="docutils literal notranslate"><span class="pre">host</span></code>
|
||
is empty, there is no default and you must pass a value for
|
||
<code class="docutils literal notranslate"><span class="pre">server_hostname</span></code>. To disable hostname verification (which is a
|
||
serious security risk) you must pass an empty string here and pass
|
||
an <code class="docutils literal notranslate"><span class="pre">ssl.SSLContext</span></code> object whose <code class="docutils literal notranslate"><span class="pre">verify_mode</span></code> is set to
|
||
<code class="docutils literal notranslate"><span class="pre">ssl.CERT_NONE</span></code> as the <code class="docutils literal notranslate"><span class="pre">ssl</span></code> argument.</li>
|
||
</ul>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">create_server(protocol_factory,</span> <span class="pre">host,</span> <span class="pre">port,</span> <span class="pre"><options>)</span></code>.
|
||
Enters a serving loop that accepts connections.
|
||
This is a coroutine that completes once the serving loop is set up
|
||
to serve. The return value is a <code class="docutils literal notranslate"><span class="pre">Server</span></code> object which can be used
|
||
to stop the serving loop in a controlled fashion (see below).
|
||
Multiple sockets may be bound if the specified address allows
|
||
both IPv4 and IPv6 connections.<p>Each time a connection is accepted,
|
||
<code class="docutils literal notranslate"><span class="pre">protocol_factory</span></code> is called without arguments(**) to create a
|
||
Protocol, a bidirectional stream Transport is created to represent
|
||
the network side of the connection, and the two are tied together by
|
||
calling <code class="docutils literal notranslate"><span class="pre">protocol.connection_made(transport)</span></code>.</p>
|
||
<p>(**) See previous footnote for <code class="docutils literal notranslate"><span class="pre">create_connection()</span></code>. However, since
|
||
<code class="docutils literal notranslate"><span class="pre">protocol_factory()</span></code> is called once for each new incoming
|
||
connection, it should return a new Protocol object each time it is
|
||
called.</p>
|
||
<p>The <options> are all specified using optional keyword arguments:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">ssl</span></code>: Pass an <code class="docutils literal notranslate"><span class="pre">ssl.SSLContext</span></code> object (or an object with the
|
||
same interface) to override the default SSL context object to be
|
||
used. (Unlike for <code class="docutils literal notranslate"><span class="pre">create_connection()</span></code>, passing <code class="docutils literal notranslate"><span class="pre">True</span></code> does
|
||
not make sense here – the <code class="docutils literal notranslate"><span class="pre">SSLContext</span></code> object is needed to
|
||
specify the certificate and key.)</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">backlog</span></code>: Backlog value to be passed to the <code class="docutils literal notranslate"><span class="pre">listen()</span></code> call.
|
||
The default is implementation-dependent; in the default
|
||
implementation the default value is <code class="docutils literal notranslate"><span class="pre">100</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">reuse_address</span></code>: Whether to set the <code class="docutils literal notranslate"><span class="pre">SO_REUSEADDR</span></code> option on
|
||
the socket. The default is <code class="docutils literal notranslate"><span class="pre">True</span></code> on UNIX, <code class="docutils literal notranslate"><span class="pre">False</span></code> on
|
||
Windows.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">family</span></code>, <code class="docutils literal notranslate"><span class="pre">flags</span></code>: Address family and flags to be passed
|
||
through to <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code>. The family defaults to
|
||
<code class="docutils literal notranslate"><span class="pre">AF_UNSPEC</span></code>; the flags default to <code class="docutils literal notranslate"><span class="pre">AI_PASSIVE</span></code>. (The socket
|
||
type is always <code class="docutils literal notranslate"><span class="pre">SOCK_STREAM</span></code>; the socket protocol always set to
|
||
<code class="docutils literal notranslate"><span class="pre">0</span></code>, to let <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> choose.)</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">sock</span></code>: An optional socket to be used instead of using the
|
||
<code class="docutils literal notranslate"><span class="pre">host</span></code>, <code class="docutils literal notranslate"><span class="pre">port</span></code>, <code class="docutils literal notranslate"><span class="pre">family</span></code> and <code class="docutils literal notranslate"><span class="pre">flags</span></code> arguments. If this
|
||
is given, <code class="docutils literal notranslate"><span class="pre">host</span></code> and <code class="docutils literal notranslate"><span class="pre">port</span></code> must be explicitly set to <code class="docutils literal notranslate"><span class="pre">None</span></code>.</li>
|
||
</ul>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">create_datagram_endpoint(protocol_factory,</span> <span class="pre">local_addr=None,</span>
|
||
<span class="pre">remote_addr=None,</span> <span class="pre"><options>)</span></code>. Creates an endpoint for sending and
|
||
receiving datagrams (typically UDP packets). Because of the nature
|
||
of datagram traffic, there are no separate calls to set up client
|
||
and server side, since usually a single endpoint acts as both client
|
||
and server. This is a coroutine that returns a <code class="docutils literal notranslate"><span class="pre">(transport,</span>
|
||
<span class="pre">protocol)</span></code> pair on success, or raises an exception on failure. If
|
||
the coroutine returns successfully, the transport will call
|
||
callbacks on the protocol whenever a datagram is received or the
|
||
socket is closed; it is up to the protocol to call methods on the
|
||
protocol to send datagrams. The transport returned is a
|
||
<code class="docutils literal notranslate"><span class="pre">DatagramTransport</span></code>. The protocol returned is a
|
||
<code class="docutils literal notranslate"><span class="pre">DatagramProtocol</span></code>. These are described later.<p>Mandatory positional argument:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">protocol_factory</span></code>: A class or factory function that will be
|
||
called exactly once, without arguments, to construct the protocol
|
||
object to be returned. The interface between datagram transport
|
||
and protocol is described below.</li>
|
||
</ul>
|
||
<p>Optional arguments that may be specified positionally or as keyword
|
||
arguments:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">local_addr</span></code>: An optional tuple indicating the address to which
|
||
the socket will be bound. If given this must be a <code class="docutils literal notranslate"><span class="pre">(host,</span>
|
||
<span class="pre">port)</span></code> pair. It will be passed to <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> to be
|
||
resolved and the result will be passed to the <code class="docutils literal notranslate"><span class="pre">bind()</span></code> method of
|
||
the socket created. If <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> returns more than one
|
||
address, they will be tried in turn. If omitted, no <code class="docutils literal notranslate"><span class="pre">bind()</span></code>
|
||
call will be made.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">remote_addr</span></code>: An optional tuple indicating the address to which
|
||
the socket will be “connected”. (Since there is no such thing as
|
||
a datagram connection, this just specifies a default value for the
|
||
destination address of outgoing datagrams.) If given this must be
|
||
a <code class="docutils literal notranslate"><span class="pre">(host,</span> <span class="pre">port)</span></code> pair. It will be passed to <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code>
|
||
to be resolved and the result will be passed to <code class="docutils literal notranslate"><span class="pre">sock_connect()</span></code>
|
||
together with the socket created. If <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> returns
|
||
more than one address, they will be tried in turn. If omitted,
|
||
no <code class="docutils literal notranslate"><span class="pre">sock_connect()</span></code> call will be made.</li>
|
||
</ul>
|
||
<p>The <options> are all specified using optional keyword arguments:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">family</span></code>, <code class="docutils literal notranslate"><span class="pre">proto</span></code>, <code class="docutils literal notranslate"><span class="pre">flags</span></code>: Address family, protocol and
|
||
flags to be passed through to <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code>. These all
|
||
default to <code class="docutils literal notranslate"><span class="pre">0</span></code>, which means “not specified”. (The socket type
|
||
is always <code class="docutils literal notranslate"><span class="pre">SOCK_DGRAM</span></code>.) If any of these values are not
|
||
specified, the <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> method will choose appropriate
|
||
values.</li>
|
||
</ul>
|
||
<p>Note that if both <code class="docutils literal notranslate"><span class="pre">local_addr</span></code> and <code class="docutils literal notranslate"><span class="pre">remote_addr</span></code> are present,
|
||
all combinations of local and remote addresses with matching address
|
||
family will be tried.</p>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
<section id="wrapped-socket-methods">
|
||
<h4><a class="toc-backref" href="#wrapped-socket-methods" role="doc-backlink">Wrapped Socket Methods</a></h4>
|
||
<p>The following methods for doing async I/O on sockets are not for
|
||
general use. They are primarily meant for transport implementations
|
||
working with IOCP through the <code class="docutils literal notranslate"><span class="pre">ProactorEventLoop</span></code> class. However,
|
||
they are easily implementable for other event loop types, so there is
|
||
no reason not to require them. The socket argument has to be a
|
||
non-blocking socket.</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">sock_recv(sock,</span> <span class="pre">n)</span></code>. Receive up to <code class="docutils literal notranslate"><span class="pre">n</span></code> bytes from socket
|
||
<code class="docutils literal notranslate"><span class="pre">sock</span></code>. Returns a Future whose result on success will be a
|
||
bytes object.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">sock_sendall(sock,</span> <span class="pre">data)</span></code>. Send bytes <code class="docutils literal notranslate"><span class="pre">data</span></code> to socket
|
||
<code class="docutils literal notranslate"><span class="pre">sock</span></code>. Returns a Future whose result on success will be
|
||
<code class="docutils literal notranslate"><span class="pre">None</span></code>. Note: the name uses <code class="docutils literal notranslate"><span class="pre">sendall</span></code> instead of <code class="docutils literal notranslate"><span class="pre">send</span></code>, to
|
||
reflect that the semantics and signature of this method echo those
|
||
of the standard library socket method <code class="docutils literal notranslate"><span class="pre">sendall()</span></code> rather than
|
||
<code class="docutils literal notranslate"><span class="pre">send()</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">sock_connect(sock,</span> <span class="pre">address)</span></code>. Connect to the given address.
|
||
Returns a Future whose result on success will be <code class="docutils literal notranslate"><span class="pre">None</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">sock_accept(sock)</span></code>. Accept a connection from a socket. The
|
||
socket must be in listening mode and bound to an address. Returns a
|
||
Future whose result on success will be a tuple <code class="docutils literal notranslate"><span class="pre">(conn,</span> <span class="pre">peer)</span></code>
|
||
where <code class="docutils literal notranslate"><span class="pre">conn</span></code> is a connected non-blocking socket and <code class="docutils literal notranslate"><span class="pre">peer</span></code> is
|
||
the peer address.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="i-o-callbacks">
|
||
<h4><a class="toc-backref" href="#i-o-callbacks" role="doc-backlink">I/O Callbacks</a></h4>
|
||
<p>These methods are primarily meant for transport implementations
|
||
working with a selector. They are implemented by
|
||
<code class="docutils literal notranslate"><span class="pre">SelectorEventLoop</span></code> but not by <code class="docutils literal notranslate"><span class="pre">ProactorEventLoop</span></code>. Custom event
|
||
loop implementations may or may not implement them.</p>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">fd</span></code> arguments below may be integer file descriptors, or
|
||
“file-like” objects with a <code class="docutils literal notranslate"><span class="pre">fileno()</span></code> method that wrap integer file
|
||
descriptors. Not all file-like objects or file descriptors are
|
||
acceptable. Sockets (and socket file descriptors) are always
|
||
accepted. On Windows no other types are supported. On UNIX, pipes
|
||
and possibly tty devices are also supported, but disk files are not.
|
||
Exactly which special file types are supported may vary by platform
|
||
and per selector implementation. (Experimentally, there is at least
|
||
one kind of pseudo-tty on OS X that is supported by <code class="docutils literal notranslate"><span class="pre">select</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">poll</span></code> but not by <code class="docutils literal notranslate"><span class="pre">kqueue</span></code>: it is used by Emacs shell windows.)</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">add_reader(fd,</span> <span class="pre">callback,</span> <span class="pre">*args)</span></code>. Arrange for
|
||
<code class="docutils literal notranslate"><span class="pre">callback(*args)</span></code> to be called whenever file descriptor <code class="docutils literal notranslate"><span class="pre">fd</span></code> is
|
||
deemed ready for reading. Calling <code class="docutils literal notranslate"><span class="pre">add_reader()</span></code> again for the
|
||
same file descriptor implies a call to <code class="docutils literal notranslate"><span class="pre">remove_reader()</span></code> for the
|
||
same file descriptor.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">add_writer(fd,</span> <span class="pre">callback,</span> <span class="pre">*args)</span></code>. Like <code class="docutils literal notranslate"><span class="pre">add_reader()</span></code>,
|
||
but registers the callback for writing instead of for reading.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">remove_reader(fd)</span></code>. Cancels the current read callback for file
|
||
descriptor <code class="docutils literal notranslate"><span class="pre">fd</span></code>, if one is set. If no callback is currently set
|
||
for the file descriptor, this is a no-op and returns <code class="docutils literal notranslate"><span class="pre">False</span></code>.
|
||
Otherwise, it removes the callback arrangement and returns <code class="docutils literal notranslate"><span class="pre">True</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">remove_writer(fd)</span></code>. This is to <code class="docutils literal notranslate"><span class="pre">add_writer()</span></code> as
|
||
<code class="docutils literal notranslate"><span class="pre">remove_reader()</span></code> is to <code class="docutils literal notranslate"><span class="pre">add_reader()</span></code>.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="pipes-and-subprocesses">
|
||
<h4><a class="toc-backref" href="#pipes-and-subprocesses" role="doc-backlink">Pipes and Subprocesses</a></h4>
|
||
<p>These methods are supported by <code class="docutils literal notranslate"><span class="pre">SelectorEventLoop</span></code> on UNIX and
|
||
<code class="docutils literal notranslate"><span class="pre">ProactorEventLoop</span></code> on Windows.</p>
|
||
<p>The transports and protocols used with pipes and subprocesses differ
|
||
from those used with regular stream connections. These are described
|
||
later.</p>
|
||
<p>Each of the methods below has a <code class="docutils literal notranslate"><span class="pre">protocol_factory</span></code> argument, similar
|
||
to <code class="docutils literal notranslate"><span class="pre">create_connection()</span></code>; this will be called exactly once, without
|
||
arguments, to construct the protocol object to be returned.</p>
|
||
<p>Each method is a coroutine that returns a <code class="docutils literal notranslate"><span class="pre">(transport,</span> <span class="pre">protocol)</span></code>
|
||
pair on success, or raises an exception on failure.</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">connect_read_pipe(protocol_factory,</span> <span class="pre">pipe)</span></code>: Create a
|
||
unidrectional stream connection from a file-like object wrapping the
|
||
read end of a UNIX pipe, which must be in non-blocking mode. The
|
||
transport returned is a <code class="docutils literal notranslate"><span class="pre">ReadTransport</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">connect_write_pipe(protocol_factory,</span> <span class="pre">pipe)</span></code>: Create a
|
||
unidrectional stream connection from a file-like object wrapping the
|
||
write end of a UNIX pipe, which must be in non-blocking mode. The
|
||
transport returned is a <code class="docutils literal notranslate"><span class="pre">WriteTransport</span></code>; it does not have any
|
||
read-related methods. The protocol returned is a <code class="docutils literal notranslate"><span class="pre">BaseProtocol</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">subprocess_shell(protocol_factory,</span> <span class="pre">cmd,</span> <span class="pre"><options>)</span></code>: Create a
|
||
subprocess from <code class="docutils literal notranslate"><span class="pre">cmd</span></code>, which is a string using the platform’s
|
||
“shell” syntax. This is similar to the standard library
|
||
<code class="docutils literal notranslate"><span class="pre">subprocess.Popen()</span></code> class called with <code class="docutils literal notranslate"><span class="pre">shell=True</span></code>. The
|
||
remaining arguments and return value are described below.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">subprocess_exec(protocol_factory,</span> <span class="pre">*args,</span> <span class="pre"><options>)</span></code>: Create a
|
||
subprocess from one or more string arguments, where the first string
|
||
specifies the program to execute, and the remaining strings specify
|
||
the program’s arguments. (Thus, together the string arguments form
|
||
the <code class="docutils literal notranslate"><span class="pre">sys.argv</span></code> value of the program, assuming it is a Python
|
||
script.) This is similar to the standard library
|
||
<code class="docutils literal notranslate"><span class="pre">subprocess.Popen()</span></code> class called with <code class="docutils literal notranslate"><span class="pre">shell=False</span></code> and the
|
||
list of strings passed as the first argument; however, where
|
||
<code class="docutils literal notranslate"><span class="pre">Popen()</span></code> takes a single argument which is list of strings,
|
||
<code class="docutils literal notranslate"><span class="pre">subprocess_exec()</span></code> takes multiple string arguments. The
|
||
remaining arguments and return value are described below.</li>
|
||
</ul>
|
||
<p>Apart from the way the program to execute is specified, the two
|
||
<code class="docutils literal notranslate"><span class="pre">subprocess_*()</span></code> methods behave the same. The transport returned is
|
||
a <code class="docutils literal notranslate"><span class="pre">SubprocessTransport</span></code> which has a different interface than the
|
||
common bidirectional stream transport. The protocol returned is a
|
||
<code class="docutils literal notranslate"><span class="pre">SubprocessProtocol</span></code> which also has a custom interface.</p>
|
||
<p>The <options> are all specified using optional keyword arguments:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">stdin</span></code>: Either a file-like object representing the pipe to be
|
||
connected to the subprocess’s standard input stream using
|
||
<code class="docutils literal notranslate"><span class="pre">connect_write_pipe()</span></code>, or the constant <code class="docutils literal notranslate"><span class="pre">subprocess.PIPE</span></code> (the
|
||
default). By default a new pipe will be created and connected.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">stdout</span></code>: Either a file-like object representing the pipe to be
|
||
connected to the subprocess’s standard output stream using
|
||
<code class="docutils literal notranslate"><span class="pre">connect_read_pipe()</span></code>, or the constant <code class="docutils literal notranslate"><span class="pre">subprocess.PIPE</span></code> (the
|
||
default). By default a new pipe will be created and connected.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">stderr</span></code>: Either a file-like object representing the pipe to be
|
||
connected to the subprocess’s standard error stream using
|
||
<code class="docutils literal notranslate"><span class="pre">connect_read_pipe()</span></code>, or one of the constants <code class="docutils literal notranslate"><span class="pre">subprocess.PIPE</span></code>
|
||
(the default) or <code class="docutils literal notranslate"><span class="pre">subprocess.STDOUT</span></code>. By default a new pipe will
|
||
be created and connected. When <code class="docutils literal notranslate"><span class="pre">subprocess.STDOUT</span></code> is specified,
|
||
the subprocess’s standard error stream will be connected to the same
|
||
pipe as the standard output stream.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">bufsize</span></code>: The buffer size to be used when creating a pipe; this
|
||
is passed to <code class="docutils literal notranslate"><span class="pre">subprocess.Popen()</span></code>. In the default implementation
|
||
this defaults to zero, and on Windows it must be zero; these
|
||
defaults deviate from <code class="docutils literal notranslate"><span class="pre">subprocess.Popen()</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">executable</span></code>, <code class="docutils literal notranslate"><span class="pre">preexec_fn</span></code>, <code class="docutils literal notranslate"><span class="pre">close_fds</span></code>, <code class="docutils literal notranslate"><span class="pre">cwd</span></code>, <code class="docutils literal notranslate"><span class="pre">env</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">startupinfo</span></code>, <code class="docutils literal notranslate"><span class="pre">creationflags</span></code>, <code class="docutils literal notranslate"><span class="pre">restore_signals</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">start_new_session</span></code>, <code class="docutils literal notranslate"><span class="pre">pass_fds</span></code>: These optional arguments are
|
||
passed to <code class="docutils literal notranslate"><span class="pre">subprocess.Popen()</span></code> without interpretation.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="signal-callbacks">
|
||
<h4><a class="toc-backref" href="#signal-callbacks" role="doc-backlink">Signal callbacks</a></h4>
|
||
<p>These methods are only supported on UNIX.</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">add_signal_handler(sig,</span> <span class="pre">callback,</span> <span class="pre">*args)</span></code>. Whenever signal
|
||
<code class="docutils literal notranslate"><span class="pre">sig</span></code> is received, arrange for <code class="docutils literal notranslate"><span class="pre">callback(*args)</span></code> to be called.
|
||
Specifying another callback for the same signal replaces the
|
||
previous handler (only one handler can be active per signal). The
|
||
<code class="docutils literal notranslate"><span class="pre">sig</span></code> must be a valid signal number defined in the <code class="docutils literal notranslate"><span class="pre">signal</span></code>
|
||
module. If the signal cannot be handled this raises an exception:
|
||
<code class="docutils literal notranslate"><span class="pre">ValueError</span></code> if it is not a valid signal or if it is an
|
||
uncatchable signal (e.g. <code class="docutils literal notranslate"><span class="pre">SIGKILL</span></code>), <code class="docutils literal notranslate"><span class="pre">RuntimeError</span></code> if this
|
||
particular event loop instance cannot handle signals (since signals
|
||
are global per process, only an event loop associated with the main
|
||
thread can handle signals).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">remove_signal_handler(sig)</span></code>. Removes the handler for signal
|
||
<code class="docutils literal notranslate"><span class="pre">sig</span></code>, if one is set. Raises the same exceptions as
|
||
<code class="docutils literal notranslate"><span class="pre">add_signal_handler()</span></code> (except that it may return <code class="docutils literal notranslate"><span class="pre">False</span></code>
|
||
instead raising <code class="docutils literal notranslate"><span class="pre">RuntimeError</span></code> for uncatchable signals). Returns
|
||
<code class="docutils literal notranslate"><span class="pre">True</span></code> if a handler was removed successfully, <code class="docutils literal notranslate"><span class="pre">False</span></code> if no
|
||
handler was set.</li>
|
||
</ul>
|
||
<p>Note: If these methods are statically known to be unsupported, they
|
||
may raise <code class="docutils literal notranslate"><span class="pre">NotImplementedError</span></code> instead of <code class="docutils literal notranslate"><span class="pre">RuntimeError</span></code>.</p>
|
||
</section>
|
||
</section>
|
||
<section id="mutual-exclusion-of-callbacks">
|
||
<h3><a class="toc-backref" href="#mutual-exclusion-of-callbacks" role="doc-backlink">Mutual Exclusion of Callbacks</a></h3>
|
||
<p>An event loop should enforce mutual exclusion of callbacks, i.e. it
|
||
should never start a callback while a previously callback is still
|
||
running. This should apply across all types of callbacks, regardless
|
||
of whether they are scheduled using <code class="docutils literal notranslate"><span class="pre">call_soon()</span></code>, <code class="docutils literal notranslate"><span class="pre">call_later()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">call_at()</span></code>, <code class="docutils literal notranslate"><span class="pre">call_soon_threadsafe()</span></code>, <code class="docutils literal notranslate"><span class="pre">add_reader()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">add_writer()</span></code>, or <code class="docutils literal notranslate"><span class="pre">add_signal_handler()</span></code>.</p>
|
||
</section>
|
||
<section id="exceptions">
|
||
<h3><a class="toc-backref" href="#exceptions" role="doc-backlink">Exceptions</a></h3>
|
||
<p>There are two categories of exceptions in Python: those that derive
|
||
from the <code class="docutils literal notranslate"><span class="pre">Exception</span></code> class and those that derive from
|
||
<code class="docutils literal notranslate"><span class="pre">BaseException</span></code>. Exceptions deriving from <code class="docutils literal notranslate"><span class="pre">Exception</span></code> will
|
||
generally be caught and handled appropriately; for example, they will
|
||
be passed through by Futures, and they will be logged and ignored when
|
||
they occur in a callback.</p>
|
||
<p>However, exceptions deriving only from <code class="docutils literal notranslate"><span class="pre">BaseException</span></code> are typically
|
||
not caught, and will usually cause the program to terminate with a
|
||
traceback. In some cases they are caught and re-raised. (Examples of
|
||
this category include <code class="docutils literal notranslate"><span class="pre">KeyboardInterrupt</span></code> and <code class="docutils literal notranslate"><span class="pre">SystemExit</span></code>; it is
|
||
usually unwise to treat these the same as most other exceptions.)</p>
|
||
<p>The event loop passes the latter category into its <em>exception
|
||
handler</em>. This is a callback which accepts a <em>context</em> dict as a
|
||
parameter:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">exception_handler</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
|
||
<span class="o">...</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><em>context</em> may have many different keys but several of them are very
|
||
widely used:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">'message'</span></code>: error message.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">'exception'</span></code>: exception instance; <code class="docutils literal notranslate"><span class="pre">None</span></code> if there is no
|
||
exception.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">'source_traceback'</span></code>: a list of strings representing stack at the
|
||
point the object involved in the error was created.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">'handle_traceback'</span></code>: a list of strings representing the stack at
|
||
the moment the handle involved in the error was created.</li>
|
||
</ul>
|
||
<p>The loop has the following methods related to exception handling:</p>
|
||
<ul>
|
||
<li><code class="docutils literal notranslate"><span class="pre">get_exception_handler()</span></code> returns the current exception handler
|
||
registered for the loop.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">set_exception_handler(handler)</span></code> sets the exception handler.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">default_exception_handler(context)</span></code> the <em>default</em> exception
|
||
handler for this loop implementation.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">call_exception_handler(context)</span></code> passes <em>context</em> into the
|
||
registered exception handler. This allows handling uncaught
|
||
exceptions uniformly by third-party libraries.<p>The loop uses <code class="docutils literal notranslate"><span class="pre">default_exception_handler()</span></code> if the default was not
|
||
overridden by explicit <code class="docutils literal notranslate"><span class="pre">set_exception_handler()</span></code> call.</p>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
<section id="debug-mode">
|
||
<h3><a class="toc-backref" href="#debug-mode" role="doc-backlink">Debug Mode</a></h3>
|
||
<p>By default the loop operates in <em>release</em> mode. Applications may
|
||
enable <em>debug</em> mode better error reporting at the cost of some
|
||
performance.</p>
|
||
<p>In debug mode many additional checks are enabled, for example:</p>
|
||
<ul>
|
||
<li>Source tracebacks are available for unhandled exceptions in futures/tasks.</li>
|
||
<li>The loop checks for slow callbacks to detect accidental blocking for I/O.<p>The <code class="docutils literal notranslate"><span class="pre">loop.slow_callback_duration</span></code> attribute controls the maximum
|
||
execution time allowed between two <em>yield points</em> before a slow
|
||
callback is reported. The default value is 0.1 seconds; it may be
|
||
changed by assigning to it.</p>
|
||
</li>
|
||
</ul>
|
||
<p>There are two methods related to debug mode:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">get_debug()</span></code> returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if <em>debug</em> mode is enabled,
|
||
<code class="docutils literal notranslate"><span class="pre">False</span></code> otherwise.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">set_debug(enabled)</span></code> enables <em>debug</em> mode if the argument is <code class="docutils literal notranslate"><span class="pre">True</span></code>.</li>
|
||
</ul>
|
||
<p>Debug mode is automatically enabled if the <code class="docutils literal notranslate"><span class="pre">PYTHONASYNCIODEBUG</span></code>
|
||
<em>environment variable</em> is defined and not empty.</p>
|
||
</section>
|
||
<section id="handles">
|
||
<h3><a class="toc-backref" href="#handles" role="doc-backlink">Handles</a></h3>
|
||
<p>The various methods for registering one-off callbacks
|
||
(<code class="docutils literal notranslate"><span class="pre">call_soon()</span></code>, <code class="docutils literal notranslate"><span class="pre">call_later()</span></code>, <code class="docutils literal notranslate"><span class="pre">call_at()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">call_soon_threadsafe()</span></code>) all return an object representing the
|
||
registration that can be used to cancel the callback. This object is
|
||
called a <code class="docutils literal notranslate"><span class="pre">Handle</span></code>. Handles are opaque and have only one public
|
||
method:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">cancel()</span></code>: Cancel the callback.</li>
|
||
</ul>
|
||
<p>Note that <code class="docutils literal notranslate"><span class="pre">add_reader()</span></code>, <code class="docutils literal notranslate"><span class="pre">add_writer()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">add_signal_handler()</span></code> do not return Handles.</p>
|
||
</section>
|
||
<section id="servers">
|
||
<h3><a class="toc-backref" href="#servers" role="doc-backlink">Servers</a></h3>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">create_server()</span></code> method returns a <code class="docutils literal notranslate"><span class="pre">Server</span></code> instance, which
|
||
wraps the sockets (or other network objects) used to accept requests.
|
||
This class has two public methods:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">close()</span></code>: Close the service. This stops accepting new requests
|
||
but does not cancel requests that have already been accepted and are
|
||
currently being handled.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">wait_closed()</span></code>: A coroutine that blocks until the service is
|
||
closed and all accepted requests have been handled.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="futures">
|
||
<h3><a class="toc-backref" href="#futures" role="doc-backlink">Futures</a></h3>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">asyncio.Future</span></code> class here is intentionally similar to the
|
||
<code class="docutils literal notranslate"><span class="pre">concurrent.futures.Future</span></code> class specified by <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>, but there
|
||
are slight differences. Whenever this PEP talks about Futures or
|
||
futures this should be understood to refer to <code class="docutils literal notranslate"><span class="pre">asyncio.Future</span></code> unless
|
||
<code class="docutils literal notranslate"><span class="pre">concurrent.futures.Future</span></code> is explicitly mentioned. The supported
|
||
public API is as follows, indicating the differences with <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">cancel()</span></code>. If the Future is already done (or cancelled), do
|
||
nothing and return <code class="docutils literal notranslate"><span class="pre">False</span></code>. Otherwise, this attempts to cancel
|
||
the Future and returns <code class="docutils literal notranslate"><span class="pre">True</span></code>. If the cancellation attempt is
|
||
successful, eventually the Future’s state will change to cancelled
|
||
(so that <code class="docutils literal notranslate"><span class="pre">cancelled()</span></code> will return <code class="docutils literal notranslate"><span class="pre">True</span></code>)
|
||
and the callbacks will be scheduled. For regular Futures,
|
||
cancellation will always succeed immediately; but for Tasks (see
|
||
below) the task may ignore or delay the cancellation attempt.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">cancelled()</span></code>. Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the Future was successfully
|
||
cancelled.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">done()</span></code>. Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the Future is done. Note that a
|
||
cancelled Future is considered done too (here and everywhere).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">result()</span></code>. Returns the result set with <code class="docutils literal notranslate"><span class="pre">set_result()</span></code>, or
|
||
raises the exception set with <code class="docutils literal notranslate"><span class="pre">set_exception()</span></code>. Raises
|
||
<code class="docutils literal notranslate"><span class="pre">CancelledError</span></code> if cancelled. Difference with <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>: This has
|
||
no timeout argument and does <em>not</em> wait; if the future is not yet
|
||
done, it raises an exception.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">exception()</span></code>. Returns the exception if set with
|
||
<code class="docutils literal notranslate"><span class="pre">set_exception()</span></code>, or <code class="docutils literal notranslate"><span class="pre">None</span></code> if a result was set with
|
||
<code class="docutils literal notranslate"><span class="pre">set_result()</span></code>. Raises <code class="docutils literal notranslate"><span class="pre">CancelledError</span></code> if cancelled.
|
||
Difference with <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>: This has no timeout argument and does
|
||
<em>not</em> wait; if the future is not yet done, it raises an exception.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">add_done_callback(fn)</span></code>. Add a callback to be run when the Future
|
||
becomes done (or is cancelled). If the Future is already done (or
|
||
cancelled), schedules the callback to using <code class="docutils literal notranslate"><span class="pre">call_soon()</span></code>.
|
||
Difference with <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>: The callback is never called immediately,
|
||
and always in the context of the caller – typically this is a
|
||
thread. You can think of this as calling the callback through
|
||
<code class="docutils literal notranslate"><span class="pre">call_soon()</span></code>. Note that in order to match <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>, the callback
|
||
(unlike all other callbacks defined in this PEP, and ignoring the
|
||
convention from the section “Callback Style” below) is always called
|
||
with a single argument, the Future object. (The motivation for
|
||
strictly serializing callbacks scheduled with <code class="docutils literal notranslate"><span class="pre">call_soon()</span></code>
|
||
applies here too.)</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">remove_done_callback(fn)</span></code>. Remove the argument from the list of
|
||
callbacks. This method is not defined by <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>. The argument
|
||
must be equal (using <code class="docutils literal notranslate"><span class="pre">==</span></code>) to the argument passed to
|
||
<code class="docutils literal notranslate"><span class="pre">add_done_callback()</span></code>. Returns the number of times the callback
|
||
was removed.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">set_result(result)</span></code>. The Future must not be done (nor cancelled)
|
||
already. This makes the Future done and schedules the callbacks.
|
||
Difference with <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>: This is a public API.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">set_exception(exception)</span></code>. The Future must not be done (nor
|
||
cancelled) already. This makes the Future done and schedules the
|
||
callbacks. Difference with <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>: This is a public API.</li>
|
||
</ul>
|
||
<p>The internal method <code class="docutils literal notranslate"><span class="pre">set_running_or_notify_cancel()</span></code> is not
|
||
supported; there is no way to set the running state. Likewise,
|
||
the method <code class="docutils literal notranslate"><span class="pre">running()</span></code> is not supported.</p>
|
||
<p>The following exceptions are defined:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">InvalidStateError</span></code>. Raised whenever the Future is not in a state
|
||
acceptable to the method being called (e.g. calling <code class="docutils literal notranslate"><span class="pre">set_result()</span></code>
|
||
on a Future that is already done, or calling <code class="docutils literal notranslate"><span class="pre">result()</span></code> on a Future
|
||
that is not yet done).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">InvalidTimeoutError</span></code>. Raised by <code class="docutils literal notranslate"><span class="pre">result()</span></code> and <code class="docutils literal notranslate"><span class="pre">exception()</span></code>
|
||
when a nonzero <code class="docutils literal notranslate"><span class="pre">timeout</span></code> argument is given.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">CancelledError</span></code>. An alias for
|
||
<code class="docutils literal notranslate"><span class="pre">concurrent.futures.CancelledError</span></code>. Raised when <code class="docutils literal notranslate"><span class="pre">result()</span></code> or
|
||
<code class="docutils literal notranslate"><span class="pre">exception()</span></code> is called on a Future that is cancelled.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">TimeoutError</span></code>. An alias for <code class="docutils literal notranslate"><span class="pre">concurrent.futures.TimeoutError</span></code>.
|
||
May be raised by <code class="docutils literal notranslate"><span class="pre">run_until_complete()</span></code>.</li>
|
||
</ul>
|
||
<p>A Future is associated with an event loop when it is created.</p>
|
||
<p>A <code class="docutils literal notranslate"><span class="pre">asyncio.Future</span></code> object is not acceptable to the <code class="docutils literal notranslate"><span class="pre">wait()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">as_completed()</span></code> functions in the <code class="docutils literal notranslate"><span class="pre">concurrent.futures</span></code> package.
|
||
However, there are similar APIs <code class="docutils literal notranslate"><span class="pre">asyncio.wait()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">asyncio.as_completed()</span></code>, described below.</p>
|
||
<p>A <code class="docutils literal notranslate"><span class="pre">asyncio.Future</span></code> object is acceptable to a <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> expression
|
||
when used in a coroutine. This is implemented through the
|
||
<code class="docutils literal notranslate"><span class="pre">__iter__()</span></code> interface on the Future. See the section “Coroutines
|
||
and the Scheduler” below.</p>
|
||
<p>When a Future is garbage-collected, if it has an associated exception
|
||
but neither <code class="docutils literal notranslate"><span class="pre">result()</span></code> nor <code class="docutils literal notranslate"><span class="pre">exception()</span></code> has ever been called, the
|
||
exception is logged. (When a coroutine uses <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> to wait
|
||
for a Future, that Future’s <code class="docutils literal notranslate"><span class="pre">result()</span></code> method is called once the
|
||
coroutine is resumed.)</p>
|
||
<p>In the future (pun intended) we may unify <code class="docutils literal notranslate"><span class="pre">asyncio.Future</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">concurrent.futures.Future</span></code>, e.g. by adding an <code class="docutils literal notranslate"><span class="pre">__iter__()</span></code> method
|
||
to the latter that works with <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code>. To prevent accidentally
|
||
blocking the event loop by calling e.g. <code class="docutils literal notranslate"><span class="pre">result()</span></code> on a Future
|
||
that’s not done yet, the blocking operation may detect that an event
|
||
loop is active in the current thread and raise an exception instead.
|
||
However the current PEP strives to have no dependencies beyond Python
|
||
3.3, so changes to <code class="docutils literal notranslate"><span class="pre">concurrent.futures.Future</span></code> are off the table for
|
||
now.</p>
|
||
<p>There are some public functions related to Futures:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">asyncio.async(arg)</span></code>. This takes an argument that is either a
|
||
coroutine object or a Future (i.e., anything you can use with
|
||
<code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code>) and returns a Future. If the argument is a Future,
|
||
it is returned unchanged; if it is a coroutine object, it wraps it
|
||
in a Task (remember that <code class="docutils literal notranslate"><span class="pre">Task</span></code> is a subclass of <code class="docutils literal notranslate"><span class="pre">Future</span></code>).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">asyncio.wrap_future(future)</span></code>. This takes a <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a> Future
|
||
(i.e., an instance of <code class="docutils literal notranslate"><span class="pre">concurrent.futures.Future</span></code>) and returns a
|
||
Future compatible with the event loop (i.e., a <code class="docutils literal notranslate"><span class="pre">asyncio.Future</span></code>
|
||
instance).</li>
|
||
</ul>
|
||
</section>
|
||
<section id="transports">
|
||
<h3><a class="toc-backref" href="#transports" role="doc-backlink">Transports</a></h3>
|
||
<p>Transports and protocols are strongly influenced by Twisted and PEP
|
||
3153. Users rarely implement or instantiate transports – rather,
|
||
event loops offer utility methods to set up transports.</p>
|
||
<p>Transports work in conjunction with protocols. Protocols are
|
||
typically written without knowing or caring about the exact type of
|
||
transport used, and transports can be used with a wide variety of
|
||
protocols. For example, an HTTP client protocol implementation may be
|
||
used with either a plain socket transport or an SSL/TLS transport.
|
||
The plain socket transport can be used with many different protocols
|
||
besides HTTP (e.g. SMTP, IMAP, POP, FTP, IRC, SPDY).</p>
|
||
<p>The most common type of transport is a bidirectional stream transport.
|
||
There are also unidirectional stream transports (used for pipes) and
|
||
datagram transports (used by the <code class="docutils literal notranslate"><span class="pre">create_datagram_endpoint()</span></code>
|
||
method).</p>
|
||
<section id="methods-for-all-transports">
|
||
<h4><a class="toc-backref" href="#methods-for-all-transports" role="doc-backlink">Methods For All Transports</a></h4>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">get_extra_info(name,</span> <span class="pre">default=None)</span></code>. This is a catch-all method
|
||
that returns implementation-specific information about a transport.
|
||
The first argument is the name of the extra field to be retrieved.
|
||
The optional second argument is a default value to be returned.
|
||
Consult the implementation documentation to find out the supported
|
||
extra field names. For an unsupported name, the default is always
|
||
returned.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="bidirectional-stream-transports">
|
||
<h4><a class="toc-backref" href="#bidirectional-stream-transports" role="doc-backlink">Bidirectional Stream Transports</a></h4>
|
||
<p>A bidirectional stream transport is an abstraction on top of a socket
|
||
or something similar (for example, a pair of UNIX pipes or an SSL/TLS
|
||
connection).</p>
|
||
<p>Most connections have an asymmetric nature: the client and server
|
||
usually have very different roles and behaviors. Hence, the interface
|
||
between transport and protocol is also asymmetric. From the
|
||
protocol’s point of view, <em>writing</em> data is done by calling the
|
||
<code class="docutils literal notranslate"><span class="pre">write()</span></code> method on the transport object; this buffers the data and
|
||
returns immediately. However, the transport takes a more active role
|
||
in <em>reading</em> data: whenever some data is read from the socket (or
|
||
other data source), the transport calls the protocol’s
|
||
<code class="docutils literal notranslate"><span class="pre">data_received()</span></code> method.</p>
|
||
<p>Nevertheless, the interface between transport and protocol used by
|
||
bidirectional streams is the same for clients as it is for servers,
|
||
since the connection between a client and a server is essentially a
|
||
pair of streams, one in each direction.</p>
|
||
<p>Bidirectional stream transports have the following public methods:</p>
|
||
<ul>
|
||
<li><code class="docutils literal notranslate"><span class="pre">write(data)</span></code>. Write some bytes. The argument must be a bytes
|
||
object. Returns <code class="docutils literal notranslate"><span class="pre">None</span></code>. The transport is free to buffer the
|
||
bytes, but it must eventually cause the bytes to be transferred to
|
||
the entity at the other end, and it must maintain stream behavior.
|
||
That is, <code class="docutils literal notranslate"><span class="pre">t.write(b'abc');</span> <span class="pre">t.write(b'def')</span></code> is equivalent to
|
||
<code class="docutils literal notranslate"><span class="pre">t.write(b'abcdef')</span></code>, as well as to:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">t</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="sa">b</span><span class="s1">'a'</span><span class="p">)</span>
|
||
<span class="n">t</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="sa">b</span><span class="s1">'b'</span><span class="p">)</span>
|
||
<span class="n">t</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="sa">b</span><span class="s1">'c'</span><span class="p">)</span>
|
||
<span class="n">t</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="sa">b</span><span class="s1">'d'</span><span class="p">)</span>
|
||
<span class="n">t</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="sa">b</span><span class="s1">'e'</span><span class="p">)</span>
|
||
<span class="n">t</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="sa">b</span><span class="s1">'f'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">writelines(iterable)</span></code>. Equivalent to:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">data</span> <span class="ow">in</span> <span class="n">iterable</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">write_eof()</span></code>. Close the writing end of the connection.
|
||
Subsequent calls to <code class="docutils literal notranslate"><span class="pre">write()</span></code> are not allowed. Once all buffered
|
||
data is transferred, the transport signals to the other end that no
|
||
more data will be received. Some protocols don’t support this
|
||
operation; in that case, calling <code class="docutils literal notranslate"><span class="pre">write_eof()</span></code> will raise an
|
||
exception. (Note: This used to be called <code class="docutils literal notranslate"><span class="pre">half_close()</span></code>, but
|
||
unless you already know what it is for, that name doesn’t indicate
|
||
<em>which</em> end is closed.)</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">can_write_eof()</span></code>. Return <code class="docutils literal notranslate"><span class="pre">True</span></code> if the protocol supports
|
||
<code class="docutils literal notranslate"><span class="pre">write_eof()</span></code>, <code class="docutils literal notranslate"><span class="pre">False</span></code> if it does not. (This method typically
|
||
returns a fixed value that depends only on the specific Transport
|
||
class, not on the state of the Transport object. It is needed
|
||
because some protocols need to change their behavior when
|
||
<code class="docutils literal notranslate"><span class="pre">write_eof()</span></code> is unavailable. For example, in HTTP, to send data
|
||
whose size is not known ahead of time, the end of the data is
|
||
typically indicated using <code class="docutils literal notranslate"><span class="pre">write_eof()</span></code>; however, SSL/TLS does not
|
||
support this, and an HTTP protocol implementation would have to use
|
||
the “chunked” transfer encoding in this case. But if the data size
|
||
is known ahead of time, the best approach in both cases is to use
|
||
the Content-Length header.)</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">get_write_buffer_size()</span></code>. Return the current size of the
|
||
transport’s write buffer in bytes. This only knows about the write
|
||
buffer managed explicitly by the transport; buffering in other
|
||
layers of the network stack or elsewhere of the network is not
|
||
reported.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">set_write_buffer_limits(high=None,</span> <span class="pre">low=None)</span></code>. Set the high- and
|
||
low-water limits for flow control.<p>These two values control when to call the protocol’s
|
||
<code class="docutils literal notranslate"><span class="pre">pause_writing()</span></code> and <code class="docutils literal notranslate"><span class="pre">resume_writing()</span></code> methods. If specified,
|
||
the low-water limit must be less than or equal to the high-water
|
||
limit. Neither value can be negative.</p>
|
||
<p>The defaults are implementation-specific. If only the high-water
|
||
limit is given, the low-water limit defaults to an
|
||
implementation-specific value less than or equal to the high-water
|
||
limit. Setting high to zero forces low to zero as well, and causes
|
||
<code class="docutils literal notranslate"><span class="pre">pause_writing()</span></code> to be called whenever the buffer becomes
|
||
non-empty. Setting low to zero causes <code class="docutils literal notranslate"><span class="pre">resume_writing()</span></code> to be
|
||
called only once the buffer is empty. Use of zero for either limit
|
||
is generally sub-optimal as it reduces opportunities for doing I/O
|
||
and computation concurrently.</p>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">pause_reading()</span></code>. Suspend delivery of data to the protocol until
|
||
a subsequent <code class="docutils literal notranslate"><span class="pre">resume_reading()</span></code> call. Between <code class="docutils literal notranslate"><span class="pre">pause_reading()</span></code>
|
||
and <code class="docutils literal notranslate"><span class="pre">resume_reading()</span></code>, the protocol’s <code class="docutils literal notranslate"><span class="pre">data_received()</span></code> method
|
||
will not be called.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">resume_reading()</span></code>. Restart delivery of data to the protocol via
|
||
<code class="docutils literal notranslate"><span class="pre">data_received()</span></code>. Note that “paused” is a binary state –
|
||
<code class="docutils literal notranslate"><span class="pre">pause_reading()</span></code> should only be called when the transport is not
|
||
paused, while <code class="docutils literal notranslate"><span class="pre">resume_reading()</span></code> should only be called when the
|
||
transport is paused.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">close()</span></code>. Sever the connection with the entity at the other end.
|
||
Any data buffered by <code class="docutils literal notranslate"><span class="pre">write()</span></code> will (eventually) be transferred
|
||
before the connection is actually closed. The protocol’s
|
||
<code class="docutils literal notranslate"><span class="pre">data_received()</span></code> method will not be called again. Once all
|
||
buffered data has been flushed, the protocol’s <code class="docutils literal notranslate"><span class="pre">connection_lost()</span></code>
|
||
method will be called with <code class="docutils literal notranslate"><span class="pre">None</span></code> as the argument. Note that
|
||
this method does not wait for all that to happen.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">abort()</span></code>. Immediately sever the connection. Any data still
|
||
buffered by the transport is thrown away. Soon, the protocol’s
|
||
<code class="docutils literal notranslate"><span class="pre">connection_lost()</span></code> method will be called with <code class="docutils literal notranslate"><span class="pre">None</span></code> as
|
||
argument.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="unidirectional-stream-transports">
|
||
<h4><a class="toc-backref" href="#unidirectional-stream-transports" role="doc-backlink">Unidirectional Stream Transports</a></h4>
|
||
<p>A writing stream transport supports the <code class="docutils literal notranslate"><span class="pre">write()</span></code>, <code class="docutils literal notranslate"><span class="pre">writelines()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">write_eof()</span></code>, <code class="docutils literal notranslate"><span class="pre">can_write_eof()</span></code>, <code class="docutils literal notranslate"><span class="pre">close()</span></code> and <code class="docutils literal notranslate"><span class="pre">abort()</span></code> methods
|
||
described for bidirectional stream transports.</p>
|
||
<p>A reading stream transport supports the <code class="docutils literal notranslate"><span class="pre">pause_reading()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">resume_reading()</span></code> and <code class="docutils literal notranslate"><span class="pre">close()</span></code> methods described for
|
||
bidirectional stream transports.</p>
|
||
<p>A writing stream transport calls only <code class="docutils literal notranslate"><span class="pre">connection_made()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">connection_lost()</span></code> on its associated protocol.</p>
|
||
<p>A reading stream transport can call all protocol methods specified in
|
||
the Protocols section below (i.e., the previous two plus
|
||
<code class="docutils literal notranslate"><span class="pre">data_received()</span></code> and <code class="docutils literal notranslate"><span class="pre">eof_received()</span></code>).</p>
|
||
</section>
|
||
<section id="datagram-transports">
|
||
<h4><a class="toc-backref" href="#datagram-transports" role="doc-backlink">Datagram Transports</a></h4>
|
||
<p>Datagram transports have these methods:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">sendto(data,</span> <span class="pre">addr=None)</span></code>. Sends a datagram (a bytes object).
|
||
The optional second argument is the destination address. If
|
||
omitted, <code class="docutils literal notranslate"><span class="pre">remote_addr</span></code> must have been specified in the
|
||
<code class="docutils literal notranslate"><span class="pre">create_datagram_endpoint()</span></code> call that created this transport. If
|
||
present, and <code class="docutils literal notranslate"><span class="pre">remote_addr</span></code> was specified, they must match. The
|
||
(data, addr) pair may be sent immediately or buffered. The return
|
||
value is <code class="docutils literal notranslate"><span class="pre">None</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">abort()</span></code>. Immediately close the transport. Buffered data will
|
||
be discarded.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">close()</span></code>. Close the transport. Buffered data will be
|
||
transmitted asynchronously.</li>
|
||
</ul>
|
||
<p>Datagram transports call the following methods on the associated
|
||
protocol object: <code class="docutils literal notranslate"><span class="pre">connection_made()</span></code>, <code class="docutils literal notranslate"><span class="pre">connection_lost()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">error_received()</span></code> and <code class="docutils literal notranslate"><span class="pre">datagram_received()</span></code>. (“Connection”
|
||
in these method names is a slight misnomer, but the concepts still
|
||
exist: <code class="docutils literal notranslate"><span class="pre">connection_made()</span></code> means the transport representing the
|
||
endpoint has been created, and <code class="docutils literal notranslate"><span class="pre">connection_lost()</span></code> means the
|
||
transport is closed.)</p>
|
||
</section>
|
||
<section id="subprocess-transports">
|
||
<h4><a class="toc-backref" href="#subprocess-transports" role="doc-backlink">Subprocess Transports</a></h4>
|
||
<p>Subprocess transports have the following methods:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">get_pid()</span></code>. Return the process ID of the subprocess.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">get_returncode()</span></code>. Return the process return code, if the
|
||
process has exited; otherwise <code class="docutils literal notranslate"><span class="pre">None</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">get_pipe_transport(fd)</span></code>. Return the pipe transport (a
|
||
unidirectional stream transport) corresponding to the argument,
|
||
which should be 0, 1 or 2 representing stdin, stdout or stderr (of
|
||
the subprocess). If there is no such pipe transport, return
|
||
<code class="docutils literal notranslate"><span class="pre">None</span></code>. For stdin, this is a writing transport; for stdout and
|
||
stderr this is a reading transport. You must use this method to get
|
||
a transport you can use to write to the subprocess’s stdin.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">send_signal(signal)</span></code>. Send a signal to the subprocess.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">terminate()</span></code>. Terminate the subprocess.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">kill()</span></code>. Kill the subprocess. On Windows this is an alias for
|
||
<code class="docutils literal notranslate"><span class="pre">terminate()</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">close()</span></code>. This is an alias for <code class="docutils literal notranslate"><span class="pre">terminate()</span></code>.</li>
|
||
</ul>
|
||
<p>Note that <code class="docutils literal notranslate"><span class="pre">send_signal()</span></code>, <code class="docutils literal notranslate"><span class="pre">terminate()</span></code> and <code class="docutils literal notranslate"><span class="pre">kill()</span></code> wrap the
|
||
corresponding methods in the standard library <code class="docutils literal notranslate"><span class="pre">subprocess</span></code> module.</p>
|
||
</section>
|
||
</section>
|
||
<section id="protocols">
|
||
<h3><a class="toc-backref" href="#protocols" role="doc-backlink">Protocols</a></h3>
|
||
<p>Protocols are always used in conjunction with transports. While a few
|
||
common protocols are provided (e.g. decent though not necessarily
|
||
excellent HTTP client and server implementations), most protocols will
|
||
be implemented by user code or third-party libraries.</p>
|
||
<p>Like for transports, we distinguish between stream protocols, datagram
|
||
protocols, and perhaps other custom protocols. The most common type
|
||
of protocol is a bidirectional stream protocol. (There are no
|
||
unidirectional protocols.)</p>
|
||
<section id="stream-protocols">
|
||
<h4><a class="toc-backref" href="#stream-protocols" role="doc-backlink">Stream Protocols</a></h4>
|
||
<p>A (bidirectional) stream protocol must implement the following
|
||
methods, which will be called by the transport. Think of these as
|
||
callbacks that are always called by the event loop in the right
|
||
context. (See the “Context” section way above.)</p>
|
||
<ul>
|
||
<li><code class="docutils literal notranslate"><span class="pre">connection_made(transport)</span></code>. Indicates that the transport is
|
||
ready and connected to the entity at the other end. The protocol
|
||
should probably save the transport reference as an instance variable
|
||
(so it can call its <code class="docutils literal notranslate"><span class="pre">write()</span></code> and other methods later), and may
|
||
write an initial greeting or request at this point.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">data_received(data)</span></code>. The transport has read some bytes from the
|
||
connection. The argument is always a non-empty bytes object. There
|
||
are no guarantees about the minimum or maximum size of the data
|
||
passed along this way. <code class="docutils literal notranslate"><span class="pre">p.data_received(b'abcdef')</span></code> should be
|
||
treated exactly equivalent to:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">p</span><span class="o">.</span><span class="n">data_received</span><span class="p">(</span><span class="sa">b</span><span class="s1">'abc'</span><span class="p">)</span>
|
||
<span class="n">p</span><span class="o">.</span><span class="n">data_received</span><span class="p">(</span><span class="sa">b</span><span class="s1">'def'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">eof_received()</span></code>. This is called when the other end called
|
||
<code class="docutils literal notranslate"><span class="pre">write_eof()</span></code> (or something equivalent). If this returns a false
|
||
value (including <code class="docutils literal notranslate"><span class="pre">None</span></code>), the transport will close itself. If it
|
||
returns a true value, closing the transport is up to the protocol.
|
||
However, for SSL/TLS connections this is ignored, because the TLS
|
||
standard requires that no more data is sent and the connection is
|
||
closed as soon as a “closure alert” is received.<p>The default implementation returns <code class="docutils literal notranslate"><span class="pre">None</span></code>.</p>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">pause_writing()</span></code>. Asks that the protocol temporarily stop
|
||
writing data to the transport. Heeding the request is optional, but
|
||
the transport’s buffer may grow without bounds if you keep writing.
|
||
The buffer size at which this is called can be controlled through
|
||
the transport’s <code class="docutils literal notranslate"><span class="pre">set_write_buffer_limits()</span></code> method.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">resume_writing()</span></code>. Tells the protocol that it is safe to start
|
||
writing data to the transport again. Note that this may be called
|
||
directly by the transport’s <code class="docutils literal notranslate"><span class="pre">write()</span></code> method (as opposed to being
|
||
called indirectly using <code class="docutils literal notranslate"><span class="pre">call_soon()</span></code>), so that the protocol may
|
||
be aware of its paused state immediately after <code class="docutils literal notranslate"><span class="pre">write()</span></code> returns.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">connection_lost(exc)</span></code>. The transport has been closed or aborted,
|
||
has detected that the other end has closed the connection cleanly,
|
||
or has encountered an unexpected error. In the first three cases
|
||
the argument is <code class="docutils literal notranslate"><span class="pre">None</span></code>; for an unexpected error, the argument is
|
||
the exception that caused the transport to give up.</li>
|
||
</ul>
|
||
<p>Here is a table indicating the order and multiplicity of the basic
|
||
calls:</p>
|
||
<ol class="arabic simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">connection_made()</span></code> – exactly once</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">data_received()</span></code> – zero or more times</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">eof_received()</span></code> – at most once</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">connection_lost()</span></code> – exactly once</li>
|
||
</ol>
|
||
<p>Calls to <code class="docutils literal notranslate"><span class="pre">pause_writing()</span></code> and <code class="docutils literal notranslate"><span class="pre">resume_writing()</span></code> occur in pairs
|
||
and only between #1 and #4. These pairs will not be nested. The
|
||
final <code class="docutils literal notranslate"><span class="pre">resume_writing()</span></code> call may be omitted; i.e. a paused
|
||
connection may be lost and never be resumed.</p>
|
||
</section>
|
||
<section id="datagram-protocols">
|
||
<h4><a class="toc-backref" href="#datagram-protocols" role="doc-backlink">Datagram Protocols</a></h4>
|
||
<p>Datagram protocols have <code class="docutils literal notranslate"><span class="pre">connection_made()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">connection_lost()</span></code> methods with the same signatures as stream
|
||
protocols. (As explained in the section about datagram transports, we
|
||
prefer the slightly odd nomenclature over defining different method
|
||
names to indicating the opening and closing of the socket.)</p>
|
||
<p>In addition, they have the following methods:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">datagram_received(data,</span> <span class="pre">addr)</span></code>. Indicates that a datagram
|
||
<code class="docutils literal notranslate"><span class="pre">data</span></code> (a bytes objects) was received from remote address <code class="docutils literal notranslate"><span class="pre">addr</span></code>
|
||
(an IPv4 2-tuple or an IPv6 4-tuple).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">error_received(exc)</span></code>. Indicates that a send or receive operation
|
||
raised an <code class="docutils literal notranslate"><span class="pre">OSError</span></code> exception. Since datagram errors may be
|
||
transient, it is up to the protocol to call the transport’s
|
||
<code class="docutils literal notranslate"><span class="pre">close()</span></code> method if it wants to close the endpoint.</li>
|
||
</ul>
|
||
<p>Here is a chart indicating the order and multiplicity of calls:</p>
|
||
<ol class="arabic simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">connection_made()</span></code> – exactly once</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">datagram_received()</span></code>, <code class="docutils literal notranslate"><span class="pre">error_received()</span></code> – zero or more times</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">connection_lost()</span></code> – exactly once</li>
|
||
</ol>
|
||
</section>
|
||
<section id="subprocess-protocol">
|
||
<h4><a class="toc-backref" href="#subprocess-protocol" role="doc-backlink">Subprocess Protocol</a></h4>
|
||
<p>Subprocess protocols have <code class="docutils literal notranslate"><span class="pre">connection_made()</span></code>, <code class="docutils literal notranslate"><span class="pre">connection_lost()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">pause_writing()</span></code> and <code class="docutils literal notranslate"><span class="pre">resume_writing()</span></code> methods with the same
|
||
signatures as stream protocols. In addition, they have the following
|
||
methods:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">pipe_data_received(fd,</span> <span class="pre">data)</span></code>. Called when the subprocess writes
|
||
data to its stdout or stderr. <code class="docutils literal notranslate"><span class="pre">fd</span></code> is the file descriptor (1 for
|
||
stdout, 2 for stderr). <code class="docutils literal notranslate"><span class="pre">data</span></code> is a <code class="docutils literal notranslate"><span class="pre">bytes</span></code> object.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">pipe_connection_lost(fd,</span> <span class="pre">exc)</span></code>. Called when the subprocess
|
||
closes its stdin, stdout or stderr. <code class="docutils literal notranslate"><span class="pre">fd</span></code> is the file descriptor.
|
||
<code class="docutils literal notranslate"><span class="pre">exc</span></code> is an exception or <code class="docutils literal notranslate"><span class="pre">None</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">process_exited()</span></code>. Called when the subprocess has exited. To
|
||
retrieve the exit status, use the transport’s <code class="docutils literal notranslate"><span class="pre">get_returncode()</span></code>
|
||
method.</li>
|
||
</ul>
|
||
<p>Note that depending on the behavior of the subprocess it is possible
|
||
that <code class="docutils literal notranslate"><span class="pre">process_exited()</span></code> is called either before or after
|
||
<code class="docutils literal notranslate"><span class="pre">pipe_connection_lost()</span></code>. For example, if the subprocess creates a
|
||
sub-subprocess that shares its stdin/stdout/stderr and then itself
|
||
exits, <code class="docutils literal notranslate"><span class="pre">process_exited()</span></code> may be called while all the pipes are
|
||
still open. On the other hand, when the subprocess closes its
|
||
stdin/stdout/stderr but does not exit, <code class="docutils literal notranslate"><span class="pre">pipe_connection_lost()</span></code> may
|
||
be called for all three pipes without <code class="docutils literal notranslate"><span class="pre">process_exited()</span></code> being
|
||
called. If (as is the more common case) the subprocess exits and
|
||
thereby implicitly closes all pipes, the calling order is undefined.</p>
|
||
</section>
|
||
</section>
|
||
<section id="callback-style">
|
||
<h3><a class="toc-backref" href="#callback-style" role="doc-backlink">Callback Style</a></h3>
|
||
<p>Most interfaces taking a callback also take positional arguments. For
|
||
instance, to arrange for <code class="docutils literal notranslate"><span class="pre">foo("abc",</span> <span class="pre">42)</span></code> to be called soon, you
|
||
call <code class="docutils literal notranslate"><span class="pre">loop.call_soon(foo,</span> <span class="pre">"abc",</span> <span class="pre">42)</span></code>. To schedule the call
|
||
<code class="docutils literal notranslate"><span class="pre">foo()</span></code>, use <code class="docutils literal notranslate"><span class="pre">loop.call_soon(foo)</span></code>. This convention greatly
|
||
reduces the number of small lambdas required in typical callback
|
||
programming.</p>
|
||
<p>This convention specifically does <em>not</em> support keyword arguments.
|
||
Keyword arguments are used to pass optional extra information about
|
||
the callback. This allows graceful evolution of the API without
|
||
having to worry about whether a keyword might be significant to a
|
||
callee somewhere. If you have a callback that <em>must</em> be called with a
|
||
keyword argument, you can use a lambda. For example:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">loop</span><span class="o">.</span><span class="n">call_soon</span><span class="p">(</span><span class="k">lambda</span><span class="p">:</span> <span class="n">foo</span><span class="p">(</span><span class="s1">'abc'</span><span class="p">,</span> <span class="n">repeat</span><span class="o">=</span><span class="mi">42</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
<section id="coroutines-and-the-scheduler">
|
||
<h2><a class="toc-backref" href="#coroutines-and-the-scheduler" role="doc-backlink">Coroutines and the Scheduler</a></h2>
|
||
<p>This is a separate toplevel section because its status is different
|
||
from the event loop interface. Usage of coroutines is optional, and
|
||
it is perfectly fine to write code using callbacks only. On the other
|
||
hand, there is only one implementation of the scheduler/coroutine API,
|
||
and if you’re using coroutines, that’s the one you’re using.</p>
|
||
<section id="coroutines">
|
||
<h3><a class="toc-backref" href="#coroutines" role="doc-backlink">Coroutines</a></h3>
|
||
<p>A coroutine is a generator that follows certain conventions. For
|
||
documentation purposes, all coroutines should be decorated with
|
||
<code class="docutils literal notranslate"><span class="pre">@asyncio.coroutine</span></code>, but this cannot be strictly enforced.</p>
|
||
<p>Coroutines use the <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> syntax introduced in <a class="pep reference internal" href="../pep-0380/" title="PEP 380 – Syntax for Delegating to a Subgenerator">PEP 380</a>,
|
||
instead of the original <code class="docutils literal notranslate"><span class="pre">yield</span></code> syntax.</p>
|
||
<p>The word “coroutine”, like the word “generator”, is used for two
|
||
different (though related) concepts:</p>
|
||
<ul class="simple">
|
||
<li>The function that defines a coroutine (a function definition
|
||
decorated with <code class="docutils literal notranslate"><span class="pre">asyncio.coroutine</span></code>). If disambiguation is needed
|
||
we will call this a <em>coroutine function</em>.</li>
|
||
<li>The object obtained by calling a coroutine function. This object
|
||
represents a computation or an I/O operation (usually a combination)
|
||
that will complete eventually. If disambiguation is needed we will
|
||
call it a <em>coroutine object</em>.</li>
|
||
</ul>
|
||
<p>Things a coroutine can do:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">result</span> <span class="pre">=</span> <span class="pre">yield</span> <span class="pre">from</span> <span class="pre">future</span></code> – suspends the coroutine until the
|
||
future is done, then returns the future’s result, or raises an
|
||
exception, which will be propagated. (If the future is cancelled,
|
||
it will raise a <code class="docutils literal notranslate"><span class="pre">CancelledError</span></code> exception.) Note that tasks are
|
||
futures, and everything said about futures also applies to tasks.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">result</span> <span class="pre">=</span> <span class="pre">yield</span> <span class="pre">from</span> <span class="pre">coroutine</span></code> – wait for another coroutine to
|
||
produce a result (or raise an exception, which will be propagated).
|
||
The <code class="docutils literal notranslate"><span class="pre">coroutine</span></code> expression must be a <em>call</em> to another coroutine.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">return</span> <span class="pre">expression</span></code> – produce a result to the coroutine that is
|
||
waiting for this one using <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">raise</span> <span class="pre">exception</span></code> – raise an exception in the coroutine that is
|
||
waiting for this one using <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code>.</li>
|
||
</ul>
|
||
<p>Calling a coroutine does not start its code running – it is just a
|
||
generator, and the coroutine object returned by the call is really a
|
||
generator object, which doesn’t do anything until you iterate over it.
|
||
In the case of a coroutine object, there are two basic ways to start
|
||
it running: call <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span> <span class="pre">coroutine</span></code> from another coroutine
|
||
(assuming the other coroutine is already running!), or convert it to a
|
||
Task (see below).</p>
|
||
<p>Coroutines (and tasks) can only run when the event loop is running.</p>
|
||
</section>
|
||
<section id="waiting-for-multiple-coroutines">
|
||
<h3><a class="toc-backref" href="#waiting-for-multiple-coroutines" role="doc-backlink">Waiting for Multiple Coroutines</a></h3>
|
||
<p>To wait for multiple coroutines or Futures, two APIs similar to the
|
||
<code class="docutils literal notranslate"><span class="pre">wait()</span></code> and <code class="docutils literal notranslate"><span class="pre">as_completed()</span></code> APIs in the <code class="docutils literal notranslate"><span class="pre">concurrent.futures</span></code>
|
||
package are provided:</p>
|
||
<ul>
|
||
<li><code class="docutils literal notranslate"><span class="pre">asyncio.wait(fs,</span> <span class="pre">timeout=None,</span> <span class="pre">return_when=ALL_COMPLETED)</span></code>. This
|
||
is a coroutine that waits for the Futures or coroutines given by
|
||
<code class="docutils literal notranslate"><span class="pre">fs</span></code> to complete. Coroutine arguments will be wrapped in Tasks
|
||
(see below). This returns a Future whose result on success is a
|
||
tuple of two sets of Futures, <code class="docutils literal notranslate"><span class="pre">(done,</span> <span class="pre">pending)</span></code>, where <code class="docutils literal notranslate"><span class="pre">done</span></code> is
|
||
the set of original Futures (or wrapped coroutines) that are done
|
||
(or cancelled), and <code class="docutils literal notranslate"><span class="pre">pending</span></code> is the rest, i.e. those that are
|
||
still not done (nor cancelled). Note that with the defaults for
|
||
<code class="docutils literal notranslate"><span class="pre">timeout</span></code> and <code class="docutils literal notranslate"><span class="pre">return_when</span></code>, <code class="docutils literal notranslate"><span class="pre">done</span></code> will always be an empty
|
||
list. Optional arguments <code class="docutils literal notranslate"><span class="pre">timeout</span></code> and <code class="docutils literal notranslate"><span class="pre">return_when</span></code> have the
|
||
same meaning and defaults as for <code class="docutils literal notranslate"><span class="pre">concurrent.futures.wait()</span></code>:
|
||
<code class="docutils literal notranslate"><span class="pre">timeout</span></code>, if not <code class="docutils literal notranslate"><span class="pre">None</span></code>, specifies a timeout for the overall
|
||
operation; <code class="docutils literal notranslate"><span class="pre">return_when</span></code>, specifies when to stop. The constants
|
||
<code class="docutils literal notranslate"><span class="pre">FIRST_COMPLETED</span></code>, <code class="docutils literal notranslate"><span class="pre">FIRST_EXCEPTION</span></code>, <code class="docutils literal notranslate"><span class="pre">ALL_COMPLETED</span></code> are
|
||
defined with the same values and the same meanings as in <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a>:<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">ALL_COMPLETED</span></code> (default): Wait until all Futures are done (or
|
||
until the timeout occurs).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">FIRST_COMPLETED</span></code>: Wait until at least one Future is done (or
|
||
until the timeout occurs).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">FIRST_EXCEPTION</span></code>: Wait until at least one Future is done but
|
||
not cancelled with an exception set. (The exclusion of cancelled
|
||
Futures from the condition is surprising, but <a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a> does it
|
||
this way.)</li>
|
||
</ul>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">asyncio.as_completed(fs,</span> <span class="pre">timeout=None)</span></code>. Returns an iterator whose
|
||
values are Futures or coroutines; waiting for successive values
|
||
waits until the next Future or coroutine from the set <code class="docutils literal notranslate"><span class="pre">fs</span></code>
|
||
completes, and returns its result (or raises its exception). The
|
||
optional argument <code class="docutils literal notranslate"><span class="pre">timeout</span></code> has the same meaning and default as it
|
||
does for <code class="docutils literal notranslate"><span class="pre">concurrent.futures.wait()</span></code>: when the timeout occurs, the
|
||
next Future returned by the iterator will raise <code class="docutils literal notranslate"><span class="pre">TimeoutError</span></code>
|
||
when waited for. Example of use:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">as_completed</span><span class="p">(</span><span class="n">fs</span><span class="p">):</span>
|
||
<span class="n">result</span> <span class="o">=</span> <span class="k">yield from</span> <span class="n">f</span> <span class="c1"># May raise an exception.</span>
|
||
<span class="c1"># Use result.</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Note: if you do not wait for the values produced by the iterator,
|
||
your <code class="docutils literal notranslate"><span class="pre">for</span></code> loop may not make progress (since you are not allowing
|
||
other tasks to run).</p>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">asyncio.wait_for(f,</span> <span class="pre">timeout)</span></code>. This is a convenience to wait for
|
||
a single coroutine or Future with a timeout. When a timeout occurs,
|
||
it cancels the task and raises TimeoutError. To avoid the task
|
||
cancellation, wrap it in <code class="docutils literal notranslate"><span class="pre">shield()</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">asyncio.gather(f1,</span> <span class="pre">f2,</span> <span class="pre">...)</span></code>. Returns a Future which waits until
|
||
all arguments (Futures or coroutines) are done and return a list of
|
||
their corresponding results. If one or more of the arguments is
|
||
cancelled or raises an exception, the returned Future is cancelled
|
||
or has its exception set (matching what happened to the first
|
||
argument), and the remaining arguments are left running in the
|
||
background. Cancelling the returned Future does not affect the
|
||
arguments. Note that coroutine arguments are converted to Futures
|
||
using <code class="docutils literal notranslate"><span class="pre">asyncio.async()</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">asyncio.shield(f)</span></code>. Wait for a Future, shielding it from
|
||
cancellation. This returns a Future whose result or exception
|
||
is exactly the same as the argument; however, if the returned
|
||
Future is cancelled, the argument Future is unaffected.<p>A use case for this function would be a coroutine that caches a
|
||
query result for a coroutine that handles a request in an HTTP
|
||
server. When the request is cancelled by the client, we could
|
||
(arguably) want the query-caching coroutine to continue to run, so
|
||
that when the client reconnects, the query result is (hopefully)
|
||
cached. This could be written e.g. as follows:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@asyncio</span><span class="o">.</span><span class="n">coroutine</span>
|
||
<span class="k">def</span> <span class="nf">handle_request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
||
<span class="o">...</span>
|
||
<span class="n">cached_query</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_cache</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">cached_query</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="n">cached_query</span> <span class="o">=</span> <span class="k">yield from</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">shield</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fill_cache</span><span class="p">(</span><span class="o">...</span><span class="p">))</span>
|
||
<span class="o">...</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
<section id="sleeping">
|
||
<h3><a class="toc-backref" href="#sleeping" role="doc-backlink">Sleeping</a></h3>
|
||
<p>The coroutine <code class="docutils literal notranslate"><span class="pre">asyncio.sleep(delay)</span></code> returns after a given time delay.</p>
|
||
</section>
|
||
<section id="tasks">
|
||
<h3><a class="toc-backref" href="#tasks" role="doc-backlink">Tasks</a></h3>
|
||
<p>A Task is an object that manages an independently running coroutine.
|
||
The Task interface is the same as the Future interface, and in fact
|
||
<code class="docutils literal notranslate"><span class="pre">Task</span></code> is a subclass of <code class="docutils literal notranslate"><span class="pre">Future</span></code>. The task becomes done when its
|
||
coroutine returns or raises an exception; if it returns a result, that
|
||
becomes the task’s result, if it raises an exception, that becomes the
|
||
task’s exception.</p>
|
||
<p>Cancelling a task that’s not done yet throws an
|
||
<code class="docutils literal notranslate"><span class="pre">asyncio.CancelledError</span></code> exception into the coroutine. If the
|
||
coroutine doesn’t catch this (or if it re-raises it) the task will be
|
||
marked as cancelled (i.e., <code class="docutils literal notranslate"><span class="pre">cancelled()</span></code> will return <code class="docutils literal notranslate"><span class="pre">True</span></code>); but
|
||
if the coroutine somehow catches and ignores the exception it may
|
||
continue to execute (and <code class="docutils literal notranslate"><span class="pre">cancelled()</span></code> will return <code class="docutils literal notranslate"><span class="pre">False</span></code>).</p>
|
||
<p>Tasks are also useful for interoperating between coroutines and
|
||
callback-based frameworks like Twisted. After converting a coroutine
|
||
into a Task, callbacks can be added to the Task.</p>
|
||
<p>To convert a coroutine into a task, call the coroutine function and
|
||
pass the resulting coroutine object to the <code class="docutils literal notranslate"><span class="pre">loop.create_task()</span></code>
|
||
method. You may also use <code class="docutils literal notranslate"><span class="pre">asyncio.ensure_future()</span></code> for this purpose.</p>
|
||
<p>You may ask, why not automatically convert all coroutines to Tasks?
|
||
The <code class="docutils literal notranslate"><span class="pre">@asyncio.coroutine</span></code> decorator could do this. However, this would
|
||
slow things down considerably in the case where one coroutine calls
|
||
another (and so on), as switching to a “bare” coroutine has much less
|
||
overhead than switching to a Task.</p>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">Task</span></code> class is derived from <code class="docutils literal notranslate"><span class="pre">Future</span></code> adding new methods:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">current_task(loop=None)</span></code>. A <em>class method</em> returning the
|
||
currently running task in an event loop. If <em>loop</em> is <code class="docutils literal notranslate"><span class="pre">None</span></code> the
|
||
method returns the current task for the default loop. Every
|
||
coroutine is executed inside a <em>task context</em>, either a <code class="docutils literal notranslate"><span class="pre">Task</span></code>
|
||
created using <code class="docutils literal notranslate"><span class="pre">ensure_future()</span></code> or <code class="docutils literal notranslate"><span class="pre">loop.create_task()</span></code>, or by
|
||
being called from another coroutine using <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> or
|
||
<code class="docutils literal notranslate"><span class="pre">await</span></code>. This method returns <code class="docutils literal notranslate"><span class="pre">None</span></code> when called <em>outside</em> a
|
||
coroutine, e.g. in a callback scheduled using <code class="docutils literal notranslate"><span class="pre">loop.call_later()</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">all_tasks(loop=None)</span></code>. A <em>class method</em> returning a set of all
|
||
active tasks for the loop. This uses the default loop if <em>loop</em> is
|
||
<code class="docutils literal notranslate"><span class="pre">None</span></code>.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="the-scheduler">
|
||
<h3><a class="toc-backref" href="#the-scheduler" role="doc-backlink">The Scheduler</a></h3>
|
||
<p>The scheduler has no public interface. You interact with it by using
|
||
<code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span> <span class="pre">future</span></code> and <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span> <span class="pre">task</span></code>. In fact, there is no
|
||
single object representing the scheduler – its behavior is
|
||
implemented by the <code class="docutils literal notranslate"><span class="pre">Task</span></code> and <code class="docutils literal notranslate"><span class="pre">Future</span></code> classes using only the
|
||
public interface of the event loop, so it will work with third-party
|
||
event loop implementations, too.</p>
|
||
</section>
|
||
<section id="convenience-utilities">
|
||
<h3><a class="toc-backref" href="#convenience-utilities" role="doc-backlink">Convenience Utilities</a></h3>
|
||
<p>A few functions and classes are provided to simplify the writing of
|
||
basic stream-based clients and servers, such as FTP or HTTP. These
|
||
are:</p>
|
||
<ul>
|
||
<li><code class="docutils literal notranslate"><span class="pre">asyncio.open_connection(host,</span> <span class="pre">port)</span></code>: A wrapper for
|
||
<code class="docutils literal notranslate"><span class="pre">EventLoop.create_connection()</span></code> that does not require you to
|
||
provide a <code class="docutils literal notranslate"><span class="pre">Protocol</span></code> factory or class. This is a coroutine that
|
||
returns a <code class="docutils literal notranslate"><span class="pre">(reader,</span> <span class="pre">writer)</span></code> pair, where <code class="docutils literal notranslate"><span class="pre">reader</span></code> is an instance
|
||
of <code class="docutils literal notranslate"><span class="pre">StreamReader</span></code> and <code class="docutils literal notranslate"><span class="pre">writer</span></code> is an instance of
|
||
<code class="docutils literal notranslate"><span class="pre">StreamWriter</span></code> (both described below).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">asyncio.start_server(client_connected_cb,</span> <span class="pre">host,</span> <span class="pre">port)</span></code>: A wrapper
|
||
for <code class="docutils literal notranslate"><span class="pre">EventLoop.create_server()</span></code> that takes a simple callback
|
||
function rather than a <code class="docutils literal notranslate"><span class="pre">Protocol</span></code> factory or class. This is a
|
||
coroutine that returns a <code class="docutils literal notranslate"><span class="pre">Server</span></code> object just as
|
||
<code class="docutils literal notranslate"><span class="pre">create_server()</span></code> does. Each time a client connection is
|
||
accepted, <code class="docutils literal notranslate"><span class="pre">client_connected_cb(reader,</span> <span class="pre">writer)</span></code> is called, where
|
||
<code class="docutils literal notranslate"><span class="pre">reader</span></code> is an instance of <code class="docutils literal notranslate"><span class="pre">StreamReader</span></code> and <code class="docutils literal notranslate"><span class="pre">writer</span></code> is an
|
||
instance of <code class="docutils literal notranslate"><span class="pre">StreamWriter</span></code> (both described below). If the result
|
||
returned by <code class="docutils literal notranslate"><span class="pre">client_connected_cb()</span></code> is a coroutine, it is
|
||
automatically wrapped in a <code class="docutils literal notranslate"><span class="pre">Task</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">StreamReader</span></code>: A class offering an interface not unlike that of a
|
||
read-only binary stream, except that the various reading methods are
|
||
coroutines. It is normally driven by a <code class="docutils literal notranslate"><span class="pre">StreamReaderProtocol</span></code>
|
||
instance. Note that there should be only one reader. The interface
|
||
for the reader is:<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">readline()</span></code>: A coroutine that reads a string of bytes
|
||
representing a line of text ending in <code class="docutils literal notranslate"><span class="pre">'\n'</span></code>, or until the end
|
||
of the stream, whichever comes first.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">read(n)</span></code>: A coroutine that reads up to <code class="docutils literal notranslate"><span class="pre">n</span></code> bytes. If <code class="docutils literal notranslate"><span class="pre">n</span></code>
|
||
is omitted or negative, it reads until the end of the stream.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">readexactly(n)</span></code>: A coroutine that reads exactly <code class="docutils literal notranslate"><span class="pre">n</span></code> bytes, or
|
||
until the end of the stream, whichever comes first.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">exception()</span></code>: Return the exception that has been set on the
|
||
stream using <code class="docutils literal notranslate"><span class="pre">set_exception()</span></code>, or None if no exception is set.</li>
|
||
</ul>
|
||
<p>The interface for the driver is:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">feed_data(data)</span></code>: Append <code class="docutils literal notranslate"><span class="pre">data</span></code> (a <code class="docutils literal notranslate"><span class="pre">bytes</span></code> object) to the
|
||
internal buffer. This unblocks a blocked reading coroutine if it
|
||
provides sufficient data to fulfill the reader’s contract.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">feed_eof()</span></code>: Signal the end of the buffer. This unblocks a
|
||
blocked reading coroutine. No more data should be fed to the
|
||
reader after this call.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">set_exception(exc)</span></code>: Set an exception on the stream. All
|
||
subsequent reading methods will raise this exception. No more
|
||
data should be fed to the reader after this call.</li>
|
||
</ul>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">StreamWriter</span></code>: A class offering an interface not unlike that of a
|
||
write-only binary stream. It wraps a transport. The interface is
|
||
an extended subset of the transport interface: the following methods
|
||
behave the same as the corresponding transport methods: <code class="docutils literal notranslate"><span class="pre">write()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">writelines()</span></code>, <code class="docutils literal notranslate"><span class="pre">write_eof()</span></code>, <code class="docutils literal notranslate"><span class="pre">can_write_eof()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">get_extra_info()</span></code>, <code class="docutils literal notranslate"><span class="pre">close()</span></code>. Note that the writing methods
|
||
are _not_ coroutines (this is the same as for transports, but
|
||
different from the <code class="docutils literal notranslate"><span class="pre">StreamReader</span></code> class). The following method is
|
||
in addition to the transport interface:<ul>
|
||
<li><code class="docutils literal notranslate"><span class="pre">drain()</span></code>: This should be called with <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> after
|
||
writing significant data, for the purpose of flow control. The
|
||
intended use is like this:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">writer</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
||
<span class="k">yield from</span> <span class="n">writer</span><span class="o">.</span><span class="n">drain</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Note that this is not technically a coroutine: it returns either a
|
||
Future or an empty tuple (both can be passed to <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code>).
|
||
Use of this method is optional. However, when it is not used, the
|
||
internal buffer of the transport underlying the <code class="docutils literal notranslate"><span class="pre">StreamWriter</span></code>
|
||
may fill up with all data that was ever written to the writer. If
|
||
an app does not have a strict limit on how much data it writes, it
|
||
_should_ call <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span> <span class="pre">drain()</span></code> occasionally to avoid filling
|
||
up the transport buffer.</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">StreamReaderProtocol</span></code>: A protocol implementation used as an
|
||
adapter between the bidirectional stream transport/protocol
|
||
interface and the <code class="docutils literal notranslate"><span class="pre">StreamReader</span></code> and <code class="docutils literal notranslate"><span class="pre">StreamWriter</span></code> classes. It
|
||
acts as a driver for a specific <code class="docutils literal notranslate"><span class="pre">StreamReader</span></code> instance, calling
|
||
its methods <code class="docutils literal notranslate"><span class="pre">feed_data()</span></code>, <code class="docutils literal notranslate"><span class="pre">feed_eof()</span></code>, and <code class="docutils literal notranslate"><span class="pre">set_exception()</span></code>
|
||
in response to various protocol callbacks. It also controls the
|
||
behavior of the <code class="docutils literal notranslate"><span class="pre">drain()</span></code> method of the <code class="docutils literal notranslate"><span class="pre">StreamWriter</span></code> instance.</li>
|
||
</ul>
|
||
</section>
|
||
</section>
|
||
<section id="synchronization">
|
||
<h2><a class="toc-backref" href="#synchronization" role="doc-backlink">Synchronization</a></h2>
|
||
<p>Locks, events, conditions and semaphores modeled after those in the
|
||
<code class="docutils literal notranslate"><span class="pre">threading</span></code> module are implemented and can be accessed by importing
|
||
the <code class="docutils literal notranslate"><span class="pre">asyncio.locks</span></code> submodule. Queues modeled after those in the
|
||
<code class="docutils literal notranslate"><span class="pre">queue</span></code> module are implemented and can be accessed by importing the
|
||
<code class="docutils literal notranslate"><span class="pre">asyncio.queues</span></code> submodule.</p>
|
||
<p>In general these have a close correspondence to their threaded
|
||
counterparts, however, blocking methods (e.g. <code class="docutils literal notranslate"><span class="pre">acquire()</span></code> on locks,
|
||
<code class="docutils literal notranslate"><span class="pre">put()</span></code> and <code class="docutils literal notranslate"><span class="pre">get()</span></code> on queues) are coroutines, and timeout
|
||
parameters are not provided (you can use <code class="docutils literal notranslate"><span class="pre">asyncio.wait_for()</span></code> to add
|
||
a timeout to a blocking call, however).</p>
|
||
<p>The docstrings in the modules provide more complete documentation.</p>
|
||
<section id="locks">
|
||
<h3><a class="toc-backref" href="#locks" role="doc-backlink">Locks</a></h3>
|
||
<p>The following classes are provided by <code class="docutils literal notranslate"><span class="pre">asyncio.locks</span></code>. For all
|
||
these except <code class="docutils literal notranslate"><span class="pre">Event</span></code>, the <code class="docutils literal notranslate"><span class="pre">with</span></code> statement may be used in
|
||
combination with <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> to acquire the lock and ensure that
|
||
the lock is released regardless of how the <code class="docutils literal notranslate"><span class="pre">with</span></code> block is left, as
|
||
follows:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="p">(</span><span class="k">yield from</span> <span class="n">my_lock</span><span class="p">):</span>
|
||
<span class="o">...</span>
|
||
</pre></div>
|
||
</div>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">Lock</span></code>: a basic mutex, with methods <code class="docutils literal notranslate"><span class="pre">acquire()</span></code> (a coroutine),
|
||
<code class="docutils literal notranslate"><span class="pre">locked()</span></code>, and <code class="docutils literal notranslate"><span class="pre">release()</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">Event</span></code>: an event variable, with methods <code class="docutils literal notranslate"><span class="pre">wait()</span></code> (a coroutine),
|
||
<code class="docutils literal notranslate"><span class="pre">set()</span></code>, <code class="docutils literal notranslate"><span class="pre">clear()</span></code>, and <code class="docutils literal notranslate"><span class="pre">is_set()</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">Condition</span></code>: a condition variable, with methods <code class="docutils literal notranslate"><span class="pre">acquire()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">wait()</span></code>, <code class="docutils literal notranslate"><span class="pre">wait_for(predicate)</span></code> (all three coroutines),
|
||
<code class="docutils literal notranslate"><span class="pre">locked()</span></code>, <code class="docutils literal notranslate"><span class="pre">release()</span></code>, <code class="docutils literal notranslate"><span class="pre">notify()</span></code>, and <code class="docutils literal notranslate"><span class="pre">notify_all()</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">Semaphore</span></code>: a semaphore, with methods <code class="docutils literal notranslate"><span class="pre">acquire()</span></code> (a
|
||
coroutine), <code class="docutils literal notranslate"><span class="pre">locked()</span></code>, and <code class="docutils literal notranslate"><span class="pre">release()</span></code>. The constructor
|
||
argument is the initial value (default <code class="docutils literal notranslate"><span class="pre">1</span></code>).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">BoundedSemaphore</span></code>: a bounded semaphore; this is similar to
|
||
<code class="docutils literal notranslate"><span class="pre">Semaphore</span></code> but the initial value is also the maximum value.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="queues">
|
||
<h3><a class="toc-backref" href="#queues" role="doc-backlink">Queues</a></h3>
|
||
<p>The following classes and exceptions are provided by <code class="docutils literal notranslate"><span class="pre">asyncio.queues</span></code>.</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">Queue</span></code>: a standard queue, with methods <code class="docutils literal notranslate"><span class="pre">get()</span></code>, <code class="docutils literal notranslate"><span class="pre">put()</span></code> (both
|
||
coroutines), <code class="docutils literal notranslate"><span class="pre">get_nowait()</span></code>, <code class="docutils literal notranslate"><span class="pre">put_nowait()</span></code>, <code class="docutils literal notranslate"><span class="pre">empty()</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">full()</span></code>, <code class="docutils literal notranslate"><span class="pre">qsize()</span></code>, and <code class="docutils literal notranslate"><span class="pre">maxsize()</span></code>.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">PriorityQueue</span></code>: a subclass of <code class="docutils literal notranslate"><span class="pre">Queue</span></code> that retrieves entries
|
||
in priority order (lowest first).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">LifoQueue</span></code>: a subclass of <code class="docutils literal notranslate"><span class="pre">Queue</span></code> that retrieves the most
|
||
recently added entries first.</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">JoinableQueue</span></code>: a subclass of <code class="docutils literal notranslate"><span class="pre">Queue</span></code> with <code class="docutils literal notranslate"><span class="pre">task_done()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">join()</span></code> methods (the latter a coroutine).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">Empty</span></code>, <code class="docutils literal notranslate"><span class="pre">Full</span></code>: exceptions raised when <code class="docutils literal notranslate"><span class="pre">get_nowait()</span></code> or
|
||
<code class="docutils literal notranslate"><span class="pre">put_nowait()</span></code> is called on a queue that is empty or full,
|
||
respectively.</li>
|
||
</ul>
|
||
</section>
|
||
</section>
|
||
<section id="miscellaneous">
|
||
<h2><a class="toc-backref" href="#miscellaneous" role="doc-backlink">Miscellaneous</a></h2>
|
||
<section id="logging">
|
||
<h3><a class="toc-backref" href="#logging" role="doc-backlink">Logging</a></h3>
|
||
<p>All logging performed by the <code class="docutils literal notranslate"><span class="pre">asyncio</span></code> package uses a single
|
||
<code class="docutils literal notranslate"><span class="pre">logging.Logger</span></code> object, <code class="docutils literal notranslate"><span class="pre">asyncio.logger</span></code>. To customize logging
|
||
you can use the standard <code class="docutils literal notranslate"><span class="pre">Logger</span></code> API on this object. (Do not
|
||
replace the object though.)</p>
|
||
</section>
|
||
<section id="sigchld-handling-on-unix">
|
||
<h3><a class="toc-backref" href="#sigchld-handling-on-unix" role="doc-backlink"><code class="docutils literal notranslate"><span class="pre">SIGCHLD</span></code> handling on UNIX</a></h3>
|
||
<p>Efficient implementation of the <code class="docutils literal notranslate"><span class="pre">process_exited()</span></code> method on
|
||
subprocess protocols requires a <code class="docutils literal notranslate"><span class="pre">SIGCHLD</span></code> signal handler. However,
|
||
signal handlers can only be set on the event loop associated with the
|
||
main thread. In order to support spawning subprocesses from event
|
||
loops running in other threads, a mechanism exists to allow sharing a
|
||
<code class="docutils literal notranslate"><span class="pre">SIGCHLD</span></code> handler between multiple event loops. There are two
|
||
additional functions, <code class="docutils literal notranslate"><span class="pre">asyncio.get_child_watcher()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">asyncio.set_child_watcher()</span></code>, and corresponding methods on the
|
||
event loop policy.</p>
|
||
<p>There are two child watcher implementation classes,
|
||
<code class="docutils literal notranslate"><span class="pre">FastChildWatcher</span></code> and <code class="docutils literal notranslate"><span class="pre">SafeChildWatcher</span></code>. Both use <code class="docutils literal notranslate"><span class="pre">SIGCHLD</span></code>.
|
||
The <code class="docutils literal notranslate"><span class="pre">SafeChildWatcher</span></code> class is used by default; it is inefficient
|
||
when many subprocesses exist simultaneously. The <code class="docutils literal notranslate"><span class="pre">FastChildWatcher</span></code>
|
||
class is efficient, but it may interfere with other code (either C
|
||
code or Python code) that spawns subprocesses without using an
|
||
<code class="docutils literal notranslate"><span class="pre">asyncio</span></code> event loop. If you are sure you are not using other code
|
||
that spawns subprocesses, to use the fast implementation, run the
|
||
following in your main thread:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">watcher</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">FastChildWatcher</span><span class="p">()</span>
|
||
<span class="n">asyncio</span><span class="o">.</span><span class="n">set_child_watcher</span><span class="p">(</span><span class="n">watcher</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
<section id="wish-list">
|
||
<h2><a class="toc-backref" href="#wish-list" role="doc-backlink">Wish List</a></h2>
|
||
<p>(There is agreement that these features are desirable, but no
|
||
implementation was available when Python 3.4 beta 1 was released, and
|
||
the feature freeze for the rest of the Python 3.4 release cycle
|
||
prohibits adding them in this late stage. However, they will
|
||
hopefully be added in Python 3.5, and perhaps earlier in the PyPI
|
||
distribution.)</p>
|
||
<ul class="simple">
|
||
<li>Support a “start TLS” operation to upgrade a TCP socket to SSL/TLS.</li>
|
||
</ul>
|
||
<p>Former wish list items that have since been implemented (but aren’t
|
||
specified by the PEP):</p>
|
||
<ul class="simple">
|
||
<li>UNIX domain sockets.</li>
|
||
<li>A per-loop error handling callback.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="open-issues">
|
||
<h2><a class="toc-backref" href="#open-issues" role="doc-backlink">Open Issues</a></h2>
|
||
<p>(Note that these have been resolved de facto in favor of the status
|
||
quo by the acceptance of the PEP. However, the PEP’s provisional
|
||
status allows revising these decisions for Python 3.5.)</p>
|
||
<ul class="simple">
|
||
<li>Why do <code class="docutils literal notranslate"><span class="pre">create_connection()</span></code> and <code class="docutils literal notranslate"><span class="pre">create_datagram_endpoint()</span></code>
|
||
have a <code class="docutils literal notranslate"><span class="pre">proto</span></code> argument but not <code class="docutils literal notranslate"><span class="pre">create_server()</span></code>? And why are
|
||
the family, flag, proto arguments for <code class="docutils literal notranslate"><span class="pre">getaddrinfo()</span></code> sometimes
|
||
zero and sometimes named constants (whose value is also zero)?</li>
|
||
<li>Do we need another inquiry method to tell whether the loop is in the
|
||
process of stopping?</li>
|
||
<li>A fuller public API for Handle? What’s the use case?</li>
|
||
<li>A debugging API? E.g. something that logs a lot of stuff, or logs
|
||
unusual conditions (like queues filling up faster than they drain)
|
||
or even callbacks taking too much time…</li>
|
||
<li>Do we need introspection APIs? E.g. asking for the read callback
|
||
given a file descriptor. Or when the next scheduled call is. Or
|
||
the list of file descriptors registered with callbacks. Right now
|
||
these all require using internals.</li>
|
||
<li>Do we need more socket I/O methods, e.g. <code class="docutils literal notranslate"><span class="pre">sock_sendto()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">sock_recvfrom()</span></code>, and perhaps others like <code class="docutils literal notranslate"><span class="pre">pipe_read()</span></code>?
|
||
I guess users can write their own (it’s not rocket science).</li>
|
||
<li>We may need APIs to control various timeouts. E.g. we may want to
|
||
limit the time spent in DNS resolution, connecting, ssl/tls handshake,
|
||
idle connection, close/shutdown, even per session. Possibly it’s
|
||
sufficient to add <code class="docutils literal notranslate"><span class="pre">timeout</span></code> keyword arguments to some methods,
|
||
and other timeouts can probably be implemented by clever use of
|
||
<code class="docutils literal notranslate"><span class="pre">call_later()</span></code> and <code class="docutils literal notranslate"><span class="pre">Task.cancel()</span></code>. But it’s possible that some
|
||
operations need default timeouts, and we may want to change the
|
||
default for a specific operation globally (i.e., per event loop).</li>
|
||
</ul>
|
||
</section>
|
||
<section id="references">
|
||
<h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2>
|
||
<ul class="simple">
|
||
<li><a class="pep reference internal" href="../pep-0492/" title="PEP 492 – Coroutines with async and await syntax">PEP 492</a> describes the semantics of <code class="docutils literal notranslate"><span class="pre">async/await</span></code>.</li>
|
||
<li><a class="pep reference internal" href="../pep-0380/" title="PEP 380 – Syntax for Delegating to a Subgenerator">PEP 380</a> describes the semantics of <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code>.</li>
|
||
<li>Greg Ewing’s <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> tutorials:
|
||
<a class="reference external" href="http://www.cosc.canterbury.ac.nz/greg.ewing/python/yield-from/yield_from.html">http://www.cosc.canterbury.ac.nz/greg.ewing/python/yield-from/yield_from.html</a></li>
|
||
<li><a class="pep reference internal" href="../pep-3148/" title="PEP 3148 – futures - execute computations asynchronously">PEP 3148</a> describes <code class="docutils literal notranslate"><span class="pre">concurrent.futures.Future</span></code>.</li>
|
||
<li><a class="pep reference internal" href="../pep-3153/" title="PEP 3153 – Asynchronous IO support">PEP 3153</a>, while rejected, has a good write-up explaining the need
|
||
to separate transports and protocols.</li>
|
||
<li><a class="pep reference internal" href="../pep-0418/" title="PEP 418 – Add monotonic time, performance counter, and process time functions">PEP 418</a> discusses the issues of timekeeping.</li>
|
||
<li>Tulip repo: <a class="reference external" href="http://code.google.com/p/tulip/">http://code.google.com/p/tulip/</a></li>
|
||
<li>PyPI: the Python Package Index at <a class="reference external" href="http://pypi.python.org/">http://pypi.python.org/</a></li>
|
||
<li>Alyssa Coghlan wrote a nice blog post with some background, thoughts
|
||
about different approaches to async I/O, gevent, and how to use
|
||
futures with constructs like <code class="docutils literal notranslate"><span class="pre">while</span></code>, <code class="docutils literal notranslate"><span class="pre">for</span></code> and <code class="docutils literal notranslate"><span class="pre">with</span></code>:
|
||
<a class="reference external" href="http://python-notes.boredomandlaziness.org/en/latest/pep_ideas/async_programming.html">http://python-notes.boredomandlaziness.org/en/latest/pep_ideas/async_programming.html</a></li>
|
||
<li>TBD: references to the relevant parts of Twisted, Tornado, ZeroMQ,
|
||
pyftpdlib, libevent, libev, pyev, libuv, wattle, and so on.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="acknowledgments">
|
||
<h2><a class="toc-backref" href="#acknowledgments" role="doc-backlink">Acknowledgments</a></h2>
|
||
<p>Apart from <a class="pep reference internal" href="../pep-3153/" title="PEP 3153 – Asynchronous IO support">PEP 3153</a>, influences include <a class="pep reference internal" href="../pep-0380/" title="PEP 380 – Syntax for Delegating to a Subgenerator">PEP 380</a> and Greg Ewing’s
|
||
tutorial for <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code>, Twisted, Tornado, ZeroMQ, pyftpdlib, and
|
||
wattle (Steve Dower’s counter-proposal). My previous work on
|
||
asynchronous support in the NDB library for Google App Engine provided
|
||
an important starting point.</p>
|
||
<p>I am grateful for the numerous discussions on python-ideas from
|
||
September through December 2012, and many more on python-tulip since
|
||
then; a Skype session with Steve Dower and Dino Viehland; email
|
||
exchanges with and a visit by Ben Darnell; an audience with Niels
|
||
Provos (original author of libevent); and in-person meetings (as well
|
||
as frequent email exchanges) with several Twisted developers,
|
||
including Glyph, Brian Warner, David Reid, and Duncan McGreggor.</p>
|
||
<p>Contributors to the implementation include
|
||
Eli Bendersky,
|
||
Gustavo Carneiro (Gambit Research),
|
||
Saúl Ibarra Corretgé,
|
||
Geert Jansen,
|
||
A. Jesse Jiryu Davis,
|
||
Nikolay Kim,
|
||
Charles-François Natali,
|
||
Richard Oudkerk,
|
||
Antoine Pitrou,
|
||
Giampaolo Rodolá,
|
||
Andrew Svetlov,
|
||
and many others who submitted bugs and/or fixes.</p>
|
||
<p>I thank Antoine Pitrou for his feedback in his role of official PEP
|
||
BDFL.</p>
|
||
</section>
|
||
<section id="copyright">
|
||
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
|
||
<p>This document has been placed in the public domain.</p>
|
||
</section>
|
||
</section>
|
||
<hr class="docutils" />
|
||
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-3156.rst">https://github.com/python/peps/blob/main/peps/pep-3156.rst</a></p>
|
||
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-3156.rst">2024-03-21 03:48:43 GMT</a></p>
|
||
|
||
</article>
|
||
<nav id="pep-sidebar">
|
||
<h2>Contents</h2>
|
||
<ul>
|
||
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
||
<li><a class="reference internal" href="#introduction">Introduction</a><ul>
|
||
<li><a class="reference internal" href="#status">Status</a></li>
|
||
<li><a class="reference internal" href="#dependencies">Dependencies</a></li>
|
||
<li><a class="reference internal" href="#module-namespace">Module Namespace</a></li>
|
||
<li><a class="reference internal" href="#interoperability">Interoperability</a></li>
|
||
<li><a class="reference internal" href="#transports-and-protocols">Transports and Protocols</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#event-loop-interface-specification">Event Loop Interface Specification</a><ul>
|
||
<li><a class="reference internal" href="#event-loop-policy-getting-and-setting-the-current-event-loop">Event Loop Policy: Getting and Setting the Current Event Loop</a><ul>
|
||
<li><a class="reference internal" href="#passing-an-event-loop-around-explicitly">Passing an Event Loop Around Explicitly</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#specifying-times">Specifying Times</a></li>
|
||
<li><a class="reference internal" href="#embedded-event-loops">Embedded Event Loops</a></li>
|
||
<li><a class="reference internal" href="#event-loop-classes">Event Loop Classes</a></li>
|
||
<li><a class="reference internal" href="#event-loop-methods-overview">Event Loop Methods Overview</a></li>
|
||
<li><a class="reference internal" href="#event-loop-methods">Event Loop Methods</a><ul>
|
||
<li><a class="reference internal" href="#starting-stopping-and-closing">Starting, Stopping and Closing</a></li>
|
||
<li><a class="reference internal" href="#basic-callbacks">Basic Callbacks</a></li>
|
||
<li><a class="reference internal" href="#thread-interaction">Thread interaction</a></li>
|
||
<li><a class="reference internal" href="#internet-name-lookups">Internet name lookups</a></li>
|
||
<li><a class="reference internal" href="#internet-connections">Internet connections</a></li>
|
||
<li><a class="reference internal" href="#wrapped-socket-methods">Wrapped Socket Methods</a></li>
|
||
<li><a class="reference internal" href="#i-o-callbacks">I/O Callbacks</a></li>
|
||
<li><a class="reference internal" href="#pipes-and-subprocesses">Pipes and Subprocesses</a></li>
|
||
<li><a class="reference internal" href="#signal-callbacks">Signal callbacks</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#mutual-exclusion-of-callbacks">Mutual Exclusion of Callbacks</a></li>
|
||
<li><a class="reference internal" href="#exceptions">Exceptions</a></li>
|
||
<li><a class="reference internal" href="#debug-mode">Debug Mode</a></li>
|
||
<li><a class="reference internal" href="#handles">Handles</a></li>
|
||
<li><a class="reference internal" href="#servers">Servers</a></li>
|
||
<li><a class="reference internal" href="#futures">Futures</a></li>
|
||
<li><a class="reference internal" href="#transports">Transports</a><ul>
|
||
<li><a class="reference internal" href="#methods-for-all-transports">Methods For All Transports</a></li>
|
||
<li><a class="reference internal" href="#bidirectional-stream-transports">Bidirectional Stream Transports</a></li>
|
||
<li><a class="reference internal" href="#unidirectional-stream-transports">Unidirectional Stream Transports</a></li>
|
||
<li><a class="reference internal" href="#datagram-transports">Datagram Transports</a></li>
|
||
<li><a class="reference internal" href="#subprocess-transports">Subprocess Transports</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#protocols">Protocols</a><ul>
|
||
<li><a class="reference internal" href="#stream-protocols">Stream Protocols</a></li>
|
||
<li><a class="reference internal" href="#datagram-protocols">Datagram Protocols</a></li>
|
||
<li><a class="reference internal" href="#subprocess-protocol">Subprocess Protocol</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#callback-style">Callback Style</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#coroutines-and-the-scheduler">Coroutines and the Scheduler</a><ul>
|
||
<li><a class="reference internal" href="#coroutines">Coroutines</a></li>
|
||
<li><a class="reference internal" href="#waiting-for-multiple-coroutines">Waiting for Multiple Coroutines</a></li>
|
||
<li><a class="reference internal" href="#sleeping">Sleeping</a></li>
|
||
<li><a class="reference internal" href="#tasks">Tasks</a></li>
|
||
<li><a class="reference internal" href="#the-scheduler">The Scheduler</a></li>
|
||
<li><a class="reference internal" href="#convenience-utilities">Convenience Utilities</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#synchronization">Synchronization</a><ul>
|
||
<li><a class="reference internal" href="#locks">Locks</a></li>
|
||
<li><a class="reference internal" href="#queues">Queues</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#miscellaneous">Miscellaneous</a><ul>
|
||
<li><a class="reference internal" href="#logging">Logging</a></li>
|
||
<li><a class="reference internal" href="#sigchld-handling-on-unix"><code class="docutils literal notranslate"><span class="pre">SIGCHLD</span></code> handling on UNIX</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#wish-list">Wish List</a></li>
|
||
<li><a class="reference internal" href="#open-issues">Open Issues</a></li>
|
||
<li><a class="reference internal" href="#references">References</a></li>
|
||
<li><a class="reference internal" href="#acknowledgments">Acknowledgments</a></li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
</ul>
|
||
|
||
<br>
|
||
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-3156.rst">Page Source (GitHub)</a>
|
||
</nav>
|
||
</section>
|
||
<script src="../_static/colour_scheme.js"></script>
|
||
<script src="../_static/wrap_tables.js"></script>
|
||
<script src="../_static/sticky_banner.js"></script>
|
||
</body>
|
||
</html> |