Skip to content

Need to call asyncio.set_event_loop() in my tests #35

Closed
@AndreLouisCaron

Description

@AndreLouisCaron

Hi there!

I'm porting some of my tests from v0.3.0 to v0.5.0 and I have a test that behaves strangely when I switch to v0.4.1 or later.

After some debugging, I noticed that id(event_loop) inside the test and id(asyncio.get_event_loop()) return different results for versions after v0.4.1 and v0.5.0.

After adding a call to asyncio.set_event_loop(event_loop) in my tests like this:

def test_serve(event_loop, cli):
    asyncio.set_event_loop(event_loop)  # wasn't required with v0.3.0.

Notice that I'm not using @pytest.mark.asyncio here. I can't use it because I'm testing a click CLI that calls event_loop.run_until_complete() internally.

I guess this is explained by the fact that the event_loop fixture stopped calling asyncio.set_event_loop() when the @pytest.mark.asyncio(forbid_global_event_loop=...) syntax was introduced in v0.4.0.

In short, it seems like using only the event_loop fixture (e.g. without @pytest.mark.asyncio) leads to a surprising result. I thing that the (absence of a) relationship between the event_loop fixture and asyncio.get_event_loop() should be added to the documentation to make it more obvious. If you're OK with this, I can send in a PR to fix it.

In passing, I think there's a big quirk in the API here: the behaviour for using the event_loop fixture without the asyncio marker is surprising, to say to least. The havior in v0.3.0 was much better than it is now in that respect. This seems to be caused by the fact that forbid_global_event_loop is marker parameter rather than a fixture. If the policy for controlling the relationship with the default event loop were a fixture, it would allow the event_loop fixture to decide what to do with the default event loop.

I've seen @asvetlov's comments in issue #12 and PR #24. There seems to be some contention over whether returning exceptions from asyncio.get_event_loop() should be the default or not. I don't have a specific position on this, but I am convinced that either it should return the same value as the event_loop fixture or it should fail (having two event loops by default is not ideal). A neat side-effect of making the policy for the default event loop a fixture on which the event_loop fixture depends (instead of a parameter to the marker) would be to allow defining a project-specific default: each project would be able to define this new fixture as something returning a boolean (or enum value) to choose the policy and use autouse to make it a project specific default.

What are your thoughts on this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions