diff options
author | Guido van Rossum <guido@python.org> | 2007-09-27 18:01:22 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2007-09-27 18:01:22 (GMT) |
commit | f1044293fa36667b5ba11fbc7acac21a03b82710 (patch) | |
tree | 41aac1b32323f1ae889d88c097157d330dc1aff7 | |
parent | 4e02c503e789337b07cc14ece3f5adbf23732c89 (diff) | |
download | cpython-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.rst | 7 | ||||
-rw-r--r-- | Lib/test/string_tests.py | 7 | ||||
-rw-r--r-- | Lib/test/test_descr.py | 4 | ||||
-rw-r--r-- | Lib/test/test_unicode.py | 6 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 20 |
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. */ |