1616 Awaitable ,
1717 Callable ,
1818 Dict ,
19+ Generator ,
1920 Iterable ,
2021 Iterator ,
2122 List ,
2223 Literal ,
24+ Mapping ,
2325 Optional ,
26+ Sequence ,
2427 Set ,
2528 Type ,
2629 TypeVar ,
4750 StashKey ,
4851)
4952
50- _R = TypeVar ("_R" )
51-
5253_ScopeName = Literal ["session" , "package" , "module" , "class" , "function" ]
5354_T = TypeVar ("_T" )
5455
5556SimpleFixtureFunction = TypeVar (
56- "SimpleFixtureFunction" , bound = Callable [..., Awaitable [_R ]]
57+ "SimpleFixtureFunction" , bound = Callable [..., Awaitable [object ]]
5758)
5859FactoryFixtureFunction = TypeVar (
59- "FactoryFixtureFunction" , bound = Callable [..., AsyncIterator [_R ]]
60+ "FactoryFixtureFunction" , bound = Callable [..., AsyncIterator [object ]]
6061)
6162FixtureFunction = Union [SimpleFixtureFunction , FactoryFixtureFunction ]
6263FixtureFunctionMarker = Callable [[FixtureFunction ], FixtureFunction ]
@@ -204,6 +205,7 @@ def _preprocess_async_fixtures(
204205 config = collector .config
205206 asyncio_mode = _get_asyncio_mode (config )
206207 fixturemanager = config .pluginmanager .get_plugin ("funcmanage" )
208+ assert fixturemanager is not None
207209 for fixtures in fixturemanager ._arg2fixturedefs .values ():
208210 for fixturedef in fixtures :
209211 func = fixturedef .func
@@ -217,11 +219,13 @@ def _preprocess_async_fixtures(
217219 continue
218220 scope = fixturedef .scope
219221 if scope == "function" :
220- event_loop_fixture_id = "event_loop"
222+ event_loop_fixture_id : Optional [ str ] = "event_loop"
221223 else :
222224 event_loop_node = _retrieve_scope_root (collector , scope )
223225 event_loop_fixture_id = event_loop_node .stash .get (
224- _event_loop_fixture_id , None
226+ # Type ignored because of non-optimal mypy inference.
227+ _event_loop_fixture_id , # type: ignore[arg-type]
228+ None ,
225229 )
226230 _make_asyncio_fixture_function (func )
227231 function_signature = inspect .signature (func )
@@ -234,8 +238,15 @@ def _preprocess_async_fixtures(
234238 f"instead."
235239 )
236240 )
237- _inject_fixture_argnames (fixturedef , event_loop_fixture_id )
238- _synchronize_async_fixture (fixturedef , event_loop_fixture_id )
241+ # TODO: Fix type errors below.
242+ _inject_fixture_argnames (
243+ fixturedef ,
244+ event_loop_fixture_id , # type: ignore[arg-type]
245+ )
246+ _synchronize_async_fixture (
247+ fixturedef ,
248+ event_loop_fixture_id , # type: ignore[arg-type]
249+ )
239250 assert _is_asyncio_fixture_function (fixturedef .func )
240251 processed_fixturedefs .add (fixturedef )
241252
@@ -517,20 +528,20 @@ def pytest_pycollect_makeitem_preprocess_async_fixtures(
517528@pytest .hookimpl (specname = "pytest_pycollect_makeitem" , hookwrapper = True )
518529def pytest_pycollect_makeitem_convert_async_functions_to_subclass (
519530 collector : Union [pytest .Module , pytest .Class ], name : str , obj : object
520- ) -> Union [
521- pytest .Item , pytest .Collector , List [Union [pytest .Item , pytest .Collector ]], None
522- ]:
531+ ) -> Generator [None , Any , None ]:
523532 """
524533 Converts coroutines and async generators collected as pytest.Functions
525534 to AsyncFunction items.
526535 """
527536 hook_result = yield
528- node_or_list_of_nodes = hook_result .get_result ()
537+ node_or_list_of_nodes : Union [
538+ pytest .Item , pytest .Collector , List [Union [pytest .Item , pytest .Collector ]], None
539+ ] = hook_result .get_result ()
529540 if not node_or_list_of_nodes :
530541 return
531- try :
542+ if isinstance ( node_or_list_of_nodes , Sequence ) :
532543 node_iterator = iter (node_or_list_of_nodes )
533- except TypeError :
544+ else :
534545 # Treat single node as a single-element iterable
535546 node_iterator = iter ((node_or_list_of_nodes ,))
536547 updated_node_collection = []
@@ -549,8 +560,8 @@ def pytest_pycollect_makeitem_convert_async_functions_to_subclass(
549560 hook_result .force_result (updated_node_collection )
550561
551562
552- _event_loop_fixture_id = StashKey [str ]
553- _fixture_scope_by_collector_type = {
563+ _event_loop_fixture_id = StashKey [str ]()
564+ _fixture_scope_by_collector_type : Mapping [ Type [ pytest . Collector ], _ScopeName ] = {
554565 Class : "class" ,
555566 # Package is a subclass of module and the dict is used in isinstance checks
556567 # Therefore, the order matters and Package needs to appear before Module
@@ -565,7 +576,7 @@ def pytest_pycollect_makeitem_convert_async_functions_to_subclass(
565576
566577
567578@pytest .hookimpl
568- def pytest_collectstart (collector : pytest .Collector ):
579+ def pytest_collectstart (collector : pytest .Collector ) -> None :
569580 try :
570581 collector_scope = next (
571582 scope
@@ -639,8 +650,8 @@ def _patched_collect():
639650 pass
640651 return collector .__original_collect ()
641652
642- collector .__original_collect = collector .collect
643- collector .collect = _patched_collect
653+ collector .__original_collect = collector .collect # type: ignore[attr-defined]
654+ collector .collect = _patched_collect # type: ignore[method-assign]
644655 elif isinstance (collector , Class ):
645656 collector .obj .__pytest_asyncio_scoped_event_loop = scoped_event_loop
646657
@@ -708,6 +719,7 @@ def pytest_generate_tests(metafunc: Metafunc) -> None:
708719 if event_loop_fixture_id in metafunc .fixturenames :
709720 return
710721 fixturemanager = metafunc .config .pluginmanager .get_plugin ("funcmanage" )
722+ assert fixturemanager is not None
711723 if "event_loop" in metafunc .fixturenames :
712724 raise MultipleEventLoopsRequestedError (
713725 _MULTIPLE_LOOPS_REQUESTED_ERROR .format (
@@ -728,8 +740,8 @@ def pytest_generate_tests(metafunc: Metafunc) -> None:
728740
729741@pytest .hookimpl (hookwrapper = True )
730742def pytest_fixture_setup (
731- fixturedef : FixtureDef , request : SubRequest
732- ) -> Optional [ object ]:
743+ fixturedef : FixtureDef ,
744+ ) -> Generator [ None , Any , None ]:
733745 """Adjust the event loop policy when an event loop is produced."""
734746 if fixturedef .argname == "event_loop" :
735747 # The use of a fixture finalizer is preferred over the
@@ -744,7 +756,7 @@ def pytest_fixture_setup(
744756 _provide_clean_event_loop ,
745757 )
746758 outcome = yield
747- loop = outcome .get_result ()
759+ loop : asyncio . AbstractEventLoop = outcome .get_result ()
748760 # Weird behavior was observed when checking for an attribute of FixtureDef.func
749761 # Instead, we now check for a special attribute of the returned event loop
750762 fixture_filename = inspect .getsourcefile (fixturedef .func )
@@ -946,6 +958,7 @@ def _retrieve_scope_root(item: Union[Collector, Item], scope: str) -> Collector:
946958 scope_root_type = node_type_by_scope [scope ]
947959 for node in reversed (item .listchain ()):
948960 if isinstance (node , scope_root_type ):
961+ assert isinstance (node , pytest .Collector )
949962 return node
950963 error_message = (
951964 f"{ item .name } is marked to be run in an event loop with scope { scope } , "
0 commit comments