diff -r f4d49881e5d1 Objects/bytesobject.c --- a/Objects/bytesobject.c Tue Feb 10 14:49:56 2015 +0100 +++ b/Objects/bytesobject.c Tue Feb 10 23:08:36 2015 +0200 @@ -433,105 +433,46 @@ formatfloat(PyObject *v, int flags, int return result; } -/* format_long emulates the format codes d, u, o, x and X, and - * the F_ALT flag, for Python's long (unbounded) ints. It's not used for - * Python's regular ints. - * Return value: a new PyBytes*, or NULL if error. - * . *pbuf is set to point into it, - * *plen set to the # of chars following that. - * Caller must decref it when done using pbuf. - * The string starting at *pbuf is of the form - * "-"? ("0x" | "0X")? digit+ - * "0x"/"0X" are present only for x and X conversions, with F_ALT - * set in flags. The case of hex digits will be correct, - * There will be at least prec digits, zero-filled on the left if - * necessary to get that many. - * val object to be converted - * flags bitmask of format flags; only F_ALT is looked at - * prec minimum number of digits; 0-fill on left if needed - * type a character in [duoxX]; u acts the same as d - * - * CAUTION: o, x and X conversions on regular ints can never - * produce a '-' sign, but can for Python's unbounded ints. - */ - -static PyObject * -format_long(PyObject *val, int flags, int prec, int type, - char **pbuf, int *plen) +Py_LOCAL_INLINE(int) +byte_converter(PyObject *arg, char *p) { - PyObject *s; - PyObject *result = NULL; - - s = _PyUnicode_FormatLong(val, flags & F_ALT, prec, type); - if (!s) - return NULL; - result = _PyUnicode_AsASCIIString(s, "strict"); - Py_DECREF(s); - if (!result) - return NULL; - *pbuf = PyBytes_AS_STRING(result); - *plen = PyBytes_GET_SIZE(result); - return result; -} - -Py_LOCAL_INLINE(int) -formatchar(char *buf, size_t buflen, PyObject *v) -{ - PyObject *w = NULL; - /* convert bytearray to bytes */ - if (PyByteArray_Check(v)) { - w = PyBytes_FromObject(v); - if (w == NULL) - goto error; - v = w; + if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1) { + *p = PyBytes_AS_STRING(arg)[0]; + return 1; } - /* presume that the buffer is at least 2 characters long */ - if (PyBytes_Check(v)) { - if (!PyArg_Parse(v, "c;%c requires an integer in range(256) or a single byte", &buf[0])) - goto error; + else if (PyByteArray_Check(arg) && PyByteArray_Size(arg) == 1) { + *p = PyByteArray_AS_STRING(arg)[0]; + return 1; } else { - long ival = PyLong_AsLong(v); - if (ival == -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "%c requires an integer in range(256) or a single byte"); - goto error; + long ival = PyLong_AsLong(arg); + if (0 <= ival && ival <= 255) { + *p = (char)ival; + return 1; } - if (ival < 0 || ival > 255) { - PyErr_SetString(PyExc_TypeError, - "%c requires an integer in range(256) or a single byte"); - goto error; - } - buf[0] = (char)ival; } - Py_XDECREF(w); - buf[1] = '\0'; - return 1; - - error: - Py_XDECREF(w); - return -1; + PyErr_SetString(PyExc_TypeError, + "%c requires an integer in range(256) or a single byte"); + return 0; } static PyObject * -format_obj(PyObject *v) +format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen) { - PyObject *result = NULL, *w = NULL; - PyObject *func; + PyObject *func, *result; _Py_IDENTIFIER(__bytes__); - /* convert bytearray to bytes */ - if (PyByteArray_Check(v)) { - w = PyBytes_FromObject(v); - if (w == NULL) - return NULL; - v = w; - } /* is it a bytes object? */ if (PyBytes_Check(v)) { - result = v; + *pbuf = PyBytes_AS_STRING(v); + *plen = PyBytes_GET_SIZE(v); Py_INCREF(v); - Py_XDECREF(w); - return result; + return v; + } + if (PyByteArray_Check(v)) { + *pbuf = PyByteArray_AS_STRING(v); + *plen = PyByteArray_GET_SIZE(v); + Py_INCREF(v); + return v; } /* does it support __bytes__? */ func = _PyObject_LookupSpecial(v, &PyId___bytes__); @@ -547,6 +488,8 @@ format_obj(PyObject *v) Py_DECREF(result); return NULL; } + *pbuf = PyBytes_AS_STRING(result); + *plen = PyBytes_GET_SIZE(result); return result; } PyErr_Format(PyExc_TypeError, @@ -573,7 +516,6 @@ PyObject * Py_ssize_t reslen, rescnt, fmtcnt; int args_owned = 0; PyObject *result; - PyObject *repr; PyObject *dict = NULL; if (format == NULL || !PyBytes_Check(format) || args == NULL) { PyErr_BadInternalCall(); @@ -619,15 +561,13 @@ PyObject * int prec = -1; int c = '\0'; int fill; - int isnumok; + PyObject *iobj; PyObject *v = NULL; PyObject *temp = NULL; - Py_buffer buf = {NULL, NULL}; - char *pbuf; + const char *pbuf = NULL; int sign; - Py_ssize_t len; - char formatbuf[FORMATBUFLEN]; - /* For format{int,char}() */ + Py_ssize_t len = 0; + char onechar; /* For byte_converter() */ fmt++; if (*fmt == '(') { @@ -781,37 +721,21 @@ PyObject * len = 1; break; case 'a': - temp = PyObject_Repr(v); + temp = PyObject_ASCII(v); if (temp == NULL) goto error; - repr = PyUnicode_AsEncodedObject(temp, "ascii", "backslashreplace"); - if (repr == NULL) { - Py_DECREF(temp); - goto error; - } - if (PyObject_GetBuffer(repr, &buf, PyBUF_SIMPLE) != 0) { - temp = format_obj(repr); - if (temp == NULL) { - Py_DECREF(repr); - goto error; - } - Py_DECREF(repr); - repr = temp; - } - pbuf = PyBytes_AS_STRING(repr); - len = PyBytes_GET_SIZE(repr); - Py_DECREF(repr); + assert(PyUnicode_IS_ASCII(temp)); + pbuf = (const char *)PyUnicode_1BYTE_DATA(temp); + len = PyUnicode_GET_LENGTH(temp); if (prec >= 0 && len > prec) len = prec; break; case 's': // %s is only for 2/3 code; 3 only code should use %b case 'b': - temp = format_obj(v); + temp = format_obj(v, &pbuf, &len); if (temp == NULL) goto error; - pbuf = PyBytes_AS_STRING(temp); - len = PyBytes_GET_SIZE(temp); if (prec >= 0 && len > prec) len = prec; break; @@ -823,41 +747,32 @@ PyObject * case 'X': if (c == 'i') c = 'd'; - isnumok = 0; + iobj = NULL; if (PyNumber_Check(v)) { - PyObject *iobj=NULL; - if ((PyLong_Check(v))) { iobj = v; Py_INCREF(iobj); } else { iobj = PyNumber_Long(v); - } - if (iobj!=NULL) { - if (PyLong_Check(iobj)) { - int ilen; - - isnumok = 1; - temp = format_long(iobj, flags, prec, c, - &pbuf, &ilen); - Py_DECREF(iobj); - if (!temp) - goto error; - len = ilen; - sign = 1; - } - else { - Py_DECREF(iobj); - } + if (iobj != NULL && !PyLong_Check(iobj)) + Py_CLEAR(iobj); } } - if (!isnumok) { + if (iobj == NULL) { PyErr_Format(PyExc_TypeError, "%%%c format: a number is required, " "not %.200s", c, Py_TYPE(v)->tp_name); goto error; } + temp = _PyUnicode_FormatLong(iobj, flags & F_ALT, prec, c); + Py_DECREF(iobj); + if (!temp) + goto error; + assert(PyUnicode_IS_ASCII(temp)); + pbuf = (const char *)PyUnicode_1BYTE_DATA(temp); + len = PyUnicode_GET_LENGTH(temp); + sign = 1; if (flags & F_ZERO) fill = '0'; break; @@ -877,9 +792,9 @@ PyObject * fill = '0'; break; case 'c': - pbuf = formatbuf; - len = formatchar(pbuf, sizeof(formatbuf), v); - if (len < 0) + pbuf = &onechar; + len = byte_converter(v, &onechar); + if (!len) goto error; break; default: @@ -911,12 +826,10 @@ PyObject * reslen += rescnt; if (reslen < 0) { Py_DECREF(result); - PyBuffer_Release(&buf); Py_XDECREF(temp); return PyErr_NoMemory(); } if (_PyBytes_Resize(&result, reslen)) { - PyBuffer_Release(&buf); Py_XDECREF(temp); return NULL; } @@ -970,11 +883,9 @@ PyObject * if (dict && (argidx < arglen) && c != '%') { PyErr_SetString(PyExc_TypeError, "not all arguments converted during bytes formatting"); - PyBuffer_Release(&buf); Py_XDECREF(temp); goto error; } - PyBuffer_Release(&buf); Py_XDECREF(temp); } /* '%' */ } /* until end */