@@ -357,7 +357,21 @@ class PytestAsyncioFunction(pytest.Function):
357
357
"""Base class for all test functions managed by pytest-asyncio."""
358
358
359
359
@classmethod
360
- def from_function (cls , function : pytest .Function , / ) -> Self :
360
+ def substitute (cls , item : pytest .Function , / ) -> pytest .Function :
361
+ """
362
+ Returns a PytestAsyncioFunction if there is an implementation that can handle
363
+ the specified function item.
364
+
365
+ If no implementation of PytestAsyncioFunction can handle the specified item,
366
+ the item is returned unchanged.
367
+ """
368
+ for subclass in cls .__subclasses__ ():
369
+ if subclass ._can_substitute (item ):
370
+ return subclass ._from_function (item )
371
+ return item
372
+
373
+ @classmethod
374
+ def _from_function (cls , function : pytest .Function , / ) -> Self :
361
375
"""
362
376
Instantiates this specific PytestAsyncioFunction type from the specified
363
377
pytest.Function item.
@@ -373,7 +387,7 @@ def from_function(cls, function: pytest.Function, /) -> Self:
373
387
)
374
388
375
389
@staticmethod
376
- def can_substitute (item : pytest .Function ) -> bool :
390
+ def _can_substitute (item : pytest .Function ) -> bool :
377
391
"""Returns whether the specified function can be replaced by this class"""
378
392
raise NotImplementedError ()
379
393
@@ -382,7 +396,7 @@ class AsyncFunction(PytestAsyncioFunction):
382
396
"""Pytest item that is a coroutine or an asynchronous generator"""
383
397
384
398
@staticmethod
385
- def can_substitute (item : pytest .Function ) -> bool :
399
+ def _can_substitute (item : pytest .Function ) -> bool :
386
400
func = item .obj
387
401
return _is_coroutine_or_asyncgen (func )
388
402
@@ -402,7 +416,7 @@ class AsyncStaticMethod(PytestAsyncioFunction):
402
416
"""
403
417
404
418
@staticmethod
405
- def can_substitute (item : pytest .Function ) -> bool :
419
+ def _can_substitute (item : pytest .Function ) -> bool :
406
420
func = item .obj
407
421
return isinstance (func , staticmethod ) and _is_coroutine_or_asyncgen (
408
422
func .__func__
@@ -424,7 +438,7 @@ class AsyncHypothesisTest(PytestAsyncioFunction):
424
438
"""
425
439
426
440
@staticmethod
427
- def can_substitute (item : pytest .Function ) -> bool :
441
+ def _can_substitute (item : pytest .Function ) -> bool :
428
442
func = item .obj
429
443
return _is_hypothesis_test (func ) and _hypothesis_test_wraps_coroutine (func )
430
444
@@ -480,12 +494,7 @@ def pytest_pycollect_makeitem_convert_async_functions_to_subclass(
480
494
for node in node_iterator :
481
495
updated_item = node
482
496
if isinstance (node , pytest .Function ):
483
- if AsyncStaticMethod .can_substitute (node ):
484
- updated_item = AsyncStaticMethod .from_function (node )
485
- if AsyncFunction .can_substitute (node ):
486
- updated_item = AsyncFunction .from_function (node )
487
- if AsyncHypothesisTest .can_substitute (node ):
488
- updated_item = AsyncHypothesisTest .from_function (node )
497
+ updated_item = PytestAsyncioFunction .substitute (node )
489
498
updated_node_collection .append (updated_item )
490
499
491
500
hook_result .force_result (updated_node_collection )
0 commit comments