Issue #17339: Improved TypeError message in bytes constructor.

This commit is contained in:
Serhiy Storchaka 2016-04-10 14:44:59 +03:00
parent 96cdbe7bc8
commit 03f17f8671
1 changed files with 15 additions and 16 deletions

View File

@ -3469,31 +3469,24 @@ _PyBytes_FromTuple(PyObject *x)
} }
static PyObject * static PyObject *
_PyBytes_FromIterator(PyObject *x) _PyBytes_FromIterator(PyObject *it, PyObject *x)
{ {
char *str; char *str;
PyObject *it;
Py_ssize_t i, size; Py_ssize_t i, size;
_PyBytesWriter writer; _PyBytesWriter writer;
_PyBytesWriter_Init(&writer);
/* For iterator version, create a string object and resize as needed */ /* For iterator version, create a string object and resize as needed */
size = PyObject_LengthHint(x, 64); size = PyObject_LengthHint(x, 64);
if (size == -1 && PyErr_Occurred()) if (size == -1 && PyErr_Occurred())
return NULL; return NULL;
_PyBytesWriter_Init(&writer);
str = _PyBytesWriter_Alloc(&writer, size); str = _PyBytesWriter_Alloc(&writer, size);
if (str == NULL) if (str == NULL)
return NULL; return NULL;
writer.overallocate = 1; writer.overallocate = 1;
size = writer.allocated; size = writer.allocated;
/* Get the iterator */
it = PyObject_GetIter(x);
if (it == NULL)
goto error;
/* Run the iterator to exhaustion */ /* Run the iterator to exhaustion */
for (i = 0; ; i++) { for (i = 0; ; i++) {
PyObject *item; PyObject *item;
@ -3529,19 +3522,19 @@ _PyBytes_FromIterator(PyObject *x)
} }
*str++ = (char) value; *str++ = (char) value;
} }
Py_DECREF(it);
return _PyBytesWriter_Finish(&writer, str); return _PyBytesWriter_Finish(&writer, str);
error: error:
_PyBytesWriter_Dealloc(&writer); _PyBytesWriter_Dealloc(&writer);
Py_XDECREF(it);
return NULL; return NULL;
} }
PyObject * PyObject *
PyBytes_FromObject(PyObject *x) PyBytes_FromObject(PyObject *x)
{ {
PyObject *it, *result;
if (x == NULL) { if (x == NULL) {
PyErr_BadInternalCall(); PyErr_BadInternalCall();
return NULL; return NULL;
@ -3562,13 +3555,19 @@ PyBytes_FromObject(PyObject *x)
if (PyTuple_CheckExact(x)) if (PyTuple_CheckExact(x))
return _PyBytes_FromTuple(x); return _PyBytes_FromTuple(x);
if (PyUnicode_Check(x)) { if (!PyUnicode_Check(x)) {
PyErr_SetString(PyExc_TypeError, it = PyObject_GetIter(x);
"cannot convert unicode object to bytes"); if (it != NULL) {
return NULL; result = _PyBytes_FromIterator(it, x);
Py_DECREF(it);
return result;
}
} }
return _PyBytes_FromIterator(x); PyErr_Format(PyExc_TypeError,
"cannot convert '%.200s' object to bytes",
x->ob_type->tp_name);
return NULL;
} }
static PyObject * static PyObject *