Index: Lib/_pyio.py =================================================================== --- Lib/_pyio.py (revision 73251) +++ Lib/_pyio.py (working copy) @@ -1467,10 +1467,11 @@ try: name = self.name except AttributeError: - return "<_pyio.TextIOWrapper encoding={0!r}>".format(self.encoding) + return ("<_pyio.TextIOWrapper encoding={0!r} " + "errors={1!r}>".format(self.encoding, self.errors)) else: - return "<_pyio.TextIOWrapper name={0!r} encoding={1!r}>".format( - name, self.encoding) + return ("<_pyio.TextIOWrapper name={0!r} encoding={1!r} " + "errors={2!r}>".format(name, self.encoding, self.errors)) @property def encoding(self): Index: Lib/test/test_io.py =================================================================== --- Lib/test/test_io.py (revision 73251) +++ Lib/test/test_io.py (working copy) @@ -1513,6 +1513,7 @@ t = self.TextIOWrapper(b) t.__init__(b, encoding="latin1", newline="\r\n") self.assertEquals(t.encoding, "latin1") + self.assertEquals(t.errors, "strict") self.assertEquals(t.line_buffering, False) t.__init__(b, encoding="utf8", line_buffering=True) self.assertEquals(t.encoding, "utf8") @@ -1537,16 +1538,19 @@ def test_repr(self): raw = self.BytesIO("hello".encode("utf-8")) b = self.BufferedReader(raw) - t = self.TextIOWrapper(b, encoding="utf-8") + t = self.TextIOWrapper(b, encoding="utf-8", errors='replace') modname = self.TextIOWrapper.__module__ self.assertEqual(repr(t), - "<%s.TextIOWrapper encoding='utf-8'>" % modname) + "<%s.TextIOWrapper encoding='utf-8' errors='replace'>" + % modname) raw.name = "dummy" self.assertEqual(repr(t), - "<%s.TextIOWrapper name='dummy' encoding='utf-8'>" % modname) + "<%s.TextIOWrapper name='dummy' encoding='utf-8' " + "errors='replace'>" % modname) raw.name = b"dummy" self.assertEqual(repr(t), - "<%s.TextIOWrapper name=b'dummy' encoding='utf-8'>" % modname) + "<%s.TextIOWrapper name=b'dummy' encoding='utf-8' " + "errors='replace'>" % modname) def test_line_buffering(self): r = self.BytesIO() Index: Modules/_io/textio.c =================================================================== --- Modules/_io/textio.c (revision 73251) +++ Modules/_io/textio.c (working copy) @@ -90,6 +90,18 @@ Py_RETURN_NONE; } +PyDoc_STRVAR(TextIOBase_errors_doc, + "Encoding errors handler of the text stream.\n" + "\n" + "Subclasses should override.\n" + ); + +static PyObject * +TextIOBase_errors_get(PyObject *self, void *context) +{ + Py_RETURN_NONE; +} + PyDoc_STRVAR(TextIOBase_newlines_doc, "Line endings translated so far.\n" "\n" @@ -115,6 +127,7 @@ static PyGetSetDef TextIOBase_getset[] = { {"encoding", (getter)TextIOBase_encoding_get, NULL, TextIOBase_encoding_doc}, + {"errors", (getter)TextIOBase_errors_get, NULL, TextIOBase_errors_doc}, {"newlines", (getter)TextIOBase_newlines_get, NULL, TextIOBase_newlines_doc}, {NULL} }; @@ -2308,24 +2321,27 @@ static PyObject * TextIOWrapper_repr(PyTextIOWrapperObject *self) { - PyObject *nameobj, *res; + PyObject *nameobj, *res, *errors; CHECK_INITIALIZED(self); nameobj = PyObject_GetAttrString((PyObject *) self, "name"); + errors = PyUnicode_FromEncodedObject(self->errors, NULL, "strict"); if (nameobj == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) PyErr_Clear(); else return NULL; - res = PyUnicode_FromFormat("<_io.TextIOWrapper encoding=%R>", - self->encoding); + res = PyUnicode_FromFormat("<_io.TextIOWrapper encoding=%R errors=%R>", + self->encoding, errors); } else { - res = PyUnicode_FromFormat("<_io.TextIOWrapper name=%R encoding=%R>", - nameobj, self->encoding); + res = PyUnicode_FromFormat("<_io.TextIOWrapper name=%R encoding=%R " + "errors=%R>", nameobj, self->encoding, + errors); Py_DECREF(nameobj); } + Py_DECREF(errors); return res; } @@ -2462,6 +2478,13 @@ } static PyObject * +TextIOWrapper_errors_get(PyTextIOWrapperObject *self, void *context) +{ + CHECK_INITIALIZED(self); + return PyUnicode_FromEncodedObject(self->errors, NULL, "strict"); +} + +static PyObject * TextIOWrapper_chunk_size_get(PyTextIOWrapperObject *self, void *context) { CHECK_INITIALIZED(self); @@ -2519,6 +2542,7 @@ /* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL}, */ {"newlines", (getter)TextIOWrapper_newlines_get, NULL, NULL}, + {"errors", (getter)TextIOWrapper_errors_get, NULL, NULL}, {"_CHUNK_SIZE", (getter)TextIOWrapper_chunk_size_get, (setter)TextIOWrapper_chunk_size_set, NULL}, {NULL}