blob: 7cae8b2965323b64011b6f62c7b5263eacc05c7a [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__'
Serhiy Storchakabad12572014-12-15 14:03:42 +0200369 PickleTestMemIO.__qualname__ = PickleTestMemIO.__name__
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000370 __main__.PickleTestMemIO = PickleTestMemIO
371 submemio = PickleTestMemIO(buf, 80)
372 submemio.seek(2)
373
374 # We only support pickle protocol 2 and onward since we use extended
375 # __reduce__ API of PEP 307 to provide pickling support.
Serhiy Storchakabad12572014-12-15 14:03:42 +0200376 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000377 for obj in (memio, submemio):
378 obj2 = pickle.loads(pickle.dumps(obj, protocol=proto))
379 self.assertEqual(obj.getvalue(), obj2.getvalue())
380 self.assertEqual(obj.__class__, obj2.__class__)
381 self.assertEqual(obj.foo, obj2.foo)
382 self.assertEqual(obj.tell(), obj2.tell())
Alexandre Vassalotti6eea8182013-04-14 00:56:39 -0700383 obj2.close()
384 self.assertRaises(ValueError, pickle.dumps, obj2, proto)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000385 del __main__.PickleTestMemIO
386
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000387
Antoine Pitrou972ee132010-09-06 18:48:21 +0000388class BytesIOMixin:
389
390 def test_getbuffer(self):
391 memio = self.ioclass(b"1234567890")
392 buf = memio.getbuffer()
393 self.assertEqual(bytes(buf), b"1234567890")
394 memio.seek(5)
395 buf = memio.getbuffer()
396 self.assertEqual(bytes(buf), b"1234567890")
397 # Trying to change the size of the BytesIO while a buffer is exported
398 # raises a BufferError.
399 self.assertRaises(BufferError, memio.write, b'x' * 100)
400 self.assertRaises(BufferError, memio.truncate)
401 # Mutating the buffer updates the BytesIO
402 buf[3:6] = b"abc"
403 self.assertEqual(bytes(buf), b"123abc7890")
404 self.assertEqual(memio.getvalue(), b"123abc7890")
405 # After the buffer gets released, we can resize the BytesIO again
406 del buf
407 support.gc_collect()
408 memio.truncate()
409
410
411class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin,
412 BytesIOMixin, unittest.TestCase):
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000413
414 UnsupportedOperation = pyio.UnsupportedOperation
415
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000416 @staticmethod
417 def buftype(s):
418 return s.encode("ascii")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000419 ioclass = pyio.BytesIO
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000420 EOF = b""
421
422 def test_read1(self):
423 buf = self.buftype("1234567890")
424 memio = self.ioclass(buf)
425
426 self.assertRaises(TypeError, memio.read1)
427 self.assertEqual(memio.read(), buf)
428
429 def test_readinto(self):
430 buf = self.buftype("1234567890")
431 memio = self.ioclass(buf)
432
433 b = bytearray(b"hello")
434 self.assertEqual(memio.readinto(b), 5)
435 self.assertEqual(b, b"12345")
436 self.assertEqual(memio.readinto(b), 5)
437 self.assertEqual(b, b"67890")
438 self.assertEqual(memio.readinto(b), 0)
439 self.assertEqual(b, b"67890")
440 b = bytearray(b"hello world")
441 memio.seek(0)
442 self.assertEqual(memio.readinto(b), 10)
443 self.assertEqual(b, b"1234567890d")
444 b = bytearray(b"")
445 memio.seek(0)
446 self.assertEqual(memio.readinto(b), 0)
447 self.assertEqual(b, b"")
448 self.assertRaises(TypeError, memio.readinto, '')
449 import array
450 a = array.array('b', b"hello world")
451 memio = self.ioclass(buf)
452 memio.readinto(a)
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +0000453 self.assertEqual(a.tobytes(), b"1234567890d")
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000454 memio.close()
455 self.assertRaises(ValueError, memio.readinto, b)
Benjamin Petersonfa735552010-11-20 17:24:04 +0000456 memio = self.ioclass(b"123")
457 b = bytearray()
458 memio.seek(42)
459 memio.readinto(b)
460 self.assertEqual(b, b"")
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000461
462 def test_relative_seek(self):
463 buf = self.buftype("1234567890")
464 memio = self.ioclass(buf)
465
466 self.assertEqual(memio.seek(-1, 1), 0)
467 self.assertEqual(memio.seek(3, 1), 3)
468 self.assertEqual(memio.seek(-4, 1), 0)
469 self.assertEqual(memio.seek(-1, 2), 9)
470 self.assertEqual(memio.seek(1, 1), 10)
471 self.assertEqual(memio.seek(1, 2), 11)
472 memio.seek(-3, 2)
473 self.assertEqual(memio.read(), buf[-3:])
474 memio.seek(0)
475 memio.seek(1, 1)
476 self.assertEqual(memio.read(), buf[1:])
477
478 def test_unicode(self):
479 memio = self.ioclass()
480
481 self.assertRaises(TypeError, self.ioclass, "1234567890")
482 self.assertRaises(TypeError, memio.write, "1234567890")
483 self.assertRaises(TypeError, memio.writelines, ["1234567890"])
484
485 def test_bytes_array(self):
486 buf = b"1234567890"
487 import array
488 a = array.array('b', list(buf))
489 memio = self.ioclass(a)
490 self.assertEqual(memio.getvalue(), buf)
491 self.assertEqual(memio.write(a), 10)
492 self.assertEqual(memio.getvalue(), buf)
493
Alexandre Vassalottiba5c7432009-08-04 23:19:13 +0000494 def test_issue5449(self):
495 buf = self.buftype("1234567890")
496 self.ioclass(initial_bytes=buf)
497 self.assertRaises(TypeError, self.ioclass, buf, foo=None)
498
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000499
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000500class TextIOTestMixin:
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000501
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000502 def test_newlines_property(self):
503 memio = self.ioclass(newline=None)
504 # The C StringIO decodes newlines in write() calls, but the Python
505 # implementation only does when reading. This function forces them to
506 # be decoded for testing.
507 def force_decode():
508 memio.seek(0)
509 memio.read()
510 self.assertEqual(memio.newlines, None)
511 memio.write("a\n")
512 force_decode()
513 self.assertEqual(memio.newlines, "\n")
514 memio.write("b\r\n")
515 force_decode()
516 self.assertEqual(memio.newlines, ("\n", "\r\n"))
517 memio.write("c\rd")
518 force_decode()
519 self.assertEqual(memio.newlines, ("\r", "\n", "\r\n"))
520
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000521 def test_relative_seek(self):
522 memio = self.ioclass()
523
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200524 self.assertRaises(OSError, memio.seek, -1, 1)
525 self.assertRaises(OSError, memio.seek, 3, 1)
526 self.assertRaises(OSError, memio.seek, -3, 1)
527 self.assertRaises(OSError, memio.seek, -1, 2)
528 self.assertRaises(OSError, memio.seek, 1, 1)
529 self.assertRaises(OSError, memio.seek, 1, 2)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000530
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000531 def test_textio_properties(self):
532 memio = self.ioclass()
533
534 # These are just dummy values but we nevertheless check them for fear
535 # of unexpected breakage.
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000536 self.assertIsNone(memio.encoding)
537 self.assertIsNone(memio.errors)
538 self.assertFalse(memio.line_buffering)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000539
Serhiy Storchaka1812bd42014-02-05 13:42:01 +0200540 def test_newline_default(self):
541 memio = self.ioclass("a\nb\r\nc\rd")
542 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
543 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
544
545 memio = self.ioclass()
546 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
547 memio.seek(0)
548 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
549 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
550
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000551 def test_newline_none(self):
552 # newline=None
553 memio = self.ioclass("a\nb\r\nc\rd", newline=None)
554 self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"])
555 memio.seek(0)
556 self.assertEqual(memio.read(1), "a")
557 self.assertEqual(memio.read(2), "\nb")
558 self.assertEqual(memio.read(2), "\nc")
559 self.assertEqual(memio.read(1), "\n")
Serhiy Storchaka1812bd42014-02-05 13:42:01 +0200560 self.assertEqual(memio.getvalue(), "a\nb\nc\nd")
561
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562 memio = self.ioclass(newline=None)
563 self.assertEqual(2, memio.write("a\n"))
564 self.assertEqual(3, memio.write("b\r\n"))
565 self.assertEqual(3, memio.write("c\rd"))
566 memio.seek(0)
567 self.assertEqual(memio.read(), "a\nb\nc\nd")
Antoine Pitrou57839a62014-02-02 23:37:29 +0100568 self.assertEqual(memio.getvalue(), "a\nb\nc\nd")
Serhiy Storchaka1812bd42014-02-05 13:42:01 +0200569
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000570 memio = self.ioclass("a\r\nb", newline=None)
571 self.assertEqual(memio.read(3), "a\nb")
572
573 def test_newline_empty(self):
574 # newline=""
575 memio = self.ioclass("a\nb\r\nc\rd", newline="")
576 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
577 memio.seek(0)
578 self.assertEqual(memio.read(4), "a\nb\r")
579 self.assertEqual(memio.read(2), "\nc")
580 self.assertEqual(memio.read(1), "\r")
Antoine Pitrou57839a62014-02-02 23:37:29 +0100581 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
Serhiy Storchaka1812bd42014-02-05 13:42:01 +0200582
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000583 memio = self.ioclass(newline="")
584 self.assertEqual(2, memio.write("a\n"))
585 self.assertEqual(2, memio.write("b\r"))
586 self.assertEqual(2, memio.write("\nc"))
587 self.assertEqual(2, memio.write("\rd"))
588 memio.seek(0)
589 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
Serhiy Storchaka1812bd42014-02-05 13:42:01 +0200590 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000591
592 def test_newline_lf(self):
593 # newline="\n"
Serhiy Storchaka1812bd42014-02-05 13:42:01 +0200594 memio = self.ioclass("a\nb\r\nc\rd", newline="\n")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000595 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
Serhiy Storchaka1812bd42014-02-05 13:42:01 +0200596 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
597
598 memio = self.ioclass(newline="\n")
599 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
600 memio.seek(0)
601 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
602 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000603
604 def test_newline_cr(self):
605 # newline="\r"
606 memio = self.ioclass("a\nb\r\nc\rd", newline="\r")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000607 self.assertEqual(memio.read(), "a\rb\r\rc\rd")
608 memio.seek(0)
609 self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
Serhiy Storchaka1812bd42014-02-05 13:42:01 +0200610 self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd")
611
612 memio = self.ioclass(newline="\r")
613 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
614 memio.seek(0)
615 self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
Antoine Pitrou57839a62014-02-02 23:37:29 +0100616 memio.seek(0)
617 self.assertEqual(memio.readlines(), ["a\r", "b\r", "\r", "c\r", "d"])
618 self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000619
620 def test_newline_crlf(self):
621 # newline="\r\n"
622 memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000623 self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd")
624 memio.seek(0)
625 self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
Antoine Pitrou57839a62014-02-02 23:37:29 +0100626 memio.seek(0)
627 self.assertEqual(memio.readlines(), ["a\r\n", "b\r\r\n", "c\rd"])
628 self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000629
Serhiy Storchaka1812bd42014-02-05 13:42:01 +0200630 memio = self.ioclass(newline="\r\n")
631 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
632 memio.seek(0)
633 self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
634 self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd")
635
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000636 def test_issue5265(self):
637 # StringIO can duplicate newlines in universal newlines mode
638 memio = self.ioclass("a\r\nb\r\n", newline=None)
639 self.assertEqual(memio.read(5), "a\nb\n")
Antoine Pitrou57839a62014-02-02 23:37:29 +0100640 self.assertEqual(memio.getvalue(), "a\nb\n")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000642 def test_newline_argument(self):
643 self.assertRaises(TypeError, self.ioclass, newline=b"\n")
644 self.assertRaises(ValueError, self.ioclass, newline="error")
645 # These should not raise an error
646 for newline in (None, "", "\n", "\r", "\r\n"):
647 self.ioclass(newline=newline)
648
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000649
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000650class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin,
651 TextIOTestMixin, unittest.TestCase):
652 buftype = str
653 ioclass = pyio.StringIO
654 UnsupportedOperation = pyio.UnsupportedOperation
655 EOF = ""
656
Serhiy Storchakac92ea762014-01-29 11:33:26 +0200657 def test_lone_surrogates(self):
658 # Issue #20424
659 memio = self.ioclass('\ud800')
660 self.assertEqual(memio.read(), '\ud800')
661
662 memio = self.ioclass()
663 memio.write('\ud800')
664 self.assertEqual(memio.getvalue(), '\ud800')
665
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000666
667class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase):
668 """Test if pickle restores properly the internal state of StringIO.
669 """
670 buftype = str
671 UnsupportedOperation = pyio.UnsupportedOperation
672 EOF = ""
673
674 class ioclass(pyio.StringIO):
675 def __new__(cls, *args, **kwargs):
676 return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs)))
677 def __init__(self, *args, **kwargs):
678 pass
679
680
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000681class CBytesIOTest(PyBytesIOTest):
682 ioclass = io.BytesIO
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000683 UnsupportedOperation = io.UnsupportedOperation
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000684
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000685 def test_getstate(self):
686 memio = self.ioclass()
687 state = memio.__getstate__()
688 self.assertEqual(len(state), 3)
689 bytearray(state[0]) # Check if state[0] supports the buffer interface.
Ezio Melottie9615932010-01-24 19:26:24 +0000690 self.assertIsInstance(state[1], int)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000691 self.assertTrue(isinstance(state[2], dict) or state[2] is None)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000692 memio.close()
693 self.assertRaises(ValueError, memio.__getstate__)
694
695 def test_setstate(self):
696 # This checks whether __setstate__ does proper input validation.
697 memio = self.ioclass()
698 memio.__setstate__((b"no error", 0, None))
699 memio.__setstate__((bytearray(b"no error"), 0, None))
700 memio.__setstate__((b"no error", 0, {'spam': 3}))
701 self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None))
702 self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None))
703 self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None))
704 self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0))
705 self.assertRaises(TypeError, memio.__setstate__, (b"len-test", 0))
706 self.assertRaises(TypeError, memio.__setstate__)
707 self.assertRaises(TypeError, memio.__setstate__, 0)
708 memio.close()
709 self.assertRaises(ValueError, memio.__setstate__, (b"closed", 0, None))
710
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200711 check_sizeof = support.check_sizeof
712
713 @support.cpython_only
714 def test_sizeof(self):
Antoine Pitrou754d5ef2012-07-30 13:58:42 +0200715 basesize = support.calcobjsize('P2nN2Pn')
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200716 check = self.check_sizeof
717 self.assertEqual(object.__sizeof__(io.BytesIO()), basesize)
718 check(io.BytesIO(), basesize )
719 check(io.BytesIO(b'a'), basesize + 1 + 1 )
720 check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 )
721
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000722class CStringIOTest(PyStringIOTest):
723 ioclass = io.StringIO
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000724 UnsupportedOperation = io.UnsupportedOperation
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000725
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000726 # XXX: For the Python version of io.StringIO, this is highly
727 # dependent on the encoding used for the underlying buffer.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000728 def test_widechar(self):
729 buf = self.buftype("\U0002030a\U00020347")
730 memio = self.ioclass(buf)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000731
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000732 self.assertEqual(memio.getvalue(), buf)
733 self.assertEqual(memio.write(buf), len(buf))
734 self.assertEqual(memio.tell(), len(buf))
735 self.assertEqual(memio.getvalue(), buf)
736 self.assertEqual(memio.write(buf), len(buf))
737 self.assertEqual(memio.tell(), len(buf) * 2)
738 self.assertEqual(memio.getvalue(), buf + buf)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000739
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000740 def test_getstate(self):
741 memio = self.ioclass()
742 state = memio.__getstate__()
743 self.assertEqual(len(state), 4)
Ezio Melottie9615932010-01-24 19:26:24 +0000744 self.assertIsInstance(state[0], str)
745 self.assertIsInstance(state[1], str)
746 self.assertIsInstance(state[2], int)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000747 self.assertTrue(isinstance(state[3], dict) or state[3] is None)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000748 memio.close()
749 self.assertRaises(ValueError, memio.__getstate__)
750
751 def test_setstate(self):
752 # This checks whether __setstate__ does proper input validation.
753 memio = self.ioclass()
754 memio.__setstate__(("no error", "\n", 0, None))
755 memio.__setstate__(("no error", "", 0, {'spam': 3}))
756 self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None))
757 self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None))
758 self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None))
759 self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None))
760 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None))
761 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0))
762 self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0))
763 self.assertRaises(TypeError, memio.__setstate__)
764 self.assertRaises(TypeError, memio.__setstate__, 0)
765 memio.close()
766 self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None))
767
768
769class CStringIOPickleTest(PyStringIOPickleTest):
770 UnsupportedOperation = io.UnsupportedOperation
771
772 class ioclass(io.StringIO):
773 def __new__(cls, *args, **kwargs):
774 return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs)))
775 def __init__(self, *args, **kwargs):
776 pass
777
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000778
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000779def test_main():
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000780 tests = [PyBytesIOTest, PyStringIOTest, CBytesIOTest, CStringIOTest,
781 PyStringIOPickleTest, CStringIOPickleTest]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000782 support.run_unittest(*tests)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000783
784if __name__ == '__main__':
785 test_main()