[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