diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3054,8 +3054,9 @@ goto onError; if (!PyUnicode_Check(unicode)) { PyErr_Format(PyExc_TypeError, - "decoder did not return a str object (type=%.400s)", - Py_TYPE(unicode)->tp_name); + "decoder returned '%.400s' instead of 'str', " + "use codecs.encode for bytes->%.400s conversions", + Py_TYPE(unicode)->tp_name, Py_TYPE(unicode)->tp_name); Py_DECREF(unicode); goto onError; } @@ -3437,8 +3438,9 @@ } PyErr_Format(PyExc_TypeError, - "encoder did not return a bytes object (type=%.400s)", - Py_TYPE(v)->tp_name); + "encoder returned '%.400s' instead of 'bytes', " + "use codecs.decode for str->%.400s conversions", + Py_TYPE(v)->tp_name, Py_TYPE(v)->tp_name); Py_DECREF(v); return NULL; } @@ -10933,11 +10935,26 @@ static char *kwlist[] = {"encoding", "errors", 0}; char *encoding = NULL; char *errors = NULL; + PyObject *result; + PyObject *exc = NULL, *val, *tb; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:encode", kwlist, &encoding, &errors)) return NULL; - return PyUnicode_AsEncodedString(self, encoding, errors); + result = PyUnicode_AsEncodedString(self, encoding, errors); + if (result == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Fetch(&exc, &val, &tb); + PyErr_Format(PyExc_TypeError, "invalid input type for %s codec (%U)", + encoding, val); + } + else if (PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Fetch(&exc, &val, &tb); + PyErr_Format(PyExc_ValueError, "invalid input value for %s codec (%U)", + encoding, val); + } + } + return result; } PyDoc_STRVAR(expandtabs__doc__,