Issue #5734: BufferedRWPair was poorly tested and had several glaring bugs.
Patch by Brian Quinlan.
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index c3ca1cd..4b654a0 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -1846,7 +1846,7 @@
static int
BufferedRWPair_init(BufferedRWPairObject *self, PyObject *args,
- PyObject *kwds)
+ PyObject *kwds)
{
PyObject *reader, *writer;
Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
@@ -1865,29 +1865,18 @@
if (_PyIOBase_checkWritable(writer, Py_True) == NULL)
return -1;
- args = Py_BuildValue("(n)", buffer_size);
- if (args == NULL) {
- Py_CLEAR(self->reader);
- return -1;
- }
- self->reader = (BufferedObject *)PyType_GenericNew(
- &PyBufferedReader_Type, args, NULL);
- Py_DECREF(args);
+ self->reader = (BufferedObject *) PyObject_CallFunction(
+ (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
if (self->reader == NULL)
return -1;
- args = Py_BuildValue("(n)", buffer_size);
- if (args == NULL) {
- Py_CLEAR(self->reader);
- return -1;
- }
- self->writer = (BufferedObject *)PyType_GenericNew(
- &PyBufferedWriter_Type, args, NULL);
- Py_DECREF(args);
+ self->writer = (BufferedObject *) PyObject_CallFunction(
+ (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
if (self->writer == NULL) {
Py_CLEAR(self->reader);
return -1;
}
+
return 0;
}
@@ -1952,6 +1941,12 @@
}
static PyObject *
+BufferedRWPair_readinto(BufferedRWPairObject *self, PyObject *args)
+{
+ return _forward_call(self->reader, "readinto", args);
+}
+
+static PyObject *
BufferedRWPair_write(BufferedRWPairObject *self, PyObject *args)
{
return _forward_call(self->writer, "write", args);
@@ -2000,12 +1995,17 @@
return _forward_call(self->reader, "isatty", args);
}
+static PyObject *
+BufferedRWPair_closed_get(BufferedRWPairObject *self, void *context)
+{
+ return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
+}
static PyMethodDef BufferedRWPair_methods[] = {
{"read", (PyCFunction)BufferedRWPair_read, METH_VARARGS},
{"peek", (PyCFunction)BufferedRWPair_peek, METH_VARARGS},
{"read1", (PyCFunction)BufferedRWPair_read1, METH_VARARGS},
- {"readinto", (PyCFunction)Buffered_readinto, METH_VARARGS},
+ {"readinto", (PyCFunction)BufferedRWPair_readinto, METH_VARARGS},
{"write", (PyCFunction)BufferedRWPair_write, METH_VARARGS},
{"flush", (PyCFunction)BufferedRWPair_flush, METH_NOARGS},
@@ -2019,6 +2019,11 @@
{NULL, NULL}
};
+static PyGetSetDef BufferedRWPair_getset[] = {
+ {"closed", (getter)BufferedRWPair_closed_get, NULL, NULL},
+ {0}
+};
+
PyTypeObject PyBufferedRWPair_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"_io.BufferedRWPair", /*tp_name*/
@@ -2050,7 +2055,7 @@
0, /* tp_iternext */
BufferedRWPair_methods, /* tp_methods */
0, /* tp_members */
- 0, /* tp_getset */
+ BufferedRWPair_getset, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */