Describe the bug
There is a race condition in code that handles connection timeout. If you call cancel on a task that is currently pending in create_connection and connection timeout was already fired then asyncio.CancelledError is not propagated and you get asyncio.TimeoutError instead. The main problem is in how timeouts are handled in async_timeout package. When exitting the context manager after timeout had passed all CancelledError exceptions are swallowed and TimeoutError is raised instead. Unfortunately this is true also if you explicitly cancel the task yourself.
The main problem is that you cannot cancel a task that is using aiohttp because you never know if CancelledError will be raised.
To Reproduce
EDIT: THIS REPRODUCER DOES NOT SHOW THE BEHAVIOUR CORRECTLY - PLEASE REFER TO COMMENTS BELLOW!
import asyncio
from async_timeout import timeout
async def test_task():
with timeout(1):
await asyncio.sleep(10)
async def main():
t = asyncio.create_task(test_task())
await asyncio.sleep(2)
t.cancel()
try:
await t
except asyncio.TimeoutError:
print("Raised TimeoutError")
except asyncio.CancelledError:
print("Raised CancelledError")
asyncio.run(main())
Expected behavior
asyncio.CancelledError should never be suppressed when you cancel the task explicitly.
Logs/tracebacks
Python Version
aiohttp Version
multidict Version
yarl Version
OS
Linux
Related component
Client
Additional context
No response
Code of Conduct
Describe the bug
There is a race condition in code that handles connection timeout. If you call
cancelon a task that is currently pending increate_connectionand connection timeout was already fired thenasyncio.CancelledErroris not propagated and you getasyncio.TimeoutErrorinstead. The main problem is in how timeouts are handled in async_timeout package. When exitting the context manager after timeout had passed allCancelledErrorexceptions are swallowed andTimeoutErroris raised instead. Unfortunately this is true also if you explicitly cancel the task yourself.The main problem is that you cannot cancel a task that is using aiohttp because you never know if
CancelledErrorwill be raised.To Reproduce
EDIT: THIS REPRODUCER DOES NOT SHOW THE BEHAVIOUR CORRECTLY - PLEASE REFER TO COMMENTS BELLOW!
Expected behavior
asyncio.CancelledErrorshould never be suppressed when you cancel the task explicitly.Logs/tracebacks
Python Version
Python 3.8.10aiohttp Version
3.7.4.post0multidict Version
4.7.6yarl Version
1.6.0OS
Linux
Related component
Client
Additional context
No response
Code of Conduct