mirror of https://github.com/python/cpython
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>
This commit is contained in:
parent
b949845b36
commit
7d7817cf0f
|
@ -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
|
||||
|
|
|
@ -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."""
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
:func:`concurrent.futures.wait` no longer blocks forever when given duplicate Futures. Patch by Kumar Aditya.
|
Loading…
Reference in New Issue