summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2007-09-27 18:01:22 (GMT)
committerGuido van Rossum <guido@python.org>2007-09-27 18:01:22 (GMT)
commitf1044293fa36667b5ba11fbc7acac21a03b82710 (patch)
tree41aac1b32323f1ae889d88c097157d330dc1aff7
parent4e02c503e789337b07cc14ece3f5adbf23732c89 (diff)
downloadcpython-f1044293fa36667b5ba11fbc7acac21a03b82710.zip
cpython-f1044293fa36667b5ba11fbc7acac21a03b82710.tar.gz
cpython-f1044293fa36667b5ba11fbc7acac21a03b82710.tar.bz2
Patch # 1145 by Thomas Lee:
str.join(...) now applies str() to the sequence elements if they're not strings alraedy, except for bytes, which still raise TypeError (for the same reasons why ""==b"" raises it).
-rw-r--r--Doc/library/stdtypes.rst7
-rw-r--r--Lib/test/string_tests.py7
-rw-r--r--Lib/test/test_descr.py4
-rw-r--r--Lib/test/test_unicode.py6
-rw-r--r--Objects/unicodeobject.c20
5 files changed, 28 insertions, 16 deletions
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 1a0bdf3..136a8d5 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -789,8 +789,11 @@ functions based on regular expressions.
.. method:: str.join(seq)
- Return a string which is the concatenation of the strings in the sequence *seq*.
- The separator between elements is the string providing this method.
+ Return a string which is the concatenation of the values in the sequence
+ *seq*. Non-string values in *seq* will be converted to a string using their
+ respective ``str()`` value. If there are any :class:`bytes` objects in
+ *seq*, a :exc:`TypeError` will be raised. The separator between elements is
+ the string providing this method.
.. method:: str.ljust(width[, fillchar])
diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py
index 9e178ca..cb8900d 100644
--- a/Lib/test/string_tests.py
+++ b/Lib/test/string_tests.py
@@ -13,6 +13,7 @@ class Sequence:
class BadSeq1(Sequence):
def __init__(self): self.seq = [7, 'hello', 123]
+ def __str__(self): return '{0} {1} {2}'.format(*self.seq)
class BadSeq2(Sequence):
def __init__(self): self.seq = ['a', 'b', 'c']
@@ -987,19 +988,19 @@ class MixinStrUnicodeUserStringTest:
self.checkequal('abc', 'a', 'join', ('abc',))
self.checkequal('z', 'a', 'join', UserList(['z']))
self.checkequal('a.b.c', '.', 'join', ['a', 'b', 'c'])
- self.checkraises(TypeError, '.', 'join', ['a', 'b', 3])
+ self.checkequal('a.b.3', '.', 'join', ['a', 'b', 3])
for i in [5, 25, 125]:
self.checkequal(((('a' * i) + '-') * i)[:-1], '-', 'join',
['a' * i] * i)
self.checkequal(((('a' * i) + '-') * i)[:-1], '-', 'join',
('a' * i,) * i)
- self.checkraises(TypeError, ' ', 'join', BadSeq1())
+ self.checkequal(str(BadSeq1()), ' ', 'join', BadSeq1())
self.checkequal('a b c', ' ', 'join', BadSeq2())
self.checkraises(TypeError, ' ', 'join')
self.checkraises(TypeError, ' ', 'join', 7)
- self.checkraises(TypeError, ' ', 'join', Sequence([7, 'hello', 123]))
+ self.checkraises(TypeError, ' ', 'join', [1, 2, bytes()])
try:
def f():
yield 4 + ""
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 12bec1a..67ae239 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -3238,10 +3238,6 @@ def strops():
except ValueError: pass
else: raise TestFailed("''.split('') doesn't raise ValueError")
- try: ''.join([0])
- except TypeError: pass
- else: raise TestFailed("''.join([0]) doesn't raise TypeError")
-
try: ''.rindex('5')
except ValueError: pass
else: raise TestFailed("''.rindex('5') doesn't raise ValueError")
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 64cca3f..1358419 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -178,6 +178,10 @@ class UnicodeTest(
def test_join(self):
string_tests.MixinStrUnicodeUserStringTest.test_join(self)
+ class MyWrapper:
+ def __init__(self, sval): self.sval = sval
+ def __str__(self): return self.sval
+
# mixed arguments
self.checkequalnofix('a b c d', ' ', 'join', ['a', 'b', 'c', 'd'])
self.checkequalnofix('abcd', '', 'join', ('a', 'b', 'c', 'd'))
@@ -186,6 +190,8 @@ class UnicodeTest(
self.checkequalnofix('a b c d', ' ', 'join', ['a', 'b', 'c', 'd'])
self.checkequalnofix('abcd', '', 'join', ('a', 'b', 'c', 'd'))
self.checkequalnofix('w x y z', ' ', 'join', string_tests.Sequence('wxyz'))
+ self.checkequalnofix('1 2 foo', ' ', 'join', [1, 2, MyWrapper('foo')])
+ self.checkraises(TypeError, ' ', 'join', [1, 2, 3, bytes()])
def test_replace(self):
string_tests.CommonTest.test_replace(self)
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index c40f0be..ad78492 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -5412,14 +5412,20 @@ PyUnicode_Join(PyObject *separator, PyObject *seq)
item = PySequence_Fast_GET_ITEM(fseq, i);
/* Convert item to Unicode. */
- if (! PyUnicode_Check(item) && ! PyString_Check(item)) {
- PyErr_Format(PyExc_TypeError,
- "sequence item %zd: expected string or Unicode,"
- " %.80s found",
- i, Py_Type(item)->tp_name);
- goto onError;
+ if (!PyString_Check(item) && !PyUnicode_Check(item))
+ {
+ if (PyBytes_Check(item))
+ {
+ PyErr_Format(PyExc_TypeError,
+ "sequence item %d: join() will not operate on "
+ "bytes objects", i);
+ goto onError;
+ }
+ item = PyObject_Unicode(item);
}
- item = PyUnicode_FromObject(item);
+ else
+ item = PyUnicode_FromObject(item);
+
if (item == NULL)
goto onError;
/* We own a reference to item from here on. */