bpo-33238: Add InvalidStateError to concurrent.futures. (GH-7056)

Future.set_result and Future.set_exception now raise InvalidStateError
if the futures are not pending or running. This mirrors the behavior
of asyncio.Future, and prevents AssertionErrors in asyncio.wrap_future
when set_result is called multiple times.
This commit is contained in:
jhaydaman 2018-05-30 02:15:06 -05:00 committed by Andrew Svetlov
parent bb9474f1fb
commit 0a28c0d12e
6 changed files with 59 additions and 6 deletions

View file

@ -10,6 +10,7 @@ from concurrent.futures._base import (FIRST_COMPLETED,
ALL_COMPLETED,
CancelledError,
TimeoutError,
InvalidStateError,
BrokenExecutor,
Future,
Executor,

View file

@ -53,6 +53,10 @@ class TimeoutError(Error):
"""The operation exceeded the given deadline."""
pass
class InvalidStateError(Error):
"""The operation is not allowed in this state."""
pass
class _Waiter(object):
"""Provides the event that wait() and as_completed() block on."""
def __init__(self):
@ -513,6 +517,8 @@ class Future(object):
Should only be used by Executor implementations and unit tests.
"""
with self._condition:
if self._state in {CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED}:
raise InvalidStateError('{}: {!r}'.format(self._state, self))
self._result = result
self._state = FINISHED
for waiter in self._waiters:
@ -526,6 +532,8 @@ class Future(object):
Should only be used by Executor implementations and unit tests.
"""
with self._condition:
if self._state in {CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED}:
raise InvalidStateError('{}: {!r}'.format(self._state, self))
self._exception = exception
self._state = FINISHED
for waiter in self._waiters: