@@ -605,6 +605,119 @@ async def test_debug_mode_visible():
605605 result .assert_outcomes (passed = 1 )
606606
607607
608+ @pytest .mark .parametrize (
609+ ("fixture_scope" , "wider_scope" ),
610+ [
611+ ("function" , "module" ),
612+ ("function" , "package" ),
613+ ("function" , "session" ),
614+ ("module" , "session" ),
615+ ("package" , "session" ),
616+ ],
617+ )
618+ def test_sync_fixture_sees_its_own_loop_when_wider_scoped_loop_active (
619+ pytester : Pytester ,
620+ fixture_scope : str ,
621+ wider_scope : str ,
622+ ) -> None :
623+ pytester .makeini ("[pytest]\n asyncio_default_fixture_loop_scope = function" )
624+ pytester .makeconftest (dedent (f"""\
625+ import asyncio
626+ import pytest_asyncio
627+
628+ class CustomEventLoop(asyncio.SelectorEventLoop):
629+ pass
630+
631+ def pytest_asyncio_loop_factories(config, item):
632+ return {{"custom": CustomEventLoop}}
633+
634+ @pytest_asyncio.fixture(
635+ autouse=True,
636+ scope="{ wider_scope } ",
637+ loop_scope="{ wider_scope } ",
638+ )
639+ async def wider_scoped_fixture():
640+ yield
641+
642+ @pytest_asyncio.fixture(
643+ autouse=True,
644+ scope="{ fixture_scope } ",
645+ loop_scope="{ fixture_scope } ",
646+ )
647+ def sync_fixture_captures_loop():
648+ return id(asyncio.get_event_loop())
649+ """ ))
650+ pytester .makepyfile (dedent (f"""\
651+ import asyncio
652+ import pytest
653+
654+ pytest_plugins = "pytest_asyncio"
655+
656+ @pytest.mark.asyncio(loop_scope="{ fixture_scope } ")
657+ async def test_sync_fixture_and_test_see_same_loop(sync_fixture_captures_loop):
658+ assert sync_fixture_captures_loop == id(asyncio.get_running_loop())
659+ """ ))
660+ result = pytester .runpytest ("--asyncio-mode=strict" )
661+ result .assert_outcomes (passed = 1 )
662+
663+
664+ @pytest .mark .parametrize (
665+ ("fixture_scope" , "wider_scope" ),
666+ [
667+ ("function" , "module" ),
668+ ("function" , "session" ),
669+ ("module" , "session" ),
670+ ],
671+ )
672+ def test_sync_generator_fixture_teardown_sees_own_loop (
673+ pytester : Pytester ,
674+ fixture_scope : str ,
675+ wider_scope : str ,
676+ ) -> None :
677+ pytester .makeini ("[pytest]\n asyncio_default_fixture_loop_scope = function" )
678+ pytester .makeconftest (dedent (f"""\
679+ import asyncio
680+ import pytest_asyncio
681+
682+ class CustomEventLoop(asyncio.SelectorEventLoop):
683+ pass
684+
685+ def pytest_asyncio_loop_factories(config, item):
686+ return {{"custom": CustomEventLoop}}
687+
688+ @pytest_asyncio.fixture(
689+ autouse=True,
690+ scope="{ wider_scope } ",
691+ loop_scope="{ wider_scope } ",
692+ )
693+ async def wider_scoped_fixture():
694+ yield
695+
696+ @pytest_asyncio.fixture(
697+ autouse=True,
698+ scope="{ fixture_scope } ",
699+ loop_scope="{ fixture_scope } ",
700+ )
701+ def sync_generator_fixture():
702+ loop_at_setup = id(asyncio.get_event_loop())
703+ yield loop_at_setup
704+ loop_at_teardown = id(asyncio.get_event_loop())
705+ assert loop_at_setup == loop_at_teardown
706+ """ ))
707+ pytester .makepyfile (dedent (f"""\
708+ import asyncio
709+ import pytest
710+
711+ pytest_plugins = "pytest_asyncio"
712+
713+ @pytest.mark.asyncio(loop_scope="{ fixture_scope } ")
714+ async def test_generator_fixture_sees_correct_loop(sync_generator_fixture):
715+ assert sync_generator_fixture == id(asyncio.get_running_loop())
716+ """ ))
717+ result = pytester .runpytest ("--asyncio-mode=strict" )
718+ result .assert_outcomes (passed = 1 )
719+
720+
608721@pytest .mark .parametrize ("loop_scope" , ("module" , "package" , "session" ))
609722def test_async_generator_fixture_teardown_runs_under_custom_factory (
610723 pytester : Pytester ,
0 commit comments