blob: 13d7e1710011f8cd3ee4f1fbaa515a07976c3b8b [file] [log] [blame]
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001"""Unit tests for memory-based file-like objects.
2StringIO -- for unicode strings
3BytesIO -- for bytes
4"""
5
6import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import support
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00008
9import io
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000010import _pyio as pyio
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +000011import pickle
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000012
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000013class MemorySeekTestMixin:
14
15 def testInit(self):
16 buf = self.buftype("1234567890")
17 bytesIo = self.ioclass(buf)
18
19 def testRead(self):
20 buf = self.buftype("1234567890")
21 bytesIo = self.ioclass(buf)
22
23 self.assertEquals(buf[:1], bytesIo.read(1))
24 self.assertEquals(buf[1:5], bytesIo.read(4))
25 self.assertEquals(buf[5:], bytesIo.read(900))
26 self.assertEquals(self.EOF, bytesIo.read())
27
28 def testReadNoArgs(self):
29 buf = self.buftype("1234567890")
30 bytesIo = self.ioclass(buf)
31
32 self.assertEquals(buf, bytesIo.read())
33 self.assertEquals(self.EOF, bytesIo.read())
34
35 def testSeek(self):
36 buf = self.buftype("1234567890")
37 bytesIo = self.ioclass(buf)
38
39 bytesIo.read(5)
40 bytesIo.seek(0)
41 self.assertEquals(buf, bytesIo.read())
42
43 bytesIo.seek(3)
44 self.assertEquals(buf[3:], bytesIo.read())
45 self.assertRaises(TypeError, bytesIo.seek, 0.0)
46
47 def testTell(self):
48 buf = self.buftype("1234567890")
49 bytesIo = self.ioclass(buf)
50
51 self.assertEquals(0, bytesIo.tell())
52 bytesIo.seek(5)
53 self.assertEquals(5, bytesIo.tell())
54 bytesIo.seek(10000)
55 self.assertEquals(10000, bytesIo.tell())
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000056
57
58class MemoryTestMixin:
59
Benjamin Petersond2e0c792009-05-01 20:40:59 +000060 def test_detach(self):
61 buf = self.ioclass()
62 self.assertRaises(self.UnsupportedOperation, buf.detach)
63
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000064 def write_ops(self, f, t):
65 self.assertEqual(f.write(t("blah.")), 5)
66 self.assertEqual(f.seek(0), 0)
67 self.assertEqual(f.write(t("Hello.")), 6)
68 self.assertEqual(f.tell(), 6)
69 self.assertEqual(f.seek(5), 5)
70 self.assertEqual(f.tell(), 5)
71 self.assertEqual(f.write(t(" world\n\n\n")), 9)
72 self.assertEqual(f.seek(0), 0)
73 self.assertEqual(f.write(t("h")), 1)
74 self.assertEqual(f.truncate(12), 12)
Antoine Pitrou905a2ff2010-01-31 22:47:27 +000075 self.assertEqual(f.tell(), 1)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000076
77 def test_write(self):
78 buf = self.buftype("hello world\n")
79 memio = self.ioclass(buf)
80
81 self.write_ops(memio, self.buftype)
82 self.assertEqual(memio.getvalue(), buf)
83 memio = self.ioclass()
84 self.write_ops(memio, self.buftype)
85 self.assertEqual(memio.getvalue(), buf)
86 self.assertRaises(TypeError, memio.write, None)
87 memio.close()
88 self.assertRaises(ValueError, memio.write, self.buftype(""))
89
90 def test_writelines(self):
91 buf = self.buftype("1234567890")
92 memio = self.ioclass()
93
94 self.assertEqual(memio.writelines([buf] * 100), None)
95 self.assertEqual(memio.getvalue(), buf * 100)
96 memio.writelines([])
97 self.assertEqual(memio.getvalue(), buf * 100)
98 memio = self.ioclass()
99 self.assertRaises(TypeError, memio.writelines, [buf] + [1])
100 self.assertEqual(memio.getvalue(), buf)
101 self.assertRaises(TypeError, memio.writelines, None)
102 memio.close()
103 self.assertRaises(ValueError, memio.writelines, [])
104
105 def test_writelines_error(self):
106 memio = self.ioclass()
107 def error_gen():
108 yield self.buftype('spam')
109 raise KeyboardInterrupt
110
111 self.assertRaises(KeyboardInterrupt, memio.writelines, error_gen())
112
113 def test_truncate(self):
114 buf = self.buftype("1234567890")
115 memio = self.ioclass(buf)
116
117 self.assertRaises(ValueError, memio.truncate, -1)
118 memio.seek(6)
119 self.assertEqual(memio.truncate(), 6)
120 self.assertEqual(memio.getvalue(), buf[:6])
121 self.assertEqual(memio.truncate(4), 4)
122 self.assertEqual(memio.getvalue(), buf[:4])
Antoine Pitrou905a2ff2010-01-31 22:47:27 +0000123 self.assertEqual(memio.tell(), 6)
124 memio.seek(0, 2)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000125 memio.write(buf)
126 self.assertEqual(memio.getvalue(), buf[:4] + buf)
127 pos = memio.tell()
128 self.assertEqual(memio.truncate(None), pos)
129 self.assertEqual(memio.tell(), pos)
130 self.assertRaises(TypeError, memio.truncate, '0')
131 memio.close()
132 self.assertRaises(ValueError, memio.truncate, 0)
133
134 def test_init(self):
135 buf = self.buftype("1234567890")
136 memio = self.ioclass(buf)
137 self.assertEqual(memio.getvalue(), buf)
138 memio = self.ioclass(None)
139 self.assertEqual(memio.getvalue(), self.EOF)
140 memio.__init__(buf * 2)
141 self.assertEqual(memio.getvalue(), buf * 2)
142 memio.__init__(buf)
143 self.assertEqual(memio.getvalue(), buf)
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000144 self.assertRaises(TypeError, memio.__init__, [])
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000145
146 def test_read(self):
147 buf = self.buftype("1234567890")
148 memio = self.ioclass(buf)
149
150 self.assertEqual(memio.read(0), self.EOF)
151 self.assertEqual(memio.read(1), buf[:1])
152 self.assertEqual(memio.read(4), buf[1:5])
153 self.assertEqual(memio.read(900), buf[5:])
154 self.assertEqual(memio.read(), self.EOF)
155 memio.seek(0)
156 self.assertEqual(memio.read(), buf)
157 self.assertEqual(memio.read(), self.EOF)
158 self.assertEqual(memio.tell(), 10)
159 memio.seek(0)
160 self.assertEqual(memio.read(-1), buf)
161 memio.seek(0)
Alexandre Vassalotti5da31eb2008-05-06 20:30:41 +0000162 self.assertEqual(type(memio.read()), type(buf))
Alexandre Vassalotti4833b3c2008-05-06 23:47:23 +0000163 memio.seek(100)
164 self.assertEqual(type(memio.read()), type(buf))
Alexandre Vassalotti5da31eb2008-05-06 20:30:41 +0000165 memio.seek(0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000166 self.assertEqual(memio.read(None), buf)
167 self.assertRaises(TypeError, memio.read, '')
168 memio.close()
169 self.assertRaises(ValueError, memio.read)
170
171 def test_readline(self):
172 buf = self.buftype("1234567890\n")
173 memio = self.ioclass(buf * 2)
174
175 self.assertEqual(memio.readline(0), self.EOF)
176 self.assertEqual(memio.readline(), buf)
177 self.assertEqual(memio.readline(), buf)
178 self.assertEqual(memio.readline(), self.EOF)
179 memio.seek(0)
180 self.assertEqual(memio.readline(5), buf[:5])
181 self.assertEqual(memio.readline(5), buf[5:10])
182 self.assertEqual(memio.readline(5), buf[10:15])
183 memio.seek(0)
184 self.assertEqual(memio.readline(-1), buf)
185 memio.seek(0)
186 self.assertEqual(memio.readline(0), self.EOF)
187
188 buf = self.buftype("1234567890\n")
189 memio = self.ioclass((buf * 3)[:-1])
190 self.assertEqual(memio.readline(), buf)
191 self.assertEqual(memio.readline(), buf)
192 self.assertEqual(memio.readline(), buf[:-1])
193 self.assertEqual(memio.readline(), self.EOF)
194 memio.seek(0)
Alexandre Vassalotti5da31eb2008-05-06 20:30:41 +0000195 self.assertEqual(type(memio.readline()), type(buf))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000196 self.assertEqual(memio.readline(), buf)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000197 self.assertRaises(TypeError, memio.readline, '')
198 memio.close()
199 self.assertRaises(ValueError, memio.readline)
200
201 def test_readlines(self):
202 buf = self.buftype("1234567890\n")
203 memio = self.ioclass(buf * 10)
204
205 self.assertEqual(memio.readlines(), [buf] * 10)
206 memio.seek(5)
207 self.assertEqual(memio.readlines(), [buf[5:]] + [buf] * 9)
208 memio.seek(0)
209 self.assertEqual(memio.readlines(15), [buf] * 2)
210 memio.seek(0)
211 self.assertEqual(memio.readlines(-1), [buf] * 10)
212 memio.seek(0)
213 self.assertEqual(memio.readlines(0), [buf] * 10)
214 memio.seek(0)
Alexandre Vassalotti5da31eb2008-05-06 20:30:41 +0000215 self.assertEqual(type(memio.readlines()[0]), type(buf))
216 memio.seek(0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000217 self.assertEqual(memio.readlines(None), [buf] * 10)
218 self.assertRaises(TypeError, memio.readlines, '')
219 memio.close()
220 self.assertRaises(ValueError, memio.readlines)
221
222 def test_iterator(self):
223 buf = self.buftype("1234567890\n")
224 memio = self.ioclass(buf * 10)
225
226 self.assertEqual(iter(memio), memio)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000227 self.assertTrue(hasattr(memio, '__iter__'))
228 self.assertTrue(hasattr(memio, '__next__'))
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000229 i = 0
230 for line in memio:
231 self.assertEqual(line, buf)
232 i += 1
233 self.assertEqual(i, 10)
234 memio.seek(0)
235 i = 0
236 for line in memio:
237 self.assertEqual(line, buf)
238 i += 1
239 self.assertEqual(i, 10)
240 memio = self.ioclass(buf * 2)
241 memio.close()
242 self.assertRaises(ValueError, memio.__next__)
243
244 def test_getvalue(self):
245 buf = self.buftype("1234567890")
246 memio = self.ioclass(buf)
247
248 self.assertEqual(memio.getvalue(), buf)
249 memio.read()
250 self.assertEqual(memio.getvalue(), buf)
Alexandre Vassalotti5da31eb2008-05-06 20:30:41 +0000251 self.assertEqual(type(memio.getvalue()), type(buf))
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000252 memio = self.ioclass(buf * 1000)
253 self.assertEqual(memio.getvalue()[-3:], self.buftype("890"))
254 memio = self.ioclass(buf)
255 memio.close()
256 self.assertRaises(ValueError, memio.getvalue)
257
258 def test_seek(self):
259 buf = self.buftype("1234567890")
260 memio = self.ioclass(buf)
261
262 memio.read(5)
263 self.assertRaises(ValueError, memio.seek, -1)
264 self.assertRaises(ValueError, memio.seek, 1, -1)
265 self.assertRaises(ValueError, memio.seek, 1, 3)
266 self.assertEqual(memio.seek(0), 0)
267 self.assertEqual(memio.seek(0, 0), 0)
268 self.assertEqual(memio.read(), buf)
269 self.assertEqual(memio.seek(3), 3)
270 self.assertEqual(memio.seek(0, 1), 3)
271 self.assertEqual(memio.read(), buf[3:])
272 self.assertEqual(memio.seek(len(buf)), len(buf))
273 self.assertEqual(memio.read(), self.EOF)
274 memio.seek(len(buf) + 1)
275 self.assertEqual(memio.read(), self.EOF)
276 self.assertEqual(memio.seek(0, 2), len(buf))
277 self.assertEqual(memio.read(), self.EOF)
278 memio.close()
279 self.assertRaises(ValueError, memio.seek, 0)
280
281 def test_overseek(self):
282 buf = self.buftype("1234567890")
283 memio = self.ioclass(buf)
284
285 self.assertEqual(memio.seek(len(buf) + 1), 11)
286 self.assertEqual(memio.read(), self.EOF)
287 self.assertEqual(memio.tell(), 11)
288 self.assertEqual(memio.getvalue(), buf)
289 memio.write(self.EOF)
290 self.assertEqual(memio.getvalue(), buf)
291 memio.write(buf)
292 self.assertEqual(memio.getvalue(), buf + self.buftype('\0') + buf)
293
294 def test_tell(self):
295 buf = self.buftype("1234567890")
296 memio = self.ioclass(buf)
297
298 self.assertEqual(memio.tell(), 0)
299 memio.seek(5)
300 self.assertEqual(memio.tell(), 5)
301 memio.seek(10000)
302 self.assertEqual(memio.tell(), 10000)
303 memio.close()
304 self.assertRaises(ValueError, memio.tell)
305
306 def test_flush(self):
307 buf = self.buftype("1234567890")
308 memio = self.ioclass(buf)
309
310 self.assertEqual(memio.flush(), None)
311
312 def test_flags(self):
313 memio = self.ioclass()
314
315 self.assertEqual(memio.writable(), True)
316 self.assertEqual(memio.readable(), True)
317 self.assertEqual(memio.seekable(), True)
318 self.assertEqual(memio.isatty(), False)
319 self.assertEqual(memio.closed, False)
320 memio.close()
321 self.assertEqual(memio.writable(), True)
322 self.assertEqual(memio.readable(), True)
323 self.assertEqual(memio.seekable(), True)
324 self.assertRaises(ValueError, memio.isatty)
325 self.assertEqual(memio.closed, True)
326
327 def test_subclassing(self):
328 buf = self.buftype("1234567890")
329 def test1():
330 class MemIO(self.ioclass):
331 pass
332 m = MemIO(buf)
333 return m.getvalue()
334 def test2():
335 class MemIO(self.ioclass):
336 def __init__(me, a, b):
337 self.ioclass.__init__(me, a)
338 m = MemIO(buf, None)
339 return m.getvalue()
340 self.assertEqual(test1(), buf)
341 self.assertEqual(test2(), buf)
342
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000343 def test_instance_dict_leak(self):
344 # Test case for issue #6242.
345 # This will be caught by regrtest.py -R if this leak.
346 for _ in range(100):
347 memio = self.ioclass()
348 memio.foo = 1
349
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000350 def test_pickling(self):
351 buf = self.buftype("1234567890")
352 memio = self.ioclass(buf)
353 memio.foo = 42
354 memio.seek(2)
355
356 class PickleTestMemIO(self.ioclass):
357 def __init__(me, initvalue, foo):
358 self.ioclass.__init__(me, initvalue)
359 me.foo = foo
360 # __getnewargs__ is undefined on purpose. This checks that PEP 307
361 # is used to provide pickling support.
362
363 # Pickle expects the class to be on the module level. Here we use a
364 # little hack to allow the PickleTestMemIO class to derive from
365 # self.ioclass without having to define all combinations explictly on
366 # the module-level.
367 import __main__
368 PickleTestMemIO.__module__ = '__main__'
369 __main__.PickleTestMemIO = PickleTestMemIO
370 submemio = PickleTestMemIO(buf, 80)
371 submemio.seek(2)
372
373 # We only support pickle protocol 2 and onward since we use extended
374 # __reduce__ API of PEP 307 to provide pickling support.
375 for proto in range(2, pickle.HIGHEST_PROTOCOL):
376 for obj in (memio, submemio):
377 obj2 = pickle.loads(pickle.dumps(obj, protocol=proto))
378 self.assertEqual(obj.getvalue(), obj2.getvalue())
379 self.assertEqual(obj.__class__, obj2.__class__)
380 self.assertEqual(obj.foo, obj2.foo)
381 self.assertEqual(obj.tell(), obj2.tell())
382 obj.close()
383 self.assertRaises(ValueError, pickle.dumps, obj, proto)
384 del __main__.PickleTestMemIO
385
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000386
Antoine Pitrou972ee132010-09-06 18:48:21 +0000387class BytesIOMixin:
388
389 def test_getbuffer(self):
390 memio = self.ioclass(b"1234567890")
391 buf = memio.getbuffer()
392 self.assertEqual(bytes(buf), b"1234567890")
393 memio.seek(5)
394 buf = memio.getbuffer()
395 self.assertEqual(bytes(buf), b"1234567890")
396 # Trying to change the size of the BytesIO while a buffer is exported
397 # raises a BufferError.
398 self.assertRaises(BufferError, memio.write, b'x' * 100)
399 self.assertRaises(BufferError, memio.truncate)
400 # Mutating the buffer updates the BytesIO
401 buf[3:6] = b"abc"
402 self.assertEqual(bytes(buf), b"123abc7890")
403 self.assertEqual(memio.getvalue(), b"123abc7890")
404 # After the buffer gets released, we can resize the BytesIO again
405 del buf
406 support.gc_collect()
407 memio.truncate()
408
409
410class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin,
411 BytesIOMixin, unittest.TestCase):
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000412
413 UnsupportedOperation = pyio.UnsupportedOperation
414
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000415 @staticmethod
416 def buftype(s):
417 return s.encode("ascii")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000418 ioclass = pyio.BytesIO
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000419 EOF = b""
420
421 def test_read1(self):
422 buf = self.buftype("1234567890")
423 memio = self.ioclass(buf)
424
425 self.assertRaises(TypeError, memio.read1)
426 self.assertEqual(memio.read(), buf)
427
428 def test_readinto(self):
429 buf = self.buftype("1234567890")
430 memio = self.ioclass(buf)
431
432 b = bytearray(b"hello")
433 self.assertEqual(memio.readinto(b), 5)
434 self.assertEqual(b, b"12345")
435 self.assertEqual(memio.readinto(b), 5)
436 self.assertEqual(b, b"67890")
437 self.assertEqual(memio.readinto(b), 0)
438 self.assertEqual(b, b"67890")
439 b = bytearray(b"hello world")
440 memio.seek(0)
441 self.assertEqual(memio.readinto(b), 10)
442 self.assertEqual(b, b"1234567890d")
443 b = bytearray(b"")
444 memio.seek(0)
445 self.assertEqual(memio.readinto(b), 0)
446 self.assertEqual(b, b"")
447 self.assertRaises(TypeError, memio.readinto, '')
448 import array
449 a = array.array('b', b"hello world")
450 memio = self.ioclass(buf)
451 memio.readinto(a)
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +0000452 self.assertEqual(a.tobytes(), b"1234567890d")
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000453 memio.close()
454 self.assertRaises(ValueError, memio.readinto, b)
Benjamin Petersonfa735552010-11-20 17:24:04 +0000455 memio = self.ioclass(b"123")
456 b = bytearray()
457 memio.seek(42)
458 memio.readinto(b)
459 self.assertEqual(b, b"")
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000460
461 def test_relative_seek(self):
462 buf = self.buftype("1234567890")
463 memio = self.ioclass(buf)
464
465 self.assertEqual(memio.seek(-1, 1), 0)
466 self.assertEqual(memio.seek(3, 1), 3)
467 self.assertEqual(memio.seek(-4, 1), 0)
468 self.assertEqual(memio.seek(-1, 2), 9)
469 self.assertEqual(memio.seek(1, 1), 10)
470 self.assertEqual(memio.seek(1, 2), 11)
471 memio.seek(-3, 2)
472 self.assertEqual(memio.read(), buf[-3:])
473 memio.seek(0)
474 memio.seek(1, 1)
475 self.assertEqual(memio.read(), buf[1:])
476
477 def test_unicode(self):
478 memio = self.ioclass()
479
480 self.assertRaises(TypeError, self.ioclass, "1234567890")
481 self.assertRaises(TypeError, memio.write, "1234567890")
482 self.assertRaises(TypeError, memio.writelines, ["1234567890"])
483
484 def test_bytes_array(self):
485 buf = b"1234567890"
486 import array
487 a = array.array('b', list(buf))
488 memio = self.ioclass(a)
489 self.assertEqual(memio.getvalue(), buf)
490 self.assertEqual(memio.write(a), 10)
491 self.assertEqual(memio.getvalue(), buf)
492
Alexandre Vassalottiba5c7432009-08-04 23:19:13 +0000493 def test_issue5449(self):
494 buf = self.buftype("1234567890")
495 self.ioclass(initial_bytes=buf)
496 self.assertRaises(TypeError, self.ioclass, buf, foo=None)
497
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000498
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000499class TextIOTestMixin:
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000500
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000501 def test_newlines_property(self):
502 memio = self.ioclass(newline=None)
503 # The C StringIO decodes newlines in write() calls, but the Python
504 # implementation only does when reading. This function forces them to
505 # be decoded for testing.
506 def force_decode():
507 memio.seek(0)
508 memio.read()
509 self.assertEqual(memio.newlines, None)
510 memio.write("a\n")
511 force_decode()
512 self.assertEqual(memio.newlines, "\n")
513 memio.write("b\r\n")
514 force_decode()
515 self.assertEqual(memio.newlines, ("\n", "\r\n"))
516 memio.write("c\rd")
517 force_decode()
518 self.assertEqual(memio.newlines, ("\r", "\n", "\r\n"))
519
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000520 def test_relative_seek(self):
521 memio = self.ioclass()
522
523 self.assertRaises(IOError, memio.seek, -1, 1)
524 self.assertRaises(IOError, memio.seek, 3, 1)
525 self.assertRaises(IOError, memio.seek, -3, 1)
526 self.assertRaises(IOError, memio.seek, -1, 2)
527 self.assertRaises(IOError, memio.seek, 1, 1)
528 self.assertRaises(IOError, memio.seek, 1, 2)
529
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000530 def test_textio_properties(self):
531 memio = self.ioclass()
532
533 # These are just dummy values but we nevertheless check them for fear
534 # of unexpected breakage.
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000535 self.assertIsNone(memio.encoding)
536 self.assertIsNone(memio.errors)
537 self.assertFalse(memio.line_buffering)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000538
539 def test_newline_none(self):
540 # newline=None
541 memio = self.ioclass("a\nb\r\nc\rd", newline=None)
542 self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"])
543 memio.seek(0)
544 self.assertEqual(memio.read(1), "a")
545 self.assertEqual(memio.read(2), "\nb")
546 self.assertEqual(memio.read(2), "\nc")
547 self.assertEqual(memio.read(1), "\n")
548 memio = self.ioclass(newline=None)
549 self.assertEqual(2, memio.write("a\n"))
550 self.assertEqual(3, memio.write("b\r\n"))
551 self.assertEqual(3, memio.write("c\rd"))
552 memio.seek(0)
553 self.assertEqual(memio.read(), "a\nb\nc\nd")
554 memio = self.ioclass("a\r\nb", newline=None)
555 self.assertEqual(memio.read(3), "a\nb")
556
557 def test_newline_empty(self):
558 # newline=""
559 memio = self.ioclass("a\nb\r\nc\rd", newline="")
560 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
561 memio.seek(0)
562 self.assertEqual(memio.read(4), "a\nb\r")
563 self.assertEqual(memio.read(2), "\nc")
564 self.assertEqual(memio.read(1), "\r")
565 memio = self.ioclass(newline="")
566 self.assertEqual(2, memio.write("a\n"))
567 self.assertEqual(2, memio.write("b\r"))
568 self.assertEqual(2, memio.write("\nc"))
569 self.assertEqual(2, memio.write("\rd"))
570 memio.seek(0)
571 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
572
573 def test_newline_lf(self):
574 # newline="\n"
575 memio = self.ioclass("a\nb\r\nc\rd")
576 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
577
578 def test_newline_cr(self):
579 # newline="\r"
580 memio = self.ioclass("a\nb\r\nc\rd", newline="\r")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000581 self.assertEqual(memio.read(), "a\rb\r\rc\rd")
582 memio.seek(0)
583 self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
584
585 def test_newline_crlf(self):
586 # newline="\r\n"
587 memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000588 self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd")
589 memio.seek(0)
590 self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
591
592 def test_issue5265(self):
593 # StringIO can duplicate newlines in universal newlines mode
594 memio = self.ioclass("a\r\nb\r\n", newline=None)
595 self.assertEqual(memio.read(5), "a\nb\n")
596
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000597 def test_newline_argument(self):
598 self.assertRaises(TypeError, self.ioclass, newline=b"\n")
599 self.assertRaises(ValueError, self.ioclass, newline="error")
600 # These should not raise an error
601 for newline in (None, "", "\n", "\r", "\r\n"):
602 self.ioclass(newline=newline)
603
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000604
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000605class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin,
606 TextIOTestMixin, unittest.TestCase):
607 buftype = str
608 ioclass = pyio.StringIO
609 UnsupportedOperation = pyio.UnsupportedOperation
610 EOF = ""
611
612
613class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase):
614 """Test if pickle restores properly the internal state of StringIO.
615 """
616 buftype = str
617 UnsupportedOperation = pyio.UnsupportedOperation
618 EOF = ""
619
620 class ioclass(pyio.StringIO):
621 def __new__(cls, *args, **kwargs):
622 return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs)))
623 def __init__(self, *args, **kwargs):
624 pass
625
626
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000627class CBytesIOTest(PyBytesIOTest):
628 ioclass = io.BytesIO
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000629 UnsupportedOperation = io.UnsupportedOperation
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000630
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000631 def test_getstate(self):
632 memio = self.ioclass()
633 state = memio.__getstate__()
634 self.assertEqual(len(state), 3)
635 bytearray(state[0]) # Check if state[0] supports the buffer interface.
Ezio Melottie9615932010-01-24 19:26:24 +0000636 self.assertIsInstance(state[1], int)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000637 self.assert_(isinstance(state[2], dict) or state[2] is None)
638 memio.close()
639 self.assertRaises(ValueError, memio.__getstate__)
640
641 def test_setstate(self):
642 # This checks whether __setstate__ does proper input validation.
643 memio = self.ioclass()
644 memio.__setstate__((b"no error", 0, None))
645 memio.__setstate__((bytearray(b"no error"), 0, None))
646 memio.__setstate__((b"no error", 0, {'spam': 3}))
647 self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None))
648 self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None))
649 self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None))
650 self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0))
651 self.assertRaises(TypeError, memio.__setstate__, (b"len-test", 0))
652 self.assertRaises(TypeError, memio.__setstate__)
653 self.assertRaises(TypeError, memio.__setstate__, 0)
654 memio.close()
655 self.assertRaises(ValueError, memio.__setstate__, (b"closed", 0, None))
656
657
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000658class CStringIOTest(PyStringIOTest):
659 ioclass = io.StringIO
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000660 UnsupportedOperation = io.UnsupportedOperation
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000661
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000662 # XXX: For the Python version of io.StringIO, this is highly
663 # dependent on the encoding used for the underlying buffer.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000664 def test_widechar(self):
665 buf = self.buftype("\U0002030a\U00020347")
666 memio = self.ioclass(buf)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000667
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000668 self.assertEqual(memio.getvalue(), buf)
669 self.assertEqual(memio.write(buf), len(buf))
670 self.assertEqual(memio.tell(), len(buf))
671 self.assertEqual(memio.getvalue(), buf)
672 self.assertEqual(memio.write(buf), len(buf))
673 self.assertEqual(memio.tell(), len(buf) * 2)
674 self.assertEqual(memio.getvalue(), buf + buf)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000675
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000676 def test_getstate(self):
677 memio = self.ioclass()
678 state = memio.__getstate__()
679 self.assertEqual(len(state), 4)
Ezio Melottie9615932010-01-24 19:26:24 +0000680 self.assertIsInstance(state[0], str)
681 self.assertIsInstance(state[1], str)
682 self.assertIsInstance(state[2], int)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000683 self.assert_(isinstance(state[3], dict) or state[3] is None)
684 memio.close()
685 self.assertRaises(ValueError, memio.__getstate__)
686
687 def test_setstate(self):
688 # This checks whether __setstate__ does proper input validation.
689 memio = self.ioclass()
690 memio.__setstate__(("no error", "\n", 0, None))
691 memio.__setstate__(("no error", "", 0, {'spam': 3}))
692 self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None))
693 self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None))
694 self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None))
695 self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None))
696 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None))
697 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0))
698 self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0))
699 self.assertRaises(TypeError, memio.__setstate__)
700 self.assertRaises(TypeError, memio.__setstate__, 0)
701 memio.close()
702 self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None))
703
704
705class CStringIOPickleTest(PyStringIOPickleTest):
706 UnsupportedOperation = io.UnsupportedOperation
707
708 class ioclass(io.StringIO):
709 def __new__(cls, *args, **kwargs):
710 return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs)))
711 def __init__(self, *args, **kwargs):
712 pass
713
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000714
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000715def test_main():
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000716 tests = [PyBytesIOTest, PyStringIOTest, CBytesIOTest, CStringIOTest,
717 PyStringIOPickleTest, CStringIOPickleTest]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000718 support.run_unittest(*tests)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000719
720if __name__ == '__main__':
721 test_main()