Published On: 2014-06-12|Last Updated: 2014-06-12|Categories: Python|Tags: , |

asyncio では timeout を設定しても coroutine には asyncio.TimeoutError は送出されず、asyncio.CancelledError が送出されます。 (*1)
asyncio.TimeoutError は coroutine を呼び出した点に送出されます。 (*2)
つまり、coroutine では自分が cancel されたのか timeout したのかは判別できません。

#!python3.4
import asyncio

@asyncio.coroutine
def mycoro():
    try:
        yield from asyncio.sleep(1000, loop=loop)
    except Exception as e: # *1
        assert isinstance(e, asyncio.CancelledError)
        raise

loop = asyncio.get_event_loop()
f = asyncio.wait_for(mycoro(), 1, loop=loop)
try:
    loop.run_until_complete(f)
except Exception as e: # *2
    assert isinstance(e, asyncio.TimeoutError)

処理を担う coroutine と timeout を担う coroutine を分ければいいだけですが、厄介な設計ではあります。

関連