Skip to content

got Future <Future pending> attached to a different loop #166

Description

@kaijajan

I'm working on a pytest/pytest-asyncio/asyncio test, however, I encounterd a strange issue "got Future attached to a different loop"
Not quite sure if my issue is exactly the same as others.
I created client/server tests using pytest and asyncio, the fixture would return a client object contains asyncio streams object.
But while multiple tests executed in tests, the error "got Future attached to a different loop" shows. (the test would pass if only one test func in script)
And have been studying for a while and have no clue how to move on.
Any idea which step went wrong? and Anyone knows how to solve the issue?
Thanks

my test code:
https://github.com/kaijajan/pytest_asyncio_issue

The following block is the log.

❯ pytest -v --capture=no
=========================================== test session starts ============================================
platform darwin -- Python 3.7.7, pytest-5.4.3, py-1.8.1, pluggy-0.13.1 -- /usr/local/opt/python/bin/python3.7
cachedir: .pytest_cache
metadata: {'Python': '3.7.7', 'Platform': 'Darwin-18.6.0-x86_64-i386-64bit', 'Packages': {'pytest': '5.4.3', 'py': '1.8.1', 'pluggy': '0.13.1'}, 'Plugins': {'timeout': '1.3.4', 'metadata': '1.9.0', 'asyncio': '0.12.0', 'html': '2.1.1'}}
rootdir: /Volumes/MacData/workspaces/python/temp/pytest_asyncio_issue
plugins: timeout-1.3.4, metadata-1.9.0, asyncio-0.12.0, html-2.1.1
collected 2 items                                                                                          

test_1.py::test_1 client init
connecting
connected, yielding
received: hello 0 returned
received: hello 1 returned
received: hello 2 returned
received: hello 3 returned
received: hello 4 returned
received: hello 5 returned
received: hello 6 returned
received: hello 7 returned
received: hello 8 returned
received: hello 9 returned
hello world
PASSED
test_1.py::test_2 FAILED

================================================= FAILURES =================================================
__________________________________________________ test_2 __________________________________________________

client = <client.SimpleClient object at 0x10dd3b610>

    @pytest.mark.usefixtures('client')
    @pytest.mark.asyncio
    async def test_2(client):
        for i in range(10):
            await client.send(f'hello {i}')
>           data = await client.receive()

test_1.py:21: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
client.py:25: in receive
    tmp = await self.reader.read(size)
/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/streams.py:640: in read
    await self._wait_for_data('read')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <StreamReader transport=<_SelectorSocketTransport fd=17>>, func_name = 'read'

    async def _wait_for_data(self, func_name):
        """Wait until feed_data() or feed_eof() is called.
    
        If stream was paused, automatically resume it.
        """
        # StreamReader uses a future to link the protocol feed_data() method
        # to a read coroutine. Running two read coroutines at the same time
        # would have an unexpected behaviour. It would not possible to know
        # which coroutine would get the next data.
        if self._waiter is not None:
            raise RuntimeError(
                f'{func_name}() called while another coroutine is '
                f'already waiting for incoming data')
    
        assert not self._eof, '_wait_for_data after EOF'
    
        # Waiting for data while paused will make deadlock, so prevent it.
        # This is essential for readexactly(n) for case when n > self._limit.
        if self._paused:
            self._paused = False
            self._transport.resume_reading()
    
        self._waiter = self._loop.create_future()
        try:
>           await self._waiter
E           RuntimeError: Task <Task pending coro=<test_2() running at /Volumes/MacData/workspaces/python/temp/pytest_asyncio_issue/test_1.py:21> cb=[_run_until_complete_cb() at /usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py:157]> got Future <Future pending> attached to a different loop

/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/streams.py:473: RuntimeError
========================================= short test summary info ==========================================
FAILED test_1.py::test_2 - RuntimeError: Task <Task pending coro=<test_2() running at /Volumes/MacData/wo...
======================================= 1 failed, 1 passed in 1.13s ========================================

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions