Skip to content

Commit b38cdaa

Browse files
authored
Update the concurrent library + Added tests (#6673)
* Updated concurrent library * Added test_concurrent_futures from v3.13.11 * Annotated failing tests in test_concurrent_futures
1 parent a3425b4 commit b38cdaa

File tree

15 files changed

+2400
-101
lines changed

15 files changed

+2400
-101
lines changed

Lib/concurrent/futures/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
'ALL_COMPLETED',
2424
'CancelledError',
2525
'TimeoutError',
26+
'InvalidStateError',
2627
'BrokenExecutor',
2728
'Future',
2829
'Executor',
@@ -50,4 +51,4 @@ def __getattr__(name):
5051
ThreadPoolExecutor = te
5152
return te
5253

53-
raise AttributeError(f"module {__name__} has no attribute {name}")
54+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

Lib/concurrent/futures/_base.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ class CancelledError(Error):
5050
"""The Future was cancelled."""
5151
pass
5252

53-
class TimeoutError(Error):
54-
"""The operation exceeded the given deadline."""
55-
pass
53+
TimeoutError = TimeoutError # make local alias for the standard exception
5654

5755
class InvalidStateError(Error):
5856
"""The operation is not allowed in this state."""
@@ -284,7 +282,7 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED):
284282
A named 2-tuple of sets. The first set, named 'done', contains the
285283
futures that completed (is finished or cancelled) before the wait
286284
completed. The second set, named 'not_done', contains uncompleted
287-
futures. Duplicate futures given to *fs* are removed and will be
285+
futures. Duplicate futures given to *fs* are removed and will be
288286
returned only once.
289287
"""
290288
fs = set(fs)
@@ -312,6 +310,18 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED):
312310
done.update(waiter.finished_futures)
313311
return DoneAndNotDoneFutures(done, fs - done)
314312

313+
314+
def _result_or_cancel(fut, timeout=None):
315+
try:
316+
try:
317+
return fut.result(timeout)
318+
finally:
319+
fut.cancel()
320+
finally:
321+
# Break a reference cycle with the exception in self._exception
322+
del fut
323+
324+
315325
class Future(object):
316326
"""Represents the result of an asynchronous computation."""
317327

@@ -386,7 +396,7 @@ def done(self):
386396
return self._state in [CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED]
387397

388398
def __get_result(self):
389-
if self._exception:
399+
if self._exception is not None:
390400
try:
391401
raise self._exception
392402
finally:
@@ -606,9 +616,9 @@ def result_iterator():
606616
while fs:
607617
# Careful not to keep a reference to the popped future
608618
if timeout is None:
609-
yield fs.pop().result()
619+
yield _result_or_cancel(fs.pop())
610620
else:
611-
yield fs.pop().result(end_time - time.monotonic())
621+
yield _result_or_cancel(fs.pop(), end_time - time.monotonic())
612622
finally:
613623
for future in fs:
614624
future.cancel()

0 commit comments

Comments
 (0)