python (3.11.7)
1 """Unit tests for memory-based file-like objects.
2 StringIO -- for unicode strings
3 BytesIO -- for bytes
4 """
5
6 import unittest
7 from test import support
8
9 import io
10 import _pyio as pyio
11 import pickle
12 import sys
13
14 class ESC[4;38;5;81mIntLike:
15 def __init__(self, num):
16 self._num = num
17 def __index__(self):
18 return self._num
19 __int__ = __index__
20
21 class ESC[4;38;5;81mMemorySeekTestMixin:
22
23 def testInit(self):
24 buf = self.buftype("1234567890")
25 bytesIo = self.ioclass(buf)
26
27 def testRead(self):
28 buf = self.buftype("1234567890")
29 bytesIo = self.ioclass(buf)
30
31 self.assertEqual(buf[:1], bytesIo.read(1))
32 self.assertEqual(buf[1:5], bytesIo.read(4))
33 self.assertEqual(buf[5:], bytesIo.read(900))
34 self.assertEqual(self.EOF, bytesIo.read())
35
36 def testReadNoArgs(self):
37 buf = self.buftype("1234567890")
38 bytesIo = self.ioclass(buf)
39
40 self.assertEqual(buf, bytesIo.read())
41 self.assertEqual(self.EOF, bytesIo.read())
42
43 def testSeek(self):
44 buf = self.buftype("1234567890")
45 bytesIo = self.ioclass(buf)
46
47 bytesIo.read(5)
48 bytesIo.seek(0)
49 self.assertEqual(buf, bytesIo.read())
50
51 bytesIo.seek(3)
52 self.assertEqual(buf[3:], bytesIo.read())
53 self.assertRaises(TypeError, bytesIo.seek, 0.0)
54
55 def testTell(self):
56 buf = self.buftype("1234567890")
57 bytesIo = self.ioclass(buf)
58
59 self.assertEqual(0, bytesIo.tell())
60 bytesIo.seek(5)
61 self.assertEqual(5, bytesIo.tell())
62 bytesIo.seek(10000)
63 self.assertEqual(10000, bytesIo.tell())
64
65
66 class ESC[4;38;5;81mMemoryTestMixin:
67
68 def test_detach(self):
69 buf = self.ioclass()
70 self.assertRaises(self.UnsupportedOperation, buf.detach)
71
72 def write_ops(self, f, t):
73 self.assertEqual(f.write(t("blah.")), 5)
74 self.assertEqual(f.seek(0), 0)
75 self.assertEqual(f.write(t("Hello.")), 6)
76 self.assertEqual(f.tell(), 6)
77 self.assertEqual(f.seek(5), 5)
78 self.assertEqual(f.tell(), 5)
79 self.assertEqual(f.write(t(" world\n\n\n")), 9)
80 self.assertEqual(f.seek(0), 0)
81 self.assertEqual(f.write(t("h")), 1)
82 self.assertEqual(f.truncate(12), 12)
83 self.assertEqual(f.tell(), 1)
84
85 def test_write(self):
86 buf = self.buftype("hello world\n")
87 memio = self.ioclass(buf)
88
89 self.write_ops(memio, self.buftype)
90 self.assertEqual(memio.getvalue(), buf)
91 memio = self.ioclass()
92 self.write_ops(memio, self.buftype)
93 self.assertEqual(memio.getvalue(), buf)
94 self.assertRaises(TypeError, memio.write, None)
95 memio.close()
96 self.assertRaises(ValueError, memio.write, self.buftype(""))
97
98 def test_writelines(self):
99 buf = self.buftype("1234567890")
100 memio = self.ioclass()
101
102 self.assertEqual(memio.writelines([buf] * 100), None)
103 self.assertEqual(memio.getvalue(), buf * 100)
104 memio.writelines([])
105 self.assertEqual(memio.getvalue(), buf * 100)
106 memio = self.ioclass()
107 self.assertRaises(TypeError, memio.writelines, [buf] + [1])
108 self.assertEqual(memio.getvalue(), buf)
109 self.assertRaises(TypeError, memio.writelines, None)
110 memio.close()
111 self.assertRaises(ValueError, memio.writelines, [])
112
113 def test_writelines_error(self):
114 memio = self.ioclass()
115 def error_gen():
116 yield self.buftype('spam')
117 raise KeyboardInterrupt
118
119 self.assertRaises(KeyboardInterrupt, memio.writelines, error_gen())
120
121 def test_truncate(self):
122 buf = self.buftype("1234567890")
123 memio = self.ioclass(buf)
124
125 self.assertRaises(ValueError, memio.truncate, -1)
126 self.assertRaises(ValueError, memio.truncate, IntLike(-1))
127 memio.seek(6)
128 self.assertEqual(memio.truncate(IntLike(8)), 8)
129 self.assertEqual(memio.getvalue(), buf[:8])
130 self.assertEqual(memio.truncate(), 6)
131 self.assertEqual(memio.getvalue(), buf[:6])
132 self.assertEqual(memio.truncate(4), 4)
133 self.assertEqual(memio.getvalue(), buf[:4])
134 self.assertEqual(memio.tell(), 6)
135 memio.seek(0, 2)
136 memio.write(buf)
137 self.assertEqual(memio.getvalue(), buf[:4] + buf)
138 pos = memio.tell()
139 self.assertEqual(memio.truncate(None), pos)
140 self.assertEqual(memio.tell(), pos)
141 self.assertRaises(TypeError, memio.truncate, '0')
142 memio.close()
143 self.assertRaises(ValueError, memio.truncate, 0)
144 self.assertRaises(ValueError, memio.truncate, IntLike(0))
145
146 def test_init(self):
147 buf = self.buftype("1234567890")
148 memio = self.ioclass(buf)
149 self.assertEqual(memio.getvalue(), buf)
150 memio = self.ioclass(None)
151 self.assertEqual(memio.getvalue(), self.EOF)
152 memio.__init__(buf * 2)
153 self.assertEqual(memio.getvalue(), buf * 2)
154 memio.__init__(buf)
155 self.assertEqual(memio.getvalue(), buf)
156 self.assertRaises(TypeError, memio.__init__, [])
157
158 def test_read(self):
159 buf = self.buftype("1234567890")
160 memio = self.ioclass(buf)
161
162 self.assertEqual(memio.read(0), self.EOF)
163 self.assertEqual(memio.read(1), buf[:1])
164 self.assertEqual(memio.read(4), buf[1:5])
165 self.assertEqual(memio.read(900), buf[5:])
166 self.assertEqual(memio.read(), self.EOF)
167 memio.seek(0)
168 self.assertEqual(memio.read(IntLike(0)), self.EOF)
169 self.assertEqual(memio.read(IntLike(1)), buf[:1])
170 self.assertEqual(memio.read(IntLike(4)), buf[1:5])
171 self.assertEqual(memio.read(IntLike(900)), buf[5:])
172 memio.seek(0)
173 self.assertEqual(memio.read(), buf)
174 self.assertEqual(memio.read(), self.EOF)
175 self.assertEqual(memio.tell(), 10)
176 memio.seek(0)
177 self.assertEqual(memio.read(-1), buf)
178 memio.seek(0)
179 self.assertEqual(memio.read(IntLike(-1)), buf)
180 memio.seek(0)
181 self.assertEqual(type(memio.read()), type(buf))
182 memio.seek(100)
183 self.assertEqual(type(memio.read()), type(buf))
184 memio.seek(0)
185 self.assertEqual(memio.read(None), buf)
186 self.assertRaises(TypeError, memio.read, '')
187 memio.seek(len(buf) + 1)
188 self.assertEqual(memio.read(1), self.EOF)
189 memio.seek(len(buf) + 1)
190 self.assertEqual(memio.read(IntLike(1)), self.EOF)
191 memio.seek(len(buf) + 1)
192 self.assertEqual(memio.read(), self.EOF)
193 memio.close()
194 self.assertRaises(ValueError, memio.read)
195
196 def test_readline(self):
197 buf = self.buftype("1234567890\n")
198 memio = self.ioclass(buf * 2)
199
200 self.assertEqual(memio.readline(0), self.EOF)
201 self.assertEqual(memio.readline(IntLike(0)), self.EOF)
202 self.assertEqual(memio.readline(), buf)
203 self.assertEqual(memio.readline(), buf)
204 self.assertEqual(memio.readline(), self.EOF)
205 memio.seek(0)
206 self.assertEqual(memio.readline(5), buf[:5])
207 self.assertEqual(memio.readline(5), buf[5:10])
208 self.assertEqual(memio.readline(5), buf[10:15])
209 memio.seek(0)
210 self.assertEqual(memio.readline(IntLike(5)), buf[:5])
211 self.assertEqual(memio.readline(IntLike(5)), buf[5:10])
212 self.assertEqual(memio.readline(IntLike(5)), buf[10:15])
213 memio.seek(0)
214 self.assertEqual(memio.readline(-1), buf)
215 memio.seek(0)
216 self.assertEqual(memio.readline(IntLike(-1)), buf)
217 memio.seek(0)
218 self.assertEqual(memio.readline(0), self.EOF)
219 self.assertEqual(memio.readline(IntLike(0)), self.EOF)
220 # Issue #24989: Buffer overread
221 memio.seek(len(buf) * 2 + 1)
222 self.assertEqual(memio.readline(), self.EOF)
223
224 buf = self.buftype("1234567890\n")
225 memio = self.ioclass((buf * 3)[:-1])
226 self.assertEqual(memio.readline(), buf)
227 self.assertEqual(memio.readline(), buf)
228 self.assertEqual(memio.readline(), buf[:-1])
229 self.assertEqual(memio.readline(), self.EOF)
230 memio.seek(0)
231 self.assertEqual(type(memio.readline()), type(buf))
232 self.assertEqual(memio.readline(), buf)
233 self.assertRaises(TypeError, memio.readline, '')
234 memio.close()
235 self.assertRaises(ValueError, memio.readline)
236
237 def test_readlines(self):
238 buf = self.buftype("1234567890\n")
239 memio = self.ioclass(buf * 10)
240
241 self.assertEqual(memio.readlines(), [buf] * 10)
242 memio.seek(5)
243 self.assertEqual(memio.readlines(), [buf[5:]] + [buf] * 9)
244 memio.seek(0)
245 self.assertEqual(memio.readlines(15), [buf] * 2)
246 memio.seek(0)
247 self.assertEqual(memio.readlines(-1), [buf] * 10)
248 memio.seek(0)
249 self.assertEqual(memio.readlines(0), [buf] * 10)
250 memio.seek(0)
251 self.assertEqual(type(memio.readlines()[0]), type(buf))
252 memio.seek(0)
253 self.assertEqual(memio.readlines(None), [buf] * 10)
254 self.assertRaises(TypeError, memio.readlines, '')
255 # Issue #24989: Buffer overread
256 memio.seek(len(buf) * 10 + 1)
257 self.assertEqual(memio.readlines(), [])
258 memio.close()
259 self.assertRaises(ValueError, memio.readlines)
260
261 def test_iterator(self):
262 buf = self.buftype("1234567890\n")
263 memio = self.ioclass(buf * 10)
264
265 self.assertEqual(iter(memio), memio)
266 self.assertTrue(hasattr(memio, '__iter__'))
267 self.assertTrue(hasattr(memio, '__next__'))
268 i = 0
269 for line in memio:
270 self.assertEqual(line, buf)
271 i += 1
272 self.assertEqual(i, 10)
273 memio.seek(0)
274 i = 0
275 for line in memio:
276 self.assertEqual(line, buf)
277 i += 1
278 self.assertEqual(i, 10)
279 # Issue #24989: Buffer overread
280 memio.seek(len(buf) * 10 + 1)
281 self.assertEqual(list(memio), [])
282 memio = self.ioclass(buf * 2)
283 memio.close()
284 self.assertRaises(ValueError, memio.__next__)
285
286 def test_getvalue(self):
287 buf = self.buftype("1234567890")
288 memio = self.ioclass(buf)
289
290 self.assertEqual(memio.getvalue(), buf)
291 memio.read()
292 self.assertEqual(memio.getvalue(), buf)
293 self.assertEqual(type(memio.getvalue()), type(buf))
294 memio = self.ioclass(buf * 1000)
295 self.assertEqual(memio.getvalue()[-3:], self.buftype("890"))
296 memio = self.ioclass(buf)
297 memio.close()
298 self.assertRaises(ValueError, memio.getvalue)
299
300 def test_seek(self):
301 buf = self.buftype("1234567890")
302 memio = self.ioclass(buf)
303
304 memio.read(5)
305 self.assertRaises(ValueError, memio.seek, -1)
306 self.assertRaises(ValueError, memio.seek, 1, -1)
307 self.assertRaises(ValueError, memio.seek, 1, 3)
308 self.assertEqual(memio.seek(0), 0)
309 self.assertEqual(memio.seek(0, 0), 0)
310 self.assertEqual(memio.read(), buf)
311 self.assertEqual(memio.seek(3), 3)
312 self.assertEqual(memio.seek(0, 1), 3)
313 self.assertEqual(memio.read(), buf[3:])
314 self.assertEqual(memio.seek(len(buf)), len(buf))
315 self.assertEqual(memio.read(), self.EOF)
316 memio.seek(len(buf) + 1)
317 self.assertEqual(memio.read(), self.EOF)
318 self.assertEqual(memio.seek(0, 2), len(buf))
319 self.assertEqual(memio.read(), self.EOF)
320 memio.close()
321 self.assertRaises(ValueError, memio.seek, 0)
322
323 def test_overseek(self):
324 buf = self.buftype("1234567890")
325 memio = self.ioclass(buf)
326
327 self.assertEqual(memio.seek(len(buf) + 1), 11)
328 self.assertEqual(memio.read(), self.EOF)
329 self.assertEqual(memio.tell(), 11)
330 self.assertEqual(memio.getvalue(), buf)
331 memio.write(self.EOF)
332 self.assertEqual(memio.getvalue(), buf)
333 memio.write(buf)
334 self.assertEqual(memio.getvalue(), buf + self.buftype('\0') + buf)
335
336 def test_tell(self):
337 buf = self.buftype("1234567890")
338 memio = self.ioclass(buf)
339
340 self.assertEqual(memio.tell(), 0)
341 memio.seek(5)
342 self.assertEqual(memio.tell(), 5)
343 memio.seek(10000)
344 self.assertEqual(memio.tell(), 10000)
345 memio.close()
346 self.assertRaises(ValueError, memio.tell)
347
348 def test_flush(self):
349 buf = self.buftype("1234567890")
350 memio = self.ioclass(buf)
351
352 self.assertEqual(memio.flush(), None)
353
354 def test_flags(self):
355 memio = self.ioclass()
356
357 self.assertEqual(memio.writable(), True)
358 self.assertEqual(memio.readable(), True)
359 self.assertEqual(memio.seekable(), True)
360 self.assertEqual(memio.isatty(), False)
361 self.assertEqual(memio.closed, False)
362 memio.close()
363 self.assertRaises(ValueError, memio.writable)
364 self.assertRaises(ValueError, memio.readable)
365 self.assertRaises(ValueError, memio.seekable)
366 self.assertRaises(ValueError, memio.isatty)
367 self.assertEqual(memio.closed, True)
368
369 def test_subclassing(self):
370 buf = self.buftype("1234567890")
371 def test1():
372 class ESC[4;38;5;81mMemIO(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mioclass):
373 pass
374 m = MemIO(buf)
375 return m.getvalue()
376 def test2():
377 class ESC[4;38;5;81mMemIO(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mioclass):
378 def __init__(me, a, b):
379 self.ioclass.__init__(me, a)
380 m = MemIO(buf, None)
381 return m.getvalue()
382 self.assertEqual(test1(), buf)
383 self.assertEqual(test2(), buf)
384
385 def test_instance_dict_leak(self):
386 # Test case for issue #6242.
387 # This will be caught by regrtest.py -R if this leak.
388 for _ in range(100):
389 memio = self.ioclass()
390 memio.foo = 1
391
392 def test_pickling(self):
393 buf = self.buftype("1234567890")
394 memio = self.ioclass(buf)
395 memio.foo = 42
396 memio.seek(2)
397
398 class ESC[4;38;5;81mPickleTestMemIO(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mioclass):
399 def __init__(me, initvalue, foo):
400 self.ioclass.__init__(me, initvalue)
401 me.foo = foo
402 # __getnewargs__ is undefined on purpose. This checks that PEP 307
403 # is used to provide pickling support.
404
405 # Pickle expects the class to be on the module level. Here we use a
406 # little hack to allow the PickleTestMemIO class to derive from
407 # self.ioclass without having to define all combinations explicitly on
408 # the module-level.
409 import __main__
410 PickleTestMemIO.__module__ = '__main__'
411 PickleTestMemIO.__qualname__ = PickleTestMemIO.__name__
412 __main__.PickleTestMemIO = PickleTestMemIO
413 submemio = PickleTestMemIO(buf, 80)
414 submemio.seek(2)
415
416 # We only support pickle protocol 2 and onward since we use extended
417 # __reduce__ API of PEP 307 to provide pickling support.
418 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
419 for obj in (memio, submemio):
420 obj2 = pickle.loads(pickle.dumps(obj, protocol=proto))
421 self.assertEqual(obj.getvalue(), obj2.getvalue())
422 self.assertEqual(obj.__class__, obj2.__class__)
423 self.assertEqual(obj.foo, obj2.foo)
424 self.assertEqual(obj.tell(), obj2.tell())
425 obj2.close()
426 self.assertRaises(ValueError, pickle.dumps, obj2, proto)
427 del __main__.PickleTestMemIO
428
429
430 class ESC[4;38;5;81mPyBytesIOTest(ESC[4;38;5;149mMemoryTestMixin, ESC[4;38;5;149mMemorySeekTestMixin, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
431 # Test _pyio.BytesIO; class also inherited for testing C implementation
432
433 UnsupportedOperation = pyio.UnsupportedOperation
434
435 @staticmethod
436 def buftype(s):
437 return s.encode("ascii")
438 ioclass = pyio.BytesIO
439 EOF = b""
440
441 def test_getbuffer(self):
442 memio = self.ioclass(b"1234567890")
443 buf = memio.getbuffer()
444 self.assertEqual(bytes(buf), b"1234567890")
445 memio.seek(5)
446 buf = memio.getbuffer()
447 self.assertEqual(bytes(buf), b"1234567890")
448 # Trying to change the size of the BytesIO while a buffer is exported
449 # raises a BufferError.
450 self.assertRaises(BufferError, memio.write, b'x' * 100)
451 self.assertRaises(BufferError, memio.truncate)
452 self.assertRaises(BufferError, memio.close)
453 self.assertFalse(memio.closed)
454 # Mutating the buffer updates the BytesIO
455 buf[3:6] = b"abc"
456 self.assertEqual(bytes(buf), b"123abc7890")
457 self.assertEqual(memio.getvalue(), b"123abc7890")
458 # After the buffer gets released, we can resize and close the BytesIO
459 # again
460 del buf
461 support.gc_collect()
462 memio.truncate()
463 memio.close()
464 self.assertRaises(ValueError, memio.getbuffer)
465
466 def test_getbuffer_empty(self):
467 memio = self.ioclass()
468 buf = memio.getbuffer()
469 self.assertEqual(bytes(buf), b"")
470 # Trying to change the size of the BytesIO while a buffer is exported
471 # raises a BufferError.
472 self.assertRaises(BufferError, memio.write, b'x')
473 buf2 = memio.getbuffer()
474 self.assertRaises(BufferError, memio.write, b'x')
475 buf.release()
476 self.assertRaises(BufferError, memio.write, b'x')
477 buf2.release()
478 memio.write(b'x')
479
480 def test_read1(self):
481 buf = self.buftype("1234567890")
482 self.assertEqual(self.ioclass(buf).read1(), buf)
483 self.assertEqual(self.ioclass(buf).read1(-1), buf)
484
485 def test_readinto(self):
486 buf = self.buftype("1234567890")
487 memio = self.ioclass(buf)
488
489 b = bytearray(b"hello")
490 self.assertEqual(memio.readinto(b), 5)
491 self.assertEqual(b, b"12345")
492 self.assertEqual(memio.readinto(b), 5)
493 self.assertEqual(b, b"67890")
494 self.assertEqual(memio.readinto(b), 0)
495 self.assertEqual(b, b"67890")
496 b = bytearray(b"hello world")
497 memio.seek(0)
498 self.assertEqual(memio.readinto(b), 10)
499 self.assertEqual(b, b"1234567890d")
500 b = bytearray(b"")
501 memio.seek(0)
502 self.assertEqual(memio.readinto(b), 0)
503 self.assertEqual(b, b"")
504 self.assertRaises(TypeError, memio.readinto, '')
505 import array
506 a = array.array('b', b"hello world")
507 memio = self.ioclass(buf)
508 memio.readinto(a)
509 self.assertEqual(a.tobytes(), b"1234567890d")
510 memio.close()
511 self.assertRaises(ValueError, memio.readinto, b)
512 memio = self.ioclass(b"123")
513 b = bytearray()
514 memio.seek(42)
515 memio.readinto(b)
516 self.assertEqual(b, b"")
517
518 def test_relative_seek(self):
519 buf = self.buftype("1234567890")
520 memio = self.ioclass(buf)
521
522 self.assertEqual(memio.seek(-1, 1), 0)
523 self.assertEqual(memio.seek(3, 1), 3)
524 self.assertEqual(memio.seek(-4, 1), 0)
525 self.assertEqual(memio.seek(-1, 2), 9)
526 self.assertEqual(memio.seek(1, 1), 10)
527 self.assertEqual(memio.seek(1, 2), 11)
528 memio.seek(-3, 2)
529 self.assertEqual(memio.read(), buf[-3:])
530 memio.seek(0)
531 memio.seek(1, 1)
532 self.assertEqual(memio.read(), buf[1:])
533
534 def test_unicode(self):
535 memio = self.ioclass()
536
537 self.assertRaises(TypeError, self.ioclass, "1234567890")
538 self.assertRaises(TypeError, memio.write, "1234567890")
539 self.assertRaises(TypeError, memio.writelines, ["1234567890"])
540
541 def test_bytes_array(self):
542 buf = b"1234567890"
543 import array
544 a = array.array('b', list(buf))
545 memio = self.ioclass(a)
546 self.assertEqual(memio.getvalue(), buf)
547 self.assertEqual(memio.write(a), 10)
548 self.assertEqual(memio.getvalue(), buf)
549
550 def test_issue5449(self):
551 buf = self.buftype("1234567890")
552 self.ioclass(initial_bytes=buf)
553 self.assertRaises(TypeError, self.ioclass, buf, foo=None)
554
555
556 class ESC[4;38;5;81mTextIOTestMixin:
557
558 def test_newlines_property(self):
559 memio = self.ioclass(newline=None)
560 # The C StringIO decodes newlines in write() calls, but the Python
561 # implementation only does when reading. This function forces them to
562 # be decoded for testing.
563 def force_decode():
564 memio.seek(0)
565 memio.read()
566 self.assertEqual(memio.newlines, None)
567 memio.write("a\n")
568 force_decode()
569 self.assertEqual(memio.newlines, "\n")
570 memio.write("b\r\n")
571 force_decode()
572 self.assertEqual(memio.newlines, ("\n", "\r\n"))
573 memio.write("c\rd")
574 force_decode()
575 self.assertEqual(memio.newlines, ("\r", "\n", "\r\n"))
576
577 def test_relative_seek(self):
578 memio = self.ioclass()
579
580 self.assertRaises(OSError, memio.seek, -1, 1)
581 self.assertRaises(OSError, memio.seek, 3, 1)
582 self.assertRaises(OSError, memio.seek, -3, 1)
583 self.assertRaises(OSError, memio.seek, -1, 2)
584 self.assertRaises(OSError, memio.seek, 1, 1)
585 self.assertRaises(OSError, memio.seek, 1, 2)
586
587 def test_textio_properties(self):
588 memio = self.ioclass()
589
590 # These are just dummy values but we nevertheless check them for fear
591 # of unexpected breakage.
592 self.assertIsNone(memio.encoding)
593 self.assertIsNone(memio.errors)
594 self.assertFalse(memio.line_buffering)
595
596 def test_newline_default(self):
597 memio = self.ioclass("a\nb\r\nc\rd")
598 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
599 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
600
601 memio = self.ioclass()
602 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
603 memio.seek(0)
604 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
605 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
606
607 def test_newline_none(self):
608 # newline=None
609 memio = self.ioclass("a\nb\r\nc\rd", newline=None)
610 self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"])
611 memio.seek(0)
612 self.assertEqual(memio.read(1), "a")
613 self.assertEqual(memio.read(2), "\nb")
614 self.assertEqual(memio.read(2), "\nc")
615 self.assertEqual(memio.read(1), "\n")
616 self.assertEqual(memio.getvalue(), "a\nb\nc\nd")
617
618 memio = self.ioclass(newline=None)
619 self.assertEqual(2, memio.write("a\n"))
620 self.assertEqual(3, memio.write("b\r\n"))
621 self.assertEqual(3, memio.write("c\rd"))
622 memio.seek(0)
623 self.assertEqual(memio.read(), "a\nb\nc\nd")
624 self.assertEqual(memio.getvalue(), "a\nb\nc\nd")
625
626 memio = self.ioclass("a\r\nb", newline=None)
627 self.assertEqual(memio.read(3), "a\nb")
628
629 def test_newline_empty(self):
630 # newline=""
631 memio = self.ioclass("a\nb\r\nc\rd", newline="")
632 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
633 memio.seek(0)
634 self.assertEqual(memio.read(4), "a\nb\r")
635 self.assertEqual(memio.read(2), "\nc")
636 self.assertEqual(memio.read(1), "\r")
637 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
638
639 memio = self.ioclass(newline="")
640 self.assertEqual(2, memio.write("a\n"))
641 self.assertEqual(2, memio.write("b\r"))
642 self.assertEqual(2, memio.write("\nc"))
643 self.assertEqual(2, memio.write("\rd"))
644 memio.seek(0)
645 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
646 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
647
648 def test_newline_lf(self):
649 # newline="\n"
650 memio = self.ioclass("a\nb\r\nc\rd", newline="\n")
651 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
652 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
653
654 memio = self.ioclass(newline="\n")
655 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
656 memio.seek(0)
657 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
658 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
659
660 def test_newline_cr(self):
661 # newline="\r"
662 memio = self.ioclass("a\nb\r\nc\rd", newline="\r")
663 self.assertEqual(memio.read(), "a\rb\r\rc\rd")
664 memio.seek(0)
665 self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
666 self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd")
667
668 memio = self.ioclass(newline="\r")
669 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
670 memio.seek(0)
671 self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
672 memio.seek(0)
673 self.assertEqual(memio.readlines(), ["a\r", "b\r", "\r", "c\r", "d"])
674 self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd")
675
676 def test_newline_crlf(self):
677 # newline="\r\n"
678 memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n")
679 self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd")
680 memio.seek(0)
681 self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
682 memio.seek(0)
683 self.assertEqual(memio.readlines(), ["a\r\n", "b\r\r\n", "c\rd"])
684 self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd")
685
686 memio = self.ioclass(newline="\r\n")
687 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
688 memio.seek(0)
689 self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
690 self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd")
691
692 def test_issue5265(self):
693 # StringIO can duplicate newlines in universal newlines mode
694 memio = self.ioclass("a\r\nb\r\n", newline=None)
695 self.assertEqual(memio.read(5), "a\nb\n")
696 self.assertEqual(memio.getvalue(), "a\nb\n")
697
698 def test_newline_argument(self):
699 self.assertRaises(TypeError, self.ioclass, newline=b"\n")
700 self.assertRaises(ValueError, self.ioclass, newline="error")
701 # These should not raise an error
702 for newline in (None, "", "\n", "\r", "\r\n"):
703 self.ioclass(newline=newline)
704
705
706 class ESC[4;38;5;81mPyStringIOTest(ESC[4;38;5;149mMemoryTestMixin, ESC[4;38;5;149mMemorySeekTestMixin,
707 ESC[4;38;5;149mTextIOTestMixin, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
708 buftype = str
709 ioclass = pyio.StringIO
710 UnsupportedOperation = pyio.UnsupportedOperation
711 EOF = ""
712
713 def test_lone_surrogates(self):
714 # Issue #20424
715 memio = self.ioclass('\ud800')
716 self.assertEqual(memio.read(), '\ud800')
717
718 memio = self.ioclass()
719 memio.write('\ud800')
720 self.assertEqual(memio.getvalue(), '\ud800')
721
722
723 class ESC[4;38;5;81mPyStringIOPickleTest(ESC[4;38;5;149mTextIOTestMixin, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
724 """Test if pickle restores properly the internal state of StringIO.
725 """
726 buftype = str
727 UnsupportedOperation = pyio.UnsupportedOperation
728 EOF = ""
729
730 class ESC[4;38;5;81mioclass(ESC[4;38;5;149mpyioESC[4;38;5;149m.ESC[4;38;5;149mStringIO):
731 def __new__(cls, *args, **kwargs):
732 return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs)))
733 def __init__(self, *args, **kwargs):
734 pass
735
736
737 class ESC[4;38;5;81mCBytesIOTest(ESC[4;38;5;149mPyBytesIOTest):
738 ioclass = io.BytesIO
739 UnsupportedOperation = io.UnsupportedOperation
740
741 def test_getstate(self):
742 memio = self.ioclass()
743 state = memio.__getstate__()
744 self.assertEqual(len(state), 3)
745 bytearray(state[0]) # Check if state[0] supports the buffer interface.
746 self.assertIsInstance(state[1], int)
747 if state[2] is not None:
748 self.assertIsInstance(state[2], dict)
749 memio.close()
750 self.assertRaises(ValueError, memio.__getstate__)
751
752 def test_setstate(self):
753 # This checks whether __setstate__ does proper input validation.
754 memio = self.ioclass()
755 memio.__setstate__((b"no error", 0, None))
756 memio.__setstate__((bytearray(b"no error"), 0, None))
757 memio.__setstate__((b"no error", 0, {'spam': 3}))
758 self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None))
759 self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None))
760 self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None))
761 self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0))
762 self.assertRaises(TypeError, memio.__setstate__, (b"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__, (b"closed", 0, None))
767
768 check_sizeof = support.check_sizeof
769
770 @support.cpython_only
771 def test_sizeof(self):
772 basesize = support.calcobjsize('P2n2Pn')
773 check = self.check_sizeof
774 self.assertEqual(object.__sizeof__(io.BytesIO()), basesize)
775 check(io.BytesIO(), basesize )
776 n = 1000 # use a variable to prevent constant folding
777 check(io.BytesIO(b'a' * n), basesize + sys.getsizeof(b'a' * n))
778
779 # Various tests of copy-on-write behaviour for BytesIO.
780
781 def _test_cow_mutation(self, mutation):
782 # Common code for all BytesIO copy-on-write mutation tests.
783 imm = b' ' * 1024
784 old_rc = sys.getrefcount(imm)
785 memio = self.ioclass(imm)
786 self.assertEqual(sys.getrefcount(imm), old_rc + 1)
787 mutation(memio)
788 self.assertEqual(sys.getrefcount(imm), old_rc)
789
790 @support.cpython_only
791 def test_cow_truncate(self):
792 # Ensure truncate causes a copy.
793 def mutation(memio):
794 memio.truncate(1)
795 self._test_cow_mutation(mutation)
796
797 @support.cpython_only
798 def test_cow_write(self):
799 # Ensure write that would not cause a resize still results in a copy.
800 def mutation(memio):
801 memio.seek(0)
802 memio.write(b'foo')
803 self._test_cow_mutation(mutation)
804
805 @support.cpython_only
806 def test_cow_setstate(self):
807 # __setstate__ should cause buffer to be released.
808 memio = self.ioclass(b'foooooo')
809 state = memio.__getstate__()
810 def mutation(memio):
811 memio.__setstate__(state)
812 self._test_cow_mutation(mutation)
813
814 @support.cpython_only
815 def test_cow_mutable(self):
816 # BytesIO should accept only Bytes for copy-on-write sharing, since
817 # arbitrary buffer-exporting objects like bytearray() aren't guaranteed
818 # to be immutable.
819 ba = bytearray(1024)
820 old_rc = sys.getrefcount(ba)
821 memio = self.ioclass(ba)
822 self.assertEqual(sys.getrefcount(ba), old_rc)
823
824 class ESC[4;38;5;81mCStringIOTest(ESC[4;38;5;149mPyStringIOTest):
825 ioclass = io.StringIO
826 UnsupportedOperation = io.UnsupportedOperation
827
828 # XXX: For the Python version of io.StringIO, this is highly
829 # dependent on the encoding used for the underlying buffer.
830 def test_widechar(self):
831 buf = self.buftype("\U0002030a\U00020347")
832 memio = self.ioclass(buf)
833
834 self.assertEqual(memio.getvalue(), buf)
835 self.assertEqual(memio.write(buf), len(buf))
836 self.assertEqual(memio.tell(), len(buf))
837 self.assertEqual(memio.getvalue(), buf)
838 self.assertEqual(memio.write(buf), len(buf))
839 self.assertEqual(memio.tell(), len(buf) * 2)
840 self.assertEqual(memio.getvalue(), buf + buf)
841
842 def test_getstate(self):
843 memio = self.ioclass()
844 state = memio.__getstate__()
845 self.assertEqual(len(state), 4)
846 self.assertIsInstance(state[0], str)
847 self.assertIsInstance(state[1], str)
848 self.assertIsInstance(state[2], int)
849 if state[3] is not None:
850 self.assertIsInstance(state[3], dict)
851 memio.close()
852 self.assertRaises(ValueError, memio.__getstate__)
853
854 def test_setstate(self):
855 # This checks whether __setstate__ does proper input validation.
856 memio = self.ioclass()
857 memio.__setstate__(("no error", "\n", 0, None))
858 memio.__setstate__(("no error", "", 0, {'spam': 3}))
859 self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None))
860 self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None))
861 self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None))
862 self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None))
863 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None))
864 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0))
865 self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0))
866 self.assertRaises(TypeError, memio.__setstate__)
867 self.assertRaises(TypeError, memio.__setstate__, 0)
868 memio.close()
869 self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None))
870
871
872 class ESC[4;38;5;81mCStringIOPickleTest(ESC[4;38;5;149mPyStringIOPickleTest):
873 UnsupportedOperation = io.UnsupportedOperation
874
875 class ESC[4;38;5;81mioclass(ESC[4;38;5;149mioESC[4;38;5;149m.ESC[4;38;5;149mStringIO):
876 def __new__(cls, *args, **kwargs):
877 return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs)))
878 def __init__(self, *args, **kwargs):
879 pass
880
881
882 if __name__ == '__main__':
883 unittest.main()