Index: Python/bltinmodule.c =================================================================== --- Python/bltinmodule.c (revision 58683) +++ Python/bltinmodule.c (working copy) @@ -1797,6 +1797,7 @@ SETBUILTIN("True", Py_True); SETBUILTIN("bool", &PyBool_Type); SETBUILTIN("memoryview", &PyMemoryView_Type); + SETBUILTIN("buffer", &PyBytes_Type); SETBUILTIN("bytes", &PyBytes_Type); SETBUILTIN("classmethod", &PyClassMethod_Type); #ifndef WITHOUT_COMPLEX Index: Objects/bytesobject.c =================================================================== --- Objects/bytesobject.c (revision 58683) +++ Objects/bytesobject.c (working copy) @@ -395,7 +395,7 @@ if (i < 0) i += Py_Size(self); if (i < 0 || i >= Py_Size(self)) { - PyErr_SetString(PyExc_IndexError, "bytes index out of range"); + PyErr_SetString(PyExc_IndexError, "buffer index out of range"); return NULL; } return PyInt_FromLong((unsigned char)(self->ob_bytes[i])); @@ -414,7 +414,7 @@ i += PyBytes_GET_SIZE(self); if (i < 0 || i >= Py_Size(self)) { - PyErr_SetString(PyExc_IndexError, "bytes index out of range"); + PyErr_SetString(PyExc_IndexError, "buffer index out of range"); return NULL; } return PyInt_FromLong((unsigned char)(self->ob_bytes[i])); @@ -451,7 +451,7 @@ } } else { - PyErr_SetString(PyExc_TypeError, "bytes indices must be integers"); + PyErr_SetString(PyExc_TypeError, "buffer indices must be integers"); return NULL; } } @@ -551,7 +551,7 @@ i += Py_Size(self); if (i < 0 || i >= Py_Size(self)) { - PyErr_SetString(PyExc_IndexError, "bytes index out of range"); + PyErr_SetString(PyExc_IndexError, "buffer index out of range"); return -1; } @@ -587,7 +587,7 @@ i += PyBytes_GET_SIZE(self); if (i < 0 || i >= Py_Size(self)) { - PyErr_SetString(PyExc_IndexError, "bytes index out of range"); + PyErr_SetString(PyExc_IndexError, "buffer index out of range"); return -1; } @@ -619,7 +619,7 @@ } } else { - PyErr_SetString(PyExc_TypeError, "bytes indices must be integer"); + PyErr_SetString(PyExc_TypeError, "buffer indices must be integer"); return -1; } @@ -889,11 +889,14 @@ bytes_repr(PyBytesObject *self) { static const char *hexdigits = "0123456789abcdef"; - size_t newsize = 3 + 4 * Py_Size(self); + const char *quote_prefix = "buffer(b'"; + const char *quote_postfix = "')"; + /* 9 prefix + 2 postfix */ + size_t newsize = 11 + 4 * Py_Size(self); PyObject *v; - if (newsize > PY_SSIZE_T_MAX || newsize / 4 != Py_Size(self)) { + if (newsize > PY_SSIZE_T_MAX || (newsize-11) / 4 != Py_Size(self)) { PyErr_SetString(PyExc_OverflowError, - "bytes object is too large to make repr"); + "buffer object is too large to make repr"); return NULL; } v = PyUnicode_FromUnicode(NULL, newsize); @@ -904,17 +907,17 @@ register Py_ssize_t i; register Py_UNICODE c; register Py_UNICODE *p; - int quote = '\''; p = PyUnicode_AS_UNICODE(v); - *p++ = 'b'; - *p++ = quote; + while (*quote_prefix) + *p++ = *quote_prefix++; + for (i = 0; i < Py_Size(self); i++) { /* There's at least enough room for a hex escape and a closing quote. */ assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 5); c = self->ob_bytes[i]; - if (c == quote || c == '\\') + if (c == '\'' || c == '\\') *p++ = '\\', *p++ = c; else if (c == '\t') *p++ = '\\', *p++ = 't'; @@ -934,7 +937,9 @@ *p++ = c; } assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1); - *p++ = quote; + while (*quote_postfix) { + *p++ = *quote_postfix++; + } *p = '\0'; if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) { Py_DECREF(v); @@ -947,7 +952,7 @@ static PyObject * bytes_str(PyBytesObject *self) { - return PyString_FromStringAndSize(self->ob_bytes, Py_Size(self)); + return bytes_repr(self); } static PyObject * @@ -2028,7 +2033,7 @@ PyDoc_STRVAR(replace__doc__, "B.replace (old, new[, count]) -> bytes\n\ \n\ -Return a copy of bytes B with all occurrences of subsection\n\ +Return a copy of B with all occurrences of subsection\n\ old replaced by new. If the optional argument count is\n\ given, only the first count occurrences are replaced."); @@ -2176,9 +2181,9 @@ } PyDoc_STRVAR(split__doc__, -"B.split([sep [, maxsplit]]) -> list of bytes\n\ +"B.split([sep [, maxsplit]]) -> list of buffer\n\ \n\ -Return a list of the bytes in the string B, using sep as the delimiter.\n\ +Return a list of the buffer in the string B, using sep as the delimiter.\n\ If sep is not given, B is split on ASCII whitespace charcters\n\ (space, tab, return, newline, formfeed, vertical tab).\n\ If maxsplit is given, at most maxsplit splits are done."); @@ -2260,7 +2265,7 @@ \n\ Searches for the separator sep in B, and returns the part before it,\n\ the separator itself, and the part after it. If the separator is not\n\ -found, returns B and two empty bytes."); +found, returns B and two empty buffer."); static PyObject * bytes_partition(PyBytesObject *self, PyObject *sep_obj) @@ -2287,7 +2292,7 @@ \n\ Searches for the separator sep in B, starting at the end of B, and returns\n\ the part before it, the separator itself, and the part after it. If the\n\ -separator is not found, returns two empty bytes and B."); +separator is not found, returns two empty buffer and B."); static PyObject * bytes_rpartition(PyBytesObject *self, PyObject *sep_obj) @@ -2384,10 +2389,10 @@ } PyDoc_STRVAR(rsplit__doc__, -"B.rsplit(sep [,maxsplit]) -> list of bytes\n\ +"B.rsplit(sep [,maxsplit]) -> list of buffer\n\ \n\ -Return a list of the sections in the byte B, using sep as the delimiter,\n\ -starting at the end of the bytes and working to the front.\n\ +Return a list of the sections in B, using sep as the delimiter,\n\ +starting at the end of B and working to the front.\n\ If sep is not given, B is split on ASCII whitespace characters\n\ (space, tab, return, newline, formfeed, vertical tab).\n\ If maxsplit is given, at most maxsplit splits are done."); @@ -2458,7 +2463,7 @@ "B.extend(iterable int) -> None\n\ \n\ Append all the elements from the iterator or sequence to the\n\ -end of the bytes."); +end of B."); static PyObject * bytes_extend(PyBytesObject *self, PyObject *arg) { @@ -2475,7 +2480,7 @@ PyDoc_STRVAR(reverse__doc__, "B.reverse() -> None\n\ \n\ -Reverse the order of the values in bytes in place."); +Reverse the order of the values in B in place."); static PyObject * bytes_reverse(PyBytesObject *self, PyObject *unused) { @@ -2497,7 +2502,7 @@ PyDoc_STRVAR(insert__doc__, "B.insert(index, int) -> None\n\ \n\ -Insert a single item into the bytes before the given index."); +Insert a single item into the buffer before the given index."); static PyObject * bytes_insert(PyBytesObject *self, PyObject *args) { @@ -2536,7 +2541,7 @@ PyDoc_STRVAR(append__doc__, "B.append(int) -> None\n\ \n\ -Append a single item to the end of the bytes."); +Append a single item to the end of B."); static PyObject * bytes_append(PyBytesObject *self, PyObject *arg) { @@ -2561,7 +2566,7 @@ PyDoc_STRVAR(pop__doc__, "B.pop([index]) -> int\n\ \n\ -Remove and return a single item from the bytes. If no index\n\ +Remove and return a single item from B. If no index\n\ argument is give, will pop the last value."); static PyObject * bytes_pop(PyBytesObject *self, PyObject *args) @@ -2595,7 +2600,7 @@ PyDoc_STRVAR(remove__doc__, "B.remove(int) -> None\n\ \n\ -Remove the first occurance of a value in bytes"); +Remove the first occurance of a value in B."); static PyObject * bytes_remove(PyBytesObject *self, PyObject *arg) { @@ -2644,7 +2649,7 @@ } PyDoc_STRVAR(strip__doc__, -"B.strip([bytes]) -> bytes\n\ +"B.strip([bytes]) -> buffer\n\ \n\ Strip leading and trailing bytes contained in the argument.\n\ If the argument is omitted, strip ASCII whitespace."); @@ -2680,7 +2685,7 @@ } PyDoc_STRVAR(lstrip__doc__, -"B.lstrip([bytes]) -> bytes\n\ +"B.lstrip([bytes]) -> buffer\n\ \n\ Strip leading bytes contained in the argument.\n\ If the argument is omitted, strip leading ASCII whitespace."); @@ -2713,7 +2718,7 @@ } PyDoc_STRVAR(rstrip__doc__, -"B.rstrip([bytes]) -> bytes\n\ +"B.rstrip([bytes]) -> buffer\n\ \n\ Strip trailing bytes contained in the argument.\n\ If the argument is omitted, strip trailing ASCII whitespace."); @@ -2850,11 +2855,11 @@ } PyDoc_STRVAR(fromhex_doc, -"bytes.fromhex(string) -> bytes\n\ +"buffer.fromhex(string) -> buffer\n\ \n\ -Create a bytes object from a string of hexadecimal numbers.\n\ +Create a buffer object from a string of hexadecimal numbers.\n\ Spaces between two numbers are accepted. Example:\n\ -bytes.fromhex('10 1112') -> b'\\x10\\x11\\x12'."); +buffer.fromhex('10 1112') -> buffer(b'\\x10\\x11\\x12')."); static int hex_digit_to_int(Py_UNICODE c) @@ -3019,7 +3024,7 @@ }; PyDoc_STRVAR(bytes_doc, -"bytes([iterable]) -> new array of bytes.\n\ +"buffer([iterable]) -> new array of bytes.\n\ \n\ If an argument is given it must be an iterable yielding ints in range(256)."); @@ -3027,7 +3032,7 @@ PyTypeObject PyBytes_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "bytes", + "buffer", sizeof(PyBytesObject), 0, (destructor)bytes_dealloc, /* tp_dealloc */ Index: Objects/stringobject.c =================================================================== --- Objects/stringobject.c (revision 58683) +++ Objects/stringobject.c (working copy) @@ -629,7 +629,7 @@ Py_ssize_t length = PyString_GET_SIZE(op); size_t newsize = 3 + 4 * Py_Size(op); PyObject *v; - if (newsize > PY_SSIZE_T_MAX || newsize / 4 != Py_Size(op)) { + if (newsize > PY_SSIZE_T_MAX || (newsize-3) / 4 != Py_Size(op)) { PyErr_SetString(PyExc_OverflowError, "string is too large to make repr"); } @@ -660,7 +660,7 @@ ; } - *p++ = 's', *p++ = quote; + *p++ = 'b', *p++ = quote; for (i = 0; i < Py_Size(op); i++) { /* There's at least enough room for a hex escape and a closing quote. */ @@ -705,8 +705,7 @@ { assert(PyString_Check(s)); if (PyString_CheckExact(s)) { - Py_INCREF(s); - return s; + return PyString_Repr(s, 1); } else { /* Subtype -- return genuine string with the same value. */ @@ -732,7 +731,7 @@ if (PyBytes_Check(bb)) return PyBytes_Concat((PyObject *)a, bb); PyErr_Format(PyExc_TypeError, - "cannot concatenate 'str8' and '%.200s' objects", + "cannot concatenate 'bytes' and '%.200s' objects", Py_Type(bb)->tp_name); return NULL; } @@ -3072,7 +3071,7 @@ PyTypeObject PyString_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "str8", + "bytes", sizeof(PyStringObject), sizeof(char), string_dealloc, /* tp_dealloc */ Index: Lib/test/test_bytes.py =================================================================== --- Lib/test/test_bytes.py (revision 58683) +++ Lib/test/test_bytes.py (working copy) @@ -79,6 +79,15 @@ self.assertEqual(repr(b"abc"), "b'abc'") self.assertEqual(repr(b"'"), "b'\\''") + def test_str(self): + self.assertEqual(str(bytes()), "b''") + self.assertEqual(str(bytes([0])), "b'\\x00'") + self.assertEqual(str(bytes([0, 1, 254, 255])), + "b'\\x00\\x01\\xfe\\xff'") + self.assertEqual(str(b"abc"), "b'abc'") + self.assertEqual(str(b"'"), "b'\\''") + + def test_compare(self): b1 = bytes([1, 2, 3]) b2 = bytes([1, 2, 3])