@@ -605,6 +605,127 @@ 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(
658+ sync_fixture_captures_loop,
659+ ):
660+ assert sync_fixture_captures_loop == id(
661+ asyncio.get_running_loop()
662+ )
663+ """ ))
664+ result = pytester .runpytest ("--asyncio-mode=strict" )
665+ result .assert_outcomes (passed = 1 )
666+
667+
668+ @pytest .mark .parametrize (
669+ ("fixture_scope" , "wider_scope" ),
670+ [
671+ ("function" , "module" ),
672+ ("function" , "session" ),
673+ ("module" , "session" ),
674+ ],
675+ )
676+ def test_sync_generator_fixture_teardown_sees_own_loop (
677+ pytester : Pytester ,
678+ fixture_scope : str ,
679+ wider_scope : str ,
680+ ) -> None :
681+ pytester .makeini ("[pytest]\n asyncio_default_fixture_loop_scope = function" )
682+ pytester .makeconftest (dedent (f"""\
683+ import asyncio
684+ import pytest_asyncio
685+
686+ class CustomEventLoop(asyncio.SelectorEventLoop):
687+ pass
688+
689+ def pytest_asyncio_loop_factories(config, item):
690+ return {{"custom": CustomEventLoop}}
691+
692+ @pytest_asyncio.fixture(
693+ autouse=True,
694+ scope="{ wider_scope } ",
695+ loop_scope="{ wider_scope } ",
696+ )
697+ async def wider_scoped_fixture():
698+ yield
699+
700+ @pytest_asyncio.fixture(
701+ autouse=True,
702+ scope="{ fixture_scope } ",
703+ loop_scope="{ fixture_scope } ",
704+ )
705+ def sync_generator_fixture():
706+ loop_at_setup = id(asyncio.get_event_loop())
707+ yield loop_at_setup
708+ loop_at_teardown = id(asyncio.get_event_loop())
709+ assert loop_at_setup == loop_at_teardown
710+ """ ))
711+ pytester .makepyfile (dedent (f"""\
712+ import asyncio
713+ import pytest
714+
715+ pytest_plugins = "pytest_asyncio"
716+
717+ @pytest.mark.asyncio(loop_scope="{ fixture_scope } ")
718+ async def test_generator_fixture_sees_correct_loop(
719+ sync_generator_fixture,
720+ ):
721+ assert sync_generator_fixture == id(
722+ asyncio.get_running_loop()
723+ )
724+ """ ))
725+ result = pytester .runpytest ("--asyncio-mode=strict" )
726+ result .assert_outcomes (passed = 1 )
727+
728+
608729@pytest .mark .parametrize ("loop_scope" , ("module" , "package" , "session" ))
609730def test_async_generator_fixture_teardown_runs_under_custom_factory (
610731 pytester : Pytester ,
0 commit comments