Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/1419.deprecated.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Overriding the *event_loop_policy* fixture is deprecated. Use the ``pytest_asyncio_loop_factories`` hook instead.
4 changes: 4 additions & 0 deletions docs/how-to-guides/multiple_loops.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
How to test with different event loops
======================================

.. warning::

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:`custom_loop_factory` for details.

Parametrizing the *event_loop_policy* fixture parametrizes all async tests. The following example causes all async tests to run multiple times, once for each event loop in the fixture parameters:

.. include:: multiple_loops_example.py
Expand Down
2 changes: 1 addition & 1 deletion docs/how-to-guides/uvloop.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Using the event_loop_policy fixture

.. note::

``asyncio.AbstractEventLoopPolicy`` is deprecated as of Python 3.14 (removal planned for 3.16), and ``uvloop.EventLoopPolicy`` will be removed alongside it. Prefer the hook approach above.
``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.

For older versions of Python and uvloop, you can override the *event_loop_policy* fixture in your *conftest.py:*

Expand Down
5 changes: 5 additions & 0 deletions docs/reference/fixtures/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Fixtures

event_loop_policy
=================

.. warning::

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.

Returns the event loop policy used to create asyncio event loops.
The default return value is *asyncio.get_event_loop_policy().*

Expand Down

This file was deleted.

13 changes: 13 additions & 0 deletions pytest_asyncio/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,13 @@ def inner(*args, **kwargs):

@pytest.hookimpl(wrapper=True)
def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
if (
fixturedef.argname == "event_loop_policy"
and fixturedef.func.__module__ != __name__
):
warnings.warn(
PytestDeprecationWarning(_EVENT_LOOP_POLICY_FIXTURE_DEPRECATION_WARNING),
)
asyncio_mode = _get_asyncio_mode(request.config)
if not _is_asyncio_fixture_function(fixturedef.func):
if asyncio_mode == Mode.STRICT:
Expand Down Expand Up @@ -962,6 +969,12 @@ def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
mark.asyncio 'loop_factories' must be a non-empty sequence of strings.
"""

_EVENT_LOOP_POLICY_FIXTURE_DEPRECATION_WARNING = """\
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 to customize event loop creation.\
"""


def _parse_asyncio_marker(
asyncio_marker: Mark,
Expand Down
4 changes: 2 additions & 2 deletions tests/markers/test_class_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ async def test_does_not_use_custom_event_loop_policy():
pytest_args.extend(["-W", "default"])
result = pytester.runpytest(*pytest_args)
if sys.version_info >= (3, 14):
result.assert_outcomes(passed=2, warnings=3)
result.assert_outcomes(passed=2, warnings=4)
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
else:
result.assert_outcomes(passed=2)
Expand Down Expand Up @@ -168,7 +168,7 @@ async def test_parametrized_loop(self, request):
pytest_args.extend(["-W", "default"])
result = pytester.runpytest(*pytest_args)
if sys.version_info >= (3, 14):
result.assert_outcomes(passed=2, warnings=2)
result.assert_outcomes(passed=2, warnings=4)
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
else:
result.assert_outcomes(passed=2)
Expand Down
49 changes: 47 additions & 2 deletions tests/markers/test_function_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ async def test_uses_custom_event_loop_policy():
pytest_args.extend(["-W", "default"])
result = pytester.runpytest(*pytest_args)
if sys.version_info >= (3, 14):
result.assert_outcomes(passed=1, warnings=2)
result.assert_outcomes(passed=1, warnings=3)
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
else:
result.assert_outcomes(passed=1)
Expand Down Expand Up @@ -148,12 +148,57 @@ async def test_parametrized_loop():
pytest_args.extend(["-W", "default"])
result = pytester.runpytest(*pytest_args)
if sys.version_info >= (3, 14):
result.assert_outcomes(passed=2, warnings=3)
result.assert_outcomes(passed=2, warnings=5)
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
else:
result.assert_outcomes(passed=2)


def test_event_loop_policy_fixture_override_emits_deprecation_warning(
pytester: Pytester,
):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent("""\
import asyncio
import pytest

pytestmark = pytest.mark.asyncio

@pytest.fixture
def event_loop_policy():
return asyncio.DefaultEventLoopPolicy()

async def test_anything():
pass
"""),
)
result = pytester.runpytest("--asyncio-mode=strict", "-W", "default")
result.assert_outcomes(passed=1)
result.stdout.fnmatch_lines(
"*PytestDeprecationWarning*event_loop_policy*deprecated*"
)


def test_default_event_loop_policy_fixture_does_not_warn(
pytester: Pytester,
):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(
dedent("""\
import pytest

pytestmark = pytest.mark.asyncio

async def test_anything():
pass
"""),
)
result = pytester.runpytest("--asyncio-mode=strict", "-W", "default")
result.assert_outcomes(passed=1)
result.stdout.no_fnmatch_line("*PytestDeprecationWarning*event_loop_policy*")


def test_asyncio_mark_provides_function_scoped_loop_to_fixtures(
pytester: Pytester,
):
Expand Down
4 changes: 2 additions & 2 deletions tests/markers/test_module_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ async def test_does_not_use_custom_event_loop_policy():
pytest_args.extend(["-W", "default"])
result = pytester.runpytest(*pytest_args)
if sys.version_info >= (3, 14):
result.assert_outcomes(passed=2, warnings=3)
result.assert_outcomes(passed=2, warnings=4)
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
else:
result.assert_outcomes(passed=2)
Expand Down Expand Up @@ -118,7 +118,7 @@ async def test_parametrized_loop():
pytest_args.extend(["-W", "default"])
result = pytester.runpytest(*pytest_args)
if sys.version_info >= (3, 14):
result.assert_outcomes(passed=2, warnings=2)
result.assert_outcomes(passed=2, warnings=4)
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
else:
result.assert_outcomes(passed=2)
Expand Down
4 changes: 2 additions & 2 deletions tests/markers/test_package_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ async def test_also_uses_custom_event_loop_policy():
pytest_args.extend(["-W", "default"])
result = pytester.runpytest(*pytest_args)
if sys.version_info >= (3, 14):
result.assert_outcomes(passed=2, warnings=3)
result.assert_outcomes(passed=2, warnings=4)
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
else:
result.assert_outcomes(passed=2)
Expand Down Expand Up @@ -153,7 +153,7 @@ async def test_parametrized_loop():
pytest_args.extend(["-W", "default"])
result = pytester.runpytest(*pytest_args)
if sys.version_info >= (3, 14):
result.assert_outcomes(passed=2, warnings=2)
result.assert_outcomes(passed=2, warnings=4)
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
else:
result.assert_outcomes(passed=2)
Expand Down
4 changes: 2 additions & 2 deletions tests/markers/test_session_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ async def test_also_uses_custom_event_loop_policy():
pytest_args.extend(["-W", "default"])
result = pytester.runpytest(*pytest_args)
if sys.version_info >= (3, 14):
result.assert_outcomes(passed=2, warnings=3)
result.assert_outcomes(passed=2, warnings=4)
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
else:
result.assert_outcomes(passed=2)
Expand Down Expand Up @@ -154,7 +154,7 @@ async def test_parametrized_loop():
pytest_args.extend(["-W", "default"])
result = pytester.runpytest(*pytest_args)
if sys.version_info >= (3, 14):
result.assert_outcomes(passed=2, warnings=2)
result.assert_outcomes(passed=2, warnings=4)
result.stdout.fnmatch_lines("*DefaultEventLoopPolicy*")
else:
result.assert_outcomes(passed=2)
Expand Down
Loading