blob: 6ab83282fef28696c0c7162415b6510f9b575e97 [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
Alexandre Vassalottiba5c7432009-08-04 23:19:13 +0000464 def test_issue5449(self):
465 buf = self.buftype("1234567890")
466 self.ioclass(initial_bytes=buf)
467 self.assertRaises(TypeError, self.ioclass, buf, foo=None)
468
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000469
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000470class TextIOTestMixin:
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000471
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000472 def test_relative_seek(self):
473 memio = self.ioclass()
474
475 self.assertRaises(IOError, memio.seek, -1, 1)
476 self.assertRaises(IOError, memio.seek, 3, 1)
477 self.assertRaises(IOError, memio.seek, -3, 1)
478 self.assertRaises(IOError, memio.seek, -1, 2)
479 self.assertRaises(IOError, memio.seek, 1, 1)
480 self.assertRaises(IOError, memio.seek, 1, 2)
481
482 def test_textio_properties(self):
483 memio = self.ioclass()
484
485 # These are just dummy values but we nevertheless check them for fear
486 # of unexpected breakage.
487 self.assertTrue(memio.encoding is None)
488 self.assertEqual(memio.errors, "strict")
489 self.assertEqual(memio.line_buffering, False)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000490
491 def test_newlines_property(self):
492 memio = self.ioclass(newline=None)
493 # The C StringIO decodes newlines in write() calls, but the Python
494 # implementation only does when reading. This function forces them to
495 # be decoded for testing.
496 def force_decode():
497 memio.seek(0)
498 memio.read()
499 self.assertEqual(memio.newlines, None)
500 memio.write("a\n")
501 force_decode()
502 self.assertEqual(memio.newlines, "\n")
503 memio.write("b\r\n")
504 force_decode()
505 self.assertEqual(memio.newlines, ("\n", "\r\n"))
506 memio.write("c\rd")
507 force_decode()
508 self.assertEqual(memio.newlines, ("\r", "\n", "\r\n"))
509
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000510 def test_relative_seek(self):
511 memio = self.ioclass()
512
513 self.assertRaises(IOError, memio.seek, -1, 1)
514 self.assertRaises(IOError, memio.seek, 3, 1)
515 self.assertRaises(IOError, memio.seek, -3, 1)
516 self.assertRaises(IOError, memio.seek, -1, 2)
517 self.assertRaises(IOError, memio.seek, 1, 1)
518 self.assertRaises(IOError, memio.seek, 1, 2)
519
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000520 def test_textio_properties(self):
521 memio = self.ioclass()
522
523 # These are just dummy values but we nevertheless check them for fear
524 # of unexpected breakage.
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000525 self.assertIsNone(memio.encoding)
526 self.assertIsNone(memio.errors)
527 self.assertFalse(memio.line_buffering)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000528
529 def test_newline_none(self):
530 # newline=None
531 memio = self.ioclass("a\nb\r\nc\rd", newline=None)
532 self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"])
533 memio.seek(0)
534 self.assertEqual(memio.read(1), "a")
535 self.assertEqual(memio.read(2), "\nb")
536 self.assertEqual(memio.read(2), "\nc")
537 self.assertEqual(memio.read(1), "\n")
538 memio = self.ioclass(newline=None)
539 self.assertEqual(2, memio.write("a\n"))
540 self.assertEqual(3, memio.write("b\r\n"))
541 self.assertEqual(3, memio.write("c\rd"))
542 memio.seek(0)
543 self.assertEqual(memio.read(), "a\nb\nc\nd")
544 memio = self.ioclass("a\r\nb", newline=None)
545 self.assertEqual(memio.read(3), "a\nb")
546
547 def test_newline_empty(self):
548 # newline=""
549 memio = self.ioclass("a\nb\r\nc\rd", newline="")
550 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
551 memio.seek(0)
552 self.assertEqual(memio.read(4), "a\nb\r")
553 self.assertEqual(memio.read(2), "\nc")
554 self.assertEqual(memio.read(1), "\r")
555 memio = self.ioclass(newline="")
556 self.assertEqual(2, memio.write("a\n"))
557 self.assertEqual(2, memio.write("b\r"))
558 self.assertEqual(2, memio.write("\nc"))
559 self.assertEqual(2, memio.write("\rd"))
560 memio.seek(0)
561 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
562
563 def test_newline_lf(self):
564 # newline="\n"
565 memio = self.ioclass("a\nb\r\nc\rd")
566 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
567
568 def test_newline_cr(self):
569 # newline="\r"
570 memio = self.ioclass("a\nb\r\nc\rd", newline="\r")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000571 self.assertEqual(memio.read(), "a\rb\r\rc\rd")
572 memio.seek(0)
573 self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
574
575 def test_newline_crlf(self):
576 # newline="\r\n"
577 memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000578 self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd")
579 memio.seek(0)
580 self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
581
582 def test_issue5265(self):
583 # StringIO can duplicate newlines in universal newlines mode
584 memio = self.ioclass("a\r\nb\r\n", newline=None)
585 self.assertEqual(memio.read(5), "a\nb\n")
586
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000587 def test_newline_argument(self):
588 self.assertRaises(TypeError, self.ioclass, newline=b"\n")
589 self.assertRaises(ValueError, self.ioclass, newline="error")
590 # These should not raise an error
591 for newline in (None, "", "\n", "\r", "\r\n"):
592 self.ioclass(newline=newline)
593
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000594
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000595class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin,
596 TextIOTestMixin, unittest.TestCase):
597 buftype = str
598 ioclass = pyio.StringIO
599 UnsupportedOperation = pyio.UnsupportedOperation
600 EOF = ""
601
602
603class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase):
604 """Test if pickle restores properly the internal state of StringIO.
605 """
606 buftype = str
607 UnsupportedOperation = pyio.UnsupportedOperation
608 EOF = ""
609
610 class ioclass(pyio.StringIO):
611 def __new__(cls, *args, **kwargs):
612 return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs)))
613 def __init__(self, *args, **kwargs):
614 pass
615
616
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000617class CBytesIOTest(PyBytesIOTest):
618 ioclass = io.BytesIO
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000619 UnsupportedOperation = io.UnsupportedOperation
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000621 def test_getstate(self):
622 memio = self.ioclass()
623 state = memio.__getstate__()
624 self.assertEqual(len(state), 3)
625 bytearray(state[0]) # Check if state[0] supports the buffer interface.
626 self.assert_(isinstance(state[1], int))
627 self.assert_(isinstance(state[2], dict) or state[2] is None)
628 memio.close()
629 self.assertRaises(ValueError, memio.__getstate__)
630
631 def test_setstate(self):
632 # This checks whether __setstate__ does proper input validation.
633 memio = self.ioclass()
634 memio.__setstate__((b"no error", 0, None))
635 memio.__setstate__((bytearray(b"no error"), 0, None))
636 memio.__setstate__((b"no error", 0, {'spam': 3}))
637 self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None))
638 self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None))
639 self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None))
640 self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0))
641 self.assertRaises(TypeError, memio.__setstate__, (b"len-test", 0))
642 self.assertRaises(TypeError, memio.__setstate__)
643 self.assertRaises(TypeError, memio.__setstate__, 0)
644 memio.close()
645 self.assertRaises(ValueError, memio.__setstate__, (b"closed", 0, None))
646
647
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648class CStringIOTest(PyStringIOTest):
649 ioclass = io.StringIO
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000650 UnsupportedOperation = io.UnsupportedOperation
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000652 # XXX: For the Python version of io.StringIO, this is highly
653 # dependent on the encoding used for the underlying buffer.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000654 def test_widechar(self):
655 buf = self.buftype("\U0002030a\U00020347")
656 memio = self.ioclass(buf)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000657
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000658 self.assertEqual(memio.getvalue(), buf)
659 self.assertEqual(memio.write(buf), len(buf))
660 self.assertEqual(memio.tell(), len(buf))
661 self.assertEqual(memio.getvalue(), buf)
662 self.assertEqual(memio.write(buf), len(buf))
663 self.assertEqual(memio.tell(), len(buf) * 2)
664 self.assertEqual(memio.getvalue(), buf + buf)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000665
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000666 def test_getstate(self):
667 memio = self.ioclass()
668 state = memio.__getstate__()
669 self.assertEqual(len(state), 4)
670 self.assert_(isinstance(state[0], str))
671 self.assert_(isinstance(state[1], str))
672 self.assert_(isinstance(state[2], int))
673 self.assert_(isinstance(state[3], dict) or state[3] is None)
674 memio.close()
675 self.assertRaises(ValueError, memio.__getstate__)
676
677 def test_setstate(self):
678 # This checks whether __setstate__ does proper input validation.
679 memio = self.ioclass()
680 memio.__setstate__(("no error", "\n", 0, None))
681 memio.__setstate__(("no error", "", 0, {'spam': 3}))
682 self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None))
683 self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None))
684 self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None))
685 self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None))
686 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None))
687 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0))
688 self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0))
689 self.assertRaises(TypeError, memio.__setstate__)
690 self.assertRaises(TypeError, memio.__setstate__, 0)
691 memio.close()
692 self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None))
693
694
695class CStringIOPickleTest(PyStringIOPickleTest):
696 UnsupportedOperation = io.UnsupportedOperation
697
698 class ioclass(io.StringIO):
699 def __new__(cls, *args, **kwargs):
700 return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs)))
701 def __init__(self, *args, **kwargs):
702 pass
703
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000704
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000705def test_main():
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000706 tests = [PyBytesIOTest, PyStringIOTest, CBytesIOTest, CStringIOTest,
707 PyStringIOPickleTest, CStringIOPickleTest]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000708 support.run_unittest(*tests)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000709
710if __name__ == '__main__':
711 test_main()