diff -r 483096ef1cf6 Lib/_pyio.py --- a/Lib/_pyio.py Wed Jan 29 11:45:31 2014 +0200 +++ b/Lib/_pyio.py Wed Jan 29 12:16:31 2014 +0200 @@ -2050,7 +2050,14 @@ """ def __init__(self, initial_value="", newline="\n"): - super(StringIO, self).__init__(BytesIO(), + if initial_value is not None: + if not isinstance(initial_value, str): + raise TypeError("initial_value must be str or None, not {0}" + .format(type(initial_value).__name__)) + initial_value = initial_value.encode('utf-8', 'surrogatepass') + else: + initial_value = b'' + super(StringIO, self).__init__(BytesIO(initial_value), encoding="utf-8", errors="surrogatepass", newline=newline) @@ -2058,12 +2065,6 @@ # C version, even under Windows. if newline is None: self._writetranslate = False - if initial_value is not None: - if not isinstance(initial_value, str): - raise TypeError("initial_value must be str or None, not {0}" - .format(type(initial_value).__name__)) - self.write(initial_value) - self.seek(0) def getvalue(self): self.flush() diff -r 483096ef1cf6 Lib/test/test_memoryio.py --- a/Lib/test/test_memoryio.py Wed Jan 29 11:45:31 2014 +0200 +++ b/Lib/test/test_memoryio.py Wed Jan 29 12:16:31 2014 +0200 @@ -539,53 +539,81 @@ def test_newline_none(self): # newline=None memio = self.ioclass("a\nb\r\nc\rd", newline=None) + #self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"]) memio.seek(0) self.assertEqual(memio.read(1), "a") self.assertEqual(memio.read(2), "\nb") self.assertEqual(memio.read(2), "\nc") self.assertEqual(memio.read(1), "\n") + memio = self.ioclass(newline=None) self.assertEqual(2, memio.write("a\n")) self.assertEqual(3, memio.write("b\r\n")) self.assertEqual(3, memio.write("c\rd")) + #self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") memio.seek(0) self.assertEqual(memio.read(), "a\nb\nc\nd") + memio = self.ioclass("a\r\nb", newline=None) self.assertEqual(memio.read(3), "a\nb") def test_newline_empty(self): # newline="" memio = self.ioclass("a\nb\r\nc\rd", newline="") + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"]) memio.seek(0) self.assertEqual(memio.read(4), "a\nb\r") self.assertEqual(memio.read(2), "\nc") self.assertEqual(memio.read(1), "\r") + memio = self.ioclass(newline="") self.assertEqual(2, memio.write("a\n")) self.assertEqual(2, memio.write("b\r")) self.assertEqual(2, memio.write("\nc")) self.assertEqual(2, memio.write("\rd")) + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") memio.seek(0) self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"]) def test_newline_lf(self): # newline="\n" - memio = self.ioclass("a\nb\r\nc\rd") + memio = self.ioclass("a\nb\r\nc\rd", newline="\n") + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") + self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"]) + + memio = self.ioclass(newline="\n") + self.assertEqual(memio.write("a\nb\r\nc\rd"), 8) + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") + memio.seek(0) self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"]) def test_newline_cr(self): # newline="\r" memio = self.ioclass("a\nb\r\nc\rd", newline="\r") - self.assertEqual(memio.read(), "a\rb\r\rc\rd") + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") + self.assertEqual(memio.read(), "a\nb\r\nc\rd") + memio.seek(0) + self.assertEqual(list(memio),['a\nb\r', '\nc\r', 'd']) + + memio = self.ioclass(newline="\r") + self.assertEqual(memio.write("a\nb\r\nc\rd"), 8) + self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd") memio.seek(0) self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"]) def test_newline_crlf(self): # newline="\r\n" memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n") - self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd") + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") + self.assertEqual(memio.read(), "a\nb\r\nc\rd") + memio.seek(0) + self.assertEqual(list(memio), ['a\nb\r\n', 'c\rd']) + + memio = self.ioclass(newline="\r\n") + self.assertEqual(memio.write("a\nb\r\nc\rd"), 8) + self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd") memio.seek(0) self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"]) diff -r 483096ef1cf6 Modules/_io/stringio.c --- a/Modules/_io/stringio.c Wed Jan 29 11:45:31 2014 +0200 +++ b/Modules/_io/stringio.c Wed Jan 29 12:16:31 2014 +0200 @@ -735,14 +735,12 @@ else value_len = 0; if (value_len > 0) { - /* This is a heuristic, for newline translation might change - the string length. */ - if (resize_buffer(self, 0) < 0) + if (resize_buffer(self, value_len) < 0) return -1; + if (!PyUnicode_AsUCS4(value, self->buf, value_len, 0)) + return -1; + self->string_size = self->pos = value_len; self->state = STATE_REALIZED; - self->pos = 0; - if (write_str(self, value) < 0) - return -1; } else { /* Empty stringio object, we can start by accumulating */