Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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/924.changed.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The default value of ``asyncio_default_fixture_loop_scope`` is now ``function``. The deprecated unset behavior and warning have been removed.
20 changes: 2 additions & 18 deletions pytest_asyncio/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def pytest_addoption(parser: Parser, pluginmanager: PytestPluginManager) -> None
"asyncio_default_fixture_loop_scope",
type="string",
help="default scope of the asyncio event loop used to execute async fixtures",
default=None,
default="function",
)
parser.addini(
"asyncio_default_test_loop_scope",
Expand Down Expand Up @@ -271,16 +271,6 @@ def _collect_hook_loop_factories(
return factories


_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET = """\
The configuration option "asyncio_default_fixture_loop_scope" is unset.
The event loop scope for asynchronous fixtures will default to the "fixture" caching \
scope. Future versions of pytest-asyncio will default the loop scope for asynchronous \
fixtures to "function" scope. Set the default fixture loop scope explicitly in order \
to avoid unexpected behavior in the future. Valid fixture loop scopes are: \
"function", "class", "module", "package", "session"
"""


def _validate_scope(scope: str | None, option_name: str) -> None:
if scope is None:
return
Expand All @@ -295,8 +285,6 @@ def _validate_scope(scope: str | None, option_name: str) -> None:
def pytest_configure(config: Config) -> None:
default_fixture_loop_scope = config.getini("asyncio_default_fixture_loop_scope")
_validate_scope(default_fixture_loop_scope, "asyncio_default_fixture_loop_scope")
if not default_fixture_loop_scope:
warnings.warn(PytestDeprecationWarning(_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET))

default_test_loop_scope = config.getini("asyncio_default_test_loop_scope")
_validate_scope(default_test_loop_scope, "asyncio_default_test_loop_scope")
Expand Down Expand Up @@ -925,11 +913,7 @@ def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
if not _is_coroutine_or_asyncgen(fixturedef.func):
return (yield)
default_loop_scope = request.config.getini("asyncio_default_fixture_loop_scope")
loop_scope = (
getattr(fixturedef.func, "_loop_scope", None)
or default_loop_scope
or fixturedef.scope
)
loop_scope = getattr(fixturedef.func, "_loop_scope", None) or default_loop_scope
runner_fixture_id = f"_{loop_scope}_scoped_runner"
runner = request.getfixturevalue(runner_fixture_id)
# Prevent the runner closing before the fixture's async teardown.
Expand Down
26 changes: 26 additions & 0 deletions tests/test_fixture_loop_scopes.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,32 @@ async def test_runs_in_same_loop_as_fixture(fixture):
result.assert_outcomes(passed=1)


def test_default_fixture_loop_scope_is_function_when_unset(pytester: Pytester):
Comment thread
SahilArchitect marked this conversation as resolved.
pytester.makepyfile(dedent("""
import asyncio
import pytest
import pytest_asyncio

@pytest_asyncio.fixture(scope="module")
async def fixture_loop():
return asyncio.get_running_loop()

@pytest.mark.asyncio(loop_scope="module")
async def test_fixture_uses_default_function_loop_scope(fixture_loop):
assert asyncio.get_running_loop() is fixture_loop
"""))

result = pytester.runpytest_subprocess("--asyncio-mode=strict", "-W", "error")
result.assert_outcomes(errors=1)
result.stdout.fnmatch_lines(
[
"*asyncio_default_fixture_loop_scope=function*",
"*ScopeMismatch*function scoped fixture _function_scoped_runner*"
"module scoped request object*",
]
)


@pytest.mark.parametrize("default_loop_scope", ("function", "module", "session"))
def test_default_loop_scope_config_option_changes_fixture_loop_scope(
pytester: Pytester,
Expand Down
Loading