Closed
Description
Hello there,
I'm using asyncio-0.15.1 and it seems there is a bug when pytest is interrupted during the setup code of an async generator fixture.
Minimal reproduction test module:
import pytest
import asyncio
@pytest.fixture
async def fixture():
await asyncio.sleep(5)
yield
await asyncio.sleep(1)
@pytest.mark.asyncio
async def test_keyboard_interrupt(fixture):
pass
If I hit Ctrl-C during fixture setup, it results in:
D:\python>pytest test_keyboard_interrupt.py
============================================================================================ test session starts ============================================================================================
platform win32 -- Python 3.8.5, pytest-6.1.2, py-1.9.0, pluggy-0.13.1
rootdir: D:\python
plugins: asyncio-0.15.1
collected 1 item
test_keyboard_interrupt.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! KeyboardInterrupt !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
c:\users\kasyc\appdata\local\programs\python\python38\lib\asyncio\windows_events.py:779: KeyboardInterrupt
(to show a full traceback on KeyboardInterrupt use --full-trace)
Traceback (most recent call last):
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\Users\kasyc\AppData\Local\Programs\Python\Python38\Scripts\pytest.exe\__main__.py", line 7, in <module>
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\config\__init__.py", line 187, in console_main
code = main()
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\config\__init__.py", line 164, in main
ret = config.hook.pytest_cmdline_main(
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\hooks.py", line 286, in __call__
return self._hookexec(self, self.get_hookimpls(), kwargs)
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\manager.py", line 93, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\manager.py", line 84, in <lambda>
self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\callers.py", line 208, in _multicall
return outcome.get_result()
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\callers.py", line 187, in _multicall
res = hook_impl.function(*args)
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\main.py", line 306, in pytest_cmdline_main
return wrap_session(config, _main)
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\main.py", line 294, in wrap_session
config.hook.pytest_sessionfinish(
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\hooks.py", line 286, in __call__
return self._hookexec(self, self.get_hookimpls(), kwargs)
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\manager.py", line 93, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\manager.py", line 84, in <lambda>
self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\callers.py", line 203, in _multicall
gen.send(outcome)
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\terminal.py", line 794, in pytest_sessionfinish
outcome.get_result()
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pluggy\callers.py", line 187, in _multicall
res = hook_impl.function(*args)
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\runner.py", line 104, in pytest_sessionfinish
session._setupstate.teardown_all()
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\runner.py", line 411, in teardown_all
self._pop_and_teardown()
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\runner.py", line 386, in _pop_and_teardown
self._teardown_with_finalization(colitem)
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\runner.py", line 404, in _teardown_with_finalization
self._callfinalizers(colitem)
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\runner.py", line 401, in _callfinalizers
raise exc
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\runner.py", line 394, in _callfinalizers
fin()
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\fixtures.py", line 1032, in finish
raise exc
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\_pytest\fixtures.py", line 1025, in finish
func()
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pytest_asyncio\plugin.py", line 139, in finalizer
loop.run_until_complete(async_finalizer())
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\asyncio\base_events.py", line 616, in run_until_complete
return future.result()
File "c:\users\kasyc\appdata\local\programs\python\python38\lib\site-packages\pytest_asyncio\plugin.py", line 131, in async_finalizer
await gen_obj.__anext__()
RuntimeError: anext(): asynchronous generator is already running
It seems we would need to transform:
request.addfinalizer(finalizer)
return loop.run_until_complete(setup())
into:
result = loop.run_until_complete(setup())
request.addfinalizer(finalizer)
return result
so that the cleanup code will only be executed if the setup code is finished.
Metadata
Metadata
Assignees
Labels
No labels