summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKumar Aditya <59607654+kumaraditya303@users.noreply.github.com>2022-01-04 13:36:13 (GMT)
committerGitHub <noreply@github.com>2022-01-04 13:36:13 (GMT)
commit7d7817cf0f826e566d8370a0e974bbfed6611d91 (patch)
tree9d7e29dfd0e13cbdc6e0bed9bdca8f457ad12c4f
parentb949845b36b999185ed2bdf8a04dca1da39f3002 (diff)
downloadcpython-7d7817cf0f826e566d8370a0e974bbfed6611d91.zip
cpython-7d7817cf0f826e566d8370a0e974bbfed6611d91.tar.gz
cpython-7d7817cf0f826e566d8370a0e974bbfed6611d91.tar.bz2
bpo-20369: concurrent.futures.wait() now deduplicates futures given a… (GH-30168)
* bpo-20369: concurrent.futures.wait() now deduplicates futures given as arg. * 📜🤖 Added by blurb_it. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
-rw-r--r--Doc/library/concurrent.futures.rst3
-rw-r--r--Lib/concurrent/futures/_base.py13
-rw-r--r--Lib/test/test_concurrent_futures.py8
-rw-r--r--Misc/NEWS.d/next/Library/2021-12-17-12-06-40.bpo-20369.zzLuBz.rst1
4 files changed, 18 insertions, 7 deletions
diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst
index c9f6aa1..0432fcd 100644
--- a/Doc/library/concurrent.futures.rst
+++ b/Doc/library/concurrent.futures.rst
@@ -444,7 +444,8 @@ Module Functions
.. function:: wait(fs, timeout=None, return_when=ALL_COMPLETED)
Wait for the :class:`Future` instances (possibly created by different
- :class:`Executor` instances) given by *fs* to complete. Returns a named
+ :class:`Executor` instances) given by *fs* to complete. Duplicate futures
+ given to *fs* are removed and will be returned only once. Returns a named
2-tuple of sets. The first set, named ``done``, contains the futures that
completed (finished or cancelled futures) before the wait completed. The
second set, named ``not_done``, contains the futures that did not complete
diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py
index b033739..c5912c2 100644
--- a/Lib/concurrent/futures/_base.py
+++ b/Lib/concurrent/futures/_base.py
@@ -282,13 +282,14 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED):
A named 2-tuple of sets. The first set, named 'done', contains the
futures that completed (is finished or cancelled) before the wait
completed. The second set, named 'not_done', contains uncompleted
- futures.
+ futures. Duplicate futures given to *fs* are removed and will be
+ returned only once.
"""
+ fs = set(fs)
with _AcquireFutures(fs):
- done = set(f for f in fs
- if f._state in [CANCELLED_AND_NOTIFIED, FINISHED])
- not_done = set(fs) - done
-
+ done = {f for f in fs
+ if f._state in [CANCELLED_AND_NOTIFIED, FINISHED]}
+ not_done = fs - done
if (return_when == FIRST_COMPLETED) and done:
return DoneAndNotDoneFutures(done, not_done)
elif (return_when == FIRST_EXCEPTION) and done:
@@ -307,7 +308,7 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED):
f._waiters.remove(waiter)
done.update(waiter.finished_futures)
- return DoneAndNotDoneFutures(done, set(fs) - done)
+ return DoneAndNotDoneFutures(done, fs - done)
class Future(object):
"""Represents the result of an asynchronous computation."""
diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py
index bbb6aa1..71c88a3 100644
--- a/Lib/test/test_concurrent_futures.py
+++ b/Lib/test/test_concurrent_futures.py
@@ -578,6 +578,14 @@ create_executor_tests(ProcessPoolShutdownTest,
class WaitTests:
+ def test_20369(self):
+ # See https://bugs.python.org/issue20369
+ future = self.executor.submit(time.sleep, 1.5)
+ done, not_done = futures.wait([future, future],
+ return_when=futures.ALL_COMPLETED)
+ self.assertEqual({future}, done)
+ self.assertEqual(set(), not_done)
+
def test_first_completed(self):
future1 = self.executor.submit(mul, 21, 2)
diff --git a/Misc/NEWS.d/next/Library/2021-12-17-12-06-40.bpo-20369.zzLuBz.rst b/Misc/NEWS.d/next/Library/2021-12-17-12-06-40.bpo-20369.zzLuBz.rst
new file mode 100644
index 0000000..cc5cd00
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-12-17-12-06-40.bpo-20369.zzLuBz.rst
@@ -0,0 +1 @@
+:func:`concurrent.futures.wait` no longer blocks forever when given duplicate Futures. Patch by Kumar Aditya.