@@ -213,7 +213,8 @@ def pytest_pycollect_makeitem(
213213        and  _hypothesis_test_wraps_coroutine (obj )
214214    ):
215215        item  =  pytest .Function .from_parent (collector , name = name )
216-         if  "asyncio"  in  item .keywords :
216+         marker  =  item .get_closest_marker ("asyncio" )
217+         if  marker  is  not None :
217218            return  list (collector ._genfunctions (name , obj ))
218219        else :
219220            if  _get_asyncio_mode (item .config ) ==  Mode .AUTO :
@@ -390,16 +391,19 @@ def pytest_pyfunc_call(pyfuncitem: pytest.Function) -> Optional[object]:
390391    Wraps marked tests in a synchronous function 
391392    where the wrapped test coroutine is executed in an event loop. 
392393    """ 
393-     if  "asyncio"  in  pyfuncitem .keywords :
394+     marker  =  pyfuncitem .get_closest_marker ("asyncio" )
395+     if  marker  is  not None :
394396        funcargs : Dict [str , object ] =  pyfuncitem .funcargs   # type: ignore[name-defined] 
395397        loop  =  cast (asyncio .AbstractEventLoop , funcargs ["event_loop" ])
396398        if  _is_hypothesis_test (pyfuncitem .obj ):
397399            pyfuncitem .obj .hypothesis .inner_test  =  wrap_in_sync (
400+                 pyfuncitem ,
398401                pyfuncitem .obj .hypothesis .inner_test ,
399402                _loop = loop ,
400403            )
401404        else :
402405            pyfuncitem .obj  =  wrap_in_sync (
406+                 pyfuncitem ,
403407                pyfuncitem .obj ,
404408                _loop = loop ,
405409            )
@@ -410,7 +414,11 @@ def _is_hypothesis_test(function: Any) -> bool:
410414    return  getattr (function , "is_hypothesis_test" , False )
411415
412416
413- def  wrap_in_sync (func : Callable [..., Awaitable [Any ]], _loop : asyncio .AbstractEventLoop ):
417+ def  wrap_in_sync (
418+     pyfuncitem : pytest .Function ,
419+     func : Callable [..., Awaitable [Any ]],
420+     _loop : asyncio .AbstractEventLoop ,
421+ ):
414422    """Return a sync wrapper around an async function executing it in the 
415423    current event loop.""" 
416424
@@ -424,34 +432,44 @@ def wrap_in_sync(func: Callable[..., Awaitable[Any]], _loop: asyncio.AbstractEve
424432    @functools .wraps (func ) 
425433    def  inner (** kwargs ):
426434        coro  =  func (** kwargs )
427-         if  coro  is  not None :
428-             task  =  asyncio .ensure_future (coro , loop = _loop )
429-             try :
430-                 _loop .run_until_complete (task )
431-             except  BaseException :
432-                 # run_until_complete doesn't get the result from exceptions 
433-                 # that are not subclasses of `Exception`. Consume all 
434-                 # exceptions to prevent asyncio's warning from logging. 
435-                 if  task .done () and  not  task .cancelled ():
436-                     task .exception ()
437-                 raise 
435+         if  not  inspect .isawaitable (coro ):
436+             pyfuncitem .warn (
437+                 pytest .PytestWarning (
438+                     f"The test { pyfuncitem }  
439+                     "but it is not an async function. " 
440+                     "Please remove asyncio marker. " 
441+                     "If the test is not marked explicitly, " 
442+                     "check for global markers applied via 'pytestmark'." 
443+                 )
444+             )
445+             return 
446+         task  =  asyncio .ensure_future (coro , loop = _loop )
447+         try :
448+             _loop .run_until_complete (task )
449+         except  BaseException :
450+             # run_until_complete doesn't get the result from exceptions 
451+             # that are not subclasses of `Exception`. Consume all 
452+             # exceptions to prevent asyncio's warning from logging. 
453+             if  task .done () and  not  task .cancelled ():
454+                 task .exception ()
455+             raise 
438456
439457    inner ._raw_test_func  =  func   # type: ignore[attr-defined] 
440458    return  inner 
441459
442460
443461def  pytest_runtest_setup (item : pytest .Item ) ->  None :
444-     if  "asyncio"  in  item .keywords :
445-         fixturenames  =  item .fixturenames   # type: ignore[attr-defined] 
446-         # inject an event loop fixture for all async tests 
447-         if  "event_loop"  in  fixturenames :
448-             fixturenames .remove ("event_loop" )
449-         fixturenames .insert (0 , "event_loop" )
462+     marker  =  item .get_closest_marker ("asyncio" )
463+     if  marker  is  None :
464+         return 
465+     fixturenames  =  item .fixturenames   # type: ignore[attr-defined] 
466+     # inject an event loop fixture for all async tests 
467+     if  "event_loop"  in  fixturenames :
468+         fixturenames .remove ("event_loop" )
469+     fixturenames .insert (0 , "event_loop" )
450470    obj  =  getattr (item , "obj" , None )
451-     if  (
452-         item .get_closest_marker ("asyncio" ) is  not None 
453-         and  not  getattr (obj , "hypothesis" , False )
454-         and  getattr (obj , "is_hypothesis_test" , False )
471+     if  not  getattr (obj , "hypothesis" , False ) and  getattr (
472+         obj , "is_hypothesis_test" , False 
455473    ):
456474        pytest .fail (
457475            "test function `%r` is using Hypothesis, but pytest-asyncio " 
0 commit comments