RuntimeError: Cannot run the event loop while another loop is running using pytest.main
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 25/100
- Tipo di issue
- Bug
- Chiarezza
- Da chiarire
- Stato di attività
- Ferma
- Stack tecnologico
- python
- Ambito
- testing-qa
Direzione di ricerca
Riproduci il problema con runner.py che invoca pytest.main e il test di test_file.py contrassegnato con @pytest.mark.asyncio, quindi esamina pytest_asyncio/plugin.py in corrispondenza di wrap_in_sync intorno alla riga 454. L’issue non ha un’implementazione né criteri di accettazione definiti; per considerarla completata sarebbe necessario definire e validare un punto di ingresso pytest async o un’altra soluzione compatibile.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
To give you a minimal proof of concept in python3.10:
runner.py
import pytest
import asyncio
# using nest_asyncio mitigates the problem
#import nest_asyncio
#nest_asyncio.apply()
async def runner():
pytest.main(['-k', 'test_asdf', 'test_file.py'])
loop = asyncio.get_event_loop()
loop.run_until_complete(runner())
# does not raise an exception
# pytest.main(['-k', 'test_asdf', 'test_file.py'])
test_file.py
import pytest
@pytest.mark.asyncio
async def test_asdf():
assert True
/home/peter/Documents/pytestbug/test_runner.py:14: DeprecationWarning: There is no current event loop
loop = asyncio.get_event_loop()
============================================= test session starts ==============================================
platform linux -- Python 3.10.4, pytest-7.1.2, pluggy-1.0.0
rootdir: /home/peter/Documents/pytestbug
plugins: asyncio-0.18.4.dev36+gc021932.d20220609
asyncio: mode=legacy
collected 1 item
test_file.py F [100%]
=================================================== FAILURES ===================================================
__________________________________________________ test_asdf ___________________________________________________
args = (), kwargs = {}, coro = <coroutine object test_asdf at 0x7f7c47cb3300>
old_loop = <_UnixSelectorEventLoop running=False closed=False debug=False>
task = <Task pending name='Task-2' coro=<test_asdf() running at /home/peter/Documents/pytestbug/test_file.py:5>>
@functools.wraps(func)
def inner(*args, **kwargs):
coro = func(*args, **kwargs)
if not inspect.isawaitable(coro):
pyfuncitem.warn(
pytest.PytestWarning(
f"The test {pyfuncitem} is marked with '@pytest.mark.asyncio' "
"but it is not an async function. "
"Please remove asyncio marker. "
"If the test is not marked explicitly, "
"check for global markers applied via 'pytestmark'."
)
)
return
nonlocal _loop
_loop.stop()
old_loop = _loop
# old_loop
_loop = asyncio.new_event_loop()
asyncio.set_event_loop(_loop)
task = asyncio.ensure_future(coro, loop=_loop)
try:
> _loop.run_until_complete(task)
../../.virtualenvs/pytestbug/lib/python3.10/site-packages/pytest_asyncio/plugin.py:460:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/asyncio/base_events.py:622: in run_until_complete
self._check_running()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <_UnixSelectorEventLoop running=False closed=False debug=False>
def _check_running(self):
if self.is_running():
raise RuntimeError('This event loop is already running')
if events._get_running_loop() is not None:
> raise RuntimeError(
'Cannot run the event loop while another loop is running')
E RuntimeError: Cannot run the event loop while another loop is running
/usr/lib/python3.10/asyncio/base_events.py:584: RuntimeError
=============================================== warnings summary ===============================================
../../.virtualenvs/pytestbug/lib/python3.10/site-packages/pytest_asyncio/plugin.py:191
/home/peter/.virtualenvs/pytestbug/lib/python3.10/site-packages/pytest_asyncio/plugin.py:191: DeprecationWarning: The 'asyncio_mode' default value will change to 'strict' in future, please explicitly use 'asyncio_mode=strict' or 'asyncio_mode=auto' in pytest configuration file.
config.issue_config_time_warning(LEGACY_MODE, stacklevel=2)
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================================== short test summary info ============================================
FAILED test_file.py::test_asdf - RuntimeError: Cannot run the event loop while another loop is running
========================================= 1 failed, 1 warning in 0.10s =========================================
/usr/lib/python3.10/asyncio/base_events.py:685: ResourceWarning: unclosed event loop <_UnixSelectorEventLoop running=False closed=False debug=False>
sys:1: RuntimeWarning: coroutine 'test_asdf' was never awaited
Task was destroyed but it is pending!
task: <Task pending name='Task-2' coro=<test_asdf() running at /home/peter/Documents/pytestbug/test_file.py:5>>
The cause for this exception is that my setup already has an existing running EventLoop and in that loop I invoke pytest.main.
pytest.asyncio uses wrap_in_sync in the async fixtures and tests, which calls https://github.com/pytest-dev/pytest-asyncio/blob/860ff5113c3e73ade396c632c822a171a81e5b78/pytest_asyncio/plugin.py#L454
Therefore calling run_until_complete within a coroutine raises an exception.
Code executed inside an EventLoop can't stop the current EvenntLoop, create a new loop, run the code in that loop and restore the old loop. At least not without heavy modification. Python developers also stated that this behavior will not be changed.
This can be mitigated by using nest_asyncio, however there are different eventloop implementations that are not compatible with nest_asyncio. (My project used fastapi which uses a different loop implementation)
If there is an async entrypoiny like pytest.async_main into pytest that may be used as well. If we make all functions awaitable, we would not need to use run_until_complete, but could simply use await. However I don't think that this is feasible.
In the end I just ran pytest in a subprocess to call it outside of a coroutine.
As requested I further elaborated on my problem from https://github.com/pytest-dev/pytest-asyncio/issues/359#issuecomment-1151121091
- Lingua principale
- Python
- Stelle
- 1.7k
- Fork
- 209
- Merge medio
- 1h 51m
- PR unite (30g)
- 13
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di pytest-dev/pytest-asyncio
-
Turn deprecation of the "scope" keyword argument of the asyncio marker into an errorForse già presa @mokashang l’ha presa 115 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
pytest-dev/pytest-asyncio#1475 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 56/100
pytest-dev/pytest-asyncio#1514 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Loop factory parametrization tears down async fixtures used by sync testsForse già presa @TLNing260310 l’ha presa 43 giorni fa. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 72/100
pytest-dev/pytest-asyncio#1501 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
`pytest_asyncio_loop_factories` hook is not called when `pytest.mark.asyncio` is added via parametrizationForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
pytest-dev/pytest-asyncio#1463 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Don't warn about `asyncio_default_fixture_loop_scope` unless the test suite uses `pytest-asyncio`Forse di nuovo libera @DawnofGenX l’ha presa 7 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 52/100
pytest-dev/pytest-asyncio#1344 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di pytest-dev/pytest-asyncio
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
task
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
danparshall/claude_researcher#87 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
datajoint/datajoint-python#1586 ·
I maintainer di solito rispondono entro 1 giorno
-
1D intercept of length 1 is accepted as `fix_params` in population GLM with more than 1 unitForse già presa @dhvani7014 l’ha presa oggi. Apertabug good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
flatironinstitute/nemos#642 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Broken links in the docsAperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 78/100
uniswap-python/uniswap-python#487 ·