Skip to content

Commit 9f75b3c

Browse files
committed
[fix] Fixes an issue that causes DeprecationWarnings for event loop overrides to be emitted, even though the fixture was not overridden.
Signed-off-by: Michael Seifert <m.seifert@digitalernachschub.de>
1 parent b7c66db commit 9f75b3c

File tree

2 files changed

+17
-18
lines changed

2 files changed

+17
-18
lines changed

pytest_asyncio/plugin.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -646,17 +646,6 @@ def pytest_fixture_setup(
646646
) -> Optional[object]:
647647
"""Adjust the event loop policy when an event loop is produced."""
648648
if fixturedef.argname == "event_loop":
649-
# FixtureDef.baseid is an empty string when the Fixture was found in a plugin.
650-
# This is also true, when the fixture was defined in a conftest.py
651-
# at the rootdir.
652-
fixture_filename = inspect.getsourcefile(fixturedef.func)
653-
if not getattr(fixturedef.func, "__original_func", False):
654-
_, fixture_line_number = inspect.getsourcelines(fixturedef.func)
655-
warnings.warn(
656-
_REDEFINED_EVENT_LOOP_FIXTURE_WARNING
657-
% (fixture_filename, fixture_line_number),
658-
DeprecationWarning,
659-
)
660649
# The use of a fixture finalizer is preferred over the
661650
# pytest_fixture_post_finalizer hook. The fixture finalizer is invoked once
662651
# for each fixture, whereas the hook may be invoked multiple times for
@@ -669,6 +658,16 @@ def pytest_fixture_setup(
669658
)
670659
outcome = yield
671660
loop = outcome.get_result()
661+
# Weird behavior was observed when checking for an attribute of FixtureDef.func
662+
# Instead, we now check for a special attribute of the returned event loop
663+
fixture_filename = inspect.getsourcefile(fixturedef.func)
664+
if not getattr(loop, "__original_fixture_loop", False):
665+
_, fixture_line_number = inspect.getsourcelines(fixturedef.func)
666+
warnings.warn(
667+
_REDEFINED_EVENT_LOOP_FIXTURE_WARNING
668+
% (fixture_filename, fixture_line_number),
669+
DeprecationWarning,
670+
)
672671
policy = asyncio.get_event_loop_policy()
673672
try:
674673
with warnings.catch_warnings():
@@ -836,13 +835,13 @@ def pytest_runtest_setup(item: pytest.Item) -> None:
836835
@pytest.fixture
837836
def event_loop(request: FixtureRequest) -> Iterator[asyncio.AbstractEventLoop]:
838837
"""Create an instance of the default event loop for each test case."""
839-
# Add a magic value to the fixture function, so that we can check for overrides
840-
# of this fixture in pytest_fixture_setup
841-
# The magic value must be part of the function definition, because pytest may have
842-
# multiple instances of the fixture function
843-
event_loop.__original_func = True
844-
845838
loop = asyncio.get_event_loop_policy().new_event_loop()
839+
# Add a magic value to the event loop, so pytest-asyncio can determine if the
840+
# event_loop fixture was overridden. Other implementations of event_loop don't
841+
# set this value.
842+
# The magic value must be set as part of the function definition, because pytest
843+
# seems to have multiple instances of the same FixtureDef or fixture function
844+
loop.__original_fixture_loop = True # type: ignore[attr-defined]
846845
yield loop
847846
loop.close()
848847

tests/test_event_loop_fixture_finalizer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,5 @@ async def test_ends_with_unclosed_loop():
133133
)
134134
)
135135
result = pytester.runpytest("--asyncio-mode=strict", "-W", "default")
136-
result.assert_outcomes(passed=1, warnings=2)
136+
result.assert_outcomes(passed=1, warnings=1)
137137
result.stdout.fnmatch_lines("*unclosed event loop*")

0 commit comments

Comments
 (0)