Closed
Description
This code:
import asyncio
async def gen():
try:
for x in range(100):
try:
yield x
except BaseException as e:
print('raised', repr(e))
raise
finally:
print('cleaning up!')
async def test_earlystop():
async for x in gen():
print(x)
if x > 8:
break
assert True
if __name__ == '__main__':
asyncio.run(test_earlystop())
Run it:
$ python debug.py
0
1
2
3
4
5
6
7
8
9
raised CancelledError()
cleaning up!
I was surprised to see CancelledError
rather than GeneratorExit
but it's OK. Now this code:
import asyncio
import pytest
async def gen():
try:
for x in range(100):
try:
yield x
except BaseException as e:
print('raised', repr(e))
raise
finally:
print('cleaning up!')
@pytest.mark.asyncio
async def test_earlystop():
async for x in gen():
print(x)
if x > 8:
break
assert True
Run it,
$ py.test -sv debug.py
=================================================================== test session starts ====================================================================
platform linux -- Python 3.10.12, pytest-7.4.4, pluggy-1.3.0 -- /usr/bin/python
rootdir: /home/docker-user/mpservice
configfile: pyproject.toml
plugins: asyncio-0.23.3, cov-4.1.0, anyio-4.2.0, Faker-22.4.0, pudb-0.7.0
asyncio: mode=strict
collected 1 item
debug.py::test_earlystop 0
1
2
3
4
5
6
7
8
9
PASSED
-------------------------------------------------------------------- live log teardown ---------------------------------------------------------------------
ERROR asyncio:base_events.py:1758 Task was destroyed but it is pending!
task: <Task pending name='Task-2' coro=<<async_generator_athrow without __name__>()>>
=================================================================== slowest 3 durations ====================================================================
0.11s setup tests/debug.py::test_earlystop
0.00s teardown tests/debug.py::test_earlystop
0.00s call tests/debug.py::test_earlystop
==================================================================== 1 passed in 0.18s =====================================================================
Now I don't understand why
- The
CancelledError
was not raised, it appears - The
finally
block was not executed, it appears
Of course, that "destroyed but it is pending" is also unpleasant to see.
Is there a bug in pytest-asyncio or am I missing something? I think this code should simply pass with no drama of any kind.