diff --git a/fixtures/fixture.py b/fixtures/fixture.py index 550aadb..437ef97 100644 --- a/fixtures/fixture.py +++ b/fixtures/fixture.py @@ -204,14 +204,18 @@ def setUp(self): else: details = self.getDetails() errors = [err] + self.cleanUp(raise_first=False) - try: - raise SetupError(details) - except SetupError: - errors.append(sys.exc_info()) - if issubclass(err[0], Exception): - raise MultipleExceptions(*errors) - else: - six.reraise(*err) + else: + return + + # If we got here it means we have handled an exception above. + try: + raise SetupError(details) + except SetupError: + errors.append(sys.exc_info()) + if issubclass(err[0], Exception): + raise MultipleExceptions(*errors) + else: + six.reraise(*err) def _setUp(self): """Template method for subclasses to override. diff --git a/fixtures/tests/test_fixture.py b/fixtures/tests/test_fixture.py index 6767921..370dd41 100644 --- a/fixtures/tests/test_fixture.py +++ b/fixtures/tests/test_fixture.py @@ -240,6 +240,10 @@ def _setUp(self): self.assertIsInstance(e.args[0][1], ZeroDivisionError) self.assertIsInstance(e.args[1][1], fixtures.SetupError) self.assertEqual('stuff', e.args[1][1].args[0]['log'].as_text()) + # The SetupError is not raised during the exception handling of the + # original _setUp exception. We use getattr since __context__ is + # there only for Python 3 exceptions. + self.assertIsNone(getattr(e.args[1][1], "__context__", None)) def test__setUp_fails_cleanUp_fails(self): # when _setUp fails, cleanups are called, and their failure is captured