summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2007-05-09 19:52:16 (GMT)
committerGuido van Rossum <guido@python.org>2007-05-09 19:52:16 (GMT)
commitcd6ae68943e5bd219d0f32be346d1a730635aaa4 (patch)
tree404da2460ce3677ed0facc7aef878ce1859e5f49
parent0925e419dfc5de666965dcd15ae08d045c7df36f (diff)
downloadcpython-cd6ae68943e5bd219d0f32be346d1a730635aaa4.zip
cpython-cd6ae68943e5bd219d0f32be346d1a730635aaa4.tar.gz
cpython-cd6ae68943e5bd219d0f32be346d1a730635aaa4.tar.bz2
I don't know how come bytes.join() was a class method, but that's clearly
a mistake. It's not a regular (instance) method. b".".join([b"a", b"b"]) now returns b"a.b" -- it used to return b"ab"!
-rw-r--r--Lib/test/test_bytes.py11
-rw-r--r--Objects/bytesobject.c17
2 files changed, 18 insertions, 10 deletions
diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py
index 33a4b0d..9fdca7f 100644
--- a/Lib/test/test_bytes.py
+++ b/Lib/test/test_bytes.py
@@ -466,13 +466,14 @@ class BytesTest(unittest.TestCase):
self.assertRaises(ValueError, bytes.fromhex, '12 \x00 34')
def test_join(self):
- self.assertEqual(bytes.join([]), bytes())
- self.assertEqual(bytes.join([bytes()]), bytes())
+ self.assertEqual(b"".join([]), bytes())
+ self.assertEqual(b"".join([bytes()]), bytes())
for part in [("abc",), ("a", "bc"), ("ab", "c"), ("a", "b", "c")]:
lst = map(bytes, part)
- self.assertEqual(bytes.join(lst), bytes("abc"))
- self.assertEqual(bytes.join(tuple(lst)), bytes("abc"))
- self.assertEqual(bytes.join(iter(lst)), bytes("abc"))
+ self.assertEqual(b"".join(lst), bytes("abc"))
+ self.assertEqual(b"".join(tuple(lst)), bytes("abc"))
+ self.assertEqual(b"".join(iter(lst)), bytes("abc"))
+ self.assertEqual(b".".join([b"ab", b"cd"]), b"ab.cd")
# XXX more...
def test_literal(self):
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 3a707ac..a07f9e7 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -2580,15 +2580,16 @@ bytes_alloc(PyBytesObject *self)
}
PyDoc_STRVAR(join_doc,
-"bytes.join(iterable_of_bytes) -> bytes\n\
+"B.join(iterable_of_bytes) -> bytes\n\
\n\
-Concatenates any number of bytes objects. Example:\n\
-bytes.join([bytes('ab'), bytes('pq'), bytes('rs')]) -> bytes('abpqrs').");
+Concatenates any number of bytes objects, with B in between each pair.\n\
+Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'.");
static PyObject *
-bytes_join(PyObject *cls, PyObject *it)
+bytes_join(PyBytesObject *self, PyObject *it)
{
PyObject *seq;
+ Py_ssize_t mysize = self->ob_size;
Py_ssize_t i;
Py_ssize_t n;
PyObject **items;
@@ -2613,6 +2614,8 @@ bytes_join(PyObject *cls, PyObject *it)
(long)i, obj->ob_type->tp_name);
goto error;
}
+ if (i > 0)
+ totalsize += mysize;
totalsize += PyBytes_GET_SIZE(obj);
if (totalsize < 0) {
PyErr_NoMemory();
@@ -2628,6 +2631,10 @@ bytes_join(PyObject *cls, PyObject *it)
for (i = 0; i < n; i++) {
PyObject *obj = items[i];
Py_ssize_t size = PyBytes_GET_SIZE(obj);
+ if (i > 0) {
+ memcpy(dest, self->ob_bytes, mysize);
+ dest += mysize;
+ }
memcpy(dest, PyBytes_AS_STRING(obj), size);
dest += size;
}
@@ -2775,7 +2782,7 @@ bytes_methods[] = {
{"__alloc__", (PyCFunction)bytes_alloc, METH_NOARGS, alloc_doc},
{"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS,
fromhex_doc},
- {"join", (PyCFunction)bytes_join, METH_O|METH_CLASS, join_doc},
+ {"join", (PyCFunction)bytes_join, METH_O, join_doc},
{"__reduce__", (PyCFunction)bytes_reduce, METH_NOARGS, reduce_doc},
{NULL}
};