[Python-checkins] peps: Specify Futures. Minor cleanup.

guido.van.rossum python-checkins at python.org
Thu Dec 13 20:58:54 CET 2012


http://hg.python.org/peps/rev/c716fef27fa0
changeset:   4606:c716fef27fa0
user:        Guido van Rossum <guido at google.com>
date:        Thu Dec 13 11:58:47 2012 -0800
summary:
  Specify Futures. Minor cleanup.

files:
  pep-3156.txt |  111 ++++++++++++++++++++++++++++++++------
  1 files changed, 92 insertions(+), 19 deletions(-)


diff --git a/pep-3156.txt b/pep-3156.txt
--- a/pep-3156.txt
+++ b/pep-3156.txt
@@ -145,9 +145,12 @@
 A conforming event loop object has the following methods:
 
 ..
-  Look for a better way to format method docs.  PEP 12 doesn't
-  seem to have one.  PEP 418 uses ^^^, which makes sub-headings.
-  Also think of adding subheadings.
+  Look for a better way to format method docs.  PEP 12 doesn't seem to
+  have one.  PEP 418 uses ^^^, which makes sub-headings.  PEP 3148
+  uses a markup which generates rather heavy layout using blockquote,
+  causing a blank line between each method heading and its
+  description.  Also think of adding subheadings for different
+  categories of methods.
 
 - ``run()``.  Runs the event loop until there is nothing left to do.
   This means, in particular:
@@ -183,11 +186,16 @@
   later time in a threadsafe manner, you can use
   ``ev.call_soon_threadsafe(ev.call_later, when, callback, *args)``.)
 
+- TBD: A way to register a callback that is already wrapped in a
+  ``DelayedCall``.  Maybe ``call_soon()`` could just check
+  ``isinstance(callback, DelayedCall)``?  It should silently skip
+  a canceled callback.
+
 Some methods return Futures:
 
 - ``wrap_future(future)``.  This takes a PEP 3148 Future (i.e., an
   instance of ``concurrent.futures.Future``) and returns a Future
-  compatible with this event loop.
+  compatible with the event loop (i.e., a ``tulip.Future`` instance).
 
 - ``run_in_executor(executor, function, *args)``.  Arrange to call
   ``function(*args)`` in an executor (see PEP 3148).  Returns a Future
@@ -263,30 +271,24 @@
 supports it).  The socket argument has to be a non-blocking socket.
 
 - ``sock_recv(sock, n)``.  Receive up to ``n`` bytes from socket
-  ``sock``.  Returns a ``Future`` whose result on success will be a
+  ``sock``.  Returns a Future whose result on success will be a
   bytes object on success.
 
 - ``sock_sendall(sock, data)``.  Send bytes ``data`` to the socket
-  ``sock``.  Returns a ``Future`` whose result on success will be
+  ``sock``.  Returns a Future whose result on success will be
   ``None``.  (TBD: Is it better to emulate ``sendall()`` or ``send()``
   semantics?)
 
 - ``sock_connect(sock, address)``.  Connect to the given address.
-  Returns a ``Future`` whose result on success will be ``None``.
+  Returns a Future whose result on success will be ``None``.
 
 - ``sock_accept(sock)``.  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 ``(conn, peer)``
+  Future whose result on success will be a tuple ``(conn, peer)``
   where ``conn`` is a connected non-blocking socket and ``peer`` is
   the peer address.  (TBD: People tell me that this style of API is
   too slow for high-volume servers.  So there's also
-  ``start_serving()`` above.)
-
-Other TBD:
-
-- TBD: 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.
+  ``start_serving()`` above.  Then do we still need this?)
 
 Callback Sequencing
 -------------------
@@ -320,15 +322,76 @@
 The DelayedCall Class
 ---------------------
 
-TBD.  (Only one method, ``cancel()``, and a read-only property,
-``canceled``.  Perhaps also ``callback`` and ``args`` properties.)
+The various methods for registering callbacks (e.g. ``call_later()``)
+all return an object representing the registration that can be used to
+cancel the callback.  For want of a better name this object is called
+a ``DelayedCall``, although the user never needs to instantiate
+instances of this class.  There is one public method:
 
-TBD: Find a better name?
+- ``cancel()``.  Attempt to cancel the callback.
+
+Read-only public attributes:
+
+- ``callback``.  The callback function to be called.
+
+- ``args``.  The argument tuple with which to call the callback function.
+
+- ``canceled``.  True if ``cancel()`` has been called.
+
+Note that some callbacks (e.g. those registered with ``call_later()``)
+are meant to be called only once.  Others (e.g. those registered with
+``add_reader()``) are meant to be called multiple times.
+
+TBD: An API to call the callback (encapsulating the exception handling
+necessary)?  Should it record how many times it has been called?
+Maybe this API should just be ``__call__()``?  (But it should suppress
+exceptions.)
+
+TBD: Public attribute recording the realtime value when the callback
+is scheduled?  (Since this is needed anyway for storing it in a heap.)
+
+TBD: A better name for the class?
 
 Futures
 -------
 
-TBD.
+The ``tulip.Future`` class here is intentionally similar to the
+``concurrent.futures.Future`` class specified by PEP 3148, but there
+are slight differences.  The supported public API is as follows,
+indicating the differences with PEP 3148:
+
+- ``cancel()``.
+
+- ``cancelled()``.
+
+- ``running()``.  Note that the meaning of this method is essentially
+  "cannot be cancelled and isn't done yet".
+
+- ``done()``.
+
+- ``result()``.  Difference with PEP 3148: This has no timeout
+  argument and does *not* wait; if the future is not yet done, it
+  raises an exception.
+
+- ``exception()``.  Difference with PEP 3148: This has no timeout
+  argument and does *not* wait; if the future is not yet done, it
+  raises an exception.
+
+- ``add_done_callback(fn)``.  Difference with PEP 3148: The callback
+  is never called immediately, and always in the context of the
+  caller.  (Typically, a context is a thread.)  You can think of this
+  as calling the callback through ``call_soon_threadsafe()``.  Note
+  that the callback (unlike all other callbacks defined in this PEP)
+  is always called with a single argument, the Future object.
+
+The internal methods defined in PEP 3148 are not supported.
+
+A ``tulip.Future`` object is not acceptable to the ``wait()`` and
+``as_completed()`` functions in the ``concurrent.futures`` package.
+
+A ``tulip.Future`` object is acceptable to a yield-from expression
+when used in a coroutine.  See the section "Coroutines and the
+Scheduler" below.
 
 Transports
 ----------
@@ -375,6 +438,16 @@
 Open Issues
 ===========
 
+- How to spell the past tense of 'cancel'?  American usage prefers
+  (though not absolutely dictates) 'canceled' (one ell), but outside
+  the US 'cancelled' (two ells) prevails.  PEP 3148, whose author
+  currently lives in Australia, uses ``cancelled()`` as a method name
+  on its Future class.
+
+- 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.
+
 - Should we have ``future.add_callback(callback, *args)``, using the
   convention from the section "Callback Style" above, or should we
   stick with the PEP 3148 specification of

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


More information about the Python-checkins mailing list