handle and reraise subrequest finalizer exceptions

This commit is contained in:
Ryan Fitzpatrick 2017-06-12 20:39:42 -04:00
parent f0541b685b
commit 5a856b6e29
3 changed files with 35 additions and 2 deletions

View File

@ -733,10 +733,16 @@ class FixtureDef:
self._finalizer.append(finalizer)
def finish(self):
exceptions = []
try:
while self._finalizer:
func = self._finalizer.pop()
func()
try:
func = self._finalizer.pop()
func()
except:
exceptions.append(sys.exc_info())
if exceptions:
py.builtin._reraise(*exceptions[0])
finally:
ihook = self._fixturemanager.session.ihook
ihook.pytest_fixture_post_finalizer(fixturedef=self)

1
changelog/2440.bugfix Normal file
View File

@ -0,0 +1 @@
Exceptions in a SubRequest's finish() block are suppressed until all finalizers are called, with the initial exception reraised.

View File

@ -657,6 +657,32 @@ class TestRequestBasic(object):
"*1 error*" # XXX the whole module collection fails
])
def test_request_subrequest_addfinalizer_exceptions(self, testdir):
testdir.makepyfile("""
import pytest
l = []
def _excepts():
raise Exception('Error')
@pytest.fixture
def subrequest(request):
return request
@pytest.fixture
def something(subrequest):
subrequest.addfinalizer(lambda: l.append(1))
subrequest.addfinalizer(lambda: l.append(2))
subrequest.addfinalizer(_excepts)
@pytest.fixture
def excepts(subrequest):
subrequest.addfinalizer(_excepts)
subrequest.addfinalizer(lambda: l.append(3))
def test_first(something, excepts):
pass
def test_second():
assert l == [3, 2, 1]
""")
reprec = testdir.inline_run()
reprec.assertoutcome(passed=2, failed=1)
def test_request_getmodulepath(self, testdir):
modcol = testdir.getmodulecol("def test_somefunc(): pass")
item, = testdir.genitems([modcol])