Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9d2ac22

Browse files
committed
Fix io.StringIO: String are stored encoded (using "unicode-internal" as the
encoding) which makes the buffer mutable. Strings are encoded on the way in and decoded on the way out. Use io.StringIO in test_codecs.py. Fix the base64_codec test in test_codecs.py.
1 parent c9e363c commit 9d2ac22

2 files changed

Lines changed: 33 additions & 19 deletions

File tree

Lib/io.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -581,10 +581,10 @@ class BytesIO(_MemoryIOMixin):
581581

582582
# XXX More docs
583583

584-
def __init__(self, inital_bytes=None):
584+
def __init__(self, initial_bytes=None):
585585
buffer = b""
586-
if inital_bytes is not None:
587-
buffer += inital_bytes
586+
if initial_bytes is not None:
587+
buffer += initial_bytes
588588
_MemoryIOMixin.__init__(self, buffer)
589589

590590

@@ -595,21 +595,36 @@ class StringIO(_MemoryIOMixin):
595595

596596
# XXX More docs
597597

598-
# Reuses the same code as BytesIO, just with a string rather that
599-
# bytes as the _buffer value.
598+
# Reuses the same code as BytesIO, but encode strings on the way in
599+
# and decode them on the way out.
600600

601-
# XXX This doesn't work; _MemoryIOMixin's write() and truncate()
602-
# methods assume the buffer is mutable. Simply redefining those
603-
# to use slice concatenation will make it awfully slow (in fact,
604-
# quadratic in the number of write() calls). Also, there are no
605-
# readline() and readlines() methods. Etc., etc.
606-
607-
def __init__(self, inital_string=None):
608-
buffer = ""
609-
if inital_string is not None:
610-
buffer += inital_string
601+
def __init__(self, initial_string=None):
602+
if initial_string is not None:
603+
buffer = initial_string.encode("unicode-internal")
604+
else:
605+
buffer = b""
611606
_MemoryIOMixin.__init__(self, buffer)
612607

608+
def getvalue(self):
609+
return self._buffer.encode("unicode-internal")
610+
611+
def read(self, n=-1):
612+
return super(StringIO, self).read(n*2).decode("unicode-internal")
613+
614+
def write(self, s):
615+
return super(StringIO, self).write(s.encode("unicode-internal"))//2
616+
617+
def seek(self, pos, whence=0):
618+
return super(StringIO, self).seek(2*pos, whence)//2
619+
620+
def tell(self):
621+
return super(StringIO, self).tell()//2
622+
623+
def truncate(self, pos=None):
624+
if pos is not None:
625+
pos *= 2
626+
return super(StringIO, self).truncate(pos)//2
627+
613628
def readinto(self, b: bytes) -> int:
614629
self._unsupported("readinto")
615630

Lib/test/test_codecs.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import unittest
33
import codecs
44
import sys, _testcapi, io
5-
from StringIO import StringIO
65

76
class Queue(object):
87
"""
@@ -493,7 +492,7 @@ def test_empty(self):
493492

494493
class RecodingTest(unittest.TestCase):
495494
def test_recoding(self):
496-
f = StringIO()
495+
f = io.StringIO()
497496
f2 = codecs.EncodedFile(f, "unicode_internal", "utf-8")
498497
f2.write("a")
499498
f2.close()
@@ -991,14 +990,14 @@ class Str2StrTest(unittest.TestCase):
991990

992991
def test_read(self):
993992
sin = "\x80".encode("base64_codec")
994-
reader = codecs.getreader("base64_codec")(StringIO(sin))
993+
reader = codecs.getreader("base64_codec")(io.BytesIO(sin))
995994
sout = reader.read()
996995
self.assertEqual(sout, "\x80")
997996
self.assert_(isinstance(sout, str))
998997

999998
def test_readline(self):
1000999
sin = "\x80".encode("base64_codec")
1001-
reader = codecs.getreader("base64_codec")(StringIO(sin))
1000+
reader = codecs.getreader("base64_codec")(io.BytesIO(sin))
10021001
sout = reader.readline()
10031002
self.assertEqual(sout, "\x80")
10041003
self.assert_(isinstance(sout, str))

0 commit comments

Comments
 (0)