Make the StringIO test pass.

The buffer object now special-cases Unicode when concatenating.  Sigh.
This commit is contained in:
Guido van Rossum 2007-05-08 23:08:31 +00:00
parent cfe5f20fe8
commit bc14efbd08
2 changed files with 36 additions and 23 deletions

View File

@ -1,13 +1,13 @@
# Tests StringIO and cStringIO # Tests StringIO and cStringIO
import sys
import unittest import unittest
import StringIO import StringIO
import cStringIO import cStringIO
import types
from test import test_support from test import test_support
class TestGenericStringIO(unittest.TestCase): class TestGenericStringIO:
# use a class variable MODULE to define which module is being tested # use a class variable MODULE to define which module is being tested
# Line of data to test as string # Line of data to test as string
@ -71,7 +71,7 @@ class TestGenericStringIO(unittest.TestCase):
self.assertEqual(f.closed, False) self.assertEqual(f.closed, False)
f.close() f.close()
self.assertEqual(f.closed, True) self.assertEqual(f.closed, True)
f = self.MODULE.StringIO("abc") f = self.MODULE.StringIO(self.constructor("abc"))
self.assertEqual(f.closed, False) self.assertEqual(f.closed, False)
f.close() f.close()
self.assertEqual(f.closed, True) self.assertEqual(f.closed, True)
@ -98,7 +98,7 @@ class TestGenericStringIO(unittest.TestCase):
self._fp.close() self._fp.close()
self.assertRaises(ValueError, next, self._fp) self.assertRaises(ValueError, next, self._fp)
class TestStringIO(TestGenericStringIO): class TestStringIO(TestGenericStringIO, unittest.TestCase):
MODULE = StringIO MODULE = StringIO
def test_unicode(self): def test_unicode(self):
@ -116,10 +116,11 @@ class TestStringIO(TestGenericStringIO):
f.write(str(self._line[52])) f.write(str(self._line[52]))
s = f.getvalue() s = f.getvalue()
self.assertEqual(s, str('abcuvwxyz!')) self.assertEqual(s, str('abcuvwxyz!'))
self.assertEqual(type(s), types.UnicodeType) self.assertEqual(type(s), str)
class TestcStringIO(TestGenericStringIO): class TestcStringIO(TestGenericStringIO, unittest.TestCase):
MODULE = cStringIO MODULE = cStringIO
constructor = str8
def test_unicode(self): def test_unicode(self):
@ -133,36 +134,39 @@ class TestcStringIO(TestGenericStringIO):
f.write(str(self._line[:5])) f.write(str(self._line[:5]))
s = f.getvalue() s = f.getvalue()
self.assertEqual(s, 'abcde') self.assertEqual(s, 'abcde')
self.assertEqual(type(s), types.StringType) self.assertEqual(type(s), str8)
f = self.MODULE.StringIO(str(self._line[:5])) f = self.MODULE.StringIO(str(self._line[:5]))
s = f.getvalue() s = f.getvalue()
self.assertEqual(s, 'abcde') self.assertEqual(s, 'abcde')
self.assertEqual(type(s), types.StringType) self.assertEqual(type(s), str8)
self.assertRaises(UnicodeEncodeError, self.MODULE.StringIO, # XXX This no longer fails -- the default encoding is always UTF-8.
str('\xf4', 'latin-1')) ##self.assertRaises(UnicodeDecodeError, self.MODULE.StringIO, '\xf4')
import sys
if sys.platform.startswith('java'):
# Jython doesn't have a buffer object, so we just do a useless
# fake of the buffer tests.
buffer = str
class TestBufferStringIO(TestStringIO): class TestBufferStringIO(TestStringIO):
constructor = buffer
def constructor(self, s):
return buffer(str8(s))
class TestBuffercStringIO(TestcStringIO): class TestBuffercStringIO(TestcStringIO):
constructor = buffer
def constructor(self, s):
return buffer(str8(s))
def test_main(): def test_main():
test_support.run_unittest( classes = [
TestStringIO, TestStringIO,
TestcStringIO, TestcStringIO,
]
if not sys.platform.startswith('java'):
classes.extend([
TestBufferStringIO, TestBufferStringIO,
TestBuffercStringIO TestBuffercStringIO
) ])
test_support.run_unittest(*classes)
if __name__ == '__main__': if __name__ == '__main__':
test_main() unittest.main()

View File

@ -424,15 +424,24 @@ buffer_concat(PyBufferObject *self, PyObject *other)
return NULL; return NULL;
/* optimize special case */ /* optimize special case */
/* XXX bad idea type-wise */
if ( size == 0 ) if ( size == 0 )
{ {
Py_INCREF(other); Py_INCREF(other);
return other; return other;
} }
if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 ) if (PyUnicode_Check(other)) {
return NULL; /* XXX HACK */
if ( (count = (*pb->bf_getcharbuffer)(other, 0, &ptr2)) < 0 )
return NULL;
}
else {
if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
return NULL;
}
/* XXX Should return a bytes object, really */
ob = PyString_FromStringAndSize(NULL, size + count); ob = PyString_FromStringAndSize(NULL, size + count);
if ( ob == NULL ) if ( ob == NULL )
return NULL; return NULL;