Merge pull request #3570 from sangongs/fix_stack_finalizer
Continue to call finalizers in the stack when a finalizer raises an exception
This commit is contained in:
commit
ef88251573
1
AUTHORS
1
AUTHORS
|
@ -82,6 +82,7 @@ Greg Price
|
||||||
Grig Gheorghiu
|
Grig Gheorghiu
|
||||||
Grigorii Eremeev (budulianin)
|
Grigorii Eremeev (budulianin)
|
||||||
Guido Wesdorp
|
Guido Wesdorp
|
||||||
|
Guoqiang Zhang
|
||||||
Harald Armin Massa
|
Harald Armin Massa
|
||||||
Henk-Jaap Wagenaar
|
Henk-Jaap Wagenaar
|
||||||
Hugo van Kemenade
|
Hugo van Kemenade
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Continue to call finalizers in the stack when a finalizer in a former scope raises an exception.
|
|
@ -527,10 +527,19 @@ class SetupState(object):
|
||||||
self._teardown_towards(needed_collectors)
|
self._teardown_towards(needed_collectors)
|
||||||
|
|
||||||
def _teardown_towards(self, needed_collectors):
|
def _teardown_towards(self, needed_collectors):
|
||||||
|
exc = None
|
||||||
while self.stack:
|
while self.stack:
|
||||||
if self.stack == needed_collectors[:len(self.stack)]:
|
if self.stack == needed_collectors[:len(self.stack)]:
|
||||||
break
|
break
|
||||||
self._pop_and_teardown()
|
try:
|
||||||
|
self._pop_and_teardown()
|
||||||
|
except TEST_OUTCOME:
|
||||||
|
# XXX Only first exception will be seen by user,
|
||||||
|
# ideally all should be reported.
|
||||||
|
if exc is None:
|
||||||
|
exc = sys.exc_info()
|
||||||
|
if exc:
|
||||||
|
py.builtin._reraise(*exc)
|
||||||
|
|
||||||
def prepare(self, colitem):
|
def prepare(self, colitem):
|
||||||
""" setup objects along the collector chain to the test-method
|
""" setup objects along the collector chain to the test-method
|
||||||
|
|
|
@ -81,6 +81,24 @@ class TestSetupState(object):
|
||||||
ss._callfinalizers(item)
|
ss._callfinalizers(item)
|
||||||
assert err.value.args == ("oops2",)
|
assert err.value.args == ("oops2",)
|
||||||
|
|
||||||
|
def test_teardown_multiple_scopes_one_fails(self, testdir):
|
||||||
|
module_teardown = []
|
||||||
|
|
||||||
|
def fin_func():
|
||||||
|
raise Exception("oops1")
|
||||||
|
|
||||||
|
def fin_module():
|
||||||
|
module_teardown.append("fin_module")
|
||||||
|
|
||||||
|
item = testdir.getitem("def test_func(): pass")
|
||||||
|
ss = runner.SetupState()
|
||||||
|
ss.addfinalizer(fin_module, item.listchain()[-2])
|
||||||
|
ss.addfinalizer(fin_func, item)
|
||||||
|
ss.prepare(item)
|
||||||
|
with pytest.raises(Exception, match="oops1"):
|
||||||
|
ss.teardown_exact(item, None)
|
||||||
|
assert module_teardown
|
||||||
|
|
||||||
|
|
||||||
class BaseFunctionalTests(object):
|
class BaseFunctionalTests(object):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue