blob: dcf6d51575cfad1daba667be6f63c852cc53b027 [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)
455
456 def test_relative_seek(self):
457 buf = self.buftype("1234567890")
458 memio = self.ioclass(buf)
459
460 self.assertEqual(memio.seek(-1, 1), 0)
461 self.assertEqual(memio.seek(3, 1), 3)
462 self.assertEqual(memio.seek(-4, 1), 0)
463 self.assertEqual(memio.seek(-1, 2), 9)
464 self.assertEqual(memio.seek(1, 1), 10)
465 self.assertEqual(memio.seek(1, 2), 11)
466 memio.seek(-3, 2)
467 self.assertEqual(memio.read(), buf[-3:])
468 memio.seek(0)
469 memio.seek(1, 1)
470 self.assertEqual(memio.read(), buf[1:])
471
472 def test_unicode(self):
473 memio = self.ioclass()
474
475 self.assertRaises(TypeError, self.ioclass, "1234567890")
476 self.assertRaises(TypeError, memio.write, "1234567890")
477 self.assertRaises(TypeError, memio.writelines, ["1234567890"])
478
479 def test_bytes_array(self):
480 buf = b"1234567890"
481 import array
482 a = array.array('b', list(buf))
483 memio = self.ioclass(a)
484 self.assertEqual(memio.getvalue(), buf)
485 self.assertEqual(memio.write(a), 10)
486 self.assertEqual(memio.getvalue(), buf)
487
Alexandre Vassalottiba5c7432009-08-04 23:19:13 +0000488 def test_issue5449(self):
489 buf = self.buftype("1234567890")
490 self.ioclass(initial_bytes=buf)
491 self.assertRaises(TypeError, self.ioclass, buf, foo=None)
492
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000493
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000494class TextIOTestMixin:
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000495
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000496 def test_newlines_property(self):
497 memio = self.ioclass(newline=None)
498 # The C StringIO decodes newlines in write() calls, but the Python
499 # implementation only does when reading. This function forces them to
500 # be decoded for testing.
501 def force_decode():
502 memio.seek(0)
503 memio.read()
504 self.assertEqual(memio.newlines, None)
505 memio.write("a\n")
506 force_decode()
507 self.assertEqual(memio.newlines, "\n")
508 memio.write("b\r\n")
509 force_decode()
510 self.assertEqual(memio.newlines, ("\n", "\r\n"))
511 memio.write("c\rd")
512 force_decode()
513 self.assertEqual(memio.newlines, ("\r", "\n", "\r\n"))
514
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000515 def test_relative_seek(self):
516 memio = self.ioclass()
517
518 self.assertRaises(IOError, memio.seek, -1, 1)
519 self.assertRaises(IOError, memio.seek, 3, 1)
520 self.assertRaises(IOError, memio.seek, -3, 1)
521 self.assertRaises(IOError, memio.seek, -1, 2)
522 self.assertRaises(IOError, memio.seek, 1, 1)
523 self.assertRaises(IOError, memio.seek, 1, 2)
524
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000525 def test_textio_properties(self):
526 memio = self.ioclass()
527
528 # These are just dummy values but we nevertheless check them for fear
529 # of unexpected breakage.
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000530 self.assertIsNone(memio.encoding)
531 self.assertIsNone(memio.errors)
532 self.assertFalse(memio.line_buffering)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000533
534 def test_newline_none(self):
535 # newline=None
536 memio = self.ioclass("a\nb\r\nc\rd", newline=None)
537 self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"])
538 memio.seek(0)
539 self.assertEqual(memio.read(1), "a")
540 self.assertEqual(memio.read(2), "\nb")
541 self.assertEqual(memio.read(2), "\nc")
542 self.assertEqual(memio.read(1), "\n")
543 memio = self.ioclass(newline=None)
544 self.assertEqual(2, memio.write("a\n"))
545 self.assertEqual(3, memio.write("b\r\n"))
546 self.assertEqual(3, memio.write("c\rd"))
547 memio.seek(0)
548 self.assertEqual(memio.read(), "a\nb\nc\nd")
549 memio = self.ioclass("a\r\nb", newline=None)
550 self.assertEqual(memio.read(3), "a\nb")
551
552 def test_newline_empty(self):
553 # newline=""
554 memio = self.ioclass("a\nb\r\nc\rd", newline="")
555 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
556 memio.seek(0)
557 self.assertEqual(memio.read(4), "a\nb\r")
558 self.assertEqual(memio.read(2), "\nc")
559 self.assertEqual(memio.read(1), "\r")
560 memio = self.ioclass(newline="")
561 self.assertEqual(2, memio.write("a\n"))
562 self.assertEqual(2, memio.write("b\r"))
563 self.assertEqual(2, memio.write("\nc"))
564 self.assertEqual(2, memio.write("\rd"))
565 memio.seek(0)
566 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
567
568 def test_newline_lf(self):
569 # newline="\n"
570 memio = self.ioclass("a\nb\r\nc\rd")
571 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
572
573 def test_newline_cr(self):
574 # newline="\r"
575 memio = self.ioclass("a\nb\r\nc\rd", newline="\r")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000576 self.assertEqual(memio.read(), "a\rb\r\rc\rd")
577 memio.seek(0)
578 self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
579
580 def test_newline_crlf(self):
581 # newline="\r\n"
582 memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000583 self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd")
584 memio.seek(0)
585 self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
586
587 def test_issue5265(self):
588 # StringIO can duplicate newlines in universal newlines mode
589 memio = self.ioclass("a\r\nb\r\n", newline=None)
590 self.assertEqual(memio.read(5), "a\nb\n")
591
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000592 def test_newline_argument(self):
593 self.assertRaises(TypeError, self.ioclass, newline=b"\n")
594 self.assertRaises(ValueError, self.ioclass, newline="error")
595 # These should not raise an error
596 for newline in (None, "", "\n", "\r", "\r\n"):
597 self.ioclass(newline=newline)
598
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000600class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin,
601 TextIOTestMixin, unittest.TestCase):
602 buftype = str
603 ioclass = pyio.StringIO
604 UnsupportedOperation = pyio.UnsupportedOperation
605 EOF = ""
606
607
608class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase):
609 """Test if pickle restores properly the internal state of StringIO.
610 """
611 buftype = str
612 UnsupportedOperation = pyio.UnsupportedOperation
613 EOF = ""
614
615 class ioclass(pyio.StringIO):
616 def __new__(cls, *args, **kwargs):
617 return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs)))
618 def __init__(self, *args, **kwargs):
619 pass
620
621
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622class CBytesIOTest(PyBytesIOTest):
623 ioclass = io.BytesIO
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000624 UnsupportedOperation = io.UnsupportedOperation
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000625
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000626 def test_getstate(self):
627 memio = self.ioclass()
628 state = memio.__getstate__()
629 self.assertEqual(len(state), 3)
630 bytearray(state[0]) # Check if state[0] supports the buffer interface.
Ezio Melottie9615932010-01-24 19:26:24 +0000631 self.assertIsInstance(state[1], int)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000632 self.assert_(isinstance(state[2], dict) or state[2] is None)
633 memio.close()
634 self.assertRaises(ValueError, memio.__getstate__)
635
636 def test_setstate(self):
637 # This checks whether __setstate__ does proper input validation.
638 memio = self.ioclass()
639 memio.__setstate__((b"no error", 0, None))
640 memio.__setstate__((bytearray(b"no error"), 0, None))
641 memio.__setstate__((b"no error", 0, {'spam': 3}))
642 self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None))
643 self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None))
644 self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None))
645 self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0))
646 self.assertRaises(TypeError, memio.__setstate__, (b"len-test", 0))
647 self.assertRaises(TypeError, memio.__setstate__)
648 self.assertRaises(TypeError, memio.__setstate__, 0)
649 memio.close()
650 self.assertRaises(ValueError, memio.__setstate__, (b"closed", 0, None))
651
652
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653class CStringIOTest(PyStringIOTest):
654 ioclass = io.StringIO
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000655 UnsupportedOperation = io.UnsupportedOperation
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000657 # XXX: For the Python version of io.StringIO, this is highly
658 # dependent on the encoding used for the underlying buffer.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000659 def test_widechar(self):
660 buf = self.buftype("\U0002030a\U00020347")
661 memio = self.ioclass(buf)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000662
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000663 self.assertEqual(memio.getvalue(), buf)
664 self.assertEqual(memio.write(buf), len(buf))
665 self.assertEqual(memio.tell(), len(buf))
666 self.assertEqual(memio.getvalue(), buf)
667 self.assertEqual(memio.write(buf), len(buf))
668 self.assertEqual(memio.tell(), len(buf) * 2)
669 self.assertEqual(memio.getvalue(), buf + buf)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000670
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000671 def test_getstate(self):
672 memio = self.ioclass()
673 state = memio.__getstate__()
674 self.assertEqual(len(state), 4)
Ezio Melottie9615932010-01-24 19:26:24 +0000675 self.assertIsInstance(state[0], str)
676 self.assertIsInstance(state[1], str)
677 self.assertIsInstance(state[2], int)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000678 self.assert_(isinstance(state[3], dict) or state[3] is None)
679 memio.close()
680 self.assertRaises(ValueError, memio.__getstate__)
681
682 def test_setstate(self):
683 # This checks whether __setstate__ does proper input validation.
684 memio = self.ioclass()
685 memio.__setstate__(("no error", "\n", 0, None))
686 memio.__setstate__(("no error", "", 0, {'spam': 3}))
687 self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None))
688 self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None))
689 self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None))
690 self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None))
691 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None))
692 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0))
693 self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0))
694 self.assertRaises(TypeError, memio.__setstate__)
695 self.assertRaises(TypeError, memio.__setstate__, 0)
696 memio.close()
697 self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None))
698
699
700class CStringIOPickleTest(PyStringIOPickleTest):
701 UnsupportedOperation = io.UnsupportedOperation
702
703 class ioclass(io.StringIO):
704 def __new__(cls, *args, **kwargs):
705 return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs)))
706 def __init__(self, *args, **kwargs):
707 pass
708
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000709
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000710def test_main():
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000711 tests = [PyBytesIOTest, PyStringIOTest, CBytesIOTest, CStringIOTest,
712 PyStringIOPickleTest, CStringIOPickleTest]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000713 support.run_unittest(*tests)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000714
715if __name__ == '__main__':
716 test_main()