1 """Unit tests for memory-based file-like objects.
2 StringIO -- for unicode strings
7 from test
import support
13 class MemorySeekTestMixin
:
16 buf
= self
.buftype("1234567890")
17 bytesIo
= self
.ioclass(buf
)
20 buf
= self
.buftype("1234567890")
21 bytesIo
= self
.ioclass(buf
)
23 self
.assertEquals(buf
[:1], bytesIo
.read(1))
24 self
.assertEquals(buf
[1:5], bytesIo
.read(4))
25 self
.assertEquals(buf
[5:], bytesIo
.read(900))
26 self
.assertEquals(self
.EOF
, bytesIo
.read())
28 def testReadNoArgs(self
):
29 buf
= self
.buftype("1234567890")
30 bytesIo
= self
.ioclass(buf
)
32 self
.assertEquals(buf
, bytesIo
.read())
33 self
.assertEquals(self
.EOF
, bytesIo
.read())
36 buf
= self
.buftype("1234567890")
37 bytesIo
= self
.ioclass(buf
)
41 self
.assertEquals(buf
, bytesIo
.read())
44 self
.assertEquals(buf
[3:], bytesIo
.read())
45 self
.assertRaises(TypeError, bytesIo
.seek
, 0.0)
48 buf
= self
.buftype("1234567890")
49 bytesIo
= self
.ioclass(buf
)
51 self
.assertEquals(0, bytesIo
.tell())
53 self
.assertEquals(5, bytesIo
.tell())
55 self
.assertEquals(10000, bytesIo
.tell())
58 class MemoryTestMixin
:
60 def test_detach(self
):
62 self
.assertRaises(self
.UnsupportedOperation
, buf
.detach
)
64 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)
75 self
.assertEqual(f
.tell(), 12)
78 buf
= self
.buftype("hello world\n")
79 memio
= self
.ioclass(buf
)
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)
88 self
.assertRaises(ValueError, memio
.write
, self
.buftype(""))
90 def test_writelines(self
):
91 buf
= self
.buftype("1234567890")
92 memio
= self
.ioclass()
94 self
.assertEqual(memio
.writelines([buf
] * 100), None)
95 self
.assertEqual(memio
.getvalue(), buf
* 100)
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)
103 self
.assertRaises(ValueError, memio
.writelines
, [])
105 def test_writelines_error(self
):
106 memio
= self
.ioclass()
108 yield self
.buftype('spam')
109 raise KeyboardInterrupt
111 self
.assertRaises(KeyboardInterrupt, memio
.writelines
, error_gen())
113 def test_truncate(self
):
114 buf
= self
.buftype("1234567890")
115 memio
= self
.ioclass(buf
)
117 self
.assertRaises(ValueError, memio
.truncate
, -1)
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])
123 self
.assertEqual(memio
.tell(), 4)
125 self
.assertEqual(memio
.getvalue(), buf
[:4] + buf
)
127 self
.assertEqual(memio
.truncate(None), pos
)
128 self
.assertEqual(memio
.tell(), pos
)
129 self
.assertRaises(TypeError, memio
.truncate
, '0')
131 self
.assertRaises(ValueError, memio
.truncate
, 0)
134 buf
= self
.buftype("1234567890")
135 memio
= self
.ioclass(buf
)
136 self
.assertEqual(memio
.getvalue(), buf
)
137 memio
= self
.ioclass(None)
138 self
.assertEqual(memio
.getvalue(), self
.EOF
)
139 memio
.__init
__(buf
* 2)
140 self
.assertEqual(memio
.getvalue(), buf
* 2)
142 self
.assertEqual(memio
.getvalue(), buf
)
145 buf
= self
.buftype("1234567890")
146 memio
= self
.ioclass(buf
)
148 self
.assertEqual(memio
.read(0), self
.EOF
)
149 self
.assertEqual(memio
.read(1), buf
[:1])
150 self
.assertEqual(memio
.read(4), buf
[1:5])
151 self
.assertEqual(memio
.read(900), buf
[5:])
152 self
.assertEqual(memio
.read(), self
.EOF
)
154 self
.assertEqual(memio
.read(), buf
)
155 self
.assertEqual(memio
.read(), self
.EOF
)
156 self
.assertEqual(memio
.tell(), 10)
158 self
.assertEqual(memio
.read(-1), buf
)
160 self
.assertEqual(type(memio
.read()), type(buf
))
162 self
.assertEqual(type(memio
.read()), type(buf
))
164 self
.assertEqual(memio
.read(None), buf
)
165 self
.assertRaises(TypeError, memio
.read
, '')
167 self
.assertRaises(ValueError, memio
.read
)
169 def test_readline(self
):
170 buf
= self
.buftype("1234567890\n")
171 memio
= self
.ioclass(buf
* 2)
173 self
.assertEqual(memio
.readline(0), self
.EOF
)
174 self
.assertEqual(memio
.readline(), buf
)
175 self
.assertEqual(memio
.readline(), buf
)
176 self
.assertEqual(memio
.readline(), self
.EOF
)
178 self
.assertEqual(memio
.readline(5), buf
[:5])
179 self
.assertEqual(memio
.readline(5), buf
[5:10])
180 self
.assertEqual(memio
.readline(5), buf
[10:15])
182 self
.assertEqual(memio
.readline(-1), buf
)
184 self
.assertEqual(memio
.readline(0), self
.EOF
)
186 buf
= self
.buftype("1234567890\n")
187 memio
= self
.ioclass((buf
* 3)[:-1])
188 self
.assertEqual(memio
.readline(), buf
)
189 self
.assertEqual(memio
.readline(), buf
)
190 self
.assertEqual(memio
.readline(), buf
[:-1])
191 self
.assertEqual(memio
.readline(), self
.EOF
)
193 self
.assertEqual(type(memio
.readline()), type(buf
))
194 self
.assertEqual(memio
.readline(), buf
)
195 self
.assertRaises(TypeError, memio
.readline
, '')
197 self
.assertRaises(ValueError, memio
.readline
)
199 def test_readlines(self
):
200 buf
= self
.buftype("1234567890\n")
201 memio
= self
.ioclass(buf
* 10)
203 self
.assertEqual(memio
.readlines(), [buf
] * 10)
205 self
.assertEqual(memio
.readlines(), [buf
[5:]] + [buf
] * 9)
207 self
.assertEqual(memio
.readlines(15), [buf
] * 2)
209 self
.assertEqual(memio
.readlines(-1), [buf
] * 10)
211 self
.assertEqual(memio
.readlines(0), [buf
] * 10)
213 self
.assertEqual(type(memio
.readlines()[0]), type(buf
))
215 self
.assertEqual(memio
.readlines(None), [buf
] * 10)
216 self
.assertRaises(TypeError, memio
.readlines
, '')
218 self
.assertRaises(ValueError, memio
.readlines
)
220 def test_iterator(self
):
221 buf
= self
.buftype("1234567890\n")
222 memio
= self
.ioclass(buf
* 10)
224 self
.assertEqual(iter(memio
), memio
)
225 self
.failUnless(hasattr(memio
, '__iter__'))
226 self
.failUnless(hasattr(memio
, '__next__'))
229 self
.assertEqual(line
, buf
)
231 self
.assertEqual(i
, 10)
235 self
.assertEqual(line
, buf
)
237 self
.assertEqual(i
, 10)
238 memio
= self
.ioclass(buf
* 2)
240 self
.assertRaises(ValueError, memio
.__next
__)
242 def test_getvalue(self
):
243 buf
= self
.buftype("1234567890")
244 memio
= self
.ioclass(buf
)
246 self
.assertEqual(memio
.getvalue(), buf
)
248 self
.assertEqual(memio
.getvalue(), buf
)
249 self
.assertEqual(type(memio
.getvalue()), type(buf
))
250 memio
= self
.ioclass(buf
* 1000)
251 self
.assertEqual(memio
.getvalue()[-3:], self
.buftype("890"))
252 memio
= self
.ioclass(buf
)
254 self
.assertRaises(ValueError, memio
.getvalue
)
257 buf
= self
.buftype("1234567890")
258 memio
= self
.ioclass(buf
)
261 self
.assertRaises(ValueError, memio
.seek
, -1)
262 self
.assertRaises(ValueError, memio
.seek
, 1, -1)
263 self
.assertRaises(ValueError, memio
.seek
, 1, 3)
264 self
.assertEqual(memio
.seek(0), 0)
265 self
.assertEqual(memio
.seek(0, 0), 0)
266 self
.assertEqual(memio
.read(), buf
)
267 self
.assertEqual(memio
.seek(3), 3)
268 self
.assertEqual(memio
.seek(0, 1), 3)
269 self
.assertEqual(memio
.read(), buf
[3:])
270 self
.assertEqual(memio
.seek(len(buf
)), len(buf
))
271 self
.assertEqual(memio
.read(), self
.EOF
)
272 memio
.seek(len(buf
) + 1)
273 self
.assertEqual(memio
.read(), self
.EOF
)
274 self
.assertEqual(memio
.seek(0, 2), len(buf
))
275 self
.assertEqual(memio
.read(), self
.EOF
)
277 self
.assertRaises(ValueError, memio
.seek
, 0)
279 def test_overseek(self
):
280 buf
= self
.buftype("1234567890")
281 memio
= self
.ioclass(buf
)
283 self
.assertEqual(memio
.seek(len(buf
) + 1), 11)
284 self
.assertEqual(memio
.read(), self
.EOF
)
285 self
.assertEqual(memio
.tell(), 11)
286 self
.assertEqual(memio
.getvalue(), buf
)
287 memio
.write(self
.EOF
)
288 self
.assertEqual(memio
.getvalue(), buf
)
290 self
.assertEqual(memio
.getvalue(), buf
+ self
.buftype('\0') + buf
)
293 buf
= self
.buftype("1234567890")
294 memio
= self
.ioclass(buf
)
296 self
.assertEqual(memio
.tell(), 0)
298 self
.assertEqual(memio
.tell(), 5)
300 self
.assertEqual(memio
.tell(), 10000)
302 self
.assertRaises(ValueError, memio
.tell
)
304 def test_flush(self
):
305 buf
= self
.buftype("1234567890")
306 memio
= self
.ioclass(buf
)
308 self
.assertEqual(memio
.flush(), None)
310 def test_flags(self
):
311 memio
= self
.ioclass()
313 self
.assertEqual(memio
.writable(), True)
314 self
.assertEqual(memio
.readable(), True)
315 self
.assertEqual(memio
.seekable(), True)
316 self
.assertEqual(memio
.isatty(), False)
317 self
.assertEqual(memio
.closed
, False)
319 self
.assertEqual(memio
.writable(), True)
320 self
.assertEqual(memio
.readable(), True)
321 self
.assertEqual(memio
.seekable(), True)
322 self
.assertRaises(ValueError, memio
.isatty
)
323 self
.assertEqual(memio
.closed
, True)
325 def test_subclassing(self
):
326 buf
= self
.buftype("1234567890")
328 class MemIO(self
.ioclass
):
333 class MemIO(self
.ioclass
):
334 def __init__(me
, a
, b
):
335 self
.ioclass
.__init
__(me
, a
)
338 self
.assertEqual(test1(), buf
)
339 self
.assertEqual(test2(), buf
)
342 class PyBytesIOTest(MemoryTestMixin
, MemorySeekTestMixin
, unittest
.TestCase
):
344 UnsupportedOperation
= pyio
.UnsupportedOperation
348 return s
.encode("ascii")
349 ioclass
= pyio
.BytesIO
352 def test_read1(self
):
353 buf
= self
.buftype("1234567890")
354 memio
= self
.ioclass(buf
)
356 self
.assertRaises(TypeError, memio
.read1
)
357 self
.assertEqual(memio
.read(), buf
)
359 def test_readinto(self
):
360 buf
= self
.buftype("1234567890")
361 memio
= self
.ioclass(buf
)
363 b
= bytearray(b
"hello")
364 self
.assertEqual(memio
.readinto(b
), 5)
365 self
.assertEqual(b
, b
"12345")
366 self
.assertEqual(memio
.readinto(b
), 5)
367 self
.assertEqual(b
, b
"67890")
368 self
.assertEqual(memio
.readinto(b
), 0)
369 self
.assertEqual(b
, b
"67890")
370 b
= bytearray(b
"hello world")
372 self
.assertEqual(memio
.readinto(b
), 10)
373 self
.assertEqual(b
, b
"1234567890d")
376 self
.assertEqual(memio
.readinto(b
), 0)
377 self
.assertEqual(b
, b
"")
378 self
.assertRaises(TypeError, memio
.readinto
, '')
380 a
= array
.array('b', b
"hello world")
381 memio
= self
.ioclass(buf
)
383 self
.assertEqual(a
.tostring(), b
"1234567890d")
385 self
.assertRaises(ValueError, memio
.readinto
, b
)
387 def test_relative_seek(self
):
388 buf
= self
.buftype("1234567890")
389 memio
= self
.ioclass(buf
)
391 self
.assertEqual(memio
.seek(-1, 1), 0)
392 self
.assertEqual(memio
.seek(3, 1), 3)
393 self
.assertEqual(memio
.seek(-4, 1), 0)
394 self
.assertEqual(memio
.seek(-1, 2), 9)
395 self
.assertEqual(memio
.seek(1, 1), 10)
396 self
.assertEqual(memio
.seek(1, 2), 11)
398 self
.assertEqual(memio
.read(), buf
[-3:])
401 self
.assertEqual(memio
.read(), buf
[1:])
403 def test_unicode(self
):
404 memio
= self
.ioclass()
406 self
.assertRaises(TypeError, self
.ioclass
, "1234567890")
407 self
.assertRaises(TypeError, memio
.write
, "1234567890")
408 self
.assertRaises(TypeError, memio
.writelines
, ["1234567890"])
410 def test_bytes_array(self
):
413 a
= array
.array('b', list(buf
))
414 memio
= self
.ioclass(a
)
415 self
.assertEqual(memio
.getvalue(), buf
)
416 self
.assertEqual(memio
.write(a
), 10)
417 self
.assertEqual(memio
.getvalue(), buf
)
420 class PyStringIOTest(MemoryTestMixin
, MemorySeekTestMixin
, unittest
.TestCase
):
422 ioclass
= pyio
.StringIO
423 UnsupportedOperation
= pyio
.UnsupportedOperation
426 # TextIO-specific behaviour.
428 def test_newlines_property(self
):
429 memio
= self
.ioclass(newline
=None)
430 # The C StringIO decodes newlines in write() calls, but the Python
431 # implementation only does when reading. This function forces them to
432 # be decoded for testing.
436 self
.assertEqual(memio
.newlines
, None)
439 self
.assertEqual(memio
.newlines
, "\n")
442 self
.assertEqual(memio
.newlines
, ("\n", "\r\n"))
445 self
.assertEqual(memio
.newlines
, ("\r", "\n", "\r\n"))
447 def test_relative_seek(self
):
448 memio
= self
.ioclass()
450 self
.assertRaises(IOError, memio
.seek
, -1, 1)
451 self
.assertRaises(IOError, memio
.seek
, 3, 1)
452 self
.assertRaises(IOError, memio
.seek
, -3, 1)
453 self
.assertRaises(IOError, memio
.seek
, -1, 2)
454 self
.assertRaises(IOError, memio
.seek
, 1, 1)
455 self
.assertRaises(IOError, memio
.seek
, 1, 2)
457 def test_textio_properties(self
):
458 memio
= self
.ioclass()
460 # These are just dummy values but we nevertheless check them for fear
461 # of unexpected breakage.
462 self
.assertIsNone(memio
.encoding
)
463 self
.assertIsNone(memio
.errors
)
464 self
.assertFalse(memio
.line_buffering
)
466 def test_newline_none(self
):
468 memio
= self
.ioclass("a\nb\r\nc\rd", newline
=None)
469 self
.assertEqual(list(memio
), ["a\n", "b\n", "c\n", "d"])
471 self
.assertEqual(memio
.read(1), "a")
472 self
.assertEqual(memio
.read(2), "\nb")
473 self
.assertEqual(memio
.read(2), "\nc")
474 self
.assertEqual(memio
.read(1), "\n")
475 memio
= self
.ioclass(newline
=None)
476 self
.assertEqual(2, memio
.write("a\n"))
477 self
.assertEqual(3, memio
.write("b\r\n"))
478 self
.assertEqual(3, memio
.write("c\rd"))
480 self
.assertEqual(memio
.read(), "a\nb\nc\nd")
481 memio
= self
.ioclass("a\r\nb", newline
=None)
482 self
.assertEqual(memio
.read(3), "a\nb")
484 def test_newline_empty(self
):
486 memio
= self
.ioclass("a\nb\r\nc\rd", newline
="")
487 self
.assertEqual(list(memio
), ["a\n", "b\r\n", "c\r", "d"])
489 self
.assertEqual(memio
.read(4), "a\nb\r")
490 self
.assertEqual(memio
.read(2), "\nc")
491 self
.assertEqual(memio
.read(1), "\r")
492 memio
= self
.ioclass(newline
="")
493 self
.assertEqual(2, memio
.write("a\n"))
494 self
.assertEqual(2, memio
.write("b\r"))
495 self
.assertEqual(2, memio
.write("\nc"))
496 self
.assertEqual(2, memio
.write("\rd"))
498 self
.assertEqual(list(memio
), ["a\n", "b\r\n", "c\r", "d"])
500 def test_newline_lf(self
):
502 memio
= self
.ioclass("a\nb\r\nc\rd")
503 self
.assertEqual(list(memio
), ["a\n", "b\r\n", "c\rd"])
505 def test_newline_cr(self
):
507 memio
= self
.ioclass("a\nb\r\nc\rd", newline
="\r")
509 self
.assertEqual(memio
.read(), "a\rb\r\rc\rd")
511 self
.assertEqual(list(memio
), ["a\r", "b\r", "\r", "c\r", "d"])
513 def test_newline_crlf(self
):
515 memio
= self
.ioclass("a\nb\r\nc\rd", newline
="\r\n")
517 self
.assertEqual(memio
.read(), "a\r\nb\r\r\nc\rd")
519 self
.assertEqual(list(memio
), ["a\r\n", "b\r\r\n", "c\rd"])
521 def test_issue5265(self
):
522 # StringIO can duplicate newlines in universal newlines mode
523 memio
= self
.ioclass("a\r\nb\r\n", newline
=None)
524 self
.assertEqual(memio
.read(5), "a\nb\n")
527 class CBytesIOTest(PyBytesIOTest
):
529 UnsupportedOperation
= io
.UnsupportedOperation
531 class CStringIOTest(PyStringIOTest
):
532 ioclass
= io
.StringIO
533 UnsupportedOperation
= io
.UnsupportedOperation
535 # XXX: For the Python version of io.StringIO, this is highly
536 # dependent on the encoding used for the underlying buffer.
537 def test_widechar(self
):
538 buf
= self
.buftype("\U0002030a\U00020347")
539 memio
= self
.ioclass(buf
)
541 self
.assertEqual(memio
.getvalue(), buf
)
542 self
.assertEqual(memio
.write(buf
), len(buf
))
543 self
.assertEqual(memio
.tell(), len(buf
))
544 self
.assertEqual(memio
.getvalue(), buf
)
545 self
.assertEqual(memio
.write(buf
), len(buf
))
546 self
.assertEqual(memio
.tell(), len(buf
) * 2)
547 self
.assertEqual(memio
.getvalue(), buf
+ buf
)
551 tests
= [PyBytesIOTest
, PyStringIOTest
, CBytesIOTest
, CStringIOTest
]
552 support
.run_unittest(*tests
)
554 if __name__
== '__main__':