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