Skip to content

Commit e658814

Browse files
committed
feat!: Remove deprecated event_loop_policy fixture.
1 parent 1975f90 commit e658814

13 files changed

Lines changed: 24 additions & 701 deletions

docs/how-to-guides/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ How-To Guides
1616
run_class_tests_in_same_loop
1717
run_module_tests_in_same_loop
1818
run_package_tests_in_same_loop
19-
multiple_loops
2019
parametrize_with_asyncio
2120
uvloop
2221
test_item_is_async

docs/how-to-guides/multiple_loops.rst

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

docs/how-to-guides/multiple_loops_example.py

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

docs/how-to-guides/uvloop.rst

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,3 @@ Define a ``pytest_asyncio_loop_factories`` hook in your *conftest.py* that maps
1818

1919
:doc:`custom_loop_factory`
2020
More details on the ``pytest_asyncio_loop_factories`` hook, including per-test factory selection and multiple factory parametrization.
21-
22-
Using the event_loop_policy fixture
23-
-----------------------------------
24-
25-
.. note::
26-
27-
``asyncio.AbstractEventLoopPolicy`` is deprecated as of Python 3.14 (removal planned for 3.16), and ``uvloop.EventLoopPolicy`` will be removed alongside it. Overriding the *event_loop_policy* fixture is also deprecated in pytest-asyncio. Prefer the hook approach above.
28-
29-
For older versions of Python and uvloop, you can override the *event_loop_policy* fixture in your *conftest.py:*
30-
31-
.. code-block:: python
32-
33-
import pytest
34-
import uvloop
35-
36-
37-
@pytest.fixture(scope="session")
38-
def event_loop_policy():
39-
return uvloop.EventLoopPolicy()
40-
41-
You may choose to limit the scope of the fixture to *package,* *module,* or *class,* if you only want a subset of your tests to run with uvloop.

docs/reference/fixtures/event_loop_policy_example.py

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

docs/reference/fixtures/event_loop_policy_parametrized_example.py

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

docs/reference/fixtures/index.rst

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

5-
event_loop_policy
6-
=================
7-
8-
.. warning::
9-
10-
Overriding the *event_loop_policy* fixture is deprecated and will be removed in a future version of pytest-asyncio. Use the ``pytest_asyncio_loop_factories`` hook instead. See :doc:`../hooks` for details.
11-
12-
Returns the event loop policy used to create asyncio event loops.
13-
The default return value is *asyncio.get_event_loop_policy().*
14-
15-
This fixture can be overridden when a different event loop policy should be used.
16-
17-
.. include:: event_loop_policy_example.py
18-
:code: python
19-
20-
Multiple policies can be provided via fixture parameters.
21-
The fixture is automatically applied to all pytest-asyncio tests.
22-
Therefore, all tests managed by pytest-asyncio are run once for each fixture parameter.
23-
The following example runs the test with different event loop policies.
24-
25-
.. include:: event_loop_policy_parametrized_example.py
26-
:code: python
27-
285
unused_tcp_port
296
===============
307
Finds and yields a single unused TCP port on the localhost interface. Useful for

pytest_asyncio/plugin.py

Lines changed: 24 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -804,30 +804,6 @@ def _temporary_event_loop(loop: AbstractEventLoop) -> Iterator[None]:
804804
_set_event_loop(old_loop)
805805

806806

807-
@contextlib.contextmanager
808-
def _temporary_event_loop_policy(
809-
policy: AbstractEventLoopPolicy,
810-
) -> Iterator[None]:
811-
old_loop_policy = _get_event_loop_policy()
812-
_set_event_loop_policy(policy)
813-
try:
814-
yield
815-
finally:
816-
_set_event_loop_policy(old_loop_policy)
817-
818-
819-
def _get_event_loop_policy() -> AbstractEventLoopPolicy:
820-
with warnings.catch_warnings():
821-
warnings.simplefilter("ignore", DeprecationWarning)
822-
return asyncio.get_event_loop_policy()
823-
824-
825-
def _set_event_loop_policy(policy: AbstractEventLoopPolicy) -> None:
826-
with warnings.catch_warnings():
827-
warnings.simplefilter("ignore", DeprecationWarning)
828-
asyncio.set_event_loop_policy(policy)
829-
830-
831807
def _get_event_loop_no_warn(
832808
policy: AbstractEventLoopPolicy | None = None,
833809
) -> asyncio.AbstractEventLoop:
@@ -910,13 +886,6 @@ def inner(*args, **kwargs):
910886

911887
@pytest.hookimpl(wrapper=True)
912888
def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
913-
if (
914-
fixturedef.argname == "event_loop_policy"
915-
and fixturedef.func.__module__ != __name__
916-
):
917-
warnings.warn(
918-
PytestDeprecationWarning(_EVENT_LOOP_POLICY_FIXTURE_DEPRECATION_WARNING),
919-
)
920889
asyncio_mode = _get_asyncio_mode(request.config)
921890
if not _is_asyncio_fixture_function(fixturedef.func):
922891
if asyncio_mode == Mode.STRICT:
@@ -960,12 +929,6 @@ def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
960929
mark.asyncio 'loop_factories' must be a non-empty sequence of strings.
961930
"""
962931

963-
_EVENT_LOOP_POLICY_FIXTURE_DEPRECATION_WARNING = """\
964-
Overriding the "event_loop_policy" fixture is deprecated \
965-
and will be removed in a future version of pytest-asyncio. \
966-
Use the "pytest_asyncio_loop_factories" hook to customize event loop creation.\
967-
"""
968-
969932

970933
def _parse_asyncio_marker(
971934
asyncio_marker: Mark,
@@ -1027,38 +990,35 @@ def _create_scoped_runner_fixture(scope: _ScopeName) -> Callable:
1027990
name=f"_{scope}_scoped_runner",
1028991
)
1029992
def _scoped_runner(
1030-
event_loop_policy,
1031993
_asyncio_loop_factory,
1032994
request: FixtureRequest,
1033995
) -> Iterator[Runner]:
1034-
new_loop_policy = event_loop_policy
1035996
debug_mode = _get_asyncio_debug(request.config)
1036-
with _temporary_event_loop_policy(new_loop_policy):
1037-
runner = Runner(
1038-
debug=debug_mode,
1039-
loop_factory=_asyncio_loop_factory,
1040-
).__enter__()
1041-
if _asyncio_loop_factory is not None:
1042-
_set_event_loop(runner.get_loop())
1043-
try:
1044-
yield runner
1045-
except Exception as e:
1046-
runner.__exit__(type(e), e, e.__traceback__)
1047-
else:
1048-
with warnings.catch_warnings():
1049-
warnings.filterwarnings(
1050-
"ignore", ".*BaseEventLoop.shutdown_asyncgens.*", RuntimeWarning
997+
runner = Runner(
998+
debug=debug_mode,
999+
loop_factory=_asyncio_loop_factory,
1000+
).__enter__()
1001+
if _asyncio_loop_factory is not None:
1002+
_set_event_loop(runner.get_loop())
1003+
try:
1004+
yield runner
1005+
except Exception as e:
1006+
runner.__exit__(type(e), e, e.__traceback__)
1007+
else:
1008+
with warnings.catch_warnings():
1009+
warnings.filterwarnings(
1010+
"ignore", ".*BaseEventLoop.shutdown_asyncgens.*", RuntimeWarning
1011+
)
1012+
try:
1013+
runner.__exit__(None, None, None)
1014+
except RuntimeError:
1015+
warnings.warn(
1016+
_RUNNER_TEARDOWN_WARNING % traceback.format_exc(),
1017+
RuntimeWarning,
10511018
)
1052-
try:
1053-
runner.__exit__(None, None, None)
1054-
except RuntimeError:
1055-
warnings.warn(
1056-
_RUNNER_TEARDOWN_WARNING % traceback.format_exc(),
1057-
RuntimeWarning,
1058-
)
1059-
finally:
1060-
if _asyncio_loop_factory is not None:
1061-
_set_event_loop(None)
1019+
finally:
1020+
if _asyncio_loop_factory is not None:
1021+
_set_event_loop(None)
10621022

10631023
return _scoped_runner
10641024

@@ -1074,12 +1034,6 @@ def _asyncio_loop_factory(request: FixtureRequest) -> LoopFactory | None:
10741034
return getattr(request, "param", None)
10751035

10761036

1077-
@pytest.fixture(scope="session", autouse=True)
1078-
def event_loop_policy() -> AbstractEventLoopPolicy:
1079-
"""Return an instance of the policy used to create asyncio event loops."""
1080-
return _get_event_loop_policy()
1081-
1082-
10831037
def is_async_test(item: Item) -> TypeIs[PytestAsyncioFunction]:
10841038
"""Returns whether a test item is a pytest-asyncio test"""
10851039
return isinstance(item, PytestAsyncioFunction)

tests/markers/test_class_scope.py

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from __future__ import annotations
44

55
import asyncio
6-
import sys
76
from textwrap import dedent
87

98
import pytest
@@ -98,82 +97,6 @@ async def test_this_runs_in_same_loop(self):
9897
result.assert_outcomes(passed=2)
9998

10099

101-
def test_asyncio_mark_respects_the_loop_policy(
102-
pytester: pytest.Pytester,
103-
):
104-
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
105-
pytester.makepyfile(dedent("""\
106-
import asyncio
107-
import pytest
108-
109-
class CustomEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
110-
pass
111-
112-
class TestUsesCustomEventLoop:
113-
@pytest.fixture(scope="class")
114-
def event_loop_policy(self):
115-
return CustomEventLoopPolicy()
116-
117-
@pytest.mark.asyncio
118-
async def test_uses_custom_event_loop_policy(self):
119-
assert isinstance(
120-
asyncio.get_event_loop_policy(),
121-
CustomEventLoopPolicy,
122-
)
123-
124-
@pytest.mark.asyncio
125-
async def test_does_not_use_custom_event_loop_policy():
126-
assert not isinstance(
127-
asyncio.get_event_loop_policy(),
128-
CustomEventLoopPolicy,
129-
)
130-
"""))
131-
pytest_args = ["--asyncio-mode=strict"]
132-
if sys.version_info >= (3, 14):
133-
pytest_args.extend(["-W", "default"])
134-
result = pytester.runpytest(*pytest_args)
135-
if sys.version_info >= (3, 14):
136-
result.assert_outcomes(passed=2, warnings=4)
137-
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
138-
else:
139-
result.assert_outcomes(passed=2)
140-
141-
142-
def test_asyncio_mark_respects_parametrized_loop_policies(
143-
pytester: pytest.Pytester,
144-
):
145-
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
146-
pytester.makepyfile(dedent("""\
147-
import asyncio
148-
149-
import pytest
150-
151-
@pytest.fixture(
152-
scope="class",
153-
params=[
154-
asyncio.DefaultEventLoopPolicy(),
155-
asyncio.DefaultEventLoopPolicy(),
156-
]
157-
)
158-
def event_loop_policy(request):
159-
return request.param
160-
161-
@pytest.mark.asyncio(loop_scope="class")
162-
class TestWithDifferentLoopPolicies:
163-
async def test_parametrized_loop(self, request):
164-
pass
165-
"""))
166-
pytest_args = ["--asyncio-mode=strict"]
167-
if sys.version_info >= (3, 14):
168-
pytest_args.extend(["-W", "default"])
169-
result = pytester.runpytest(*pytest_args)
170-
if sys.version_info >= (3, 14):
171-
result.assert_outcomes(passed=2, warnings=4)
172-
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
173-
else:
174-
result.assert_outcomes(passed=2)
175-
176-
177100
def test_asyncio_mark_provides_class_scoped_loop_to_fixtures(
178101
pytester: pytest.Pytester,
179102
):

0 commit comments

Comments
 (0)