mirror of
https://github.com/python/cpython.git
synced 2025-07-19 09:15:34 +00:00
(Patch contributed by Nick Coghlan.) Now joining string subtypes will always return a string. Formerly, if there were only one item, it was returned unchanged.
This commit is contained in:
parent
dd50cb748a
commit
674f241e9c
2 changed files with 31 additions and 12 deletions
|
@ -52,6 +52,29 @@ class StringTest(
|
||||||
self.checkraises(TypeError, string_tests.BadSeq1(), 'join', ' ')
|
self.checkraises(TypeError, string_tests.BadSeq1(), 'join', ' ')
|
||||||
self.checkequal('a b c', string_tests.BadSeq2(), 'join', ' ')
|
self.checkequal('a b c', string_tests.BadSeq2(), 'join', ' ')
|
||||||
|
|
||||||
|
def test_bug1001011(self):
|
||||||
|
# Make sure join returns a NEW object for single item sequences
|
||||||
|
# involving a subclass
|
||||||
|
# Make sure that it is of the appropriate type
|
||||||
|
# Check the optimisation still occurs for standard objects
|
||||||
|
class str_subclass(str): pass
|
||||||
|
s1 = str_subclass('abcd')
|
||||||
|
s2 = ''.join([s1])
|
||||||
|
self.failIf(s1 is s2)
|
||||||
|
self.assertEqual(type(s2), type(''))
|
||||||
|
s3 = 'abcd'
|
||||||
|
s4 = ''.join([s3])
|
||||||
|
self.failUnless(s3 is s4)
|
||||||
|
if test_support.have_unicode:
|
||||||
|
class unicode_subclass(unicode): pass
|
||||||
|
u1 = unicode_subclass(u'abcd')
|
||||||
|
u2 = ''.join([u1])
|
||||||
|
self.failIf(u1 is u2)
|
||||||
|
self.assertEqual(type(u2), type(u''))
|
||||||
|
u3 = u'abcd'
|
||||||
|
u4 = ''.join([u3])
|
||||||
|
self.failUnless(u3 is u4)
|
||||||
|
|
||||||
class ModuleTest(unittest.TestCase):
|
class ModuleTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_attrs(self):
|
def test_attrs(self):
|
||||||
|
|
|
@ -1618,22 +1618,18 @@ string_join(PyStringObject *self, PyObject *orig)
|
||||||
}
|
}
|
||||||
if (seqlen == 1) {
|
if (seqlen == 1) {
|
||||||
item = PySequence_Fast_GET_ITEM(seq, 0);
|
item = PySequence_Fast_GET_ITEM(seq, 0);
|
||||||
if (!PyString_Check(item) && !PyUnicode_Check(item)) {
|
if (PyString_CheckExact(item) || PyUnicode_CheckExact(item)) {
|
||||||
PyErr_Format(PyExc_TypeError,
|
Py_INCREF(item);
|
||||||
"sequence item 0: expected string,"
|
|
||||||
" %.80s found",
|
|
||||||
item->ob_type->tp_name);
|
|
||||||
Py_DECREF(seq);
|
Py_DECREF(seq);
|
||||||
return NULL;
|
return item;
|
||||||
}
|
}
|
||||||
Py_INCREF(item);
|
|
||||||
Py_DECREF(seq);
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There are at least two things to join. Do a pre-pass to figure out
|
/* There are at least two things to join, or else we have a subclass
|
||||||
* the total amount of space we'll need (sz), see whether any argument
|
* of the builtin types in the sequence.
|
||||||
* is absurd, and defer to the Unicode join if appropriate.
|
* Do a pre-pass to figure out the total amount of space we'll
|
||||||
|
* need (sz), see whether any argument is absurd, and defer to
|
||||||
|
* the Unicode join if appropriate.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < seqlen; i++) {
|
for (i = 0; i < seqlen; i++) {
|
||||||
const size_t old_sz = sz;
|
const size_t old_sz = sz;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue