[Python-checkins] cpython (3.3): Issue #20367: Fix behavior of concurrent.futures.as_completed() for duplicate

victor.stinner python-checkins at python.org
Mon Jan 27 09:13:52 CET 2014


http://hg.python.org/cpython/rev/791b69f9f96d
changeset:   88765:791b69f9f96d
branch:      3.3
parent:      88756:e02da391741f
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Mon Jan 27 09:11:48 2014 +0100
summary:
  Issue #20367: Fix behavior of concurrent.futures.as_completed() for duplicate
arguments.  Patch by Glenn Langford.

files:
  Doc/library/concurrent.futures.rst  |  3 ++-
  Lib/concurrent/futures/_base.py     |  6 ++++--
  Lib/test/test_concurrent_futures.py |  7 +++++++
  Misc/ACKS                           |  1 +
  Misc/NEWS                           |  3 +++
  5 files changed, 17 insertions(+), 3 deletions(-)


diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst
--- a/Doc/library/concurrent.futures.rst
+++ b/Doc/library/concurrent.futures.rst
@@ -368,7 +368,8 @@
 
    Returns an iterator over the :class:`Future` instances (possibly created by
    different :class:`Executor` instances) given by *fs* that yields futures as
-   they complete (finished or were cancelled).  Any futures that completed
+   they complete (finished or were cancelled). Any futures given by *fs* that
+   are duplicated will be returned once. Any futures that completed
    before :func:`as_completed` is called will be yielded first.  The returned
    iterator raises a :exc:`TimeoutError` if :meth:`~iterator.__next__` is
    called and the result isn't available after *timeout* seconds from the
diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py
--- a/Lib/concurrent/futures/_base.py
+++ b/Lib/concurrent/futures/_base.py
@@ -181,7 +181,8 @@
 
     Returns:
         An iterator that yields the given Futures as they complete (finished or
-        cancelled).
+        cancelled). If any given Futures are duplicated, they will be returned
+        once.
 
     Raises:
         TimeoutError: If the entire result iterator could not be generated
@@ -190,11 +191,12 @@
     if timeout is not None:
         end_time = timeout + time.time()
 
+    fs = set(fs)
     with _AcquireFutures(fs):
         finished = set(
                 f for f in fs
                 if f._state in [CANCELLED_AND_NOTIFIED, FINISHED])
-        pending = set(fs) - finished
+        pending = fs - finished
         waiter = _create_and_install_waiters(fs, _AS_COMPLETED)
 
     try:
diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py
--- a/Lib/test/test_concurrent_futures.py
+++ b/Lib/test/test_concurrent_futures.py
@@ -344,6 +344,13 @@
                               SUCCESSFUL_FUTURE]),
                          completed_futures)
 
+    def test_duplicate_futures(self):
+        # Issue 20367. Duplicate futures should not raise exceptions or give
+        # duplicate responses.
+        future1 = self.executor.submit(time.sleep, 2)
+        completed = [f for f in futures.as_completed([future1,future1])]
+        self.assertEqual(len(completed), 1)
+
 
 class ThreadPoolAsCompletedTests(ThreadPoolMixin, AsCompletedTests, unittest.TestCase):
     pass
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -703,6 +703,7 @@
 Torsten Landschoff
 Łukasz Langa
 Tino Lange
+Glenn Langford
 Andrew Langmead
 Detlef Lannert
 Soren Larsen
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -50,6 +50,9 @@
 Library
 -------
 
+- Issue #20367: Fix behavior of concurrent.futures.as_completed() for
+  duplicate arguments.  Patch by Glenn Langford.
+
 - Issue #8260: The read(), readline() and readlines() methods of
   codecs.StreamReader returned incomplete data when were called after
   readline() or read(size).  Based on patch by Amaury Forgeot d'Arc.

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


More information about the Python-checkins mailing list