Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing an internally async module breaks async tests that come after #210

Closed
anordal opened this issue Apr 20, 2021 · 4 comments
Closed

Comments

@anordal
Copy link

anordal commented Apr 20, 2021

Am I doing anything wrong here? This used to work until recently. The error message looks a lot like #209.

import asyncio
import pytest


async def internally_async_impl() -> int:
    return 0


def innocent_unrelated() -> int:
    return asyncio.run(internally_async_impl())


# Passes
@pytest.mark.asyncio
async def test_asyncio_before() -> None:
    await asyncio.sleep(0)


# Passes
def test_innocent_unrelated_module() -> None:
    innocent_unrelated()


# Fails
@pytest.mark.asyncio
async def test_asyncio_after() -> None:
    await asyncio.sleep(0)

The third test fails because the second stole the event loop:

==== ERRORS ====
____ ERROR at setup of test_asyncio_after ____

fixturedef = <FixtureDef argname='event_loop' scope='function' baseid=''>, request = <SubRequest 'event_loop' for <Function test_asyncio_after>>

    @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()

/usr/local/lib/python3.9/dist-packages/pytest_asyncio/plugin.py:94: 
_ _ _

self = <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x7f1a0856e3a0>

    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
                threading.current_thread() is threading.main_thread()):
            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/lib/python3.9/asyncio/events.py:642: RuntimeError

Workaround (found by accident, I don't know why this works):

 # Passes
+@pytest.mark.asyncio
 def test_innocent_unrelated_module() -> None:
     innocent_unrelated()

This is with pytest-asyncio 0.15.0.

@Tinche
Copy link
Member

Tinche commented Apr 20, 2021

Can you check master?

@anordal
Copy link
Author

anordal commented Apr 21, 2021

Can you check master

It wasn't too easy to get to a standalone pytest-asyncio setup. E.g. in virtualenv:

ModuleNotFoundError: No module named 'pytest_asyncio.plugin'; 'pytest_asyncio' is not a package

@Tinche
Copy link
Member

Tinche commented Apr 21, 2021

I believe this should be fixed by 0.15.1!

@anordal
Copy link
Author

anordal commented Apr 22, 2021

Indeed, it works after updating to 0.15.1.

Thank you Tinche, for the swift fix!

@anordal anordal closed this as completed Apr 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants