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

Most upvoted comments

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 and self._local._set_called set to True. The first time this plugin tries to setup for the marked function, get_event_loop fails due to set having already been called by the prior call to run. I did not experience this previously using this combo however

Edit: subsequent tests using the decorator do still pass though, it is only the first time it is used after asyncio.run(...) was used elsewhere

Edit 2: Swapped back to 0.14.0 and the tests pass in the same run order & environment