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         __main__.PickleTestMemIO = PickleTestMemIO
    380         submemio = PickleTestMemIO(buf, 80)
    381         submemio.seek(2)
    382 
    383         # We only support pickle protocol 2 and onward since we use extended
    384         # __reduce__ API of PEP 307 to provide pickling support.
    385         for proto in range(2, pickle.HIGHEST_PROTOCOL):
    386             for obj in (memio, submemio):
    387                 obj2 = pickle.loads(pickle.dumps(obj, protocol=proto))
    388                 self.assertEqual(obj.getvalue(), obj2.getvalue())
    389                 self.assertEqual(obj.__class__, obj2.__class__)
    390                 self.assertEqual(obj.foo, obj2.foo)
    391                 self.assertEqual(obj.tell(), obj2.tell())
    392                 obj.close()
    393                 self.assertRaises(ValueError, pickle.dumps, obj, proto)
    394         del __main__.PickleTestMemIO
    395 
    396 
    397 class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase):
    398 
    399     UnsupportedOperation = pyio.UnsupportedOperation
    400 
    401     @staticmethod
    402     def buftype(s):
    403         return s.encode("ascii")
    404     ioclass = pyio.BytesIO
    405     EOF = b""
    406 
    407     def test_read1(self):
    408         buf = self.buftype("1234567890")
    409         memio = self.ioclass(buf)
    410 
    411         self.assertRaises(TypeError, memio.read1)
    412         self.assertEqual(memio.read(), buf)
    413 
    414     def test_readinto(self):
    415         buf = self.buftype("1234567890")
    416         memio = self.ioclass(buf)
    417 
    418         b = bytearray(b"hello")
    419         self.assertEqual(memio.readinto(b), 5)
    420         self.assertEqual(b, b"12345")
    421         self.assertEqual(memio.readinto(b), 5)
    422         self.assertEqual(b, b"67890")
    423         self.assertEqual(memio.readinto(b), 0)
    424         self.assertEqual(b, b"67890")
    425         b = bytearray(b"hello world")
    426         memio.seek(0)
    427         self.assertEqual(memio.readinto(b), 10)
    428         self.assertEqual(b, b"1234567890d")
    429         b = bytearray(b"")
    430         memio.seek(0)
    431         self.assertEqual(memio.readinto(b), 0)
    432         self.assertEqual(b, b"")
    433         self.assertRaises(TypeError, memio.readinto, '')
    434         import array
    435         a = array.array(b'b', b"hello world")
    436         memio = self.ioclass(buf)
    437         memio.readinto(a)
    438         self.assertEqual(a.tostring(), b"1234567890d")
    439         memio.close()
    440         self.assertRaises(ValueError, memio.readinto, b)
    441         memio = self.ioclass(b"123")
    442         b = bytearray()
    443         memio.seek(42)
    444         memio.readinto(b)
    445         self.assertEqual(b, b"")
    446 
    447     def test_relative_seek(self):
    448         buf = self.buftype("1234567890")
    449         memio = self.ioclass(buf)
    450 
    451         self.assertEqual(memio.seek(-1, 1), 0)
    452         self.assertEqual(memio.seek(3, 1), 3)
    453         self.assertEqual(memio.seek(-4, 1), 0)
    454         self.assertEqual(memio.seek(-1, 2), 9)
    455         self.assertEqual(memio.seek(1, 1), 10)
    456         self.assertEqual(memio.seek(1, 2), 11)
    457         memio.seek(-3, 2)
    458         self.assertEqual(memio.read(), buf[-3:])
    459         memio.seek(0)
    460         memio.seek(1, 1)
    461         self.assertEqual(memio.read(), buf[1:])
    462 
    463     def test_unicode(self):
    464         memio = self.ioclass()
    465 
    466         self.assertRaises(TypeError, self.ioclass, "1234567890")
    467         self.assertRaises(TypeError, memio.write, "1234567890")
    468         self.assertRaises(TypeError, memio.writelines, ["1234567890"])
    469 
    470     def test_bytes_array(self):
    471         buf = b"1234567890"
    472         import array
    473         a = array.array(b'b', buf)
    474         memio = self.ioclass(a)
    475         self.assertEqual(memio.getvalue(), buf)
    476         self.assertEqual(memio.write(a), 10)
    477         self.assertEqual(memio.getvalue(), buf)
    478 
    479     def test_issue5449(self):
    480         buf = self.buftype("1234567890")
    481         self.ioclass(initial_bytes=buf)
    482         self.assertRaises(TypeError, self.ioclass, buf, foo=None)
    483 
    484 
    485 class TextIOTestMixin:
    486 
    487     def test_newlines_property(self):
    488         memio = self.ioclass(newline=None)
    489         # The C StringIO decodes newlines in write() calls, but the Python
    490         # implementation only does when reading.  This function forces them to
    491         # be decoded for testing.
    492         def force_decode():
    493             memio.seek(0)
    494             memio.read()
    495         self.assertEqual(memio.newlines, None)
    496         memio.write("a\n")
    497         force_decode()
    498         self.assertEqual(memio.newlines, "\n")
    499         memio.write("b\r\n")
    500         force_decode()
    501         self.assertEqual(memio.newlines, ("\n", "\r\n"))
    502         memio.write("c\rd")
    503         force_decode()
    504         self.assertEqual(memio.newlines, ("\r", "\n", "\r\n"))
    505 
    506     def test_relative_seek(self):
    507         memio = self.ioclass()
    508 
    509         self.assertRaises(IOError, memio.seek, -1, 1)
    510         self.assertRaises(IOError, memio.seek, 3, 1)
    511         self.assertRaises(IOError, memio.seek, -3, 1)
    512         self.assertRaises(IOError, memio.seek, -1, 2)
    513         self.assertRaises(IOError, memio.seek, 1, 1)
    514         self.assertRaises(IOError, memio.seek, 1, 2)
    515 
    516     def test_textio_properties(self):
    517         memio = self.ioclass()
    518 
    519         # These are just dummy values but we nevertheless check them for fear
    520         # of unexpected breakage.
    521         self.assertIsNone(memio.encoding)
    522         self.assertIsNone(memio.errors)
    523         self.assertFalse(memio.line_buffering)
    524 
    525     def test_newline_none(self):
    526         # newline=None
    527         memio = self.ioclass("a\nb\r\nc\rd", newline=None)
    528         self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"])
    529         memio.seek(0)
    530         self.assertEqual(memio.read(1), "a")
    531         self.assertEqual(memio.read(2), "\nb")
    532         self.assertEqual(memio.read(2), "\nc")
    533         self.assertEqual(memio.read(1), "\n")
    534         memio = self.ioclass(newline=None)
    535         self.assertEqual(2, memio.write("a\n"))
    536         self.assertEqual(3, memio.write("b\r\n"))
    537         self.assertEqual(3, memio.write("c\rd"))
    538         memio.seek(0)
    539         self.assertEqual(memio.read(), "a\nb\nc\nd")
    540         memio = self.ioclass("a\r\nb", newline=None)
    541         self.assertEqual(memio.read(3), "a\nb")
    542 
    543     def test_newline_empty(self):
    544         # newline=""
    545         memio = self.ioclass("a\nb\r\nc\rd", newline="")
    546         self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
    547         memio.seek(0)
    548         self.assertEqual(memio.read(4), "a\nb\r")
    549         self.assertEqual(memio.read(2), "\nc")
    550         self.assertEqual(memio.read(1), "\r")
    551         memio = self.ioclass(newline="")
    552         self.assertEqual(2, memio.write("a\n"))
    553         self.assertEqual(2, memio.write("b\r"))
    554         self.assertEqual(2, memio.write("\nc"))
    555         self.assertEqual(2, memio.write("\rd"))
    556         memio.seek(0)
    557         self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
    558 
    559     def test_newline_lf(self):
    560         # newline="\n"
    561         memio = self.ioclass("a\nb\r\nc\rd")
    562         self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
    563 
    564     def test_newline_cr(self):
    565         # newline="\r"
    566         memio = self.ioclass("a\nb\r\nc\rd", newline="\r")
    567         self.assertEqual(memio.read(), "a\rb\r\rc\rd")
    568         memio.seek(0)
    569         self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
    570 
    571     def test_newline_crlf(self):
    572         # newline="\r\n"
    573         memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n")
    574         self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd")
    575         memio.seek(0)
    576         self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
    577 
    578     def test_issue5265(self):
    579         # StringIO can duplicate newlines in universal newlines mode
    580         memio = self.ioclass("a\r\nb\r\n", newline=None)
    581         self.assertEqual(memio.read(5), "a\nb\n")
    582 
    583 
    584 class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin,
    585                      TextIOTestMixin, unittest.TestCase):
    586     buftype = unicode
    587     ioclass = pyio.StringIO
    588     UnsupportedOperation = pyio.UnsupportedOperation
    589     EOF = ""
    590 
    591 
    592 class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase):
    593     """Test if pickle restores properly the internal state of StringIO.
    594     """
    595     buftype = unicode
    596     UnsupportedOperation = pyio.UnsupportedOperation
    597     EOF = ""
    598 
    599     class ioclass(pyio.StringIO):
    600         def __new__(cls, *args, **kwargs):
    601             return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs)))
    602         def __init__(self, *args, **kwargs):
    603             pass
    604 
    605 
    606 class CBytesIOTest(PyBytesIOTest):
    607     ioclass = io.BytesIO
    608     UnsupportedOperation = io.UnsupportedOperation
    609 
    610     test_bytes_array = unittest.skip(
    611         "array.array() does not have the new buffer API"
    612     )(PyBytesIOTest.test_bytes_array)
    613 
    614 
    615     def test_getstate(self):
    616         memio = self.ioclass()
    617         state = memio.__getstate__()
    618         self.assertEqual(len(state), 3)
    619         bytearray(state[0]) # Check if state[0] supports the buffer interface.
    620         self.assertIsInstance(state[1], int)
    621         self.assertTrue(isinstance(state[2], dict) or state[2] is None)
    622         memio.close()
    623         self.assertRaises(ValueError, memio.__getstate__)
    624 
    625     def test_setstate(self):
    626         # This checks whether __setstate__ does proper input validation.
    627         memio = self.ioclass()
    628         memio.__setstate__((b"no error", 0, None))
    629         memio.__setstate__((bytearray(b"no error"), 0, None))
    630         memio.__setstate__((b"no error", 0, {'spam': 3}))
    631         self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None))
    632         self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None))
    633         self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None))
    634         self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0))
    635         self.assertRaises(TypeError, memio.__setstate__, (b"len-test", 0))
    636         self.assertRaises(TypeError, memio.__setstate__)
    637         self.assertRaises(TypeError, memio.__setstate__, 0)
    638         memio.close()
    639         self.assertRaises(ValueError, memio.__setstate__, (b"closed", 0, None))
    640 
    641     check_sizeof = support.check_sizeof
    642 
    643     @support.cpython_only
    644     def test_sizeof(self):
    645         basesize = support.calcobjsize(b'P2PP2P')
    646         check = self.check_sizeof
    647         self.assertEqual(object.__sizeof__(io.BytesIO()), basesize)
    648         check(io.BytesIO(), basesize )
    649         check(io.BytesIO(b'a'), basesize + 1 + 1 )
    650         check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 )
    651 
    652 class CStringIOTest(PyStringIOTest):
    653     ioclass = io.StringIO
    654     UnsupportedOperation = io.UnsupportedOperation
    655 
    656     # XXX: For the Python version of io.StringIO, this is highly
    657     # dependent on the encoding used for the underlying buffer.
    658     def test_widechar(self):
    659         buf = self.buftype("\U0002030a\U00020347")
    660         memio = self.ioclass(buf)
    661 
    662         self.assertEqual(memio.getvalue(), buf)
    663         self.assertEqual(memio.write(buf), len(buf))
    664         self.assertEqual(memio.tell(), len(buf))
    665         self.assertEqual(memio.getvalue(), buf)
    666         self.assertEqual(memio.write(buf), len(buf))
    667         self.assertEqual(memio.tell(), len(buf) * 2)
    668         self.assertEqual(memio.getvalue(), buf + buf)
    669 
    670     def test_getstate(self):
    671         memio = self.ioclass()
    672         state = memio.__getstate__()
    673         self.assertEqual(len(state), 4)
    674         self.assertIsInstance(state[0], unicode)
    675         self.assertIsInstance(state[1], str)
    676         self.assertIsInstance(state[2], int)
    677         self.assertTrue(isinstance(state[3], dict) or state[3] is None)
    678         memio.close()
    679         self.assertRaises(ValueError, memio.__getstate__)
    680 
    681     def test_setstate(self):
    682         # This checks whether __setstate__ does proper input validation.
    683         memio = self.ioclass()
    684         memio.__setstate__(("no error", "\n", 0, None))
    685         memio.__setstate__(("no error", "", 0, {'spam': 3}))
    686         self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None))
    687         self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None))
    688         self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None))
    689         # trunk is more tolerant than py3k on the type of the newline param
    690         #self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None))
    691         self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None))
    692         self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0))
    693         self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0))
    694         self.assertRaises(TypeError, memio.__setstate__)
    695         self.assertRaises(TypeError, memio.__setstate__, 0)
    696         memio.close()
    697         self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None))
    698 
    699 
    700 class CStringIOPickleTest(PyStringIOPickleTest):
    701     UnsupportedOperation = io.UnsupportedOperation
    702 
    703     class ioclass(io.StringIO):
    704         def __new__(cls, *args, **kwargs):
    705             return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs),
    706                                              protocol=2))
    707         def __init__(self, *args, **kwargs):
    708             pass
    709 
    710 
    711 def test_main():
    712     tests = [PyBytesIOTest, PyStringIOTest, CBytesIOTest, CStringIOTest,
    713              PyStringIOPickleTest, CStringIOPickleTest]
    714     support.run_unittest(*tests)
    715 
    716 if __name__ == '__main__':
    717     test_main()
    718