mirror of https://github.com/python/cpython
Issue #21677: Fixed chaining nonnormalized exceptions in io close() methods.
This commit is contained in:
parent
b1f59cecc9
commit
8a8f7f9830
|
@ -792,9 +792,27 @@ class CommonBufferedTests:
|
|||
with self.assertRaises(OSError) as err: # exception not swallowed
|
||||
b.close()
|
||||
self.assertEqual(err.exception.args, ('close',))
|
||||
self.assertIsInstance(err.exception.__context__, OSError)
|
||||
self.assertEqual(err.exception.__context__.args, ('flush',))
|
||||
self.assertFalse(b.closed)
|
||||
|
||||
def test_nonnormalized_close_error_on_close(self):
|
||||
# Issue #21677
|
||||
raw = self.MockRawIO()
|
||||
def bad_flush():
|
||||
raise non_existing_flush
|
||||
def bad_close():
|
||||
raise non_existing_close
|
||||
raw.close = bad_close
|
||||
b = self.tp(raw)
|
||||
b.flush = bad_flush
|
||||
with self.assertRaises(NameError) as err: # exception not swallowed
|
||||
b.close()
|
||||
self.assertIn('non_existing_close', str(err.exception))
|
||||
self.assertIsInstance(err.exception.__context__, NameError)
|
||||
self.assertIn('non_existing_flush', str(err.exception.__context__))
|
||||
self.assertFalse(b.closed)
|
||||
|
||||
def test_multi_close(self):
|
||||
raw = self.MockRawIO()
|
||||
b = self.tp(raw)
|
||||
|
@ -2576,6 +2594,39 @@ class TextIOWrapperTest(unittest.TestCase):
|
|||
self.assertRaises(OSError, txt.close) # exception not swallowed
|
||||
self.assertTrue(txt.closed)
|
||||
|
||||
def test_close_error_on_close(self):
|
||||
buffer = self.BytesIO(self.testdata)
|
||||
def bad_flush():
|
||||
raise OSError('flush')
|
||||
def bad_close():
|
||||
raise OSError('close')
|
||||
buffer.close = bad_close
|
||||
txt = self.TextIOWrapper(buffer, encoding="ascii")
|
||||
txt.flush = bad_flush
|
||||
with self.assertRaises(OSError) as err: # exception not swallowed
|
||||
txt.close()
|
||||
self.assertEqual(err.exception.args, ('close',))
|
||||
self.assertIsInstance(err.exception.__context__, OSError)
|
||||
self.assertEqual(err.exception.__context__.args, ('flush',))
|
||||
self.assertFalse(txt.closed)
|
||||
|
||||
def test_nonnormalized_close_error_on_close(self):
|
||||
# Issue #21677
|
||||
buffer = self.BytesIO(self.testdata)
|
||||
def bad_flush():
|
||||
raise non_existing_flush
|
||||
def bad_close():
|
||||
raise non_existing_close
|
||||
buffer.close = bad_close
|
||||
txt = self.TextIOWrapper(buffer, encoding="ascii")
|
||||
txt.flush = bad_flush
|
||||
with self.assertRaises(NameError) as err: # exception not swallowed
|
||||
txt.close()
|
||||
self.assertIn('non_existing_close', str(err.exception))
|
||||
self.assertIsInstance(err.exception.__context__, NameError)
|
||||
self.assertIn('non_existing_flush', str(err.exception.__context__))
|
||||
self.assertFalse(txt.closed)
|
||||
|
||||
def test_multi_close(self):
|
||||
txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii")
|
||||
txt.close()
|
||||
|
|
|
@ -22,6 +22,8 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #21677: Fixed chaining nonnormalized exceptions in io close() methods.
|
||||
|
||||
- Issue #11709: Fix the pydoc.help function to not fail when sys.stdin is not a
|
||||
valid file.
|
||||
|
||||
|
|
|
@ -549,6 +549,7 @@ buffered_close(buffered *self, PyObject *args)
|
|||
}
|
||||
else {
|
||||
PyObject *val2;
|
||||
PyErr_NormalizeException(&exc, &val, &tb);
|
||||
Py_DECREF(exc);
|
||||
Py_XDECREF(tb);
|
||||
PyErr_Fetch(&exc, &val2, &tb);
|
||||
|
|
|
@ -2614,6 +2614,7 @@ textiowrapper_close(textio *self, PyObject *args)
|
|||
}
|
||||
else {
|
||||
PyObject *val2;
|
||||
PyErr_NormalizeException(&exc, &val, &tb);
|
||||
Py_DECREF(exc);
|
||||
Py_XDECREF(tb);
|
||||
PyErr_Fetch(&exc, &val2, &tb);
|
||||
|
|
Loading…
Reference in New Issue