pytest-dev/pytest-asyncio

API for loop configuration options

asvetlov opened this issue · 1 comments

This issue doesn't propose a specific codebase change but is a point for discussing future steps in the plugin evolution.

Python has deprecated event loop policies since (unreleased) py-3.14.

The main asyncio motion idea for this and related changes is:

  1. Don't instantiate the loop explicitly, but use Runner (introduced in 3.11, there is a backport library for older Python version).
  2. Control runner behavior by debug and loop_factory arguments.
  3. There are eager tasks since 3.12; maybe the runner will have the option to configure it as well if we make an agreement

I think pytest-asyncio should reflect these changes.

  1. event_loop_policy() fixture should be deprecated along with event_loop.
  2. The library should not introduce public fixtures except unused_tcp_port and family. It is very fragile, especially if a user starts fixture overriding.
  3. Fine-grained control could be done by special pytest.mark.asyncio(...) arguments.
  4. Coarse-grained control uses configfile parameters and, maybe, cmdline args.
  5. Implementation details could vary; we are free to change them in the wild until the details are not leaked into the public space. The plugin already has a good movement in this direction, so I merely summarized what we do.

Please share your opinions in the comments, guys.

I'm not sure how we can make use of eager tasks, since I haven't used them, yet. My current understanding is that it is intended as a performance improvement.

Other than that, I totally agree with your points!

Thanks for pointing out the backport of asyncio.Runner! I wasn't aware of this, since there was no backport last time I checked. This could be the missing piece to properly tackle #127 and to simplify a lot of the code.

I think pytest-asyncio should reflect these changes.

1. `event_loop_policy()` fixture should be deprecated along with `event_loop`.

The only purpose of the event_loop_policy is to allow testing against multiple event loops. The fixture was introduced due to lack of a better idea and is currently broken for code bases that mix sync and async tests (see #796). I already tried twice to fix this without success. The fact that the code base supports both the event_loop fixture and the newer @pytest.mark.asyncio(loop_scope=…) approach complicates things even more.

I'm in favor of deprecating it, but I think we should first provide a working replacement to parametrize tests over event loop implementations. I would be interested to see an API proposal how we want users to do this. Maybe something like pytest.mark.asyncio(loop_factory=…) and/or a config option?

I fully agree with the rest of your points. Thanks for the push!