11"""pytest-asyncio implementation."""
22import asyncio
33import contextlib
4+ import functools
45import inspect
56import socket
67
@@ -139,7 +140,8 @@ def pytest_pyfunc_call(pyfuncitem):
139140 function call.
140141 """
141142 for marker_name , fixture_name in _markers_2_fixtures .items ():
142- if marker_name in pyfuncitem .keywords :
143+ if inspect .isasyncgenfunction (pyfuncitem .obj ) \
144+ and marker_name in pyfuncitem .keywords :
143145 event_loop = pyfuncitem .funcargs [fixture_name ]
144146
145147 funcargs = pyfuncitem .funcargs
@@ -152,11 +154,39 @@ def pytest_pyfunc_call(pyfuncitem):
152154 return True
153155
154156
157+ def wrap_in_sync (func ):
158+ """Return a sync wrapper around an async function."""
159+
160+ @functools .wraps (func )
161+ def inner (** kwargs ):
162+ loop = asyncio .get_event_loop_policy ().new_event_loop ()
163+ try :
164+ coro = func (** kwargs )
165+ if coro is not None :
166+ future = asyncio .ensure_future (coro , loop = loop )
167+ loop .run_until_complete (future )
168+ finally :
169+ loop .close ()
170+
171+ return inner
172+
173+
155174def pytest_runtest_setup (item ):
156175 for marker , fixture in _markers_2_fixtures .items ():
157176 if marker in item .keywords and fixture not in item .fixturenames :
158177 # inject an event loop fixture for all async tests
159178 item .fixturenames .append (fixture )
179+ if item .get_closest_marker ("asyncio" ) is not None :
180+ if hasattr (item .obj , 'hypothesis' ):
181+ # If it's a Hypothesis test, we insert the wrap_in_sync decorator
182+ item .obj .hypothesis .inner_test = wrap_in_sync (
183+ item .obj .hypothesis .inner_test
184+ )
185+ elif getattr (item .obj , 'is_hypothesis_test' , False ):
186+ pytest .fail (
187+ 'test function `%r` is using Hypothesis, but pytest-asyncio '
188+ 'only works with Hypothesis 3.64.0 or later.' % item
189+ )
160190
161191
162192# maps marker to the name of the event loop fixture that will be available
0 commit comments