blob: e5db94566fa94ba93554c4267386155379cef193 [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
Ezio Melottib3aedd42010-11-20 19:04:17 +000023 self.assertEqual(buf[:1], bytesIo.read(1))
24 self.assertEqual(buf[1:5], bytesIo.read(4))
25 self.assertEqual(buf[5:], bytesIo.read(900))
26 self.assertEqual(self.EOF, bytesIo.read())
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000027
28 def testReadNoArgs(self):
29 buf = self.buftype("1234567890")
30 bytesIo = self.ioclass(buf)
31
Ezio Melottib3aedd42010-11-20 19:04:17 +000032 self.assertEqual(buf, bytesIo.read())
33 self.assertEqual(self.EOF, bytesIo.read())
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000034
35 def testSeek(self):
36 buf = self.buftype("1234567890")
37 bytesIo = self.ioclass(buf)
38
39 bytesIo.read(5)
40 bytesIo.seek(0)
Ezio Melottib3aedd42010-11-20 19:04:17 +000041 self.assertEqual(buf, bytesIo.read())
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000042
43 bytesIo.seek(3)
Ezio Melottib3aedd42010-11-20 19:04:17 +000044 self.assertEqual(buf[3:], bytesIo.read())
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000045 self.assertRaises(TypeError, bytesIo.seek, 0.0)
46
47 def testTell(self):
48 buf = self.buftype("1234567890")
49 bytesIo = self.ioclass(buf)
50
Ezio Melottib3aedd42010-11-20 19:04:17 +000051 self.assertEqual(0, bytesIo.tell())
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000052 bytesIo.seek(5)
Ezio Melottib3aedd42010-11-20 19:04:17 +000053 self.assertEqual(5, bytesIo.tell())
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000054 bytesIo.seek(10000)
Ezio Melottib3aedd42010-11-20 19:04:17 +000055 self.assertEqual(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()
Antoine Pitrou1d857452012-09-05 20:11:49 +0200321 self.assertRaises(ValueError, memio.writable)
322 self.assertRaises(ValueError, memio.readable)
323 self.assertRaises(ValueError, memio.seekable)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000324 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)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000637 self.assertTrue(isinstance(state[2], dict) or state[2] is None)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000638 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
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200657 check_sizeof = support.check_sizeof
658
659 @support.cpython_only
660 def test_sizeof(self):
Antoine Pitrou754d5ef2012-07-30 13:58:42 +0200661 basesize = support.calcobjsize('P2nN2Pn')
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200662 check = self.check_sizeof
663 self.assertEqual(object.__sizeof__(io.BytesIO()), basesize)
664 check(io.BytesIO(), basesize )
665 check(io.BytesIO(b'a'), basesize + 1 + 1 )
666 check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 )
667
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000668class CStringIOTest(PyStringIOTest):
669 ioclass = io.StringIO
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000670 UnsupportedOperation = io.UnsupportedOperation
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000671
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000672 # XXX: For the Python version of io.StringIO, this is highly
673 # dependent on the encoding used for the underlying buffer.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000674 def test_widechar(self):
675 buf = self.buftype("\U0002030a\U00020347")
676 memio = self.ioclass(buf)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000677
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678 self.assertEqual(memio.getvalue(), buf)
679 self.assertEqual(memio.write(buf), len(buf))
680 self.assertEqual(memio.tell(), len(buf))
681 self.assertEqual(memio.getvalue(), buf)
682 self.assertEqual(memio.write(buf), len(buf))
683 self.assertEqual(memio.tell(), len(buf) * 2)
684 self.assertEqual(memio.getvalue(), buf + buf)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000685
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000686 def test_getstate(self):
687 memio = self.ioclass()
688 state = memio.__getstate__()
689 self.assertEqual(len(state), 4)
Ezio Melottie9615932010-01-24 19:26:24 +0000690 self.assertIsInstance(state[0], str)
691 self.assertIsInstance(state[1], str)
692 self.assertIsInstance(state[2], int)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000693 self.assertTrue(isinstance(state[3], dict) or state[3] is None)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000694 memio.close()
695 self.assertRaises(ValueError, memio.__getstate__)
696
697 def test_setstate(self):
698 # This checks whether __setstate__ does proper input validation.
699 memio = self.ioclass()
700 memio.__setstate__(("no error", "\n", 0, None))
701 memio.__setstate__(("no error", "", 0, {'spam': 3}))
702 self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None))
703 self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None))
704 self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None))
705 self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None))
706 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None))
707 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0))
708 self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0))
709 self.assertRaises(TypeError, memio.__setstate__)
710 self.assertRaises(TypeError, memio.__setstate__, 0)
711 memio.close()
712 self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None))
713
714
715class CStringIOPickleTest(PyStringIOPickleTest):
716 UnsupportedOperation = io.UnsupportedOperation
717
718 class ioclass(io.StringIO):
719 def __new__(cls, *args, **kwargs):
720 return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs)))
721 def __init__(self, *args, **kwargs):
722 pass
723
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000724
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000725def test_main():
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000726 tests = [PyBytesIOTest, PyStringIOTest, CBytesIOTest, CStringIOTest,
727 PyStringIOPickleTest, CStringIOPickleTest]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000728 support.run_unittest(*tests)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000729
730if __name__ == '__main__':
731 test_main()