Ensure fixtures obtained with getfixturevalue() are finalized in the correct order
Fix #1895
This commit is contained in:
parent
e1f97e41e3
commit
7dceabfcb2
|
@ -585,11 +585,13 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
||||||
# call the fixture function
|
# call the fixture function
|
||||||
fixturedef.execute(request=subrequest)
|
fixturedef.execute(request=subrequest)
|
||||||
finally:
|
finally:
|
||||||
# if fixture function failed it might have registered finalizers
|
self._schedule_finalizers(fixturedef, subrequest)
|
||||||
self.session._setupstate.addfinalizer(
|
|
||||||
functools.partial(fixturedef.finish, request=subrequest),
|
def _schedule_finalizers(self, fixturedef, subrequest):
|
||||||
subrequest.node,
|
# if fixture function failed it might have registered finalizers
|
||||||
)
|
self.session._setupstate.addfinalizer(
|
||||||
|
functools.partial(fixturedef.finish, request=subrequest), subrequest.node
|
||||||
|
)
|
||||||
|
|
||||||
def _check_scope(self, argname, invoking_scope, requested_scope):
|
def _check_scope(self, argname, invoking_scope, requested_scope):
|
||||||
if argname == "request":
|
if argname == "request":
|
||||||
|
@ -659,6 +661,16 @@ class SubRequest(FixtureRequest):
|
||||||
def addfinalizer(self, finalizer):
|
def addfinalizer(self, finalizer):
|
||||||
self._fixturedef.addfinalizer(finalizer)
|
self._fixturedef.addfinalizer(finalizer)
|
||||||
|
|
||||||
|
def _schedule_finalizers(self, fixturedef, subrequest):
|
||||||
|
# if the executing fixturedef was not explicitly requested in the argument list (via
|
||||||
|
# getfixturevalue inside the fixture call) then ensure this fixture def will be finished
|
||||||
|
# first
|
||||||
|
if fixturedef.argname not in self.funcargnames:
|
||||||
|
fixturedef.addfinalizer(
|
||||||
|
functools.partial(self._fixturedef.finish, request=self)
|
||||||
|
)
|
||||||
|
super(SubRequest, self)._schedule_finalizers(fixturedef, subrequest)
|
||||||
|
|
||||||
|
|
||||||
scopes = "session package module class function".split()
|
scopes = "session package module class function".split()
|
||||||
scopenum_function = scopes.index("function")
|
scopenum_function = scopes.index("function")
|
||||||
|
@ -858,6 +870,7 @@ class FixtureDef(object):
|
||||||
def execute(self, request):
|
def execute(self, request):
|
||||||
# get required arguments and register our own finish()
|
# get required arguments and register our own finish()
|
||||||
# with their finalization
|
# with their finalization
|
||||||
|
# TODO CHECK HOW TO AVOID EXPLICITLY FINALIZING AGAINST ARGNAMES
|
||||||
for argname in self.argnames:
|
for argname in self.argnames:
|
||||||
fixturedef = request._get_active_fixturedef(argname)
|
fixturedef = request._get_active_fixturedef(argname)
|
||||||
if argname != "request":
|
if argname != "request":
|
||||||
|
|
|
@ -327,6 +327,7 @@ class SetupState(object):
|
||||||
assert callable(finalizer)
|
assert callable(finalizer)
|
||||||
# assert colitem in self.stack # some unit tests don't setup stack :/
|
# assert colitem in self.stack # some unit tests don't setup stack :/
|
||||||
self._finalizers.setdefault(colitem, []).append(finalizer)
|
self._finalizers.setdefault(colitem, []).append(finalizer)
|
||||||
|
pass
|
||||||
|
|
||||||
def _pop_and_teardown(self):
|
def _pop_and_teardown(self):
|
||||||
colitem = self.stack.pop()
|
colitem = self.stack.pop()
|
||||||
|
|
|
@ -1866,7 +1866,7 @@ class TestAutouseManagement(object):
|
||||||
"setup-2", "step1-2", "step2-2", "teardown-2",]
|
"setup-2", "step1-2", "step2-2", "teardown-2",]
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
reprec = testdir.inline_run("-s")
|
reprec = testdir.inline_run("-v")
|
||||||
reprec.assertoutcome(passed=5)
|
reprec.assertoutcome(passed=5)
|
||||||
|
|
||||||
def test_ordering_autouse_before_explicit(self, testdir):
|
def test_ordering_autouse_before_explicit(self, testdir):
|
||||||
|
|
Loading…
Reference in New Issue