diff -r f7de67283c94 Lib/test/test_io.py --- a/Lib/test/test_io.py Thu Sep 29 19:51:46 2011 +0200 +++ b/Lib/test/test_io.py Sat Oct 01 15:56:27 2011 +0200 @@ -2413,6 +2413,20 @@ with self.open(support.TESTFN, "rb") as f: self.assertEqual(f.read(), b"456def") + def test_rwpair_collected_before_textio(self): + # Issue 13070: TextIOWrapper's finalization would segfault when called + # after the underlying BufferedRWPair got garbage collected. + for i in range(1000): + b1 = self.BufferedRWPair(self.MockRawIO(), self.MockRawIO()) + t1 = self.TextIOWrapper(b1, encoding="ascii") + b2 = self.BufferedRWPair(self.MockRawIO(), self.MockRawIO()) + t2 = self.TextIOWrapper(b2, encoding="ascii") + # circular references + t1.buddy = t2 + t2.buddy = t1 + support.gc_collect() + + class PyTextIOWrapperTest(TextIOWrapperTest): pass diff -r f7de67283c94 Modules/_io/bufferedio.c --- a/Modules/_io/bufferedio.c Thu Sep 29 19:51:46 2011 +0200 +++ b/Modules/_io/bufferedio.c Sat Oct 01 15:56:27 2011 +0200 @@ -2304,6 +2304,8 @@ static PyObject * bufferedrwpair_closed_get(rwpair *self, void *context) { + if (self->writer == NULL) + return NULL; return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed); }