Commit fb0c7cad authored by Georg Brandl's avatar Georg Brandl

Make bytes_repr return a string containing a b"" literal.

parent 1c08cd90
...@@ -516,4 +516,3 @@ keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena); ...@@ -516,4 +516,3 @@ keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena);
alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena);
PyObject* PyAST_mod2obj(mod_ty t); PyObject* PyAST_mod2obj(mod_ty t);
...@@ -69,9 +69,11 @@ class BytesTest(unittest.TestCase): ...@@ -69,9 +69,11 @@ class BytesTest(unittest.TestCase):
self.assertRaises(ValueError, bytes, [10**100]) self.assertRaises(ValueError, bytes, [10**100])
def test_repr(self): def test_repr(self):
self.assertEqual(repr(bytes()), "bytes()") self.assertEqual(repr(bytes()), "b''")
self.assertEqual(repr(bytes([0])), "bytes([0x00])") self.assertEqual(repr(bytes([0])), "b'\\0'")
self.assertEqual(repr(bytes([0, 1, 254, 255])), "bytes([0x00, 0x01, 0xfe, 0xff])") self.assertEqual(repr(bytes([0, 1, 254, 255])), "b'\\0\\x01\\xfe\\xff'")
self.assertEqual(repr(bytes('abc')), "b'abc'")
self.assertEqual(repr(bytes("'")), "b'\\''")
def test_compare(self): def test_compare(self):
b1 = bytes([1, 2, 3]) b1 = bytes([1, 2, 3])
......
...@@ -733,65 +733,63 @@ bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds) ...@@ -733,65 +733,63 @@ bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds)
return -1; return -1;
} }
/* Mostly copied from string_repr, but without the
"smart quote" functionality. */
static PyObject * static PyObject *
bytes_repr(PyBytesObject *self) bytes_repr(PyBytesObject *self)
{ {
PyObject *list; size_t newsize = 3 + 4 * self->ob_size;
PyObject *str; PyObject *v;
PyObject *result; if (newsize > PY_SSIZE_T_MAX || newsize / 4 != self->ob_size) {
int err; PyErr_SetString(PyExc_OverflowError,
int i; "bytes object is too large to make repr");
if (self->ob_size == 0)
return PyString_FromString("bytes()");
list = PyList_New(0);
if (list == NULL)
return NULL; return NULL;
str = PyString_FromString("bytes([");
if (str == NULL)
goto error;
err = PyList_Append(list, str);
Py_DECREF(str);
if (err < 0)
goto error;
for (i = 0; i < self->ob_size; i++) {
char buffer[20];
sprintf(buffer, ", 0x%02x", (unsigned char) (self->ob_bytes[i]));
str = PyString_FromString((i == 0) ? buffer+2 : buffer);
if (str == NULL)
goto error;
err = PyList_Append(list, str);
Py_DECREF(str);
if (err < 0)
goto error;
} }
v = PyString_FromStringAndSize((char *)NULL, newsize);
str = PyString_FromString("])"); if (v == NULL) {
if (str == NULL) return NULL;
goto error; }
else {
err = PyList_Append(list, str); register Py_ssize_t i;
Py_DECREF(str); register char c;
if (err < 0) register char *p;
goto error; int quote = '\'';
str = PyString_FromString(""); p = PyString_AS_STRING(v);
if (str == NULL) *p++ = 'b';
goto error; *p++ = quote;
for (i = 0; i < self->ob_size; i++) {
result = _PyString_Join(str, list); /* There's at least enough room for a hex escape
Py_DECREF(str); and a closing quote. */
Py_DECREF(list); assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
return result; c = self->ob_bytes[i];
if (c == quote || c == '\\')
error: *p++ = '\\', *p++ = c;
/* Error handling when list != NULL */ else if (c == '\t')
Py_DECREF(list); *p++ = '\\', *p++ = 't';
return NULL; else if (c == '\n')
*p++ = '\\', *p++ = 'n';
else if (c == '\r')
*p++ = '\\', *p++ = 'r';
else if (c == 0)
*p++ = '\\', *p++ = '0';
else if (c < ' ' || c >= 0x7f) {
/* For performance, we don't want to call
PyOS_snprintf here (extra layers of
function call). */
sprintf(p, "\\x%02x", c & 0xff);
p += 4;
}
else
*p++ = c;
}
assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
*p++ = quote;
*p = '\0';
_PyString_Resize(
&v, (p - PyString_AS_STRING(v)));
return v;
}
} }
static PyObject * static PyObject *
......
...@@ -1177,7 +1177,8 @@ symtable_visit_expr(struct symtable *st, expr_ty e) ...@@ -1177,7 +1177,8 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
break; break;
case Num_kind: case Num_kind:
case Str_kind: case Str_kind:
case Ellipsis_kind: case Bytes_kind:
case Ellipsis_kind:
/* Nothing to do here. */ /* Nothing to do here. */
break; break;
/* The following exprs can be assignment targets. */ /* The following exprs can be assignment targets. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment