summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2007-02-24 19:41:35 +0000
committerGeorg Brandl <georg@python.org>2007-02-24 19:41:35 +0000
commitee91be45df796b8e5721d9142a6e92e55a465451 (patch)
tree9878cc28e6145f4985c2d6e323f84657e60eb650
parentfa353657f0da969eb6bc1cf62fb3c69dd036463a (diff)
downloadcpython-git-ee91be45df796b8e5721d9142a6e92e55a465451.tar.gz
Make bytes_repr return a string containing a b"" literal.
-rw-r--r--Include/Python-ast.h1
-rw-r--r--Lib/test/test_bytes.py8
-rw-r--r--Objects/bytesobject.c106
-rw-r--r--Python/symtable.c3
4 files changed, 59 insertions, 59 deletions
diff --git a/Include/Python-ast.h b/Include/Python-ast.h
index a702dbc2fb..66d7b52580 100644
--- a/Include/Python-ast.h
+++ b/Include/Python-ast.h
@@ -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);
PyObject* PyAST_mod2obj(mod_ty t);
-
diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py
index 4dee01b7f2..83f6f93627 100644
--- a/Lib/test/test_bytes.py
+++ b/Lib/test/test_bytes.py
@@ -69,9 +69,11 @@ class BytesTest(unittest.TestCase):
self.assertRaises(ValueError, bytes, [10**100])
def test_repr(self):
- self.assertEqual(repr(bytes()), "bytes()")
- self.assertEqual(repr(bytes([0])), "bytes([0x00])")
- self.assertEqual(repr(bytes([0, 1, 254, 255])), "bytes([0x00, 0x01, 0xfe, 0xff])")
+ self.assertEqual(repr(bytes()), "b''")
+ self.assertEqual(repr(bytes([0])), "b'\\0'")
+ 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):
b1 = bytes([1, 2, 3])
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 09abaea97f..88e65858c6 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -733,65 +733,63 @@ bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds)
return -1;
}
+/* Mostly copied from string_repr, but without the
+ "smart quote" functionality. */
static PyObject *
bytes_repr(PyBytesObject *self)
{
- PyObject *list;
- PyObject *str;
- PyObject *result;
- int err;
- int i;
-
- if (self->ob_size == 0)
- return PyString_FromString("bytes()");
-
- list = PyList_New(0);
- if (list == NULL)
+ size_t newsize = 3 + 4 * self->ob_size;
+ PyObject *v;
+ if (newsize > PY_SSIZE_T_MAX || newsize / 4 != self->ob_size) {
+ PyErr_SetString(PyExc_OverflowError,
+ "bytes object is too large to make repr");
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;
}
-
- str = PyString_FromString("])");
- if (str == NULL)
- goto error;
-
- err = PyList_Append(list, str);
- Py_DECREF(str);
- if (err < 0)
- goto error;
-
- str = PyString_FromString("");
- if (str == NULL)
- goto error;
-
- result = _PyString_Join(str, list);
- Py_DECREF(str);
- Py_DECREF(list);
- return result;
-
- error:
- /* Error handling when list != NULL */
- Py_DECREF(list);
- return NULL;
+ v = PyString_FromStringAndSize((char *)NULL, newsize);
+ if (v == NULL) {
+ return NULL;
+ }
+ else {
+ register Py_ssize_t i;
+ register char c;
+ register char *p;
+ int quote = '\'';
+
+ p = PyString_AS_STRING(v);
+ *p++ = 'b';
+ *p++ = quote;
+ for (i = 0; i < self->ob_size; i++) {
+ /* There's at least enough room for a hex escape
+ and a closing quote. */
+ assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
+ c = self->ob_bytes[i];
+ if (c == quote || c == '\\')
+ *p++ = '\\', *p++ = c;
+ else if (c == '\t')
+ *p++ = '\\', *p++ = 't';
+ 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 *
diff --git a/Python/symtable.c b/Python/symtable.c
index 5f0290afa1..1d76e0d025 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -1177,7 +1177,8 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
break;
case Num_kind:
case Str_kind:
- case Ellipsis_kind:
+ case Bytes_kind:
+ case Ellipsis_kind:
/* Nothing to do here. */
break;
/* The following exprs can be assignment targets. */