gh-110378: Close invalid generators in contextmanager and asynccontextmanager (GH-110499)

contextmanager and asynccontextmanager context managers now close an invalid
underlying generator object that yields more then one value.
This commit is contained in:
Serhiy Storchaka 2023-10-10 10:43:04 +03:00 committed by GitHub
parent def7ea5cec
commit 96fed66a65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 7 deletions

View file

@ -149,7 +149,10 @@ class _GeneratorContextManager(
except StopIteration:
return False
else:
raise RuntimeError("generator didn't stop")
try:
raise RuntimeError("generator didn't stop")
finally:
self.gen.close()
else:
if value is None:
# Need to force instantiation so we can reliably
@ -191,7 +194,10 @@ class _GeneratorContextManager(
raise
exc.__traceback__ = traceback
return False
raise RuntimeError("generator didn't stop after throw()")
try:
raise RuntimeError("generator didn't stop after throw()")
finally:
self.gen.close()
class _AsyncGeneratorContextManager(
_GeneratorContextManagerBase,
@ -216,7 +222,10 @@ class _AsyncGeneratorContextManager(
except StopAsyncIteration:
return False
else:
raise RuntimeError("generator didn't stop")
try:
raise RuntimeError("generator didn't stop")
finally:
await self.gen.aclose()
else:
if value is None:
# Need to force instantiation so we can reliably
@ -258,7 +267,10 @@ class _AsyncGeneratorContextManager(
raise
exc.__traceback__ = traceback
return False
raise RuntimeError("generator didn't stop after athrow()")
try:
raise RuntimeError("generator didn't stop after athrow()")
finally:
await self.gen.aclose()
def contextmanager(func):