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