[Python-checkins] r68640 - in sandbox/trunk/io-c: _bufferedio.c _textio.c test_io.py
antoine.pitrou
python-checkins at python.org
Sat Jan 17 01:46:30 CET 2009
Author: antoine.pitrou
Date: Sat Jan 17 01:46:30 2009
New Revision: 68640
Log:
deallocating a Buffered or Text IO object could clear the err status
Modified:
sandbox/trunk/io-c/_bufferedio.c
sandbox/trunk/io-c/_textio.c
sandbox/trunk/io-c/test_io.py
Modified: sandbox/trunk/io-c/_bufferedio.c
==============================================================================
--- sandbox/trunk/io-c/_bufferedio.c (original)
+++ sandbox/trunk/io-c/_bufferedio.c Sat Jan 17 01:46:30 2009
@@ -226,6 +226,8 @@
PyObject *res;
/* XXX this is inelegant */
if (Py_TYPE(self)->tp_del == NULL) {
+ PyObject *tp, *v, *tb;
+ PyErr_Fetch(&tp, &v, &tb);
/* We need to resurrect the object as calling close() can invoke
arbitrary code. */
((PyObject *) self)->ob_refcnt++;
@@ -237,6 +239,7 @@
PyErr_Clear();
}
Py_XDECREF(res);
+ PyErr_Restore(tp, v, tb);
if (--((PyObject *) self)->ob_refcnt != 0)
return;
}
Modified: sandbox/trunk/io-c/_textio.c
==============================================================================
--- sandbox/trunk/io-c/_textio.c (original)
+++ sandbox/trunk/io-c/_textio.c Sat Jan 17 01:46:30 2009
@@ -767,6 +767,8 @@
PyObject *res;
/* XXX this is inelegant */
if (Py_TYPE(self)->tp_del == NULL && self->ok) {
+ PyObject *tp, *v, *tb;
+ PyErr_Fetch(&tp, &v, &tb);
/* We need to resurrect the object as calling close() can invoke
arbitrary code. */
((PyObject *) self)->ob_refcnt++;
@@ -778,6 +780,7 @@
PyErr_Clear();
}
Py_XDECREF(res);
+ PyErr_Restore(tp, v, tb);
if (--((PyObject *) self)->ob_refcnt != 0)
return;
}
Modified: sandbox/trunk/io-c/test_io.py
==============================================================================
--- sandbox/trunk/io-c/test_io.py (original)
+++ sandbox/trunk/io-c/test_io.py Sat Jan 17 01:46:30 2009
@@ -97,6 +97,12 @@
def readinto(self, buf):
MockRawIO.readinto(self, buf)
return len(buf) * 5
+
+
+class CloseFailureIO(MockRawIO):
+
+ def close(self):
+ raise IOError
class MockFileIO(io.BytesIO):
@@ -495,6 +501,14 @@
# bufio should now be closed, and using it a second time should raise
# a ValueError.
self.assertRaises(ValueError, _with)
+
+ def testErrorThroughDestructor(self):
+ # Test that the exception state is not modified by a destructor,
+ # even if close() fails.
+ rawio = CloseFailureIO()
+ def f():
+ self.tp(rawio).xyzzy
+ self.assertRaises(AttributeError, f)
class BufferedReaderTest(unittest.TestCase, CommonBufferedTests):
@@ -1333,6 +1347,14 @@
del t
self.assertEqual(record, [1, 2, 3])
+ def testErrorThroughDestructor(self):
+ # Test that the exception state is not modified by a destructor,
+ # even if close() fails.
+ rawio = CloseFailureIO()
+ def f():
+ io.TextIOWrapper(rawio).xyzzy
+ self.assertRaises(AttributeError, f)
+
# Systematic tests of the text I/O API
def testBasicIO(self):
More information about the Python-checkins
mailing list