#1153769: document PEP 237 changes to string formatting.
[python.git] / Lib / test / test_memoryio.py
blob0b5ec9f96ebb3d167d65106a724f11470f1e48bf
1 """Unit tests for memory-based file-like objects.
2 StringIO -- for unicode strings
3 BytesIO -- for bytes
4 """
6 from __future__ import unicode_literals
8 import unittest
9 from test import test_support
11 import io
12 import sys
13 import array
15 try:
16 import _bytesio
17 has_c_implementation = True
18 except ImportError:
19 has_c_implementation = False
22 class MemoryTestMixin:
24 def write_ops(self, f, t):
25 self.assertEqual(f.write(t("blah.")), 5)
26 self.assertEqual(f.seek(0), 0)
27 self.assertEqual(f.write(t("Hello.")), 6)
28 self.assertEqual(f.tell(), 6)
29 self.assertEqual(f.seek(5), 5)
30 self.assertEqual(f.tell(), 5)
31 self.assertEqual(f.write(t(" world\n\n\n")), 9)
32 self.assertEqual(f.seek(0), 0)
33 self.assertEqual(f.write(t("h")), 1)
34 self.assertEqual(f.truncate(12), 12)
35 self.assertEqual(f.tell(), 12)
37 def test_write(self):
38 buf = self.buftype("hello world\n")
39 memio = self.ioclass(buf)
41 self.write_ops(memio, self.buftype)
42 self.assertEqual(memio.getvalue(), buf)
43 memio = self.ioclass()
44 self.write_ops(memio, self.buftype)
45 self.assertEqual(memio.getvalue(), buf)
46 self.assertRaises(TypeError, memio.write, None)
47 memio.close()
48 self.assertRaises(ValueError, memio.write, self.buftype(""))
50 def test_writelines(self):
51 buf = self.buftype("1234567890")
52 memio = self.ioclass()
54 self.assertEqual(memio.writelines([buf] * 100), None)
55 self.assertEqual(memio.getvalue(), buf * 100)
56 memio.writelines([])
57 self.assertEqual(memio.getvalue(), buf * 100)
58 memio = self.ioclass()
59 self.assertRaises(TypeError, memio.writelines, [buf] + [1])
60 self.assertEqual(memio.getvalue(), buf)
61 self.assertRaises(TypeError, memio.writelines, None)
62 memio.close()
63 self.assertRaises(ValueError, memio.writelines, [])
65 def test_writelines_error(self):
66 memio = self.ioclass()
67 def error_gen():
68 yield self.buftype('spam')
69 raise KeyboardInterrupt
71 self.assertRaises(KeyboardInterrupt, memio.writelines, error_gen())
73 def test_truncate(self):
74 buf = self.buftype("1234567890")
75 memio = self.ioclass(buf)
77 self.assertRaises(ValueError, memio.truncate, -1)
78 memio.seek(6)
79 self.assertEqual(memio.truncate(), 6)
80 self.assertEqual(memio.getvalue(), buf[:6])
81 self.assertEqual(memio.truncate(4), 4)
82 self.assertEqual(memio.getvalue(), buf[:4])
83 self.assertEqual(memio.tell(), 4)
84 memio.write(buf)
85 self.assertEqual(memio.getvalue(), buf[:4] + buf)
86 pos = memio.tell()
87 self.assertEqual(memio.truncate(None), pos)
88 self.assertEqual(memio.tell(), pos)
89 self.assertRaises(TypeError, memio.truncate, '0')
90 memio.close()
91 self.assertRaises(ValueError, memio.truncate, 0)
93 def test_init(self):
94 buf = self.buftype("1234567890")
95 memio = self.ioclass(buf)
96 self.assertEqual(memio.getvalue(), buf)
97 memio = self.ioclass(None)
98 self.assertEqual(memio.getvalue(), self.EOF)
99 memio.__init__(buf * 2)
100 self.assertEqual(memio.getvalue(), buf * 2)
101 memio.__init__(buf)
102 self.assertEqual(memio.getvalue(), buf)
104 def test_read(self):
105 buf = self.buftype("1234567890")
106 memio = self.ioclass(buf)
108 self.assertEqual(memio.read(0), self.EOF)
109 self.assertEqual(memio.read(1), buf[:1])
110 self.assertEqual(memio.read(4), buf[1:5])
111 self.assertEqual(memio.read(900), buf[5:])
112 self.assertEqual(memio.read(), self.EOF)
113 memio.seek(0)
114 self.assertEqual(memio.read(), buf)
115 self.assertEqual(memio.read(), self.EOF)
116 self.assertEqual(memio.tell(), 10)
117 memio.seek(0)
118 self.assertEqual(memio.read(-1), buf)
119 memio.seek(0)
120 self.assertEqual(type(memio.read()), type(buf))
121 memio.seek(100)
122 self.assertEqual(type(memio.read()), type(buf))
123 memio.seek(0)
124 self.assertEqual(memio.read(None), buf)
125 self.assertRaises(TypeError, memio.read, '')
126 memio.close()
127 self.assertRaises(ValueError, memio.read)
129 def test_readline(self):
130 buf = self.buftype("1234567890\n")
131 memio = self.ioclass(buf * 2)
133 self.assertEqual(memio.readline(0), self.EOF)
134 self.assertEqual(memio.readline(), buf)
135 self.assertEqual(memio.readline(), buf)
136 self.assertEqual(memio.readline(), self.EOF)
137 memio.seek(0)
138 self.assertEqual(memio.readline(5), buf[:5])
139 self.assertEqual(memio.readline(5), buf[5:10])
140 self.assertEqual(memio.readline(5), buf[10:15])
141 memio.seek(0)
142 self.assertEqual(memio.readline(-1), buf)
143 memio.seek(0)
144 self.assertEqual(memio.readline(0), self.EOF)
146 buf = self.buftype("1234567890\n")
147 memio = self.ioclass((buf * 3)[:-1])
148 self.assertEqual(memio.readline(), buf)
149 self.assertEqual(memio.readline(), buf)
150 self.assertEqual(memio.readline(), buf[:-1])
151 self.assertEqual(memio.readline(), self.EOF)
152 memio.seek(0)
153 self.assertEqual(type(memio.readline()), type(buf))
154 self.assertEqual(memio.readline(None), buf)
155 self.assertRaises(TypeError, memio.readline, '')
156 memio.close()
157 self.assertRaises(ValueError, memio.readline)
159 def test_readlines(self):
160 buf = self.buftype("1234567890\n")
161 memio = self.ioclass(buf * 10)
163 self.assertEqual(memio.readlines(), [buf] * 10)
164 memio.seek(5)
165 self.assertEqual(memio.readlines(), [buf[5:]] + [buf] * 9)
166 memio.seek(0)
167 self.assertEqual(memio.readlines(15), [buf] * 2)
168 memio.seek(0)
169 self.assertEqual(memio.readlines(-1), [buf] * 10)
170 memio.seek(0)
171 self.assertEqual(memio.readlines(0), [buf] * 10)
172 memio.seek(0)
173 self.assertEqual(type(memio.readlines()[0]), type(buf))
174 memio.seek(0)
175 self.assertEqual(memio.readlines(None), [buf] * 10)
176 self.assertRaises(TypeError, memio.readlines, '')
177 memio.close()
178 self.assertRaises(ValueError, memio.readlines)
180 def test_iterator(self):
181 buf = self.buftype("1234567890\n")
182 memio = self.ioclass(buf * 10)
184 self.assertEqual(iter(memio), memio)
185 self.failUnless(hasattr(memio, '__iter__'))
186 self.failUnless(hasattr(memio, 'next'))
187 i = 0
188 for line in memio:
189 self.assertEqual(line, buf)
190 i += 1
191 self.assertEqual(i, 10)
192 memio.seek(0)
193 i = 0
194 for line in memio:
195 self.assertEqual(line, buf)
196 i += 1
197 self.assertEqual(i, 10)
198 memio = self.ioclass(buf * 2)
199 memio.close()
200 self.assertRaises(ValueError, memio.next)
202 def test_getvalue(self):
203 buf = self.buftype("1234567890")
204 memio = self.ioclass(buf)
206 self.assertEqual(memio.getvalue(), buf)
207 memio.read()
208 self.assertEqual(memio.getvalue(), buf)
209 self.assertEqual(type(memio.getvalue()), type(buf))
210 memio = self.ioclass(buf * 1000)
211 self.assertEqual(memio.getvalue()[-3:], self.buftype("890"))
212 memio = self.ioclass(buf)
213 memio.close()
214 self.assertRaises(ValueError, memio.getvalue)
216 def test_seek(self):
217 buf = self.buftype("1234567890")
218 memio = self.ioclass(buf)
220 memio.read(5)
221 self.assertRaises(ValueError, memio.seek, -1)
222 self.assertRaises(ValueError, memio.seek, 1, -1)
223 self.assertRaises(ValueError, memio.seek, 1, 3)
224 self.assertEqual(memio.seek(0), 0)
225 self.assertEqual(memio.seek(0, 0), 0)
226 self.assertEqual(memio.read(), buf)
227 self.assertEqual(memio.seek(3), 3)
228 self.assertEqual(memio.seek(0, 1), 3)
229 self.assertEqual(memio.read(), buf[3:])
230 self.assertEqual(memio.seek(len(buf)), len(buf))
231 self.assertEqual(memio.read(), self.EOF)
232 memio.seek(len(buf) + 1)
233 self.assertEqual(memio.read(), self.EOF)
234 self.assertEqual(memio.seek(0, 2), len(buf))
235 self.assertEqual(memio.read(), self.EOF)
236 memio.close()
237 self.assertRaises(ValueError, memio.seek, 0)
239 def test_overseek(self):
240 buf = self.buftype("1234567890")
241 memio = self.ioclass(buf)
243 self.assertEqual(memio.seek(len(buf) + 1), 11)
244 self.assertEqual(memio.read(), self.EOF)
245 self.assertEqual(memio.tell(), 11)
246 self.assertEqual(memio.getvalue(), buf)
247 memio.write(self.EOF)
248 self.assertEqual(memio.getvalue(), buf)
249 memio.write(buf)
250 self.assertEqual(memio.getvalue(), buf + self.buftype('\0') + buf)
252 def test_tell(self):
253 buf = self.buftype("1234567890")
254 memio = self.ioclass(buf)
256 self.assertEqual(memio.tell(), 0)
257 memio.seek(5)
258 self.assertEqual(memio.tell(), 5)
259 memio.seek(10000)
260 self.assertEqual(memio.tell(), 10000)
261 memio.close()
262 self.assertRaises(ValueError, memio.tell)
264 def test_flush(self):
265 buf = self.buftype("1234567890")
266 memio = self.ioclass(buf)
268 self.assertEqual(memio.flush(), None)
270 def test_flags(self):
271 memio = self.ioclass()
273 self.assertEqual(memio.writable(), True)
274 self.assertEqual(memio.readable(), True)
275 self.assertEqual(memio.seekable(), True)
276 self.assertEqual(memio.isatty(), False)
277 self.assertEqual(memio.closed, False)
278 memio.close()
279 self.assertEqual(memio.writable(), True)
280 self.assertEqual(memio.readable(), True)
281 self.assertEqual(memio.seekable(), True)
282 self.assertRaises(ValueError, memio.isatty)
283 self.assertEqual(memio.closed, True)
285 def test_subclassing(self):
286 buf = self.buftype("1234567890")
287 def test1():
288 class MemIO(self.ioclass):
289 pass
290 m = MemIO(buf)
291 return m.getvalue()
292 def test2():
293 class MemIO(self.ioclass):
294 def __init__(me, a, b):
295 self.ioclass.__init__(me, a)
296 m = MemIO(buf, None)
297 return m.getvalue()
298 self.assertEqual(test1(), buf)
299 self.assertEqual(test2(), buf)
302 class PyBytesIOTest(MemoryTestMixin, unittest.TestCase):
303 @staticmethod
304 def buftype(s):
305 return s.encode("ascii")
306 ioclass = io._BytesIO
307 EOF = b""
309 def test_read1(self):
310 buf = self.buftype("1234567890")
311 memio = self.ioclass(buf)
313 self.assertRaises(TypeError, memio.read1)
314 self.assertEqual(memio.read(), buf)
316 def test_readinto(self):
317 buf = self.buftype("1234567890")
318 memio = self.ioclass(buf)
320 b = bytearray(b"hello")
321 self.assertEqual(memio.readinto(b), 5)
322 self.assertEqual(b, b"12345")
323 self.assertEqual(memio.readinto(b), 5)
324 self.assertEqual(b, b"67890")
325 self.assertEqual(memio.readinto(b), 0)
326 self.assertEqual(b, b"67890")
327 b = bytearray(b"hello world")
328 memio.seek(0)
329 self.assertEqual(memio.readinto(b), 10)
330 self.assertEqual(b, b"1234567890d")
331 b = bytearray(b"")
332 memio.seek(0)
333 self.assertEqual(memio.readinto(b), 0)
334 self.assertEqual(b, b"")
335 self.assertRaises(TypeError, memio.readinto, '')
336 a = array.array(b'b', map(ord, b"hello world"))
337 memio = self.ioclass(buf)
338 memio.readinto(a)
339 self.assertEqual(a.tostring(), b"1234567890d")
340 memio.close()
341 self.assertRaises(ValueError, memio.readinto, b)
343 def test_relative_seek(self):
344 buf = self.buftype("1234567890")
345 memio = self.ioclass(buf)
347 self.assertEqual(memio.seek(-1, 1), 0)
348 self.assertEqual(memio.seek(3, 1), 3)
349 self.assertEqual(memio.seek(-4, 1), 0)
350 self.assertEqual(memio.seek(-1, 2), 9)
351 self.assertEqual(memio.seek(1, 1), 10)
352 self.assertEqual(memio.seek(1, 2), 11)
353 memio.seek(-3, 2)
354 self.assertEqual(memio.read(), buf[-3:])
355 memio.seek(0)
356 memio.seek(1, 1)
357 self.assertEqual(memio.read(), buf[1:])
359 def test_unicode(self):
360 memio = self.ioclass()
362 self.assertRaises(TypeError, self.ioclass, "1234567890")
363 self.assertRaises(TypeError, memio.write, "1234567890")
364 self.assertRaises(TypeError, memio.writelines, ["1234567890"])
366 def test_bytes_array(self):
367 buf = b"1234567890"
369 a = array.array(b'b', map(ord, buf))
370 memio = self.ioclass(a)
371 self.assertEqual(memio.getvalue(), buf)
372 self.assertEqual(memio.write(a), 10)
373 self.assertEqual(memio.getvalue(), buf)
376 class PyStringIOTest(MemoryTestMixin, unittest.TestCase):
377 buftype = unicode
378 ioclass = io.StringIO
379 EOF = ""
381 def test_relative_seek(self):
382 memio = self.ioclass()
384 self.assertRaises(IOError, memio.seek, -1, 1)
385 self.assertRaises(IOError, memio.seek, 3, 1)
386 self.assertRaises(IOError, memio.seek, -3, 1)
387 self.assertRaises(IOError, memio.seek, -1, 2)
388 self.assertRaises(IOError, memio.seek, 1, 1)
389 self.assertRaises(IOError, memio.seek, 1, 2)
391 # XXX: For the Python version of io.StringIO, this is highly
392 # dependent on the encoding used for the underlying buffer.
393 # def test_widechar(self):
394 # buf = self.buftype("\U0002030a\U00020347")
395 # memio = self.ioclass(buf)
397 # self.assertEqual(memio.getvalue(), buf)
398 # self.assertEqual(memio.write(buf), len(buf))
399 # self.assertEqual(memio.tell(), len(buf))
400 # self.assertEqual(memio.getvalue(), buf)
401 # self.assertEqual(memio.write(buf), len(buf))
402 # self.assertEqual(memio.tell(), len(buf) * 2)
403 # self.assertEqual(memio.getvalue(), buf + buf)
405 if has_c_implementation:
406 class CBytesIOTest(PyBytesIOTest):
407 ioclass = io.BytesIO
409 def test_main():
410 tests = [PyBytesIOTest, PyStringIOTest]
411 if has_c_implementation:
412 tests.extend([CBytesIOTest])
413 test_support.run_unittest(*tests)
415 if __name__ == '__main__':
416 test_main()