blob: b40d4194c99415edb70b2fb48a10a425d57b8106 [file] [log] [blame]
Guido van Rossum4dfe8a12006-04-22 23:28:04 +00001"""Unit tests for the bytes type."""
2
Guido van Rossumd624f182006-04-24 13:47:05 +00003import os
4import re
Guido van Rossum4dfe8a12006-04-22 23:28:04 +00005import sys
Guido van Rossumd624f182006-04-24 13:47:05 +00006import tempfile
Guido van Rossum4dfe8a12006-04-22 23:28:04 +00007import unittest
8import test.test_support
9
10
11class BytesTest(unittest.TestCase):
12
13 def test_basics(self):
14 b = bytes()
15 self.assertEqual(type(b), bytes)
16 self.assertEqual(b.__class__, bytes)
17
18 def test_empty_sequence(self):
19 b = bytes()
20 self.assertEqual(len(b), 0)
21 self.assertRaises(IndexError, lambda: b[0])
22 self.assertRaises(IndexError, lambda: b[1])
23 self.assertRaises(IndexError, lambda: b[sys.maxint])
24 self.assertRaises(IndexError, lambda: b[sys.maxint+1])
25 self.assertRaises(IndexError, lambda: b[10**100])
26 self.assertRaises(IndexError, lambda: b[-1])
27 self.assertRaises(IndexError, lambda: b[-2])
28 self.assertRaises(IndexError, lambda: b[-sys.maxint])
29 self.assertRaises(IndexError, lambda: b[-sys.maxint-1])
30 self.assertRaises(IndexError, lambda: b[-sys.maxint-2])
31 self.assertRaises(IndexError, lambda: b[-10**100])
32
33 def test_from_list(self):
34 ints = list(range(256))
35 b = bytes(i for i in ints)
36 self.assertEqual(len(b), 256)
37 self.assertEqual(list(b), ints)
38
39 def test_from_index(self):
40 class C:
41 def __init__(self, i=0):
42 self.i = i
43 def __index__(self):
44 return self.i
45 b = bytes([C(), C(1), C(254), C(255)])
46 self.assertEqual(list(b), [0, 1, 254, 255])
Guido van Rossume06b6b82006-04-23 07:43:54 +000047 self.assertRaises(ValueError, bytes, [C(-1)])
48 self.assertRaises(ValueError, bytes, [C(256)])
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000049
50 def test_constructor_type_errors(self):
Guido van Rossumd624f182006-04-24 13:47:05 +000051 self.assertRaises(TypeError, bytes, 0.0)
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000052 class C:
53 pass
Guido van Rossume06b6b82006-04-23 07:43:54 +000054 self.assertRaises(TypeError, bytes, ["0"])
55 self.assertRaises(TypeError, bytes, [0.0])
56 self.assertRaises(TypeError, bytes, [None])
57 self.assertRaises(TypeError, bytes, [C()])
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000058
59 def test_constructor_value_errors(self):
Guido van Rossume06b6b82006-04-23 07:43:54 +000060 self.assertRaises(ValueError, bytes, [-1])
61 self.assertRaises(ValueError, bytes, [-sys.maxint])
62 self.assertRaises(ValueError, bytes, [-sys.maxint-1])
Thomas Woutersd204a712006-08-22 13:41:17 +000063 self.assertRaises(ValueError, bytes, [-sys.maxint-2])
64 self.assertRaises(ValueError, bytes, [-10**100])
Guido van Rossume06b6b82006-04-23 07:43:54 +000065 self.assertRaises(ValueError, bytes, [256])
66 self.assertRaises(ValueError, bytes, [257])
67 self.assertRaises(ValueError, bytes, [sys.maxint])
Thomas Woutersd204a712006-08-22 13:41:17 +000068 self.assertRaises(ValueError, bytes, [sys.maxint+1])
69 self.assertRaises(ValueError, bytes, [10**100])
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000070
71 def test_repr(self):
Georg Brandlee91be42007-02-24 19:41:35 +000072 self.assertEqual(repr(bytes()), "b''")
73 self.assertEqual(repr(bytes([0])), "b'\\0'")
74 self.assertEqual(repr(bytes([0, 1, 254, 255])), "b'\\0\\x01\\xfe\\xff'")
75 self.assertEqual(repr(bytes('abc')), "b'abc'")
76 self.assertEqual(repr(bytes("'")), "b'\\''")
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000077
78 def test_compare(self):
79 b1 = bytes([1, 2, 3])
80 b2 = bytes([1, 2, 3])
81 b3 = bytes([1, 3])
82
83 self.failUnless(b1 == b2)
84 self.failUnless(b2 != b3)
85 self.failUnless(b1 <= b2)
86 self.failUnless(b1 <= b3)
87 self.failUnless(b1 < b3)
88 self.failUnless(b1 >= b2)
89 self.failUnless(b3 >= b2)
90 self.failUnless(b3 > b2)
91
92 self.failIf(b1 != b2)
93 self.failIf(b2 == b3)
94 self.failIf(b1 > b2)
95 self.failIf(b1 > b3)
96 self.failIf(b1 >= b3)
97 self.failIf(b1 < b2)
98 self.failIf(b3 < b2)
99 self.failIf(b3 <= b2)
100
101 def test_nohash(self):
102 self.assertRaises(TypeError, hash, bytes())
103
104 def test_doc(self):
105 self.failUnless(bytes.__doc__ != None)
106 self.failUnless(bytes.__doc__.startswith("bytes("))
107
Guido van Rossumd624f182006-04-24 13:47:05 +0000108 def test_buffer_api(self):
109 short_sample = "Hello world\n"
110 sample = short_sample + "x"*(20 - len(short_sample))
111 tfn = tempfile.mktemp()
112 try:
113 # Prepare
114 with open(tfn, "wb") as f:
115 f.write(short_sample)
116 # Test readinto
117 with open(tfn, "rb") as f:
118 b = bytes([ord('x')]*20)
119 n = f.readinto(b)
120 self.assertEqual(n, len(short_sample))
121 self.assertEqual(list(b), map(ord, sample))
122 # Test writing in binary mode
123 with open(tfn, "wb") as f:
124 f.write(b)
125 with open(tfn, "rb") as f:
126 self.assertEqual(f.read(), sample)
127 # Test writing in text mode
128 with open(tfn, "w") as f:
129 f.write(b)
130 with open(tfn, "r") as f:
131 self.assertEqual(f.read(), sample)
132 # Can't use readinto in text mode
133 with open(tfn, "r") as f:
134 self.assertRaises(TypeError, f.readinto, b)
135 finally:
136 try:
137 os.remove(tfn)
138 except os.error:
139 pass
140
141 def test_reversed(self):
142 input = map(ord, "Hello")
143 b = bytes(input)
144 output = list(reversed(b))
145 input.reverse()
146 self.assertEqual(output, input)
147
148 def test_getslice(self):
149 def by(s):
150 return bytes(map(ord, s))
151 b = by("Hello, world")
152
153 self.assertEqual(b[:5], by("Hello"))
154 self.assertEqual(b[1:5], by("ello"))
155 self.assertEqual(b[5:7], by(", "))
156 self.assertEqual(b[7:], by("world"))
157 self.assertEqual(b[7:12], by("world"))
158 self.assertEqual(b[7:100], by("world"))
159
160 self.assertEqual(b[:-7], by("Hello"))
161 self.assertEqual(b[-11:-7], by("ello"))
162 self.assertEqual(b[-7:-5], by(", "))
163 self.assertEqual(b[-5:], by("world"))
164 self.assertEqual(b[-5:12], by("world"))
165 self.assertEqual(b[-5:100], by("world"))
166 self.assertEqual(b[-100:5], by("Hello"))
167
Thomas Wouters376446d2006-12-19 08:30:14 +0000168 def test_extended_getslice(self):
169 # Test extended slicing by comparing with list slicing.
170 L = list(range(255))
171 b = bytes(L)
172 indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
173 for start in indices:
174 for stop in indices:
175 # Skip step 0 (invalid)
176 for step in indices[1:]:
177 self.assertEqual(b[start:stop:step], bytes(L[start:stop:step]))
178
Guido van Rossumd624f182006-04-24 13:47:05 +0000179 def test_regexps(self):
180 def by(s):
181 return bytes(map(ord, s))
182 b = by("Hello, world")
183 self.assertEqual(re.findall(r"\w+", b), [by("Hello"), by("world")])
184
185 def test_setitem(self):
186 b = bytes([1, 2, 3])
187 b[1] = 100
188 self.assertEqual(b, bytes([1, 100, 3]))
189 b[-1] = 200
190 self.assertEqual(b, bytes([1, 100, 200]))
191 class C:
192 def __init__(self, i=0):
193 self.i = i
194 def __index__(self):
195 return self.i
196 b[0] = C(10)
197 self.assertEqual(b, bytes([10, 100, 200]))
198 try:
199 b[3] = 0
200 self.fail("Didn't raise IndexError")
201 except IndexError:
202 pass
203 try:
204 b[-10] = 0
205 self.fail("Didn't raise IndexError")
206 except IndexError:
207 pass
208 try:
209 b[0] = 256
210 self.fail("Didn't raise ValueError")
211 except ValueError:
212 pass
213 try:
214 b[0] = C(-1)
215 self.fail("Didn't raise ValueError")
216 except ValueError:
217 pass
218 try:
219 b[0] = None
220 self.fail("Didn't raise TypeError")
221 except TypeError:
222 pass
223
224 def test_delitem(self):
225 b = bytes(range(10))
226 del b[0]
227 self.assertEqual(b, bytes(range(1, 10)))
228 del b[-1]
229 self.assertEqual(b, bytes(range(1, 9)))
230 del b[4]
231 self.assertEqual(b, bytes([1, 2, 3, 4, 6, 7, 8]))
232
233 def test_setslice(self):
234 b = bytes(range(10))
235 self.assertEqual(list(b), list(range(10)))
236
237 b[0:5] = bytes([1, 1, 1, 1, 1])
238 self.assertEqual(b, bytes([1, 1, 1, 1, 1, 5, 6, 7, 8, 9]))
239
240 del b[0:-5]
241 self.assertEqual(b, bytes([5, 6, 7, 8, 9]))
242
243 b[0:0] = bytes([0, 1, 2, 3, 4])
244 self.assertEqual(b, bytes(range(10)))
245
246 b[-7:-3] = bytes([100, 101])
247 self.assertEqual(b, bytes([0, 1, 2, 100, 101, 7, 8, 9]))
248
249 b[3:5] = [3, 4, 5, 6]
250 self.assertEqual(b, bytes(range(10)))
Thomas Wouters9a6e62b2006-08-23 23:20:29 +0000251
252 b[3:0] = [42, 42, 42]
253 self.assertEqual(b, bytes([0, 1, 2, 42, 42, 42, 3, 4, 5, 6, 7, 8, 9]))
Guido van Rossumd624f182006-04-24 13:47:05 +0000254
Thomas Wouters376446d2006-12-19 08:30:14 +0000255 def test_extended_set_del_slice(self):
256 indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
257 for start in indices:
258 for stop in indices:
259 # Skip invalid step 0
260 for step in indices[1:]:
261 L = list(range(255))
262 b = bytes(L)
263 # Make sure we have a slice of exactly the right length,
264 # but with different data.
265 data = L[start:stop:step]
266 data.reverse()
267 L[start:stop:step] = data
268 b[start:stop:step] = data
269 self.assertEquals(b, bytes(L))
270
271 del L[start:stop:step]
272 del b[start:stop:step]
273 self.assertEquals(b, bytes(L))
274
Guido van Rossumd624f182006-04-24 13:47:05 +0000275 def test_setslice_trap(self):
276 # This test verifies that we correctly handle assigning self
277 # to a slice of self (the old Lambert Meertens trap).
278 b = bytes(range(256))
279 b[8:] = b
280 self.assertEqual(b, bytes(list(range(8)) + list(range(256))))
281
282 def test_encoding(self):
283 sample = u"Hello world\n\u1234\u5678\u9abc\udef0"
284 for enc in ("utf8", "utf16"):
285 b = bytes(sample, enc)
286 self.assertEqual(b, bytes(map(ord, sample.encode(enc))))
287 self.assertRaises(UnicodeEncodeError, bytes, sample, "latin1")
288 b = bytes(sample, "latin1", "ignore")
289 self.assertEqual(b, bytes(sample[:-4]))
290
291 def test_decode(self):
292 sample = u"Hello world\n\u1234\u5678\u9abc\def0\def0"
293 for enc in ("utf8", "utf16"):
294 b = bytes(sample, enc)
295 self.assertEqual(b.decode(enc), sample)
296 sample = u"Hello world\n\x80\x81\xfe\xff"
297 b = bytes(sample, "latin1")
298 self.assertRaises(UnicodeDecodeError, b.decode, "utf8")
299 self.assertEqual(b.decode("utf8", "ignore"), "Hello world\n")
300
301 def test_from_buffer(self):
302 sample = "Hello world\n\x80\x81\xfe\xff"
303 buf = buffer(sample)
304 b = bytes(buf)
305 self.assertEqual(b, bytes(map(ord, sample)))
306
307 def test_to_str(self):
308 sample = "Hello world\n\x80\x81\xfe\xff"
309 b = bytes(sample)
310 self.assertEqual(str(b), sample)
311
312 def test_from_int(self):
313 b = bytes(0)
314 self.assertEqual(b, bytes())
315 b = bytes(10)
316 self.assertEqual(b, bytes([0]*10))
317 b = bytes(10000)
318 self.assertEqual(b, bytes([0]*10000))
319
320 def test_concat(self):
321 b1 = bytes("abc")
322 b2 = bytes("def")
323 self.assertEqual(b1 + b2, bytes("abcdef"))
324 self.assertRaises(TypeError, lambda: b1 + "def")
325 self.assertRaises(TypeError, lambda: "abc" + b2)
326
327 def test_repeat(self):
328 b = bytes("abc")
329 self.assertEqual(b * 3, bytes("abcabcabc"))
330 self.assertEqual(b * 0, bytes())
331 self.assertEqual(b * -1, bytes())
332 self.assertRaises(TypeError, lambda: b * 3.14)
333 self.assertRaises(TypeError, lambda: 3.14 * b)
334 self.assertRaises(MemoryError, lambda: b * sys.maxint)
Guido van Rossum13e57212006-04-27 22:54:26 +0000335
336 def test_repeat_1char(self):
Guido van Rossumd624f182006-04-24 13:47:05 +0000337 self.assertEqual(bytes('x')*100, bytes('x'*100))
338
Guido van Rossum13e57212006-04-27 22:54:26 +0000339 def test_iconcat(self):
340 b = bytes("abc")
341 b1 = b
342 b += bytes("def")
343 self.assertEqual(b, bytes("abcdef"))
344 self.assertEqual(b, b1)
345 self.failUnless(b is b1)
346
347 def test_irepeat(self):
348 b = bytes("abc")
349 b1 = b
350 b *= 3
351 self.assertEqual(b, bytes("abcabcabc"))
352 self.assertEqual(b, b1)
353 self.failUnless(b is b1)
354
355 def test_irepeat_1char(self):
356 b = bytes("x")
357 b1 = b
358 b *= 100
359 self.assertEqual(b, bytes("x"*100))
360 self.assertEqual(b, b1)
361 self.failUnless(b is b1)
362
363 def test_contains(self):
364 b = bytes("abc")
365 self.failUnless(ord('a') in b)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000366 self.failUnless(int(ord('a')) in b)
Guido van Rossum13e57212006-04-27 22:54:26 +0000367 self.failIf(200 in b)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000368 self.failIf(200 in b)
Guido van Rossum13e57212006-04-27 22:54:26 +0000369 self.assertRaises(ValueError, lambda: 300 in b)
370 self.assertRaises(ValueError, lambda: -1 in b)
371 self.assertRaises(TypeError, lambda: None in b)
372 self.assertRaises(TypeError, lambda: float(ord('a')) in b)
373 self.assertRaises(TypeError, lambda: "a" in b)
374 self.failUnless(bytes("") in b)
375 self.failUnless(bytes("a") in b)
376 self.failUnless(bytes("b") in b)
377 self.failUnless(bytes("c") in b)
378 self.failUnless(bytes("ab") in b)
379 self.failUnless(bytes("bc") in b)
380 self.failUnless(bytes("abc") in b)
381 self.failIf(bytes("ac") in b)
382 self.failIf(bytes("d") in b)
383 self.failIf(bytes("dab") in b)
384 self.failIf(bytes("abd") in b)
385
Guido van Rossum20188312006-05-05 15:15:40 +0000386 def test_alloc(self):
387 b = bytes()
388 alloc = b.__alloc__()
389 self.assert_(alloc >= 0)
390 seq = [alloc]
391 for i in range(100):
392 b += bytes("x")
393 alloc = b.__alloc__()
394 self.assert_(alloc >= len(b))
395 if alloc not in seq:
396 seq.append(alloc)
Guido van Rossum08e8b7a2006-05-26 19:16:09 +0000397 #print seq
Guido van Rossum20188312006-05-05 15:15:40 +0000398
Georg Brandl0b9b9e02007-02-27 08:40:54 +0000399 def test_fromhex(self):
400 self.assertRaises(TypeError, bytes.fromhex)
401 self.assertRaises(TypeError, bytes.fromhex, 1)
402 self.assertEquals(bytes.fromhex(''), bytes())
403 b = bytes([0x1a, 0x2b, 0x30])
404 self.assertEquals(bytes.fromhex('1a2B30'), b)
405 self.assertEquals(bytes.fromhex(' 1A 2B 30 '), b)
406 self.assertEquals(bytes.fromhex(buffer('')), bytes())
407 self.assertEquals(bytes.fromhex(buffer('0000')), bytes([0, 0]))
408 self.assertRaises(ValueError, bytes.fromhex, 'a')
409 self.assertRaises(ValueError, bytes.fromhex, 'rt')
410 self.assertRaises(ValueError, bytes.fromhex, '1a b cd')
411 self.assertRaises(ValueError, bytes.fromhex, '\x00')
412 self.assertRaises(ValueError, bytes.fromhex, '12 \x00 34')
413
Guido van Rossum20188312006-05-05 15:15:40 +0000414 def test_join(self):
415 self.assertEqual(bytes.join([]), bytes())
416 self.assertEqual(bytes.join([bytes()]), bytes())
417 for part in [("abc",), ("a", "bc"), ("ab", "c"), ("a", "b", "c")]:
418 lst = map(bytes, part)
419 self.assertEqual(bytes.join(lst), bytes("abc"))
420 self.assertEqual(bytes.join(tuple(lst)), bytes("abc"))
421 self.assertEqual(bytes.join(iter(lst)), bytes("abc"))
422 # XXX more...
Thomas Wouters00e41de2007-02-23 19:56:57 +0000423
424 def test_literal(self):
425 tests = [
426 (b"Wonderful spam", u"Wonderful spam"),
427 (br"Wonderful spam too", u"Wonderful spam too"),
428 (b"\xaa\x00\000\200", u"\xaa\x00\000\200"),
429 (br"\xaa\x00\000\200", ur"\xaa\x00\000\200"),
430 ]
431 for b, s in tests:
432 self.assertEqual(b, bytes(s, 'latin-1'))
433 for c in range(128, 256):
434 self.assertRaises(SyntaxError, eval,
435 'b"%s"' % chr(c))
Guido van Rossum20188312006-05-05 15:15:40 +0000436
Guido van Rossumd624f182006-04-24 13:47:05 +0000437 # Optimizations:
Guido van Rossume06b6b82006-04-23 07:43:54 +0000438 # __iter__? (optimization)
Guido van Rossumd624f182006-04-24 13:47:05 +0000439 # __reversed__? (optimization)
440
441 # XXX Some list methods?
442 # extended slicing
443 # extended slice assignment
444 # extend (same as b[len(b):] = src)
445 # reverse (in-place)
446 # remove
447 # pop
448 # NOT sort!
449 # With int arg:
Guido van Rossumd624f182006-04-24 13:47:05 +0000450 # index
451 # count
452 # append
453 # insert
454
455 # XXX Some string methods? (Those that don't use character properties)
456 # startswith
457 # endswidth
458 # find, rfind
Guido van Rossumd624f182006-04-24 13:47:05 +0000459 # index, rindex (bytes arg)
460 # join
461 # replace
462 # translate
463 # split, rsplit
464 # lstrip, rstrip, strip??
465
466 # XXX pickle and marshal support?
Guido van Rossume06b6b82006-04-23 07:43:54 +0000467
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000468
469def test_main():
Thomas Wouters5f6f27d2006-04-23 00:19:58 +0000470 test.test_support.run_unittest(BytesTest)
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000471
472
473if __name__ == "__main__":
Guido van Rossumd624f182006-04-24 13:47:05 +0000474 test_main()
475 ##unittest.main()