Kaydet (Commit) d2bb18b2 authored tarafından Alexandre Vassalotti's avatar Alexandre Vassalotti

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

üst e671fd20
......@@ -1924,8 +1924,10 @@ class StringIO(TextIOWrapper):
# 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)
......
......@@ -140,6 +140,7 @@ class MemoryTestMixin:
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 @@ class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase):
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
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment