[3.6] bpo-31271: Fix an assertion failure in io.TextIOWrapper.write. … · python/cpython@9bcbc6c (original) (raw)

File tree

3 files changed

lines changed

3 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -3163,6 +3163,14 @@ def test_read_nonbytes(self):
3163 3163 t = self.TextIOWrapper(self.StringIO('a'))
3164 3164 self.assertRaises(TypeError, t.read)
3165 3165
3166 +def test_illegal_encoder(self):
3167 +# Issue 31271: Calling write() while the return value of encoder's
3168 +# encode() is invalid shouldn't cause an assertion failure.
3169 +rot13 = codecs.lookup("rot13")
3170 +with support.swap_attr(rot13, '_is_text_encoding', True):
3171 +t = io.TextIOWrapper(io.BytesIO(b'foo'), encoding="rot13")
3172 +self.assertRaises(TypeError, t.write, 'bar')
3173 +
3166 3174 def test_illegal_decoder(self):
3167 3175 # Issue #17106
3168 3176 # Bypass the early encoding check added in issue 20404
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1 +Fix an assertion failure in the write() method of `io.TextIOWrapper`, when
2 +the encoder doesn't return a bytes object. Patch by Oren Milman.
Original file line number Diff line number Diff line change
@@ -1331,6 +1331,13 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text)
1331 1331 Py_DECREF(text);
1332 1332 if (b == NULL)
1333 1333 return NULL;
1334 +if (!PyBytes_Check(b)) {
1335 +PyErr_Format(PyExc_TypeError,
1336 +"encoder should return a bytes object, not '%.200s'",
1337 +Py_TYPE(b)->tp_name);
1338 +Py_DECREF(b);
1339 +return NULL;
1340 + }
1334 1341
1335 1342 if (self->pending_bytes == NULL) {
1336 1343 self->pending_bytes = PyList_New(0);