blob: 7dd1658ca476aa85650eb953b6de07d06a53a601 [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 Vassalotti1bfe9dc82008-05-07 01:44:31 +000011import sys
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +000012import pickle
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000013
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000014class MemorySeekTestMixin:
15
16 def testInit(self):
17 buf = self.buftype("1234567890")
18 bytesIo = self.ioclass(buf)
19
20 def testRead(self):
21 buf = self.buftype("1234567890")
22 bytesIo = self.ioclass(buf)
23
24 self.assertEquals(buf[:1], bytesIo.read(1))
25 self.assertEquals(buf[1:5], bytesIo.read(4))
26 self.assertEquals(buf[5:], bytesIo.read(900))
27 self.assertEquals(self.EOF, bytesIo.read())
28
29 def testReadNoArgs(self):
30 buf = self.buftype("1234567890")
31 bytesIo = self.ioclass(buf)
32
33 self.assertEquals(buf, bytesIo.read())
34 self.assertEquals(self.EOF, bytesIo.read())
35
36 def testSeek(self):
37 buf = self.buftype("1234567890")
38 bytesIo = self.ioclass(buf)
39
40 bytesIo.read(5)
41 bytesIo.seek(0)
42 self.assertEquals(buf, bytesIo.read())
43
44 bytesIo.seek(3)
45 self.assertEquals(buf[3:], bytesIo.read())
46 self.assertRaises(TypeError, bytesIo.seek, 0.0)
47
48 def testTell(self):
49 buf = self.buftype("1234567890")
50 bytesIo = self.ioclass(buf)
51
52 self.assertEquals(0, bytesIo.tell())
53 bytesIo.seek(5)
54 self.assertEquals(5, bytesIo.tell())
55 bytesIo.seek(10000)
56 self.assertEquals(10000, bytesIo.tell())
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000057
58
59class MemoryTestMixin:
60
Benjamin Petersond2e0c792009-05-01 20:40:59 +000061 def test_detach(self):
62 buf = self.ioclass()
63 self.assertRaises(self.UnsupportedOperation, buf.detach)
64
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000065 def write_ops(self, f, t):
66 self.assertEqual(f.write(t("blah.")), 5)
67 self.assertEqual(f.seek(0), 0)
68 self.assertEqual(f.write(t("Hello.")), 6)
69 self.assertEqual(f.tell(), 6)
70 self.assertEqual(f.seek(5), 5)
71 self.assertEqual(f.tell(), 5)
72 self.assertEqual(f.write(t(" world\n\n\n")), 9)
73 self.assertEqual(f.seek(0), 0)
74 self.assertEqual(f.write(t("h")), 1)
75 self.assertEqual(f.truncate(12), 12)
76 self.assertEqual(f.tell(), 12)
77
78 def test_write(self):
79 buf = self.buftype("hello world\n")
80 memio = self.ioclass(buf)
81
82 self.write_ops(memio, self.buftype)
83 self.assertEqual(memio.getvalue(), buf)
84 memio = self.ioclass()
85 self.write_ops(memio, self.buftype)
86 self.assertEqual(memio.getvalue(), buf)
87 self.assertRaises(TypeError, memio.write, None)
88 memio.close()
89 self.assertRaises(ValueError, memio.write, self.buftype(""))
90
91 def test_writelines(self):
92 buf = self.buftype("1234567890")
93 memio = self.ioclass()
94
95 self.assertEqual(memio.writelines([buf] * 100), None)
96 self.assertEqual(memio.getvalue(), buf * 100)
97 memio.writelines([])
98 self.assertEqual(memio.getvalue(), buf * 100)
99 memio = self.ioclass()
100 self.assertRaises(TypeError, memio.writelines, [buf] + [1])
101 self.assertEqual(memio.getvalue(), buf)
102 self.assertRaises(TypeError, memio.writelines, None)
103 memio.close()
104 self.assertRaises(ValueError, memio.writelines, [])
105
106 def test_writelines_error(self):
107 memio = self.ioclass()
108 def error_gen():
109 yield self.buftype('spam')
110 raise KeyboardInterrupt
111
112 self.assertRaises(KeyboardInterrupt, memio.writelines, error_gen())
113
114 def test_truncate(self):
115 buf = self.buftype("1234567890")
116 memio = self.ioclass(buf)
117
118 self.assertRaises(ValueError, memio.truncate, -1)
119 memio.seek(6)
120 self.assertEqual(memio.truncate(), 6)
121 self.assertEqual(memio.getvalue(), buf[:6])
122 self.assertEqual(memio.truncate(4), 4)
123 self.assertEqual(memio.getvalue(), buf[:4])
124 self.assertEqual(memio.tell(), 4)
125 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
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000387class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase):
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000388
389 UnsupportedOperation = pyio.UnsupportedOperation
390
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000391 @staticmethod
392 def buftype(s):
393 return s.encode("ascii")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000394 ioclass = pyio.BytesIO
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000395 EOF = b""
396
397 def test_read1(self):
398 buf = self.buftype("1234567890")
399 memio = self.ioclass(buf)
400
401 self.assertRaises(TypeError, memio.read1)
402 self.assertEqual(memio.read(), buf)
403
404 def test_readinto(self):
405 buf = self.buftype("1234567890")
406 memio = self.ioclass(buf)
407
408 b = bytearray(b"hello")
409 self.assertEqual(memio.readinto(b), 5)
410 self.assertEqual(b, b"12345")
411 self.assertEqual(memio.readinto(b), 5)
412 self.assertEqual(b, b"67890")
413 self.assertEqual(memio.readinto(b), 0)
414 self.assertEqual(b, b"67890")
415 b = bytearray(b"hello world")
416 memio.seek(0)
417 self.assertEqual(memio.readinto(b), 10)
418 self.assertEqual(b, b"1234567890d")
419 b = bytearray(b"")
420 memio.seek(0)
421 self.assertEqual(memio.readinto(b), 0)
422 self.assertEqual(b, b"")
423 self.assertRaises(TypeError, memio.readinto, '')
424 import array
425 a = array.array('b', b"hello world")
426 memio = self.ioclass(buf)
427 memio.readinto(a)
428 self.assertEqual(a.tostring(), b"1234567890d")
429 memio.close()
430 self.assertRaises(ValueError, memio.readinto, b)
431
432 def test_relative_seek(self):
433 buf = self.buftype("1234567890")
434 memio = self.ioclass(buf)
435
436 self.assertEqual(memio.seek(-1, 1), 0)
437 self.assertEqual(memio.seek(3, 1), 3)
438 self.assertEqual(memio.seek(-4, 1), 0)
439 self.assertEqual(memio.seek(-1, 2), 9)
440 self.assertEqual(memio.seek(1, 1), 10)
441 self.assertEqual(memio.seek(1, 2), 11)
442 memio.seek(-3, 2)
443 self.assertEqual(memio.read(), buf[-3:])
444 memio.seek(0)
445 memio.seek(1, 1)
446 self.assertEqual(memio.read(), buf[1:])
447
448 def test_unicode(self):
449 memio = self.ioclass()
450
451 self.assertRaises(TypeError, self.ioclass, "1234567890")
452 self.assertRaises(TypeError, memio.write, "1234567890")
453 self.assertRaises(TypeError, memio.writelines, ["1234567890"])
454
455 def test_bytes_array(self):
456 buf = b"1234567890"
457 import array
458 a = array.array('b', list(buf))
459 memio = self.ioclass(a)
460 self.assertEqual(memio.getvalue(), buf)
461 self.assertEqual(memio.write(a), 10)
462 self.assertEqual(memio.getvalue(), buf)
463
464
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000465class TextIOTestMixin:
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000466
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000467 def test_relative_seek(self):
468 memio = self.ioclass()
469
470 self.assertRaises(IOError, memio.seek, -1, 1)
471 self.assertRaises(IOError, memio.seek, 3, 1)
472 self.assertRaises(IOError, memio.seek, -3, 1)
473 self.assertRaises(IOError, memio.seek, -1, 2)
474 self.assertRaises(IOError, memio.seek, 1, 1)
475 self.assertRaises(IOError, memio.seek, 1, 2)
476
477 def test_textio_properties(self):
478 memio = self.ioclass()
479
480 # These are just dummy values but we nevertheless check them for fear
481 # of unexpected breakage.
482 self.assertTrue(memio.encoding is None)
483 self.assertEqual(memio.errors, "strict")
484 self.assertEqual(memio.line_buffering, False)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000485
486 def test_newlines_property(self):
487 memio = self.ioclass(newline=None)
488 # The C StringIO decodes newlines in write() calls, but the Python
489 # implementation only does when reading. This function forces them to
490 # be decoded for testing.
491 def force_decode():
492 memio.seek(0)
493 memio.read()
494 self.assertEqual(memio.newlines, None)
495 memio.write("a\n")
496 force_decode()
497 self.assertEqual(memio.newlines, "\n")
498 memio.write("b\r\n")
499 force_decode()
500 self.assertEqual(memio.newlines, ("\n", "\r\n"))
501 memio.write("c\rd")
502 force_decode()
503 self.assertEqual(memio.newlines, ("\r", "\n", "\r\n"))
504
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000505 def test_relative_seek(self):
506 memio = self.ioclass()
507
508 self.assertRaises(IOError, memio.seek, -1, 1)
509 self.assertRaises(IOError, memio.seek, 3, 1)
510 self.assertRaises(IOError, memio.seek, -3, 1)
511 self.assertRaises(IOError, memio.seek, -1, 2)
512 self.assertRaises(IOError, memio.seek, 1, 1)
513 self.assertRaises(IOError, memio.seek, 1, 2)
514
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000515 def test_textio_properties(self):
516 memio = self.ioclass()
517
518 # These are just dummy values but we nevertheless check them for fear
519 # of unexpected breakage.
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000520 self.assertIsNone(memio.encoding)
521 self.assertIsNone(memio.errors)
522 self.assertFalse(memio.line_buffering)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000523
524 def test_newline_none(self):
525 # newline=None
526 memio = self.ioclass("a\nb\r\nc\rd", newline=None)
527 self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"])
528 memio.seek(0)
529 self.assertEqual(memio.read(1), "a")
530 self.assertEqual(memio.read(2), "\nb")
531 self.assertEqual(memio.read(2), "\nc")
532 self.assertEqual(memio.read(1), "\n")
533 memio = self.ioclass(newline=None)
534 self.assertEqual(2, memio.write("a\n"))
535 self.assertEqual(3, memio.write("b\r\n"))
536 self.assertEqual(3, memio.write("c\rd"))
537 memio.seek(0)
538 self.assertEqual(memio.read(), "a\nb\nc\nd")
539 memio = self.ioclass("a\r\nb", newline=None)
540 self.assertEqual(memio.read(3), "a\nb")
541
542 def test_newline_empty(self):
543 # newline=""
544 memio = self.ioclass("a\nb\r\nc\rd", newline="")
545 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
546 memio.seek(0)
547 self.assertEqual(memio.read(4), "a\nb\r")
548 self.assertEqual(memio.read(2), "\nc")
549 self.assertEqual(memio.read(1), "\r")
550 memio = self.ioclass(newline="")
551 self.assertEqual(2, memio.write("a\n"))
552 self.assertEqual(2, memio.write("b\r"))
553 self.assertEqual(2, memio.write("\nc"))
554 self.assertEqual(2, memio.write("\rd"))
555 memio.seek(0)
556 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
557
558 def test_newline_lf(self):
559 # newline="\n"
560 memio = self.ioclass("a\nb\r\nc\rd")
561 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
562
563 def test_newline_cr(self):
564 # newline="\r"
565 memio = self.ioclass("a\nb\r\nc\rd", newline="\r")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000566 self.assertEqual(memio.read(), "a\rb\r\rc\rd")
567 memio.seek(0)
568 self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
569
570 def test_newline_crlf(self):
571 # newline="\r\n"
572 memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000573 self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd")
574 memio.seek(0)
575 self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
576
577 def test_issue5265(self):
578 # StringIO can duplicate newlines in universal newlines mode
579 memio = self.ioclass("a\r\nb\r\n", newline=None)
580 self.assertEqual(memio.read(5), "a\nb\n")
581
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000582 def test_newline_argument(self):
583 self.assertRaises(TypeError, self.ioclass, newline=b"\n")
584 self.assertRaises(ValueError, self.ioclass, newline="error")
585 # These should not raise an error
586 for newline in (None, "", "\n", "\r", "\r\n"):
587 self.ioclass(newline=newline)
588
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000589
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000590class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin,
591 TextIOTestMixin, unittest.TestCase):
592 buftype = str
593 ioclass = pyio.StringIO
594 UnsupportedOperation = pyio.UnsupportedOperation
595 EOF = ""
596
597
598class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase):
599 """Test if pickle restores properly the internal state of StringIO.
600 """
601 buftype = str
602 UnsupportedOperation = pyio.UnsupportedOperation
603 EOF = ""
604
605 class ioclass(pyio.StringIO):
606 def __new__(cls, *args, **kwargs):
607 return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs)))
608 def __init__(self, *args, **kwargs):
609 pass
610
611
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000612class CBytesIOTest(PyBytesIOTest):
613 ioclass = io.BytesIO
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000614 UnsupportedOperation = io.UnsupportedOperation
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000615
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000616 def test_getstate(self):
617 memio = self.ioclass()
618 state = memio.__getstate__()
619 self.assertEqual(len(state), 3)
620 bytearray(state[0]) # Check if state[0] supports the buffer interface.
621 self.assert_(isinstance(state[1], int))
622 self.assert_(isinstance(state[2], dict) or state[2] is None)
623 memio.close()
624 self.assertRaises(ValueError, memio.__getstate__)
625
626 def test_setstate(self):
627 # This checks whether __setstate__ does proper input validation.
628 memio = self.ioclass()
629 memio.__setstate__((b"no error", 0, None))
630 memio.__setstate__((bytearray(b"no error"), 0, None))
631 memio.__setstate__((b"no error", 0, {'spam': 3}))
632 self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None))
633 self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None))
634 self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None))
635 self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0))
636 self.assertRaises(TypeError, memio.__setstate__, (b"len-test", 0))
637 self.assertRaises(TypeError, memio.__setstate__)
638 self.assertRaises(TypeError, memio.__setstate__, 0)
639 memio.close()
640 self.assertRaises(ValueError, memio.__setstate__, (b"closed", 0, None))
641
642
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000643class CStringIOTest(PyStringIOTest):
644 ioclass = io.StringIO
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000645 UnsupportedOperation = io.UnsupportedOperation
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000646
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000647 # XXX: For the Python version of io.StringIO, this is highly
648 # dependent on the encoding used for the underlying buffer.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000649 def test_widechar(self):
650 buf = self.buftype("\U0002030a\U00020347")
651 memio = self.ioclass(buf)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000652
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653 self.assertEqual(memio.getvalue(), buf)
654 self.assertEqual(memio.write(buf), len(buf))
655 self.assertEqual(memio.tell(), len(buf))
656 self.assertEqual(memio.getvalue(), buf)
657 self.assertEqual(memio.write(buf), len(buf))
658 self.assertEqual(memio.tell(), len(buf) * 2)
659 self.assertEqual(memio.getvalue(), buf + buf)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000660
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000661 def test_getstate(self):
662 memio = self.ioclass()
663 state = memio.__getstate__()
664 self.assertEqual(len(state), 4)
665 self.assert_(isinstance(state[0], str))
666 self.assert_(isinstance(state[1], str))
667 self.assert_(isinstance(state[2], int))
668 self.assert_(isinstance(state[3], dict) or state[3] is None)
669 memio.close()
670 self.assertRaises(ValueError, memio.__getstate__)
671
672 def test_setstate(self):
673 # This checks whether __setstate__ does proper input validation.
674 memio = self.ioclass()
675 memio.__setstate__(("no error", "\n", 0, None))
676 memio.__setstate__(("no error", "", 0, {'spam': 3}))
677 self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None))
678 self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None))
679 self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None))
680 self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None))
681 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None))
682 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0))
683 self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0))
684 self.assertRaises(TypeError, memio.__setstate__)
685 self.assertRaises(TypeError, memio.__setstate__, 0)
686 memio.close()
687 self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None))
688
689
690class CStringIOPickleTest(PyStringIOPickleTest):
691 UnsupportedOperation = io.UnsupportedOperation
692
693 class ioclass(io.StringIO):
694 def __new__(cls, *args, **kwargs):
695 return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs)))
696 def __init__(self, *args, **kwargs):
697 pass
698
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000699
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000700def test_main():
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000701 tests = [PyBytesIOTest, PyStringIOTest, CBytesIOTest, CStringIOTest,
702 PyStringIOPickleTest, CStringIOPickleTest]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000703 support.run_unittest(*tests)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000704
705if __name__ == '__main__':
706 test_main()