Repository: pytest-dev/pytest-asyncio

Issue #112: Dynamically calling async fixture causes a runtime error saying "This event loop is already running"
Created: 2019-02-09T16:51:58Z
There seems to be a bug with how request.getfixturevalue(argname) interacts with pytest-asyncio. Calling the function leads to a runtime error saying the event loop is already running. If you change it from being dynamically called to being fixed in the function definition, it works as expected.
Platform Info:
platform win32 -- Python 3.7.2, pytest-4.2.0, py-1.7.0, pluggy-0.8.1
plugins: asyncio-0.11.0.dev0

Test fixture that can be used in both dynamic/fixed cases:
@pytest.fixture
async def async_fixture():
    yield 'Hi from async_fixture()!'

Successful fixed function argument fixture test:
@pytest.mark.asyncio
async def test_async_fixture_fixed(async_fixture):
    assert async_fixture == 'Hi from async_fixture()!'

Failed dynamic fixture test:
@pytest.mark.asyncio
async def test_async_fixture_dynamic(request):
    async_fixture = request.getfixturevalue('async_fixture')
    assert async_fixture == 'Hi from async_fixture()!'

Failed test trace-back:
================================== FAILURES ===================================
_________________________ test_async_fixture_dynamic __________________________

request = <FixtureRequest for <Function test_async_fixture_dynamic>>

    @pytest.mark.asyncio
    async def test_async_fixture_dynamic(request):
>       async_fixture = request.getfixturevalue('async_fixture')

tests\test_app_factory.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
venv\lib\site-packages\_pytest\fixtures.py:478: in getfixturevalue
    return self._get_active_fixturedef(argname).cached_result[0]
venv\lib\site-packages\_pytest\fixtures.py:501: in _get_active_fixturedef
    self._compute_fixture_value(fixturedef)
venv\lib\site-packages\_pytest\fixtures.py:586: in _compute_fixture_value
    fixturedef.execute(request=subrequest)
venv\lib\site-packages\_pytest\fixtures.py:881: in execute
    return hook.pytest_fixture_setup(fixturedef=self, request=request)
venv\lib\site-packages\pluggy\hooks.py:284: in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
venv\lib\site-packages\pluggy\manager.py:68: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
venv\lib\site-packages\pluggy\manager.py:62: in <lambda>
    firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
venv\lib\site-packages\_pytest\fixtures.py:923: in pytest_fixture_setup
    result = call_fixture_func(fixturefunc, request, kwargs)
venv\lib\site-packages\_pytest\fixtures.py:782: in call_fixture_func
    res = fixturefunc(**kwargs)
..\pytest-asyncio\pytest_asyncio\plugin.py:97: in wrapper
    return loop.run_until_complete(setup())
C:\Users\ykuzm\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py:571: in run_until_complete
    self.run_forever()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <_WindowsSelectorEventLoop running=False closed=False debug=False>

    def run_forever(self):
        """Run until stop() is called."""
        self._check_closed()
        if self.is_running():
>           raise RuntimeError('This event loop is already running')
E           RuntimeError: This event loop is already running

Duplicate issue #976: request.getfixturevalue(name) does not work with async fixtures
Created: 2024-10-31T12:24:24Z
Current Behavior: Calling  request.getfixturevalue(name) with the name of an async fixture raises a RuntimeError.
Expected Behavior: Calling  request.getfixturevalue(name) with the name of an async fixture should initialize the fixture correctly.
Tested on Windows 11 23H2 with Python 3.11
Installed packages
colorama==0.4.6
iniconfig==2.0.0
packaging==24.1
pluggy==1.5.0
pytest==8.3.3
pytest-asyncio==0.24.0

conftest.py
@pytest.fixture(scope="function")
async def fixture1(request):
    return True
tests/test_getfixturevalue_async.py
import pytest

# This works
async def test_direct_fixture(fixture1):
    assert True

# This not
async def test_get_fixturevalue_async(request):
    x = request.getfixturevalue("fixture1")
Traceback
tests\test_getfixturevalue_async.py:7 (test_get_fixturevalue_async)
request = <FixtureRequest for <Coroutine test_get_fixturevalue_async>>

    async def test_get_fixturevalue_async(request):
>       x = request.getfixturevalue("fixture1")

test_getfixturevalue_async.py:9: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\.venv\Lib\site-packages\_pytest\fixtures.py:532: in getfixturevalue
    fixturedef = self._get_active_fixturedef(argname)
..\.venv\Lib\site-packages\_pytest\fixtures.py:617: in _get_active_fixturedef
    fixturedef.execute(request=subrequest)
..\.venv\Lib\site-packages\_pytest\fixtures.py:1091: in execute
    result = ihook.pytest_fixture_setup(fixturedef=self, request=request)
..\.venv\Lib\site-packages\pluggy\_hooks.py:513: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
..\.venv\Lib\site-packages\pluggy\_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
..\.venv\Lib\site-packages\_pytest\setuponly.py:36: in pytest_fixture_setup
    return (yield)
..\.venv\Lib\site-packages\_pytest\fixtures.py:1140: in pytest_fixture_setup
    result = call_fixture_func(fixturefunc, request, kwargs)
..\.venv\Lib\site-packages\_pytest\fixtures.py:898: in call_fixture_func
    fixture_result = fixturefunc(**kwargs)
..\.venv\Lib\site-packages\pytest_asyncio\plugin.py:366: in _async_fixture_wrapper
    return event_loop.run_until_complete(setup())
C:\Python\3.11\Lib\asyncio\base_events.py:630: in run_until_complete
    self._check_running()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <ProactorEventLoop running=False closed=False debug=False>

    def _check_running(self):
        if self.is_running():
>           raise RuntimeError('This event loop is already running')
E           RuntimeError: This event loop is already running

C:\Python\3.11\Lib\asyncio\base_events.py:589: RuntimeError

Closing comment (2024-10-31T13:54:52Z): Duplicate of #112