Issue #6241: Better type checking for the arguments of io.StringIO.

This commit is contained in:
Alexandre Vassalotti 2009-07-22 03:07:33 +00:00
parent e671fd206b
commit d2bb18b281
3 changed files with 38 additions and 5 deletions

View file

@ -1924,8 +1924,10 @@ def __init__(self, initial_value="", newline="\n"):
# C version, even under Windows.
if newline is None:
self._writetranslate = False
if initial_value:
if initial_value is not None:
if not isinstance(initial_value, str):
raise TypeError("initial_value must be str or None, not {0}"
.format(type(initial_value).__name__))
initial_value = str(initial_value)
self.write(initial_value)
self.seek(0)

View file

@ -140,6 +140,7 @@ def test_init(self):
self.assertEqual(memio.getvalue(), buf * 2)
memio.__init__(buf)
self.assertEqual(memio.getvalue(), buf)
self.assertRaises(TypeError, memio.__init__, [])
def test_read(self):
buf = self.buftype("1234567890")
@ -530,6 +531,13 @@ def test_issue5265(self):
memio = self.ioclass("a\r\nb\r\n", newline=None)
self.assertEqual(memio.read(5), "a\nb\n")
def test_newline_argument(self):
self.assertRaises(TypeError, self.ioclass, newline=b"\n")
self.assertRaises(ValueError, self.ioclass, newline="error")
# These should not raise an error
for newline in (None, "", "\n", "\r", "\r\n"):
self.ioclass(newline=newline)
class CBytesIOTest(PyBytesIOTest):
ioclass = io.BytesIO

View file

@ -550,22 +550,42 @@ stringio_init(stringio *self, PyObject *args, PyObject *kwds)
{
char *kwlist[] = {"initial_value", "newline", NULL};
PyObject *value = NULL;
PyObject *newline_obj = NULL;
char *newline = "\n";
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oz:__init__", kwlist,
&value, &newline))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:__init__", kwlist,
&value, &newline_obj))
return -1;
/* Parse the newline argument. This used to be done with the 'z'
specifier, however this allowed any object with the buffer interface to
be converted. Thus we have to parse it manually since we only want to
allow unicode objects or None. */
if (newline_obj == Py_None) {
newline = NULL;
}
else if (newline_obj) {
if (!PyUnicode_Check(newline_obj)) {
PyErr_Format(PyExc_TypeError,
"newline must be str or None, not %.200s",
Py_TYPE(newline_obj)->tp_name);
return -1;
}
newline = _PyUnicode_AsString(newline_obj);
if (newline == NULL)
return -1;
}
if (newline && newline[0] != '\0'
&& !(newline[0] == '\n' && newline[1] == '\0')
&& !(newline[0] == '\r' && newline[1] == '\0')
&& !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
PyErr_Format(PyExc_ValueError,
"illegal newline value: %s", newline);
"illegal newline value: %R", newline_obj);
return -1;
}
if (value && value != Py_None && !PyUnicode_Check(value)) {
PyErr_Format(PyExc_ValueError,
PyErr_Format(PyExc_TypeError,
"initial_value must be str or None, not %.200s",
Py_TYPE(value)->tp_name);
return -1;
@ -577,6 +597,9 @@ stringio_init(stringio *self, PyObject *args, PyObject *kwds)
Py_CLEAR(self->writenl);
Py_CLEAR(self->decoder);
assert((newline != NULL && newline_obj != Py_None) ||
(newline == NULL && newline_obj == Py_None));
if (newline) {
self->readnl = PyUnicode_FromString(newline);
if (self->readnl == NULL)