class TransactionAbort(IOError):
pass
@async_contextmanager
async def transaction(conn):
try:
yield conn
except TransactionAbort:
...
return
else:
...
try:
await self.generator.athrow(exc_val)
except StopAsyncIteration:
return True # tell python that the exception (StopAsyncIteration) is safe to suppress
from asyncio_extras import contextmanager
def patch_context_manager():
if hasattr(contextmanager._AsyncContextManager.__aexit__, '__horcruxed__'):
return
async def __aexit__(self, exc_type, exc_val, exc_tb):
if exc_val is not None:
try:
await self.generator.athrow(exc_val)
except StopAsyncIteration:
return True
else:
try:
await self.generator.asend(None)
except StopAsyncIteration:
pass
else:
raise RuntimeError("async generator didn't stop")
__aexit__.__horcruxed__ = time.time()
contextmanager._AsyncContextManager.__aexit__ = __aexit__