@@ -49,6 +49,11 @@ class _instances:
4949 reactor = None
5050
5151
52+ class _tracking :
53+ async_yield_fixture_cache = {}
54+ to_be_torn_down = []
55+
56+
5257def _deprecate (deprecated , recommended ):
5358 def decorator (f ):
5459 @functools .wraps (f )
@@ -217,7 +222,12 @@ def pytest_fixture_setup(fixturedef, request):
217222
218223 mark = maybe_mark
219224
220- _run_inline_callbacks (_async_pytest_fixture_setup , fixturedef , request , mark )
225+ _run_inline_callbacks (
226+ _async_pytest_fixture_setup ,
227+ fixturedef ,
228+ request ,
229+ mark ,
230+ )
221231
222232 return not None
223233
@@ -240,8 +250,7 @@ def _async_pytest_fixture_setup(fixturedef, request, mark):
240250 coroutine = fixture_function (** kwargs )
241251
242252 finalizer = functools .partial (
243- _run_inline_callbacks ,
244- _async_yield_pytest_fixture_finalizer ,
253+ _tracking .to_be_torn_down .append ,
245254 coroutine ,
246255 )
247256 request .addfinalizer (finalizer )
@@ -258,11 +267,8 @@ def _async_pytest_fixture_setup(fixturedef, request, mark):
258267
259268
260269@defer .inlineCallbacks
261- def _async_yield_pytest_fixture_finalizer ( coroutine ):
270+ def tear_it_down ( deferred ):
262271 """Tear down a specific async yield fixture."""
263-
264- deferred = defer .ensureDeferred (coroutine .__anext__ ())
265-
266272 try :
267273 yield deferred
268274 except StopAsyncIteration :
@@ -296,6 +302,22 @@ def in_reactor(d, f, *args):
296302 blockingCallFromThread (_instances .reactor , f , * args )
297303
298304
305+ @pytest .hookimpl (hookwrapper = True )
306+ def pytest_runtest_teardown (item ):
307+ """Tear down collected async yield fixtures."""
308+ yield
309+
310+ deferreds = []
311+ while len (_tracking .to_be_torn_down ) > 0 :
312+ coroutine = _tracking .to_be_torn_down .pop (0 )
313+ deferred = defer .ensureDeferred (coroutine .__anext__ ())
314+
315+ deferreds .append (deferred )
316+
317+ for deferred in deferreds :
318+ _run_inline_callbacks (tear_it_down , deferred )
319+
320+
299321def pytest_pyfunc_call (pyfuncitem ):
300322 """Interface to async test call handler."""
301323 # TODO: only handle 'our' tests? what is the point of handling others?
0 commit comments