[Python-checkins] peps: Took care of a few TODOs in Tulip PEP.

guido.van.rossum python-checkins at python.org
Mon Nov 25 07:43:42 CET 2013


http://hg.python.org/peps/rev/b153272def9b
changeset:   5320:b153272def9b
user:        Guido van Rossum <guido at dropbox.com>
date:        Sun Nov 24 22:43:36 2013 -0800
summary:
  Took care of a few TODOs in Tulip PEP.

files:
  pep-3156.txt |  139 ++++++++++++++++++++++++++++++++++----
  1 files changed, 123 insertions(+), 16 deletions(-)


diff --git a/pep-3156.txt b/pep-3156.txt
--- a/pep-3156.txt
+++ b/pep-3156.txt
@@ -286,6 +286,25 @@
 ``DefaultEventLoopPolicy``.  The current event loop policy object can
 be retrieved by calling ``get_event_loop_policy()``.
 
+Passing an Event Loop Around Explicitly
+'''''''''''''''''''''''''''''''''''''''
+
+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 ``loop``.  If
+this argument is ``None`` or unspecified, such APIs will call
+``get_event_loop()`` to get the default event loop, but if the
+``loop`` 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, ``Future(loop=my_loop)`` will create a Future tied
+to the event loop ``my_loop``.  When the default current event is
+``None``, the ``loop`` keyword argument is effectively mandatory.
+
+Note that an explicitly passed event loop must still belong to the
+current thread; the ``loop`` keyword argument does not magically
+change the constraints on how an event loop can be used.
+
 Specifying Times
 ----------------
 
@@ -967,6 +986,7 @@
   nothing and return ``False``.  Otherwise, this attempts to cancel
   the Future and returns ``True``.  If the the cancellation attempt is
   successful, eventually the Future's state will change to cancelled
+  (so that ``cancelled()`` will return ``True``)
   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.
@@ -1583,6 +1603,21 @@
   is exactly the same as the argument; however, if the returned
   Future is cancelled, the argument Future is unaffected.
 
+  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::
+
+    @asyncio.coroutine
+    def handle_request(self, request):
+        ...
+        cached_query = self.get_cache(...)
+        if cached_query is None:
+            cached_query = yield from asyncio.shield(self.fill_cache(...))
+        ...
+
 Sleeping
 --------
 
@@ -1601,8 +1636,9 @@
 Cancelling a task that's not done yet throws an
 ``asyncio.CancelledError`` exception into the coroutine.  If the
 coroutine doesn't catch this (or if it re-raises it) the task will be
-marked as cancelled; but if the coroutine somehow catches and ignores
-the exception it may continue to execute.
+marked as cancelled (i.e., ``cancelled()`` will return ``True``; but
+if the coroutine somehow catches and ignores the exception it may
+continue to execute (and ``cancelled()`` will return ``False``.
 
 Tasks are also useful for interoperating between coroutines and
 callback-based frameworks like Twisted.  After converting a coroutine
@@ -1645,31 +1681,98 @@
 off the coroutine when ``connection_made()`` is called.
 
 
+Synchronization
+===============
+
+Locks, events, conditions and semaphores modeled after those in the
+``threading`` module are implemented and can be accessed by importing
+the ``asyncio.locks`` submodule.  Queus modeled after those in the
+``queue`` module are implemented and can be accessed by importing the
+``asyncio.queues`` submodule.
+
+In general these have a close correspondence to their threaded
+counterparts, however, blocking methods (e.g. ``aqcuire()`` on locks,
+``put()`` and ``get()`` on queues) are coroutines, and timeout
+parameters are not provided (you can use ``asyncio.wait_for()`` to add
+a timeout to a blocking call, however).
+
+The docstrings in the modules provide more complete documentation.
+
+Locks
+-----
+
+The following classes are provided by ``asyncio.locks``.  For all
+these except ``Event``, the ``with`` statement may be used in
+combination with ``yield from`` to acquire the lock and ensure that
+the lock is released regardless of how the ``with`` block is left, as
+follows::
+
+    with (yield from my_lock):
+        ...
+
+
+- ``Lock``: a basic mutex, with methods ``acquire()`` (a coroutine),
+  ``locked()``, and ``release()``.
+
+- ``Event``: an event variable, with methods ``wait()`` (a coroutine),
+  ``set()``, ``clear()``, and ``is_set()``.
+
+- ``Condition``: a condition variable, with methods ``acquire()``,
+  ``wait()``, ``wait_for(predicate)`` (all three coroutines),
+  ``locked()``, ``release()``, ``notify()``, and ``notify_all()``.
+
+- ``Semaphore``: a semaphore, with methods ``acquire()`` (a
+  coroutine), ``locked()``, and ``release()``.  The constructor
+  argument is the initial value (default ``1``).
+
+- ``BoundedSemaphore``: a bounded semaphore; this is similar to
+  ``Semaphore`` but the initial value is also the maximum value.
+
+Queues
+------
+
+The following classes and exceptions are provided by ``asyncio.queues``.
+
+- ``Queue``: a standard queue, with methods ``get()``, ``put()`` (both
+  coroutines), ``get_nowait()``, ''put_nowait()'', ``empty()``,
+  ``full()``, ``qsize()``, and ``maxsize()``.
+
+- ``PriorityQueue``: a subclass of ``Queue`` that retrieves entries
+  in priority order (lowest first).
+
+- ``LifoQueue``: a aubclass of ``Queue`` that retrieves the most
+  recently added entries first.
+
+- ``JoinableQueue``: a subclass of ``Queue`` with ``task_done()`` and
+  ``join()`` methods (the latter a coroutine).
+
+- ``Empty``, ``Full``: exceptions raised when ``get_nowait()`` or
+  ``put_nowait()`` is called on a queue that is empty or full,
+  respectively.
+
+
 TO DO
 =====
 
-- Document cancellation in more detail.
+- Document ``StreamReader``, ``StreamWriter``, ``open_connection()``,
+  and ``start_server()``.
 
-- Document locks and queues.
+- Document all places that take a ``loop`` keyword argument.
 
-- Document StreamReader, StreamWriter and open_connection().
+- Document ``logger`` object.
 
-- Document passing 'loop=...' everywhere.
-
-- Document logger object.
-
-- Document SIGCHILD handling API.
-
-- Compare all APIs with the source code to be sure there aren't any
-  undocumented or unimplemented features.
+- Document ``SIGCHILD`` handling API.
 
 
 Wish List
 =========
 
-- An open_server() helper.  It should take a callback which is called
-  for each accepted connection with a reader and writer; the callback
-  may be a coroutine (then it is wrapped in a task).
+(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.)
 
 - Support a "start TLS" operation to upgrade a TCP socket to SSL/TLS.
 
@@ -1681,6 +1784,10 @@
 Open Issues
 ===========
 
+(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.)
+
 - Why do ``create_connection()`` and ``create_datagram_endpoint()``
   have a ``proto`` argument but not ``create_server()``?  And why are
   the family, flag, proto arguments for ``getaddrinfo()`` sometimes

-- 
Repository URL: http://hg.python.org/peps


More information about the Python-checkins mailing list