Skip to content

Commit c3ca1f3

Browse files
committed
feat!: Removed event_loop fixture.
1 parent 22b4080 commit c3ca1f3

18 files changed

+26
-797
lines changed

docs/reference/fixtures/event_loop_example.py

Lines changed: 0 additions & 5 deletions
This file was deleted.

docs/reference/fixtures/index.rst

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,6 @@
22
Fixtures
33
========
44

5-
event_loop
6-
==========
7-
*This fixture is deprecated.*
8-
9-
*If you want to request an asyncio event loop with a scope other than function
10-
scope, use the "loop_scope" argument to* :ref:`reference/markers/asyncio` *when marking the tests.
11-
If you want to return different types of event loops, use the* :ref:`reference/fixtures/event_loop_policy`
12-
*fixture.*
13-
14-
Creates a new asyncio event loop based on the current event loop policy. The new loop
15-
is available as the return value of this fixture for synchronous functions, or via `asyncio.get_running_loop <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.get_running_loop>`__ for asynchronous functions.
16-
The event loop is closed when the fixture scope ends.
17-
The fixture scope defaults to ``function`` scope.
18-
19-
.. include:: event_loop_example.py
20-
:code: python
21-
22-
Note that, when using the ``event_loop`` fixture, you need to interact with the event loop using methods like ``event_loop.run_until_complete``. If you want to *await* code inside your test function, you need to write a coroutine and use it as a test function. The :ref:`asyncio <reference/markers/asyncio>` marker
23-
is used to mark coroutines that should be treated as test functions.
24-
25-
If you need to change the type of the event loop, prefer setting a custom event loop policy over redefining the ``event_loop`` fixture.
26-
27-
If the ``pytest.mark.asyncio`` decorator is applied to a test function, the ``event_loop``
28-
fixture will be requested automatically by the test function.
29-
30-
.. _reference/fixtures/event_loop_policy:
31-
325
event_loop_policy
336
=================
347
Returns the event loop policy used to create asyncio event loops.

pytest_asyncio/plugin.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,17 @@ def _preprocess_async_fixtures(
259259
# Ignore async fixtures without explicit asyncio mark in strict mode
260260
# This applies to pytest_trio fixtures, for example
261261
continue
262-
scope = (
262+
loop_scope = (
263263
getattr(func, "_loop_scope", None)
264264
or default_loop_scope
265265
or fixturedef.scope
266266
)
267-
if scope == "function" and "event_loop" not in fixturedef.argnames:
268-
fixturedef.argnames += ("event_loop",)
269-
_make_asyncio_fixture_function(func, scope)
267+
if (
268+
loop_scope == "function"
269+
and "_function_event_loop" not in fixturedef.argnames
270+
):
271+
fixturedef.argnames += ("_function_event_loop",)
272+
_make_asyncio_fixture_function(func, loop_scope)
270273
function_signature = inspect.signature(func)
271274
if "event_loop" in function_signature.parameters:
272275
warnings.warn(
@@ -415,7 +418,7 @@ def _get_event_loop_fixture_id_for_async_fixture(
415418
getattr(func, "_loop_scope", None) or default_loop_scope or request.scope
416419
)
417420
if loop_scope == "function":
418-
event_loop_fixture_id = "event_loop"
421+
event_loop_fixture_id = "_function_event_loop"
419422
else:
420423
event_loop_node = _retrieve_scope_root(request._pyfuncitem, loop_scope)
421424
event_loop_fixture_id = event_loop_node.stash.get(
@@ -1101,7 +1104,7 @@ def pytest_runtest_setup(item: pytest.Item) -> None:
11011104
parent_node = _retrieve_scope_root(item, scope)
11021105
event_loop_fixture_id = parent_node.stash[_event_loop_fixture_id]
11031106
else:
1104-
event_loop_fixture_id = "event_loop"
1107+
event_loop_fixture_id = "_function_event_loop"
11051108
fixturenames = item.fixturenames # type: ignore[attr-defined]
11061109
if event_loop_fixture_id not in fixturenames:
11071110
fixturenames.append(event_loop_fixture_id)
@@ -1170,11 +1173,20 @@ def _retrieve_scope_root(item: Collector | Item, scope: str) -> Collector:
11701173
raise pytest.UsageError(error_message)
11711174

11721175

1173-
@pytest.fixture
1174-
def event_loop(request: FixtureRequest) -> Iterator[asyncio.AbstractEventLoop]:
1175-
"""Create an instance of the default event loop for each test case."""
1176-
new_loop_policy = request.getfixturevalue(event_loop_policy.__name__)
1177-
with _temporary_event_loop_policy(new_loop_policy), _provide_event_loop() as loop:
1176+
@pytest.fixture(
1177+
scope="function",
1178+
name="_function_event_loop",
1179+
)
1180+
def _function_event_loop(
1181+
*args, # Function needs to accept "cls" when collected by pytest.Class
1182+
event_loop_policy,
1183+
) -> Iterator[asyncio.AbstractEventLoop]:
1184+
new_loop_policy = event_loop_policy
1185+
with (
1186+
_temporary_event_loop_policy(new_loop_policy),
1187+
_provide_event_loop() as loop,
1188+
):
1189+
asyncio.set_event_loop(loop)
11781190
yield loop
11791191

11801192

tests/async_fixtures/test_async_fixtures_scope.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
import pytest
1111

12+
import pytest_asyncio
13+
1214

1315
@pytest.fixture(scope="module")
1416
def event_loop():
@@ -18,7 +20,7 @@ def event_loop():
1820
loop.close()
1921

2022

21-
@pytest.fixture(scope="module")
23+
@pytest_asyncio.fixture(scope="module", loop_scope="module")
2224
async def async_fixture():
2325
await asyncio.sleep(0.1)
2426
return 1

tests/async_fixtures/test_parametrized_loop.py

Lines changed: 0 additions & 48 deletions
This file was deleted.

tests/conftest.py

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,3 @@
11
from __future__ import annotations
22

3-
import asyncio
4-
5-
import pytest
6-
73
pytest_plugins = "pytester"
8-
9-
10-
@pytest.fixture
11-
def dependent_fixture(event_loop):
12-
"""A fixture dependent on the event_loop fixture, doing some cleanup."""
13-
counter = 0
14-
15-
async def just_a_sleep():
16-
"""Just sleep a little while."""
17-
nonlocal event_loop
18-
await asyncio.sleep(0.1)
19-
nonlocal counter
20-
counter += 1
21-
22-
event_loop.run_until_complete(just_a_sleep())
23-
yield
24-
event_loop.run_until_complete(just_a_sleep())
25-
26-
assert counter == 2
27-
28-
29-
@pytest.fixture(scope="session", name="factory_involving_factories")
30-
def factory_involving_factories_fixture(unused_tcp_port_factory):
31-
def factory():
32-
return unused_tcp_port_factory()
33-
34-
return factory

tests/hypothesis/test_base.py

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -45,43 +45,6 @@ async def test_mark_and_parametrize(x, y):
4545
assert y in (1, 2)
4646

4747

48-
def test_can_use_explicit_event_loop_fixture(pytester: Pytester):
49-
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = module")
50-
pytester.makepyfile(
51-
dedent(
52-
"""\
53-
import asyncio
54-
import pytest
55-
from hypothesis import given
56-
import hypothesis.strategies as st
57-
58-
pytest_plugins = 'pytest_asyncio'
59-
60-
@pytest.fixture(scope="module")
61-
def event_loop():
62-
loop = asyncio.get_event_loop_policy().new_event_loop()
63-
yield loop
64-
loop.close()
65-
66-
@given(st.integers())
67-
@pytest.mark.asyncio
68-
async def test_explicit_fixture_request(event_loop, n):
69-
semaphore = asyncio.Semaphore(value=0)
70-
event_loop.call_soon(semaphore.release)
71-
await semaphore.acquire()
72-
"""
73-
)
74-
)
75-
result = pytester.runpytest_subprocess("--asyncio-mode=strict", "-W default")
76-
result.assert_outcomes(passed=1, warnings=2)
77-
result.stdout.fnmatch_lines(
78-
[
79-
'*is asynchronous and explicitly requests the "event_loop" fixture*',
80-
"*event_loop fixture provided by pytest-asyncio has been redefined*",
81-
]
82-
)
83-
84-
8548
def test_async_auto_marked(pytester: Pytester):
8649
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
8750
pytester.makepyfile(

tests/loop_fixture_scope/__init__.py

Whitespace-only changes.

tests/loop_fixture_scope/conftest.py

Lines changed: 0 additions & 17 deletions
This file was deleted.

tests/loop_fixture_scope/test_loop_fixture_scope.py

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)