[3.12] gh-112182: Replace StopIteration with RuntimeError for future (GH-113220) (GH-123033)

When an `StopIteration` raises into `asyncio.Future`, this will cause
a thread to hang. This commit address this by not raising an exception
and silently transforming the `StopIteration` with a `RuntimeError`,
which the caller can reconstruct from `fut.exception().__cause__`
(cherry picked from commit 4826d52338)

Co-authored-by: Jamie Phan <jamie@ordinarylab.dev>
This commit is contained in:
Miss Islington (bot) 2024-08-15 17:34:53 +02:00 committed by GitHub
parent 9f153a2acf
commit 41090b7ba0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 49 additions and 12 deletions

View file

@ -272,9 +272,13 @@ class Future:
raise exceptions.InvalidStateError(f'{self._state}: {self!r}')
if isinstance(exception, type):
exception = exception()
if type(exception) is StopIteration:
raise TypeError("StopIteration interacts badly with generators "
"and cannot be raised into a Future")
if isinstance(exception, StopIteration):
new_exc = RuntimeError("StopIteration interacts badly with "
"generators and cannot be raised into a "
"Future")
new_exc.__cause__ = exception
new_exc.__context__ = exception
exception = new_exc
self._exception = exception
self._exception_tb = exception.__traceback__
self._state = _FINISHED