pytest-asyncio: pytest fails while using version asyncio-0.15.0
Python: 3.8 (docker image)
My pytest setup:
...
============================= test session starts ==============================
platform linux -- Python 3.8.9, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- /builds/.../venv/bin/python3
cachedir: .pytest_cache
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/builds/.../.hypothesis/examples')
rootdir: /builds/..., configfile: pytest.ini
plugins: hypothesis-6.9.2, asyncio-0.15.0
...
an error:
...
==================================== ERRORS ====================================
_____________________ ERROR at setup of test_async_ticker ______________________
fixturedef = <FixtureDef argname='event_loop' scope='function' baseid=''>
request = <SubRequest 'event_loop' for <Function test_async_ticker>>
    @pytest.hookimpl(hookwrapper=True)
    def pytest_fixture_setup(fixturedef, request):
        """Adjust the event loop policy when an event loop is produced."""
        if fixturedef.argname == "event_loop":
            outcome = yield
            loop = outcome.get_result()
            policy = asyncio.get_event_loop_policy()
>           old_loop = policy.get_event_loop()
venv/lib/python3.8/site-packages/pytest_asyncio/plugin.py:94: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f07326b2bb0>
    def get_event_loop(self):
        """Get the event loop for the current context.
    
        Returns an instance of EventLoop or raises an exception.
        """
        if (self._local._loop is None and
                not self._local._set_called and
                isinstance(threading.current_thread(), threading._MainThread)):
            self.set_event_loop(self.new_event_loop())
    
        if self._local._loop is None:
>           raise RuntimeError('There is no current event loop in thread %r.'
                               % threading.current_thread().name)
E           RuntimeError: There is no current event loop in thread 'MainThread'.
/usr/local/lib/python3.8/asyncio/events.py:639: RuntimeError
...
The error appears when I run:
python -m pytest tests/test_dates.py::test_async_ticker -vv -duration=6  
where the test_async_ticker is:
import asyncio
import pytest
@pytest.mark.asyncio
async def test_async_ticker():
    async with dates.AsyncTicker() as ticker:
        await asyncio.sleep(0.001)
    assert ticker.time_elapsed().total_seconds() > 0
and AsyncTicker:
class AsyncTicker:
    '''Measures time between entering and exiting `async with` block.'''
    def __init__(self):
        self._start = None
        self._end = None
    async def __aenter__(self, *args, **kwargs):
        self._start = current_utc_instant()
        return self
    async def __aexit__(self, *args, **kwargs):
        self._end = current_utc_instant()
    def time_elapsed(self):
        return self._end - self._start
About this issue
- Original URL
 - State: closed
 - Created 3 years ago
 - Reactions: 6
 - Comments: 20 (8 by maintainers)
 
Commits related to this issue
- Unpin pytest-asyncio. Reverts 1945a9fc286fc0afda1e1371562a743fbe97ccb5. Issue in 0.15.0 resolved in 0.15.1. Refs #1682 Refs https://github.com/pytest-dev/pytest-asyncio/issues/209 — committed to django/channels by carltongibson 3 years ago
 - Unpin pytest-asyncio. Reverts 1945a9fc286fc0afda1e1371562a743fbe97ccb5. Issue in 0.15.0 resolved in 0.15.1. Refs #1682 Refs https://github.com/pytest-dev/pytest-asyncio/issues/209 — committed to django/channels by carltongibson 3 years ago
 
Ah, must have been caused by the loop cleanup changes in 0.15.0. Can be fixed relatively easily, just need to understand what exactly is going on first.
I have a similar issue. So far I have noted that prior tests on code that calls
asyncio.run(...)leaves the loop on main closed andself._local._set_calledset toTrue. The first time this plugin tries to setup for the marked function,get_event_loopfails due tosethaving already been called by the prior call torun. I did not experience this previously using this combo howeverEdit: subsequent tests using the decorator do still pass though, it is only the first time it is used after
asyncio.run(...)was used elsewhereEdit 2: Swapped back to 0.14.0 and the tests pass in the same run order & environment