The PEP 492 mentions that:
async with EXPR as VAR:
BLOCK
is semantically equivalent to:
mgr = (EXPR)
aexit = type(mgr).__aexit__
aenter = type(mgr).__aenter__
VAR = await aenter(mgr)
try:
BLOCK
except:
if not await aexit(mgr, *sys.exc_info()):
raise
else:
await aexit(mgr, None, None, None)
However, VAR = await aenter(mgr) is not in the try block so I am wondering if __aenter__() is allowed to fail.
For example, in this this aiohttp snippet (taken from Getting Started):
import aiohttp
import asyncio
async def main():
async with aiohttp.ClientSession() as session:
async with session.get('http://python.org') as response:
print("Status:", response.status)
print("Content-type:", response.headers['content-type'])
html = await response.text()
print("Body:", html[:15], "...")
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
session.get('http://python.org') could fail and __aexit__() would not be called to close the context.
__aexit__()would not be called to close the context. - what context are you referring to? The session will be closed because the exception happened in the body of the outerasync with. If you meanresponse, there is nothing to close becausesession.get(...)never finished running, it raised an exception instead.