Home | History | Annotate | Download | only in test
      1 """Unit tests for memory-based file-like objects.
      2 StringIO -- for unicode strings
      3 BytesIO -- for bytes
      4 """
      5 
      6 from __future__ import unicode_literals
      7 from __future__ import print_function
      8 
      9 import unittest
     10 from test import test_support as support
     11 
     12 import io
     13 import _pyio as pyio
     14 import pickle
     15 
     16 class MemorySeekTestMixin:
     17 
     18     def testInit(self):
     19         buf = self.buftype("1234567890")
     20         bytesIo = self.ioclass(buf)
     21 
     22     def testRead(self):
     23         buf = self.buftype("1234567890")
     24         bytesIo = self.ioclass(buf)
     25 
     26         self.assertEqual(buf[:1], bytesIo.read(1))
     27         self.assertEqual(buf[1:5], bytesIo.read(4))
     28         self.assertEqual(buf[5:], bytesIo.read(900))
     29         self.assertEqual(self.EOF, bytesIo.read())
     30 
     31     def testReadNoArgs(self):
     32         buf = self.buftype("1234567890")
     33         bytesIo = self.ioclass(buf)
     34 
     35         self.assertEqual(buf, bytesIo.read())
     36         self.assertEqual(self.EOF, bytesIo.read())
     37 
     38     def testSeek(self):
     39         buf = self.buftype("1234567890")
     40         bytesIo = self.ioclass(buf)
     41 
     42         bytesIo.read(5)
     43         bytesIo.seek(0)
     44         self.assertEqual(buf, bytesIo.read())
     45 
     46         bytesIo.seek(3)
     47         self.assertEqual(buf[3:], bytesIo.read())
     48         self.assertRaises(TypeError, bytesIo.seek, 0.0)
     49 
     50     def testTell(self):
     51         buf = self.buftype("1234567890")
     52         bytesIo = self.ioclass(buf)
     53 
     54         self.assertEqual(0, bytesIo.tell())
     55         bytesIo.seek(5)
     56         self.assertEqual(5, bytesIo.tell())
     57         bytesIo.seek(10000)
     58         self.assertEqual(10000, bytesIo.tell())
     59 
     60 
     61 class MemoryTestMixin:
     62 
     63     def test_detach(self):
     64         buf = self.ioclass()
     65         self.assertRaises(self.UnsupportedOperation, buf.detach)
     66 
     67     def write_ops(self, f, t):
     68         self.assertEqual(f.write(t("blah.")), 5)
     69         self.assertEqual(f.seek(0), 0)
     70         self.assertEqual(f.write(t("Hello.")), 6)
     71         self.assertEqual(f.tell(), 6)
     72         self.assertEqual(f.seek(5), 5)
     73         self.assertEqual(f.tell(), 5)
     74         self.assertEqual(f.write(t(" world\n\n\n")), 9)
     75         self.assertEqual(f.seek(0), 0)
     76         self.assertEqual(f.write(t("h")), 1)
     77         self.assertEqual(f.truncate(12), 12)
     78         self.assertEqual(f.tell(), 1)
     79 
     80     def test_write(self):
     81         buf = self.buftype("hello world\n")
     82         memio = self.ioclass(buf)
     83 
     84         self.write_ops(memio, self.buftype)
     85         self.assertEqual(memio.getvalue(), buf)
     86         memio = self.ioclass()
     87         self.write_ops(memio, self.buftype)
     88         self.assertEqual(memio.getvalue(), buf)
     89         self.assertRaises(TypeError, memio.write, None)
     90         memio.close()
     91         self.assertRaises(ValueError, memio.write, self.buftype(""))
     92 
     93     def test_writelines(self):
     94         buf = self.buftype("1234567890")
     95         memio = self.ioclass()
     96 
     97         self.assertEqual(memio.writelines([buf] * 100), None)
     98         self.assertEqual(memio.getvalue(), buf * 100)
     99         memio.writelines([])
    100         self.assertEqual(memio.getvalue(), buf * 100)
    101         memio = self.ioclass()
    102         self.assertRaises(TypeError, memio.writelines, [buf] + [1])
    103         self.assertEqual(memio.getvalue(), buf)
    104         self.assertRaises(TypeError, memio.writelines, None)
    105         memio.close()
    106         self.assertRaises(ValueError, memio.writelines, [])
    107 
    108     def test_writelines_error(self):
    109         memio = self.ioclass()
    110         def error_gen():
    111             yield self.buftype('spam')
    112             raise KeyboardInterrupt
    113 
    114         self.assertRaises(KeyboardInterrupt, memio.writelines, error_gen())
    115 
    116     def test_truncate(self):
    117         buf = self.buftype("1234567890")
    118         memio = self.ioclass(buf)
    119 
    120         self.assertRaises(ValueError, memio.truncate, -1)
    121         memio.seek(6)
    122         self.assertEqual(memio.truncate(), 6)
    123         self.assertEqual(memio.getvalue(), buf[:6])
    124         self.assertEqual(memio.truncate(4), 4)
    125         self.assertEqual(memio.getvalue(), buf[:4])
    126         # truncate() accepts long objects
    127         self.assertEqual(memio.truncate(4L), 4)
    128         self.assertEqual(memio.getvalue(), buf[:4])
    129         self.assertEqual(memio.tell(), 6)
    130         memio.seek(0, 2)
    131         memio.write(buf)
    132         self.assertEqual(memio.getvalue(), buf[:4] + buf)
    133         pos = memio.tell()
    134         self.assertEqual(memio.truncate(None), pos)
    135         self.assertEqual(memio.tell(), pos)
    136         self.assertRaises(TypeError, memio.truncate, '0')
    137         memio.close()
    138         self.assertRaises(ValueError, memio.truncate, 0)
    139 
    140     def test_init(self):
    141         buf = self.buftype("1234567890")
    142         memio = self.ioclass(buf)
    143         self.assertEqual(memio.getvalue(), buf)
    144         memio = self.ioclass(None)
    145         self.assertEqual(memio.getvalue(), self.EOF)
    146         memio.__init__(buf * 2)
    147         self.assertEqual(memio.getvalue(), buf * 2)
    148         memio.__init__(buf)
    149         self.assertEqual(memio.getvalue(), buf)
    150 
    151     def test_read(self):
    152         buf = self.buftype("1234567890")
    153         memio = self.ioclass(buf)
    154 
    155         self.assertEqual(memio.read(0), self.EOF)
    156         self.assertEqual(memio.read(1), buf[:1])
    157         # read() accepts long objects
    158         self.assertEqual(memio.read(4L), buf[1:5])
    159         self.assertEqual(memio.read(900), buf[5:])
    160         self.assertEqual(memio.read(), self.EOF)
    161         memio.seek(0)
    162         self.assertEqual(memio.read(), buf)
    163         self.assertEqual(memio.read(), self.EOF)
    164         self.assertEqual(memio.tell(), 10)
    165         memio.seek(0)
    166         self.assertEqual(memio.read(-1), buf)
    167         memio.seek(0)
    168         self.assertEqual(type(memio.read()), type(buf))
    169         memio.seek(100)
    170         self.assertEqual(type(memio.read()), type(buf))
    171         memio.seek(0)
    172         self.assertEqual(memio.read(None), buf)
    173         self.assertRaises(TypeError, memio.read, '')
    174         memio.close()
    175         self.assertRaises(ValueError, memio.read)
    176 
    177     def test_readline(self):
    178         buf = self.buftype("1234567890\n")
    179         memio = self.ioclass(buf * 2)
    180 
    181         self.assertEqual(memio.readline(0), self.EOF)
    182         self.assertEqual(memio.readline(), buf)
    183         self.assertEqual(memio.readline(), buf)
    184         self.assertEqual(memio.readline(), self.EOF)
    185         memio.seek(0)
    186         self.assertEqual(memio.readline(5), buf[:5])
    187         # readline() accepts long objects
    188         self.assertEqual(memio.readline(5L), buf[5:10])
    189         self.assertEqual(memio.readline(5), buf[10:15])
    190         memio.seek(0)
    191         self.assertEqual(memio.readline(-1), buf)
    192         memio.seek(0)
    193         self.assertEqual(memio.readline(0), self.EOF)
    194 
    195         buf = self.buftype("1234567890\n")
    196         memio = self.ioclass((buf * 3)[:-1])
    197         self.assertEqual(memio.readline(), buf)
    198         self.assertEqual(memio.readline(), buf)
    199         self.assertEqual(memio.readline(), buf[:-1])
    200         self.assertEqual(memio.readline(), self.EOF)
    201         memio.seek(0)
    202         self.assertEqual(type(memio.readline()), type(buf))
    203         self.assertEqual(memio.readline(), buf)
    204         self.assertRaises(TypeError, memio.readline, '')
    205         memio.close()
    206         self.assertRaises(ValueError,  memio.readline)
    207 
    208     def test_readlines(self):
    209         buf = self.buftype("1234567890\n")
    210         memio = self.ioclass(buf * 10)
    211 
    212         self.assertEqual(memio.readlines(), [buf] * 10)
    213         memio.seek(5)
    214         self.assertEqual(memio.readlines(), [buf[5:]] + [buf] * 9)
    215         memio.seek(0)
    216         # readlines() accepts long objects
    217         self.assertEqual(memio.readlines(15L), [buf] * 2)
    218         memio.seek(0)
    219         self.assertEqual(memio.readlines(-1), [buf] * 10)
    220         memio.seek(0)
    221         self.assertEqual(memio.readlines(0), [buf] * 10)
    222         memio.seek(0)
    223         self.assertEqual(type(memio.readlines()[0]), type(buf))
    224         memio.seek(0)
    225         self.assertEqual(memio.readlines(None), [buf] * 10)
    226         self.assertRaises(TypeError, memio.readlines, '')
    227         memio.close()
    228         self.assertRaises(ValueError, memio.readlines)
    229 
    230     def test_iterator(self):
    231         buf = self.buftype("1234567890\n")
    232         memio = self.ioclass(buf * 10)
    233 
    234         self.assertEqual(iter(memio), memio)
    235         self.assertTrue(hasattr(memio, '__iter__'))
    236         self.assertTrue(hasattr(memio, 'next'))
    237         i = 0
    238         for line in memio:
    239             self.assertEqual(line, buf)
    240             i += 1
    241         self.assertEqual(i, 10)
    242         memio.seek(0)
    243         i = 0
    244         for line in memio:
    245             self.assertEqual(line, buf)
    246             i += 1
    247         self.assertEqual(i, 10)
    248         memio = self.ioclass(buf * 2)
    249         memio.close()
    250         self.assertRaises(ValueError, next, memio)
    251 
    252     def test_getvalue(self):
    253         buf = self.buftype("1234567890")
    254         memio = self.ioclass(buf)
    255 
    256         self.assertEqual(memio.getvalue(), buf)
    257         memio.read()
    258         self.assertEqual(memio.getvalue(), buf)
    259         self.assertEqual(type(memio.getvalue()), type(buf))
    260         memio = self.ioclass(buf * 1000)
    261         self.assertEqual(memio.getvalue()[-3:], self.buftype("890"))
    262         memio = self.ioclass(buf)
    263         memio.close()
    264         self.assertRaises(ValueError, memio.getvalue)
    265 
    266     def test_seek(self):
    267         buf = self.buftype("1234567890")
    268         memio = self.ioclass(buf)
    269 
    270         memio.read(5)
    271         self.assertRaises(ValueError, memio.seek, -1)
    272         self.assertRaises(ValueError, memio.seek, 1, -1)
    273         self.assertRaises(ValueError, memio.seek, 1, 3)
    274         self.assertEqual(memio.seek(0), 0)
    275         self.assertEqual(memio.seek(0, 0), 0)
    276         self.assertEqual(memio.read(), buf)
    277         self.assertEqual(memio.seek(3), 3)
    278         # seek() accepts long objects
    279         self.assertEqual(memio.seek(3L), 3)
    280         self.assertEqual(memio.seek(0, 1), 3)
    281         self.assertEqual(memio.read(), buf[3:])
    282         self.assertEqual(memio.seek(len(buf)), len(buf))
    283         self.assertEqual(memio.read(), self.EOF)
    284         memio.seek(len(buf) + 1)
    285         self.assertEqual(memio.read(), self.EOF)
    286         self.assertEqual(memio.seek(0, 2), len(buf))
    287         self.assertEqual(memio.read(), self.EOF)
    288         memio.close()
    289         self.assertRaises(ValueError, memio.seek, 0)
    290 
    291     def test_overseek(self):
    292         buf = self.buftype("1234567890")
    293         memio = self.ioclass(buf)
    294 
    295         self.assertEqual(memio.seek(len(buf) + 1), 11)
    296         self.assertEqual(memio.read(), self.EOF)
    297         self.assertEqual(memio.tell(), 11)
    298         self.assertEqual(memio.getvalue(), buf)
    299         memio.write(self.EOF)
    300         self.assertEqual(memio.getvalue(), buf)
    301         memio.write(buf)
    302         self.assertEqual(memio.getvalue(), buf + self.buftype('\0') + buf)
    303 
    304     def test_tell(self):
    305         buf = self.buftype("1234567890")
    306         memio = self.ioclass(buf)
    307 
    308         self.assertEqual(memio.tell(), 0)
    309         memio.seek(5)
    310         self.assertEqual(memio.tell(), 5)
    311         memio.seek(10000)
    312         self.assertEqual(memio.tell(), 10000)
    313         memio.close()
    314         self.assertRaises(ValueError, memio.tell)
    315 
    316     def test_flush(self):
    317         buf = self.buftype("1234567890")
    318         memio = self.ioclass(buf)
    319 
    320         self.assertEqual(memio.flush(), None)
    321 
    322     def test_flags(self):
    323         memio = self.ioclass()
    324 
    325         self.assertEqual(memio.writable(), True)
    326         self.assertEqual(memio.readable(), True)
    327         self.assertEqual(memio.seekable(), True)
    328         self.assertEqual(memio.isatty(), False)
    329         self.assertEqual(memio.closed, False)
    330         memio.close()
    331         self.assertRaises(ValueError, memio.writable)
    332         self.assertRaises(ValueError, memio.readable)
    333         self.assertRaises(ValueError, memio.seekable)
    334         self.assertRaises(ValueError, memio.isatty)
    335         self.assertEqual(memio.closed, True)
    336 
    337     def test_subclassing(self):
    338         buf = self.buftype("1234567890")
    339         def test1():
    340             class MemIO(self.ioclass):
    341                 pass
    342             m = MemIO(buf)
    343             return m.getvalue()
    344         def test2():
    345             class MemIO(self.ioclass):
    346                 def __init__(me, a, b):
    347                     self.ioclass.__init__(me, a)
    348             m = MemIO(buf, None)
    349             return m.getvalue()
    350         self.assertEqual(test1(), buf)
    351         self.assertEqual(test2(), buf)
    352 
    353     def test_instance_dict_leak(self):
    354         # Test case for issue #6242.
    355         # This will be caught by regrtest.py -R if this leak.
    356         for _ in range(100):
    357             memio = self.ioclass()
    358             memio.foo = 1
    359 
    360     def test_pickling(self):
    361         buf = self.buftype("1234567890")
    362         memio = self.ioclass(buf)
    363         memio.foo = 42
    364         memio.seek(2)
    365 
    366         class PickleTestMemIO(self.ioclass):
    367             def __init__(me, initvalue, foo):
    368                 self.ioclass.__init__(me, initvalue)
    369                 me.foo = foo
    370             # __getnewargs__ is undefined on purpose. This checks that PEP 307
    371             # is used to provide pickling support.
    372 
    373         # Pickle expects the class to be on the module level. Here we use a
    374         # little hack to allow the PickleTestMemIO class to derive from
    375         # self.ioclass without having to define all combinations explicitly on
    376         # the module-level.
    377         import __main__
    378         PickleTestMemIO.__module__ = '__main__'
    379         PickleTestMemIO.__qualname__ = PickleTestMemIO.__name__
    380         __main__.PickleTestMemIO = PickleTestMemIO
    381         submemio = PickleTestMemIO(buf, 80)
    382         submemio.seek(2)
    383 
    384         # We only support pickle protocol 2 and onward since we use extended
    385         # __reduce__ API of PEP 307 to provide pickling support.
    386         for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
    387             for obj in (memio, submemio):
    388                 obj2 = pickle.loads(pickle.dumps(obj, protocol=proto))
    389                 self.assertEqual(obj.getvalue(), obj2.getvalue())
    390                 self.assertEqual(obj.__class__, obj2.__class__)
    391                 self.assertEqual(obj.foo, obj2.foo)
    392                 self.assertEqual(obj.tell(), obj2.tell())
    393                 obj.close()
    394                 self.assertRaises(ValueError, pickle.dumps, obj, proto)
    395         del __main__.PickleTestMemIO
    396 
    397 
    398 class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase):
    399     # Test _pyio.BytesIO; class also inherited for testing C implementation
    400 
    401     UnsupportedOperation = pyio.UnsupportedOperation
    402 
    403     @staticmethod
    404     def buftype(s):
    405         return s.encode("ascii")
    406     ioclass = pyio.BytesIO
    407     EOF = b""
    408 
    409     def test_read1(self):
    410         buf = self.buftype("1234567890")
    411         memio = self.ioclass(buf)
    412 
    413         self.assertRaises(TypeError, memio.read1)
    414         self.assertEqual(memio.read(), buf)
    415 
    416     def test_readinto(self):
    417         buf = self.buftype("1234567890")
    418         memio = self.ioclass(buf)
    419 
    420         b = bytearray(b"hello")
    421         self.assertEqual(memio.readinto(b), 5)
    422         self.assertEqual(b, b"12345")
    423         self.assertEqual(memio.readinto(b), 5)
    424         self.assertEqual(b, b"67890")
    425         self.assertEqual(memio.readinto(b), 0)
    426         self.assertEqual(b, b"67890")
    427         b = bytearray(b"hello world")
    428         memio.seek(0)
    429         self.assertEqual(memio.readinto(b), 10)
    430         self.assertEqual(b, b"1234567890d")
    431         b = bytearray(b"")
    432         memio.seek(0)
    433         self.assertEqual(memio.readinto(b), 0)
    434         self.assertEqual(b, b"")
    435         self.assertRaises(TypeError, memio.readinto, '')
    436         import array
    437         a = array.array(b'b', b"hello world")
    438         memio = self.ioclass(buf)
    439         memio.readinto(a)
    440         self.assertEqual(a.tostring(), b"1234567890d")
    441         memio.close()
    442         self.assertRaises(ValueError, memio.readinto, b)
    443         memio = self.ioclass(b"123")
    444         b = bytearray()
    445         memio.seek(42)
    446         memio.readinto(b)
    447         self.assertEqual(b, b"")
    448 
    449     def test_relative_seek(self):
    450         buf = self.buftype("1234567890")
    451         memio = self.ioclass(buf)
    452 
    453         self.assertEqual(memio.seek(-1, 1), 0)
    454         self.assertEqual(memio.seek(3, 1), 3)
    455         self.assertEqual(memio.seek(-4, 1), 0)
    456         self.assertEqual(memio.seek(-1, 2), 9)
    457         self.assertEqual(memio.seek(1, 1), 10)
    458         self.assertEqual(memio.seek(1, 2), 11)
    459         memio.seek(-3, 2)
    460         self.assertEqual(memio.read(), buf[-3:])
    461         memio.seek(0)
    462         memio.seek(1, 1)
    463         self.assertEqual(memio.read(), buf[1:])
    464 
    465     def test_unicode(self):
    466         memio = self.ioclass()
    467 
    468         self.assertRaises(TypeError, self.ioclass, "1234567890")
    469         self.assertRaises(TypeError, memio.write, "1234567890")
    470         self.assertRaises(TypeError, memio.writelines, ["1234567890"])
    471 
    472     def test_bytes_array(self):
    473         buf = b"1234567890"
    474         import array
    475         a = array.array(b'b', buf)
    476         memio = self.ioclass(a)
    477         self.assertEqual(memio.getvalue(), buf)
    478         self.assertEqual(memio.write(a), 10)
    479         self.assertEqual(memio.getvalue(), buf)
    480 
    481     def test_issue5449(self):
    482         buf = self.buftype("1234567890")
    483         self.ioclass(initial_bytes=buf)
    484         self.assertRaises(TypeError, self.ioclass, buf, foo=None)
    485 
    486 
    487 class TextIOTestMixin:
    488 
    489     def test_newlines_property(self):
    490         memio = self.ioclass(newline=None)
    491         # The C StringIO decodes newlines in write() calls, but the Python
    492         # implementation only does when reading.  This function forces them to
    493         # be decoded for testing.
    494         def force_decode():
    495             memio.seek(0)
    496             memio.read()
    497         self.assertEqual(memio.newlines, None)
    498         memio.write("a\n")
    499         force_decode()
    500         self.assertEqual(memio.newlines, "\n")
    501         memio.write("b\r\n")
    502         force_decode()
    503         self.assertEqual(memio.newlines, ("\n", "\r\n"))
    504         memio.write("c\rd")
    505         force_decode()
    506         self.assertEqual(memio.newlines, ("\r", "\n", "\r\n"))
    507 
    508     def test_relative_seek(self):
    509         memio = self.ioclass()
    510 
    511         self.assertRaises(IOError, memio.seek, -1, 1)
    512         self.assertRaises(IOError, memio.seek, 3, 1)
    513         self.assertRaises(IOError, memio.seek, -3, 1)
    514         self.assertRaises(IOError, memio.seek, -1, 2)
    515         self.assertRaises(IOError, memio.seek, 1, 1)
    516         self.assertRaises(IOError, memio.seek, 1, 2)
    517 
    518     def test_textio_properties(self):
    519         memio = self.ioclass()
    520 
    521         # These are just dummy values but we nevertheless check them for fear
    522         # of unexpected breakage.
    523         self.assertIsNone(memio.encoding)
    524         self.assertIsNone(memio.errors)
    525         self.assertFalse(memio.line_buffering)
    526 
    527     def test_newline_default(self):
    528         memio = self.ioclass("a\nb\r\nc\rd")
    529         self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
    530         self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
    531 
    532         memio = self.ioclass()
    533         self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
    534         memio.seek(0)
    535         self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
    536         self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
    537 
    538     def test_newline_none(self):
    539         # newline=None
    540         memio = self.ioclass("a\nb\r\nc\rd", newline=None)
    541         self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"])
    542         memio.seek(0)
    543         self.assertEqual(memio.read(1), "a")
    544         self.assertEqual(memio.read(2), "\nb")
    545         self.assertEqual(memio.read(2), "\nc")
    546         self.assertEqual(memio.read(1), "\n")
    547         self.assertEqual(memio.getvalue(), "a\nb\nc\nd")
    548 
    549         memio = self.ioclass(newline=None)
    550         self.assertEqual(2, memio.write("a\n"))
    551         self.assertEqual(3, memio.write("b\r\n"))
    552         self.assertEqual(3, memio.write("c\rd"))
    553         memio.seek(0)
    554         self.assertEqual(memio.read(), "a\nb\nc\nd")
    555         self.assertEqual(memio.getvalue(), "a\nb\nc\nd")
    556 
    557         memio = self.ioclass("a\r\nb", newline=None)
    558         self.assertEqual(memio.read(3), "a\nb")
    559 
    560     def test_newline_empty(self):
    561         # newline=""
    562         memio = self.ioclass("a\nb\r\nc\rd", newline="")
    563         self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
    564         memio.seek(0)
    565         self.assertEqual(memio.read(4), "a\nb\r")
    566         self.assertEqual(memio.read(2), "\nc")
    567         self.assertEqual(memio.read(1), "\r")
    568         self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
    569 
    570         memio = self.ioclass(newline="")
    571         self.assertEqual(2, memio.write("a\n"))
    572         self.assertEqual(2, memio.write("b\r"))
    573         self.assertEqual(2, memio.write("\nc"))
    574         self.assertEqual(2, memio.write("\rd"))
    575         memio.seek(0)
    576         self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
    577         self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
    578 
    579     def test_newline_lf(self):
    580         # newline="\n"
    581         memio = self.ioclass("a\nb\r\nc\rd", newline="\n")
    582         self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
    583         self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
    584 
    585         memio = self.ioclass(newline="\n")
    586         self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
    587         memio.seek(0)
    588         self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
    589         self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
    590 
    591     def test_newline_cr(self):
    592         # newline="\r"
    593         memio = self.ioclass("a\nb\r\nc\rd", newline="\r")
    594         self.assertEqual(memio.read(), "a\rb\r\rc\rd")
    595         memio.seek(0)
    596         self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
    597         self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd")
    598 
    599         memio = self.ioclass(newline="\r")
    600         self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
    601         memio.seek(0)
    602         self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
    603         memio.seek(0)
    604         self.assertEqual(memio.readlines(), ["a\r", "b\r", "\r", "c\r", "d"])
    605         self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd")
    606 
    607     def test_newline_crlf(self):
    608         # newline="\r\n"
    609         memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n")
    610         self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd")
    611         memio.seek(0)
    612         self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
    613         memio.seek(0)
    614         self.assertEqual(memio.readlines(), ["a\r\n", "b\r\r\n", "c\rd"])
    615         self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd")
    616 
    617         memio = self.ioclass(newline="\r\n")
    618         self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
    619         memio.seek(0)
    620         self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
    621         self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd")
    622 
    623     def test_issue5265(self):
    624         # StringIO can duplicate newlines in universal newlines mode
    625         memio = self.ioclass("a\r\nb\r\n", newline=None)
    626         self.assertEqual(memio.read(5), "a\nb\n")
    627         self.assertEqual(memio.getvalue(), "a\nb\n")
    628 
    629 
    630 class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin,
    631                      TextIOTestMixin, unittest.TestCase):
    632     buftype = unicode
    633     ioclass = pyio.StringIO
    634     UnsupportedOperation = pyio.UnsupportedOperation
    635     EOF = ""
    636 
    637     def test_lone_surrogates(self):
    638         # Issue #20424
    639         surrogate = unichr(0xd800)
    640         memio = self.ioclass(surrogate)
    641         self.assertEqual(memio.read(), surrogate)
    642 
    643         memio = self.ioclass()
    644         memio.write(surrogate)
    645         self.assertEqual(memio.getvalue(), surrogate)
    646 
    647 
    648 class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase):
    649     """Test if pickle restores properly the internal state of StringIO.
    650     """
    651     buftype = unicode
    652     UnsupportedOperation = pyio.UnsupportedOperation
    653     EOF = ""
    654 
    655     class ioclass(pyio.StringIO):
    656         def __new__(cls, *args, **kwargs):
    657             return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs)))
    658         def __init__(self, *args, **kwargs):
    659             pass
    660 
    661 
    662 class CBytesIOTest(PyBytesIOTest):
    663     ioclass = io.BytesIO
    664     UnsupportedOperation = io.UnsupportedOperation
    665 
    666     test_bytes_array = unittest.skip(
    667         "array.array() does not have the new buffer API"
    668     )(PyBytesIOTest.test_bytes_array)
    669 
    670 
    671     def test_getstate(self):
    672         memio = self.ioclass()
    673         state = memio.__getstate__()
    674         self.assertEqual(len(state), 3)
    675         bytearray(state[0]) # Check if state[0] supports the buffer interface.
    676         self.assertIsInstance(state[1], int)
    677         if state[2] is not None:
    678             self.assertIsInstance(state[2], dict)
    679         memio.close()
    680         self.assertRaises(ValueError, memio.__getstate__)
    681 
    682     def test_setstate(self):
    683         # This checks whether __setstate__ does proper input validation.
    684         memio = self.ioclass()
    685         memio.__setstate__((b"no error", 0, None))
    686         memio.__setstate__((bytearray(b"no error"), 0, None))
    687         memio.__setstate__((b"no error", 0, {'spam': 3}))
    688         self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None))
    689         self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None))
    690         self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None))
    691         self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0))
    692         self.assertRaises(TypeError, memio.__setstate__, (b"len-test", 0))
    693         self.assertRaises(TypeError, memio.__setstate__)
    694         self.assertRaises(TypeError, memio.__setstate__, 0)
    695         memio.close()
    696         self.assertRaises(ValueError, memio.__setstate__, (b"closed", 0, None))
    697 
    698     check_sizeof = support.check_sizeof
    699 
    700     @support.cpython_only
    701     def test_sizeof(self):
    702         basesize = support.calcobjsize(b'P2PP2P')
    703         check = self.check_sizeof
    704         self.assertEqual(object.__sizeof__(io.BytesIO()), basesize)
    705         check(io.BytesIO(), basesize )
    706         check(io.BytesIO(b'a'), basesize + 1 + 1 )
    707         check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 )
    708 
    709 class CStringIOTest(PyStringIOTest):
    710     ioclass = io.StringIO
    711     UnsupportedOperation = io.UnsupportedOperation
    712 
    713     # XXX: For the Python version of io.StringIO, this is highly
    714     # dependent on the encoding used for the underlying buffer.
    715     def test_widechar(self):
    716         buf = self.buftype("\U0002030a\U00020347")
    717         memio = self.ioclass(buf)
    718 
    719         self.assertEqual(memio.getvalue(), buf)
    720         self.assertEqual(memio.write(buf), len(buf))
    721         self.assertEqual(memio.tell(), len(buf))
    722         self.assertEqual(memio.getvalue(), buf)
    723         self.assertEqual(memio.write(buf), len(buf))
    724         self.assertEqual(memio.tell(), len(buf) * 2)
    725         self.assertEqual(memio.getvalue(), buf + buf)
    726 
    727     def test_getstate(self):
    728         memio = self.ioclass()
    729         state = memio.__getstate__()
    730         self.assertEqual(len(state), 4)
    731         self.assertIsInstance(state[0], unicode)
    732         self.assertIsInstance(state[1], str)
    733         self.assertIsInstance(state[2], int)
    734         if state[3] is not None:
    735             self.assertIsInstance(state[3], dict)
    736         memio.close()
    737         self.assertRaises(ValueError, memio.__getstate__)
    738 
    739     def test_setstate(self):
    740         # This checks whether __setstate__ does proper input validation.
    741         memio = self.ioclass()
    742         memio.__setstate__(("no error", "\n", 0, None))
    743         memio.__setstate__(("no error", "", 0, {'spam': 3}))
    744         self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None))
    745         self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None))
    746         self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None))
    747         # trunk is more tolerant than py3k on the type of the newline param
    748         #self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None))
    749         self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None))
    750         self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0))
    751         self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0))
    752         self.assertRaises(TypeError, memio.__setstate__)
    753         self.assertRaises(TypeError, memio.__setstate__, 0)
    754         memio.close()
    755         self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None))
    756 
    757 
    758 class CStringIOPickleTest(PyStringIOPickleTest):
    759     UnsupportedOperation = io.UnsupportedOperation
    760 
    761     class ioclass(io.StringIO):
    762         def __new__(cls, *args, **kwargs):
    763             return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs),
    764                                              protocol=2))
    765         def __init__(self, *args, **kwargs):
    766             pass
    767 
    768 
    769 def test_main():
    770     tests = [PyBytesIOTest, PyStringIOTest, CBytesIOTest, CStringIOTest,
    771              PyStringIOPickleTest, CStringIOPickleTest]
    772     support.run_unittest(*tests)
    773 
    774 if __name__ == '__main__':
    775     test_main()
    776