question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Conflicts with pytest-asyncio (sample with redis)

See original GitHub issue

Having following test file, things behave differently with different pytest plugins installed:

import aioredis
import pytest
from aiohttp import web


def init():
    """Create web.Application instance
    """
    app = web.Application()
    app.router.add_get('/', hello)
    app["redis_url"] = "redis://localhost:6379"
    app.on_startup.append(create_redis_pool)
    app.on_shutdown.insert(0, close_redis_pool)
    return app


async def hello(request):
    """url Handler for hello"""
    return web.Response(text='Hello, world')


async def create_redis_pool(app):
    """Create Redis connection pool"""
    redis_url = app["redis_url"]
    pool = await aioredis.create_redis_pool(redis_url, loop=app.loop)
    app["redis_pool"] = pool


async def close_redis_pool(app):
    """Close Redis connection pool"""
    pool = app["redis_pool"]
    pool.close()
    await pool.wait_closed()


# @pytest.fixture
# def loop(event_loop):
#     """Ensure usable event loop for everyone.
#
#     If you comment this fixture out, default pytest-aiohttp one is used
#     and things start failing (when redis pool is in place).
#     """
#     return event_loop


@pytest.fixture
def app(loop):
    """Application instance.
    """
    return init()


@pytest.fixture
async def cli(test_client, app, loop):
    """HTTP client for our application.
    """
    return await test_client(app)


async def test_hello(cli, loop):
    resp = await cli.get("/")
    assert resp.status == 200
    text = await resp.text()
    assert "Hello, world" in text

only pytest-aiohttp installed: all is fine

When only pytest-aiohttp is installed, the test runs well as it is.

============================================================================================= test session starts =============================================================================================
platform linux -- Python 3.6.3, pytest-3.4.0, py-1.5.2, pluggy-0.6.0
rootdir: /home/javl/devel/tis/dpo-tis-pns, inifile:
collected 1 item

tests/http/test_redisloop.py .                                                                                                                                                                          [100%]

========================================================================================== 1 passed in 0.06 seconds ===========================================================================================

[Process exited 0]

with pytest-asyncio, it fails

When also pytest-asyncio is installed, the test fails with:

self = <ConnectionsPool [db:0, size:[1:10], free:0]>

    async def wait_closed(self):
        """Wait until pool gets closed."""
        await self._close_state.wait()
        assert self._close_waiter is not None
>       await asyncio.shield(self._close_waiter, loop=self._loop)
E       RuntimeError: Task <Task pending coro=<pytest_fixture_setup.<locals>.wrapper.<locals>.setup() running at /home/javl/devel/tis/dpo-tis-pns/.tox/py36/lib/python3.6/site-packages/pytest_asyncio/plugin.p
y:117> cb=[_run_until_complete_cb() at /home/javl/.pyenv/versions/3.6.3/lib/python3.6/asyncio/base_events.py:176]> got Future <Future pending> attached to a different loop

.tox/py36/lib/python3.6/site-packages/aioredis/pool.py:177: RuntimeError
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[33] > /home/javl/devel/tis/dpo-tis-pns/.tox/py36/lib/python3.6/site-packages/aioredis/pool.py(177)wait_closed()
-> await asyncio.shield(self._close_waiter, loop=self._loop)
   6 frames hidden (try 'help hidden_frames')
(Pdb++)

fix by masking loop fixture

To fix this problem (still using pytest-asyncio plugin), one has to uncomment the loop fixture.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:3
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

5reactions
asvetlovcommented, Jul 17, 2018

pytest-asyncio and pytest-aiohttp libraries are not compatible. That’s sad but we should live with it.

0reactions
ChristopheLallementcommented, Jul 17, 2018

I think I’ve encouter same issue with a shorted code using ThreadPoolExecutor without redis. It seems that I can’t use loop fixture from pytest-aiohttp while pytest-asyncio > 0.5.0 is installed.

Following source using event_loop fixture from pytest-asyncio is working fine with pytest-asyncio == 0.8.0 installed :

import asyncio
import pytest
from concurrent.futures import ThreadPoolExecutor

def count():
    return  0


@pytest.fixture
async def my_fixture(event_loop):
    executor = ThreadPoolExecutor()    
    await event_loop.run_in_executor(executor, count)


async def test_f(my_fixture):
    pass

Following source with loop fixture from pytest-aiohttp :

  • is working fine if pytest-asyncio is not installed
  • also working fine if pytest-asyncio == 0.5.0 is installed
  • doesn’t work if pytest-asyncio == 0.8.0 is installed
import asyncio
import pytest
from concurrent.futures import ThreadPoolExecutor


def count():
    return  0


@pytest.fixture
async def my_fixture(loop):
    executor = ThreadPoolExecutor()    
    await loop.run_in_executor(executor, count)


async def test_f(my_fixture):
    pass
Read more comments on GitHub >

github_iconTop Results From Across the Web

pytest-redis - PyPI
This is a pytest plugin, that enables you to test your code that relies on a running Redis database. It allows you to...
Read more >
Redis client-side cache with async Python - Medium
Here I will highlight one feature that was released with Redis 6.0 and explain how you can use it with async python: client-side...
Read more >
pytest-asyncio has a closed event loop, but only when running ...
I have a test to verify an exception is thrown from an async response, which I'm using pytest-asyncio version 0.10.0 to run.
Read more >
Developing with asyncio — Python 3.11.1 documentation
Asynchronous programming is different from classic “sequential” programming. This page lists common mistakes and traps and explains how to avoid them.
Read more >
Asyncio Examples — redis-py dev documentation
Utilizing asyncio Redis requires an explicit disconnect of the connection since there is no asyncio deconstructor magic method. By default, a connection ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found