Index: Lib/test/test_with.py =================================================================== --- Lib/test/test_with.py (revision 77979) +++ Lib/test/test_with.py (working copy) @@ -213,11 +213,16 @@ def raiseTestException(self): raise self.TEST_EXCEPTION - def assertAfterWithManagerInvariantsWithError(self, mock_manager): + def assertAfterWithManagerInvariantsWithError(self, mock_manager, + exc_type=RuntimeError): self.assertTrue(mock_manager.enter_called) self.assertTrue(mock_manager.exit_called) - self.assertEqual(mock_manager.exit_args[0], RuntimeError) - self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION) + self.assertEqual(mock_manager.exit_args[0], exc_type) + if exc_type is RuntimeError: + self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION) + # Test the __exit__ arguments. Issue #7853 + self.assertIsInstance(mock_manager.exit_args[1], exc_type) + self.assertIsNot(mock_manager.exit_args[2], None) def assertAfterWithGeneratorInvariantsWithError(self, mock_generator): self.assertTrue(mock_generator.yielded) @@ -355,6 +360,14 @@ self.assertAfterWithManagerInvariantsWithError(cm) self.assertAfterWithGeneratorInvariantsWithError(self.resource) + def testSingleResourceZeroDivision(self): + cm = mock_contextmanager_generator() + def shouldThrow(): + with cm as self.resource: + 1 // 0 + self.assertRaises(ZeroDivisionError, shouldThrow) + self.assertAfterWithManagerInvariantsWithError(cm, ZeroDivisionError) + def testNestedSingleStatements(self): mock_a = mock_contextmanager_generator() mock_b = mock_contextmanager_generator() Index: Python/ceval.c =================================================================== --- Python/ceval.c (revision 77979) +++ Python/ceval.c (working copy) @@ -2906,14 +2906,16 @@ val = Py_None; Py_INCREF(val); } + /* Normalize the exception, either + for 'except' or '__exit__'. */ + PyErr_NormalizeException( + &exc, &val, &tb); /* Make the raw exception data available to the handler, so a program can emulate the Python main loop. Don't do this for 'finally'. */ if (b->b_type == SETUP_EXCEPT) { - PyErr_NormalizeException( - &exc, &val, &tb); set_exc_info(tstate, exc, val, tb); }