]> granicus.if.org Git - python/commitdiff
Issue #1548891: The cStringIO.StringIO() constructor now encodes unicode
authorAntoine Pitrou <solipsis@pitrou.net>
Sat, 22 Oct 2011 19:26:01 +0000 (21:26 +0200)
committerAntoine Pitrou <solipsis@pitrou.net>
Sat, 22 Oct 2011 19:26:01 +0000 (21:26 +0200)
arguments with the system default encoding just like the write() method
does, instead of converting it to a raw buffer.

Doc/library/stringio.rst
Lib/test/test_StringIO.py
Misc/NEWS
Modules/cStringIO.c

index 0177da48f52e8a1d4426c6e269273e29852b0773..612ddcd1599b7a00ee8fa3216ea5925bf4131e3c 100644 (file)
@@ -82,10 +82,7 @@ instead.
    those cases.
 
    Unlike the :mod:`StringIO` module, this module is not able to accept Unicode
-   strings that cannot be encoded as plain ASCII strings.  Calling
-   :func:`StringIO` with a Unicode string parameter populates the object with
-   the buffer representation of the Unicode string instead of encoding the
-   string.
+   strings that cannot be encoded as plain ASCII strings.
 
    Another difference from the :mod:`StringIO` module is that calling
    :func:`StringIO` with a string parameter creates a read-only object. Unlike an
index 1459e617a61411ec101b08ba9bdde102a7828ec7..bf0c733db7bfcc3237e2b5f3b1b08f1521177324 100644 (file)
@@ -134,6 +134,27 @@ class TestcStringIO(TestGenericStringIO):
         f = self.MODULE.StringIO(a)
         self.assertEqual(f.getvalue(), '\x00\x01\x02')
 
+    def test_unicode(self):
+
+        if not test_support.have_unicode: return
+
+        # The cStringIO module converts Unicode strings to character
+        # strings when writing them to cStringIO objects.
+        # Check that this works.
+
+        f = self.MODULE.StringIO()
+        f.write(u'abcde')
+        s = f.getvalue()
+        self.assertEqual(s, 'abcde')
+        self.assertEqual(type(s), str)
+
+        f = self.MODULE.StringIO(u'abcde')
+        s = f.getvalue()
+        self.assertEqual(s, 'abcde')
+        self.assertEqual(type(s), str)
+
+        self.assertRaises(UnicodeEncodeError, self.MODULE.StringIO, u'\xf4')
+
 
 import sys
 if sys.platform.startswith('java'):
index dd2874b400159771c4b6b1a3c25ac050dea456e3..b4f9be241c6447dd6b91931bad47f0efe6fdc545 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -66,6 +66,10 @@ Core and Builtins
 Library
 -------
 
+- Issue #1548891: The cStringIO.StringIO() constructor now encodes unicode
+  arguments with the system default encoding just like the write() method
+  does, instead of converting it to a raw buffer.
+
 - Issue #9168: now smtpd is able to bind privileged port.
 
 - Issue #12529: fix cgi.parse_header issue on strings with double-quotes and
index be9ad50ab65a10121f0a14119a8931cad32a92eb..89f1dd6d2d07b922ecd2db695410102ff499e682 100644 (file)
@@ -661,7 +661,11 @@ newIobject(PyObject *s) {
   char *buf;
   Py_ssize_t size;
 
-  if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
+  if (PyUnicode_Check(s)) {
+    if (PyObject_AsCharBuffer(s, (const char **)&buf, &size) != 0)
+      return NULL;
+  }
+  else if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
     PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found",
                  s->ob_type->tp_name);
     return NULL;