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

event loop is closed before my fixture's finalizer runs #30

Closed
lars-tiede opened this issue Jun 18, 2016 · 8 comments
Closed

event loop is closed before my fixture's finalizer runs #30

lars-tiede opened this issue Jun 18, 2016 · 8 comments

Comments

@lars-tiede
Copy link

lars-tiede commented Jun 18, 2016

Consider this:

import pytest


async def foo():
    print("foo")


@pytest.yield_fixture
def my_fixture(event_loop):
    print(event_loop.is_closed()) # "False"
    event_loop.run_until_complete(foo()) # "foo"

    yield None

    print(event_loop.is_closed()) # "True"... noooo!
    event_loop.run_until_complete(foo()) # goes boom


@pytest.mark.asyncio
async def test_foo(my_fixture):
    await foo()

Run this code with py.test -s <file> and you'll see the output as indicated by the comments in the code.

The event loop is closed before my finalizer code can run. This is also the case when I write my fixture without a yield, instead adding a finalizer function.

This is weird. I'm pretty sure that this worked just fine a couple of months ago.

@Tinche
Copy link
Member

Tinche commented Jun 18, 2016

Yeah, it's a known thing, discussed more at #29.

The recent changes simplified the event loop fixture so it would be easier to override. However, now the closing logic isn't in the fixture but in the plugin.

For 0.5, we should make the event_loop fixture a proper fixture, with cleanup logic inside, and remove the close from the plugin itself. The fixture will be a little more complex (which we can counteract with a recipe for overriding in the README) but it'd be more in the spirit of Pytest and would allow dependent fixtures to work properly (also allow overriding the scope etc).

Haven't gotten around to it just yet, patches welcome :)

@lars-tiede
Copy link
Author

Ah, I wasn't aware of that. If I may weigh in, I think the event loop should only be closed after my_fixture ran its cleanup code. Principle of least surprise and such. How to do this best I don't know, though :)

Back to my concrete problem: the workaround you wrote here works, however I had to add asyncio.set_event_loop() for it to work for my case.

For the sake of completeness, here's your workaround including my addition of set_event_loop():

@pytest.yield_fixture
def event_loop():
    """Create an instance of the default event loop for each test case."""
    policy = asyncio.get_event_loop_policy()
    res = policy.new_event_loop()
    asyncio.set_event_loop(res)
    res._close = res.close
    res.close = lambda: None

    yield res

    res._close()

@hynek
Copy link
Contributor

hynek commented Jul 4, 2016

FWIW I believe this is the reason why upgrading pytest-asyncio broke all my integration tests that need to close their connection fixtures at the end (getting RuntimeError: Event loop is closed). Did it work by accident before or what is the rationale? Pinning at <0.4.0 for now.

@Tinche
Copy link
Member

Tinche commented Sep 7, 2016

Hi, this issue should be solved by the latest release (0.5.0). Please close if that's the case!

@hynek
Copy link
Contributor

hynek commented Sep 8, 2016

Fixed it for me, thanks!

@Tinche Tinche closed this as completed Nov 26, 2016
smagafurov pushed a commit to smagafurov/pytest-asyncio that referenced this issue Apr 4, 2018
…ee.Proxy; also database's .allow_sync converted to context manager; database's .allow_sync setter marked as deprecated
@kmkmjhyiiiu
Copy link

I'm still facing this issue :/

@seifertm
Copy link
Contributor

@Ammadkhalid I don't mean to be rude, but your comment doesn't provide any additional information on the issue and isn't really helpful to anyone.

If you open a new Q&A discussion, we may be able to help you. If you think the bug still persists and it's a problem with pytest-asyncio, feel free to open a new issue. In any case, we can only help if you provide a minimal reproducible example.

@kmkmjhyiiiu
Copy link

@seifertm sorry for not providing information, I was creating video tutorial Setting Up Test Suits Using Pytest for a Tortoise ORM library and this is where i took advantage of this awesome Pytest plugin for asynchronous tests. I'm using this plugin version 0.21.0 However, i face the similar issue where event loop is being closed before fixture finalizer runs, https://github.com/Systembound/Just-FastApi_Tortoise-model-ORM-tests/blob/main/tests/conftest.py#L10

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

5 participants