mirror of
https://github.com/python/cpython.git
synced 2025-09-09 18:32:22 +00:00
SF patch 695710: fix bug 678519: cStringIO self iterator
(requested by GvR. patch contributed by Michael Stone)
This commit is contained in:
parent
024aaa1bfe
commit
352f9477da
2 changed files with 59 additions and 68 deletions
|
@ -58,10 +58,10 @@ class TestGenericStringIO(unittest.TestCase):
|
||||||
def test_iterator(self):
|
def test_iterator(self):
|
||||||
eq = self.assertEqual
|
eq = self.assertEqual
|
||||||
unless = self.failUnless
|
unless = self.failUnless
|
||||||
it = iter(self._fp)
|
eq(iter(self._fp), self._fp)
|
||||||
# Does this object support the iteration protocol?
|
# Does this object support the iteration protocol?
|
||||||
unless(hasattr(it, '__iter__'))
|
unless(hasattr(self._fp, '__iter__'))
|
||||||
unless(hasattr(it, 'next'))
|
unless(hasattr(self._fp, 'next'))
|
||||||
i = 0
|
i = 0
|
||||||
for line in self._fp:
|
for line in self._fp:
|
||||||
eq(line, self._line + '\n')
|
eq(line, self._line + '\n')
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "import.h"
|
#include "import.h"
|
||||||
#include "cStringIO.h"
|
#include "cStringIO.h"
|
||||||
|
#include "structmember.h"
|
||||||
|
|
||||||
PyDoc_STRVAR(cStringIO_module_documentation,
|
PyDoc_STRVAR(cStringIO_module_documentation,
|
||||||
"A simple fast partial StringIO replacement.\n"
|
"A simple fast partial StringIO replacement.\n"
|
||||||
|
@ -189,7 +190,8 @@ IO_readline(IOobject *self, PyObject *args) {
|
||||||
int n, m=-1;
|
int n, m=-1;
|
||||||
char *output;
|
char *output;
|
||||||
|
|
||||||
UNLESS (PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
|
if (args)
|
||||||
|
UNLESS (PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
|
||||||
|
|
||||||
if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
|
if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
|
||||||
if (m >= 0 && m < n) {
|
if (m >= 0 && m < n) {
|
||||||
|
@ -276,6 +278,21 @@ IO_truncate(IOobject *self, PyObject *args) {
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
IO_iternext(Iobject *self)
|
||||||
|
{
|
||||||
|
PyObject *next;
|
||||||
|
next = IO_readline((IOobject *)self, NULL);
|
||||||
|
if (!next)
|
||||||
|
return NULL;
|
||||||
|
if (!PyString_GET_SIZE(next)) {
|
||||||
|
Py_DECREF(next);
|
||||||
|
PyErr_SetNone(PyExc_StopIteration);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -435,6 +452,12 @@ static struct PyMethodDef O_methods[] = {
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PyMemberDef O_memberlist[] = {
|
||||||
|
{"softspace", T_INT, offsetof(Oobject, softspace), 0,
|
||||||
|
"flag indicating that a space needs to be printed; used by print"},
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
O_dealloc(Oobject *self) {
|
O_dealloc(Oobject *self) {
|
||||||
if (self->buf != NULL)
|
if (self->buf != NULL)
|
||||||
|
@ -442,53 +465,40 @@ O_dealloc(Oobject *self) {
|
||||||
PyObject_Del(self);
|
PyObject_Del(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
O_getattr(Oobject *self, char *name) {
|
|
||||||
if (strcmp(name, "softspace") == 0) {
|
|
||||||
return PyInt_FromLong(self->softspace);
|
|
||||||
}
|
|
||||||
return Py_FindMethod(O_methods, (PyObject *)self, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
O_setattr(Oobject *self, char *name, PyObject *value) {
|
|
||||||
long x;
|
|
||||||
if (strcmp(name, "softspace") != 0) {
|
|
||||||
PyErr_SetString(PyExc_AttributeError, name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
x = PyInt_AsLong(value);
|
|
||||||
if (x < 0 && PyErr_Occurred())
|
|
||||||
return -1;
|
|
||||||
self->softspace = x;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
|
PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
|
||||||
|
|
||||||
static PyTypeObject Otype = {
|
static PyTypeObject Otype = {
|
||||||
PyObject_HEAD_INIT(NULL)
|
PyObject_HEAD_INIT(NULL)
|
||||||
0, /*ob_size*/
|
0, /*ob_size*/
|
||||||
"cStringIO.StringO", /*tp_name*/
|
"cStringIO.StringO", /*tp_name*/
|
||||||
sizeof(Oobject), /*tp_basicsize*/
|
sizeof(Oobject), /*tp_basicsize*/
|
||||||
0, /*tp_itemsize*/
|
0, /*tp_itemsize*/
|
||||||
/* methods */
|
/* methods */
|
||||||
(destructor)O_dealloc, /*tp_dealloc*/
|
(destructor)O_dealloc, /*tp_dealloc*/
|
||||||
(printfunc)0, /*tp_print*/
|
(printfunc)0, /*tp_print*/
|
||||||
(getattrfunc)O_getattr, /*tp_getattr*/
|
0, /*tp_getattr */
|
||||||
(setattrfunc)O_setattr, /*tp_setattr*/
|
0, /*tp_setattr */
|
||||||
(cmpfunc)0, /*tp_compare*/
|
(cmpfunc)0, /*tp_compare*/
|
||||||
(reprfunc)0, /*tp_repr*/
|
(reprfunc)0, /*tp_repr*/
|
||||||
0, /*tp_as_number*/
|
0, /*tp_as_number*/
|
||||||
0, /*tp_as_sequence*/
|
0, /*tp_as_sequence*/
|
||||||
0, /*tp_as_mapping*/
|
0, /*tp_as_mapping*/
|
||||||
(hashfunc)0, /*tp_hash*/
|
(hashfunc)0, /*tp_hash*/
|
||||||
(ternaryfunc)0, /*tp_call*/
|
(ternaryfunc)0, /*tp_call*/
|
||||||
(reprfunc)0, /*tp_str*/
|
(reprfunc)0, /*tp_str*/
|
||||||
|
0, /*tp_getattro */
|
||||||
/* Space for future expansion */
|
0, /*tp_setattro */
|
||||||
0L,0L,0L,0L,
|
0, /*tp_as_buffer */
|
||||||
Otype__doc__ /* Documentation string */
|
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
||||||
|
Otype__doc__, /*tp_doc */
|
||||||
|
0, /*tp_traverse */
|
||||||
|
0, /*tp_clear */
|
||||||
|
0, /*tp_richcompare */
|
||||||
|
0, /*tp_weaklistoffset */
|
||||||
|
PyObject_SelfIter, /*tp_iter */
|
||||||
|
(iternextfunc)IO_iternext, /*tp_iternext */
|
||||||
|
O_methods, /*tp_methods */
|
||||||
|
O_memberlist /*tp_members */
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -570,28 +580,6 @@ I_dealloc(Iobject *self) {
|
||||||
PyObject_Del(self);
|
PyObject_Del(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
I_getattr(Iobject *self, char *name) {
|
|
||||||
return Py_FindMethod(I_methods, (PyObject *)self, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
I_getiter(Iobject *self)
|
|
||||||
{
|
|
||||||
PyObject *myreadline = PyObject_GetAttrString((PyObject*)self,
|
|
||||||
"readline");
|
|
||||||
PyObject *emptystring = PyString_FromString("");
|
|
||||||
PyObject *iter = NULL;
|
|
||||||
if (!myreadline || !emptystring)
|
|
||||||
goto finally;
|
|
||||||
|
|
||||||
iter = PyCallIter_New(myreadline, emptystring);
|
|
||||||
finally:
|
|
||||||
Py_XDECREF(myreadline);
|
|
||||||
Py_XDECREF(emptystring);
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Itype__doc__,
|
PyDoc_STRVAR(Itype__doc__,
|
||||||
"Simple type for treating strings as input file streams");
|
"Simple type for treating strings as input file streams");
|
||||||
|
@ -605,7 +593,7 @@ static PyTypeObject Itype = {
|
||||||
/* methods */
|
/* methods */
|
||||||
(destructor)I_dealloc, /*tp_dealloc*/
|
(destructor)I_dealloc, /*tp_dealloc*/
|
||||||
(printfunc)0, /*tp_print*/
|
(printfunc)0, /*tp_print*/
|
||||||
(getattrfunc)I_getattr, /*tp_getattr*/
|
0, /* tp_getattr */
|
||||||
(setattrfunc)0, /*tp_setattr*/
|
(setattrfunc)0, /*tp_setattr*/
|
||||||
(cmpfunc)0, /*tp_compare*/
|
(cmpfunc)0, /*tp_compare*/
|
||||||
(reprfunc)0, /*tp_repr*/
|
(reprfunc)0, /*tp_repr*/
|
||||||
|
@ -624,8 +612,9 @@ static PyTypeObject Itype = {
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
0, /* tp_richcompare */
|
0, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
(getiterfunc)I_getiter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
0, /* tp_iternext */
|
(iternextfunc)IO_iternext, /* tp_iternext */
|
||||||
|
I_methods /* tp_methods */
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -707,6 +696,8 @@ initcStringIO(void) {
|
||||||
/* Export C API */
|
/* Export C API */
|
||||||
Itype.ob_type=&PyType_Type;
|
Itype.ob_type=&PyType_Type;
|
||||||
Otype.ob_type=&PyType_Type;
|
Otype.ob_type=&PyType_Type;
|
||||||
|
if (PyType_Ready(&Otype) < 0) return;
|
||||||
|
if (PyType_Ready(&Itype) < 0) return;
|
||||||
PyDict_SetItemString(d,"cStringIO_CAPI",
|
PyDict_SetItemString(d,"cStringIO_CAPI",
|
||||||
v = PyCObject_FromVoidPtr(&CAPI,NULL));
|
v = PyCObject_FromVoidPtr(&CAPI,NULL));
|
||||||
Py_XDECREF(v);
|
Py_XDECREF(v);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue