1"""Test the arraymodule.
2   Roger E. Masse
3"""
4
5import collections.abc
6import unittest
7from test import support
8from test.support import import_helper
9from test.support import os_helper
10from test.support import _2G
11import weakref
12import pickle
13import operator
14import struct
15import sys
16
17import array
18from array import _array_reconstructor as array_reconstructor
19
20sizeof_wchar = array.array('u').itemsize
21
22
23class ArraySubclass(array.array):
24    pass
25
26class ArraySubclassWithKwargs(array.array):
27    def __init__(self, typecode, newarg=None):
28        array.array.__init__(self)
29
30typecodes = 'ubBhHiIlLfdqQ'
31
32class MiscTest(unittest.TestCase):
33
34    def test_array_is_sequence(self):
35        self.assertIsInstance(array.array("B"), collections.abc.MutableSequence)
36        self.assertIsInstance(array.array("B"), collections.abc.Reversible)
37
38    def test_bad_constructor(self):
39        self.assertRaises(TypeError, array.array)
40        self.assertRaises(TypeError, array.array, spam=42)
41        self.assertRaises(TypeError, array.array, 'xx')
42        self.assertRaises(ValueError, array.array, 'x')
43
44    @support.cpython_only
45    def test_disallow_instantiation(self):
46        my_array = array.array("I")
47        support.check_disallow_instantiation(
48            self, type(iter(my_array)), my_array
49        )
50
51    @support.cpython_only
52    def test_immutable(self):
53        # bpo-43908: check that array.array is immutable
54        with self.assertRaises(TypeError):
55            array.array.foo = 1
56
57    def test_empty(self):
58        # Exercise code for handling zero-length arrays
59        a = array.array('B')
60        a[:] = a
61        self.assertEqual(len(a), 0)
62        self.assertEqual(len(a + a), 0)
63        self.assertEqual(len(a * 3), 0)
64        a += a
65        self.assertEqual(len(a), 0)
66
67
68# Machine format codes.
69#
70# Search for "enum machine_format_code" in Modules/arraymodule.c to get the
71# authoritative values.
72UNKNOWN_FORMAT = -1
73UNSIGNED_INT8 = 0
74SIGNED_INT8 = 1
75UNSIGNED_INT16_LE = 2
76UNSIGNED_INT16_BE = 3
77SIGNED_INT16_LE = 4
78SIGNED_INT16_BE = 5
79UNSIGNED_INT32_LE = 6
80UNSIGNED_INT32_BE = 7
81SIGNED_INT32_LE = 8
82SIGNED_INT32_BE = 9
83UNSIGNED_INT64_LE = 10
84UNSIGNED_INT64_BE = 11
85SIGNED_INT64_LE = 12
86SIGNED_INT64_BE = 13
87IEEE_754_FLOAT_LE = 14
88IEEE_754_FLOAT_BE = 15
89IEEE_754_DOUBLE_LE = 16
90IEEE_754_DOUBLE_BE = 17
91UTF16_LE = 18
92UTF16_BE = 19
93UTF32_LE = 20
94UTF32_BE = 21
95
96class ArrayReconstructorTest(unittest.TestCase):
97
98    def test_error(self):
99        self.assertRaises(TypeError, array_reconstructor,
100                          "", "b", 0, b"")
101        self.assertRaises(TypeError, array_reconstructor,
102                          str, "b", 0, b"")
103        self.assertRaises(TypeError, array_reconstructor,
104                          array.array, "b", '', b"")
105        self.assertRaises(TypeError, array_reconstructor,
106                          array.array, "b", 0, "")
107        self.assertRaises(ValueError, array_reconstructor,
108                          array.array, "?", 0, b"")
109        self.assertRaises(ValueError, array_reconstructor,
110                          array.array, "b", UNKNOWN_FORMAT, b"")
111        self.assertRaises(ValueError, array_reconstructor,
112                          array.array, "b", 22, b"")
113        self.assertRaises(ValueError, array_reconstructor,
114                          array.array, "d", 16, b"a")
115
116    def test_numbers(self):
117        testcases = (
118            (['B', 'H', 'I', 'L'], UNSIGNED_INT8, '=BBBB',
119             [0x80, 0x7f, 0, 0xff]),
120            (['b', 'h', 'i', 'l'], SIGNED_INT8, '=bbb',
121             [-0x80, 0x7f, 0]),
122            (['H', 'I', 'L'], UNSIGNED_INT16_LE, '<HHHH',
123             [0x8000, 0x7fff, 0, 0xffff]),
124            (['H', 'I', 'L'], UNSIGNED_INT16_BE, '>HHHH',
125             [0x8000, 0x7fff, 0, 0xffff]),
126            (['h', 'i', 'l'], SIGNED_INT16_LE, '<hhh',
127             [-0x8000, 0x7fff, 0]),
128            (['h', 'i', 'l'], SIGNED_INT16_BE, '>hhh',
129             [-0x8000, 0x7fff, 0]),
130            (['I', 'L'], UNSIGNED_INT32_LE, '<IIII',
131             [1<<31, (1<<31)-1, 0, (1<<32)-1]),
132            (['I', 'L'], UNSIGNED_INT32_BE, '>IIII',
133             [1<<31, (1<<31)-1, 0, (1<<32)-1]),
134            (['i', 'l'], SIGNED_INT32_LE, '<iii',
135             [-1<<31, (1<<31)-1, 0]),
136            (['i', 'l'], SIGNED_INT32_BE, '>iii',
137             [-1<<31, (1<<31)-1, 0]),
138            (['L'], UNSIGNED_INT64_LE, '<QQQQ',
139             [1<<31, (1<<31)-1, 0, (1<<32)-1]),
140            (['L'], UNSIGNED_INT64_BE, '>QQQQ',
141             [1<<31, (1<<31)-1, 0, (1<<32)-1]),
142            (['l'], SIGNED_INT64_LE, '<qqq',
143             [-1<<31, (1<<31)-1, 0]),
144            (['l'], SIGNED_INT64_BE, '>qqq',
145             [-1<<31, (1<<31)-1, 0]),
146            # The following tests for INT64 will raise an OverflowError
147            # when run on a 32-bit machine. The tests are simply skipped
148            # in that case.
149            (['L'], UNSIGNED_INT64_LE, '<QQQQ',
150             [1<<63, (1<<63)-1, 0, (1<<64)-1]),
151            (['L'], UNSIGNED_INT64_BE, '>QQQQ',
152             [1<<63, (1<<63)-1, 0, (1<<64)-1]),
153            (['l'], SIGNED_INT64_LE, '<qqq',
154             [-1<<63, (1<<63)-1, 0]),
155            (['l'], SIGNED_INT64_BE, '>qqq',
156             [-1<<63, (1<<63)-1, 0]),
157            (['f'], IEEE_754_FLOAT_LE, '<ffff',
158             [16711938.0, float('inf'), float('-inf'), -0.0]),
159            (['f'], IEEE_754_FLOAT_BE, '>ffff',
160             [16711938.0, float('inf'), float('-inf'), -0.0]),
161            (['d'], IEEE_754_DOUBLE_LE, '<dddd',
162             [9006104071832581.0, float('inf'), float('-inf'), -0.0]),
163            (['d'], IEEE_754_DOUBLE_BE, '>dddd',
164             [9006104071832581.0, float('inf'), float('-inf'), -0.0])
165        )
166        for testcase in testcases:
167            valid_typecodes, mformat_code, struct_fmt, values = testcase
168            arraystr = struct.pack(struct_fmt, *values)
169            for typecode in valid_typecodes:
170                try:
171                    a = array.array(typecode, values)
172                except OverflowError:
173                    continue  # Skip this test case.
174                b = array_reconstructor(
175                    array.array, typecode, mformat_code, arraystr)
176                self.assertEqual(a, b,
177                    msg="{0!r} != {1!r}; testcase={2!r}".format(a, b, testcase))
178
179    def test_unicode(self):
180        teststr = "Bonne Journ\xe9e \U0002030a\U00020347"
181        testcases = (
182            (UTF16_LE, "UTF-16-LE"),
183            (UTF16_BE, "UTF-16-BE"),
184            (UTF32_LE, "UTF-32-LE"),
185            (UTF32_BE, "UTF-32-BE")
186        )
187        for testcase in testcases:
188            mformat_code, encoding = testcase
189            a = array.array('u', teststr)
190            b = array_reconstructor(
191                array.array, 'u', mformat_code, teststr.encode(encoding))
192            self.assertEqual(a, b,
193                msg="{0!r} != {1!r}; testcase={2!r}".format(a, b, testcase))
194
195
196class BaseTest:
197    # Required class attributes (provided by subclasses
198    # typecode: the typecode to test
199    # example: an initializer usable in the constructor for this type
200    # smallerexample: the same length as example, but smaller
201    # biggerexample: the same length as example, but bigger
202    # outside: An entry that is not in example
203    # minitemsize: the minimum guaranteed itemsize
204
205    def assertEntryEqual(self, entry1, entry2):
206        self.assertEqual(entry1, entry2)
207
208    def badtypecode(self):
209        # Return a typecode that is different from our own
210        return typecodes[(typecodes.index(self.typecode)+1) % len(typecodes)]
211
212    def test_constructor(self):
213        a = array.array(self.typecode)
214        self.assertEqual(a.typecode, self.typecode)
215        self.assertGreaterEqual(a.itemsize, self.minitemsize)
216        self.assertRaises(TypeError, array.array, self.typecode, None)
217
218    def test_len(self):
219        a = array.array(self.typecode)
220        a.append(self.example[0])
221        self.assertEqual(len(a), 1)
222
223        a = array.array(self.typecode, self.example)
224        self.assertEqual(len(a), len(self.example))
225
226    def test_buffer_info(self):
227        a = array.array(self.typecode, self.example)
228        self.assertRaises(TypeError, a.buffer_info, 42)
229        bi = a.buffer_info()
230        self.assertIsInstance(bi, tuple)
231        self.assertEqual(len(bi), 2)
232        self.assertIsInstance(bi[0], int)
233        self.assertIsInstance(bi[1], int)
234        self.assertEqual(bi[1], len(a))
235
236    def test_byteswap(self):
237        if self.typecode == 'u':
238            example = '\U00100100'
239        else:
240            example = self.example
241        a = array.array(self.typecode, example)
242        self.assertRaises(TypeError, a.byteswap, 42)
243        if a.itemsize in (1, 2, 4, 8):
244            b = array.array(self.typecode, example)
245            b.byteswap()
246            if a.itemsize==1:
247                self.assertEqual(a, b)
248            else:
249                self.assertNotEqual(a, b)
250            b.byteswap()
251            self.assertEqual(a, b)
252
253    def test_copy(self):
254        import copy
255        a = array.array(self.typecode, self.example)
256        b = copy.copy(a)
257        self.assertNotEqual(id(a), id(b))
258        self.assertEqual(a, b)
259
260    def test_deepcopy(self):
261        import copy
262        a = array.array(self.typecode, self.example)
263        b = copy.deepcopy(a)
264        self.assertNotEqual(id(a), id(b))
265        self.assertEqual(a, b)
266
267    def test_reduce_ex(self):
268        a = array.array(self.typecode, self.example)
269        for protocol in range(3):
270            self.assertIs(a.__reduce_ex__(protocol)[0], array.array)
271        for protocol in range(3, pickle.HIGHEST_PROTOCOL + 1):
272            self.assertIs(a.__reduce_ex__(protocol)[0], array_reconstructor)
273
274    def test_pickle(self):
275        for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
276            a = array.array(self.typecode, self.example)
277            b = pickle.loads(pickle.dumps(a, protocol))
278            self.assertNotEqual(id(a), id(b))
279            self.assertEqual(a, b)
280
281            a = ArraySubclass(self.typecode, self.example)
282            a.x = 10
283            b = pickle.loads(pickle.dumps(a, protocol))
284            self.assertNotEqual(id(a), id(b))
285            self.assertEqual(a, b)
286            self.assertEqual(a.x, b.x)
287            self.assertEqual(type(a), type(b))
288
289    def test_pickle_for_empty_array(self):
290        for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
291            a = array.array(self.typecode)
292            b = pickle.loads(pickle.dumps(a, protocol))
293            self.assertNotEqual(id(a), id(b))
294            self.assertEqual(a, b)
295
296            a = ArraySubclass(self.typecode)
297            a.x = 10
298            b = pickle.loads(pickle.dumps(a, protocol))
299            self.assertNotEqual(id(a), id(b))
300            self.assertEqual(a, b)
301            self.assertEqual(a.x, b.x)
302            self.assertEqual(type(a), type(b))
303
304    def test_iterator_pickle(self):
305        orig = array.array(self.typecode, self.example)
306        data = list(orig)
307        data2 = data[::-1]
308        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
309            # initial iterator
310            itorig = iter(orig)
311            d = pickle.dumps((itorig, orig), proto)
312            it, a = pickle.loads(d)
313            a.fromlist(data2)
314            self.assertEqual(type(it), type(itorig))
315            self.assertEqual(list(it), data + data2)
316
317            # running iterator
318            next(itorig)
319            d = pickle.dumps((itorig, orig), proto)
320            it, a = pickle.loads(d)
321            a.fromlist(data2)
322            self.assertEqual(type(it), type(itorig))
323            self.assertEqual(list(it), data[1:] + data2)
324
325            # empty iterator
326            for i in range(1, len(data)):
327                next(itorig)
328            d = pickle.dumps((itorig, orig), proto)
329            it, a = pickle.loads(d)
330            a.fromlist(data2)
331            self.assertEqual(type(it), type(itorig))
332            self.assertEqual(list(it), data2)
333
334            # exhausted iterator
335            self.assertRaises(StopIteration, next, itorig)
336            d = pickle.dumps((itorig, orig), proto)
337            it, a = pickle.loads(d)
338            a.fromlist(data2)
339            self.assertEqual(list(it), [])
340
341    def test_exhausted_iterator(self):
342        a = array.array(self.typecode, self.example)
343        self.assertEqual(list(a), list(self.example))
344        exhit = iter(a)
345        empit = iter(a)
346        for x in exhit:  # exhaust the iterator
347            next(empit)  # not exhausted
348        a.append(self.outside)
349        self.assertEqual(list(exhit), [])
350        self.assertEqual(list(empit), [self.outside])
351        self.assertEqual(list(a), list(self.example) + [self.outside])
352
353    def test_reverse_iterator(self):
354        a = array.array(self.typecode, self.example)
355        self.assertEqual(list(a), list(self.example))
356        self.assertEqual(list(reversed(a)), list(iter(a))[::-1])
357
358    def test_reverse_iterator_picking(self):
359        orig = array.array(self.typecode, self.example)
360        data = list(orig)
361        data2 = [self.outside] + data
362        rev_data = data[len(data)-2::-1] + [self.outside]
363        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
364            # initial iterator
365            itorig = reversed(orig)
366            d = pickle.dumps((itorig, orig), proto)
367            it, a = pickle.loads(d)
368            a.insert(0, self.outside)
369            self.assertEqual(type(it), type(itorig))
370            self.assertEqual(list(it), rev_data)
371            self.assertEqual(list(a), data2)
372
373            # running iterator
374            next(itorig)
375            d = pickle.dumps((itorig, orig), proto)
376            it, a = pickle.loads(d)
377            a.insert(0, self.outside)
378            self.assertEqual(type(it), type(itorig))
379            self.assertEqual(list(it), rev_data[1:])
380            self.assertEqual(list(a), data2)
381
382            # empty iterator
383            for i in range(1, len(data)):
384                next(itorig)
385            d = pickle.dumps((itorig, orig), proto)
386            it, a = pickle.loads(d)
387            a.insert(0, self.outside)
388            self.assertEqual(type(it), type(itorig))
389            self.assertEqual(list(it), [])
390            self.assertEqual(list(a), data2)
391
392            # exhausted iterator
393            self.assertRaises(StopIteration, next, itorig)
394            d = pickle.dumps((itorig, orig), proto)
395            it, a = pickle.loads(d)
396            a.insert(0, self.outside)
397            self.assertEqual(list(it), [])
398            self.assertEqual(list(a), data2)
399
400    def test_exhausted_reverse_iterator(self):
401        a = array.array(self.typecode, self.example)
402        self.assertEqual(list(a), list(self.example))
403        exhit = reversed(a)
404        empit = reversed(a)
405        for x in exhit:  # exhaust the iterator
406            next(empit)  # Pointing past the 0th position.
407        a.insert(0, self.outside)
408        self.assertEqual(list(exhit), [])
409        # The iterator index points past the 0th position so inserting
410        # an element in the beginning does not make it appear.
411        self.assertEqual(list(empit), [])
412        self.assertEqual(list(a), [self.outside] + list(self.example))
413
414    def test_insert(self):
415        a = array.array(self.typecode, self.example)
416        a.insert(0, self.example[0])
417        self.assertEqual(len(a), 1+len(self.example))
418        self.assertEqual(a[0], a[1])
419        self.assertRaises(TypeError, a.insert)
420        self.assertRaises(TypeError, a.insert, None)
421        self.assertRaises(TypeError, a.insert, 0, None)
422
423        a = array.array(self.typecode, self.example)
424        a.insert(-1, self.example[0])
425        self.assertEqual(
426            a,
427            array.array(
428                self.typecode,
429                self.example[:-1] + self.example[:1] + self.example[-1:]
430            )
431        )
432
433        a = array.array(self.typecode, self.example)
434        a.insert(-1000, self.example[0])
435        self.assertEqual(
436            a,
437            array.array(self.typecode, self.example[:1] + self.example)
438        )
439
440        a = array.array(self.typecode, self.example)
441        a.insert(1000, self.example[0])
442        self.assertEqual(
443            a,
444            array.array(self.typecode, self.example + self.example[:1])
445        )
446
447    def test_tofromfile(self):
448        a = array.array(self.typecode, 2*self.example)
449        self.assertRaises(TypeError, a.tofile)
450        os_helper.unlink(os_helper.TESTFN)
451        f = open(os_helper.TESTFN, 'wb')
452        try:
453            a.tofile(f)
454            f.close()
455            b = array.array(self.typecode)
456            f = open(os_helper.TESTFN, 'rb')
457            self.assertRaises(TypeError, b.fromfile)
458            b.fromfile(f, len(self.example))
459            self.assertEqual(b, array.array(self.typecode, self.example))
460            self.assertNotEqual(a, b)
461            self.assertRaises(EOFError, b.fromfile, f, len(self.example)+1)
462            self.assertEqual(a, b)
463            f.close()
464        finally:
465            if not f.closed:
466                f.close()
467            os_helper.unlink(os_helper.TESTFN)
468
469    def test_fromfile_ioerror(self):
470        # Issue #5395: Check if fromfile raises a proper OSError
471        # instead of EOFError.
472        a = array.array(self.typecode)
473        f = open(os_helper.TESTFN, 'wb')
474        try:
475            self.assertRaises(OSError, a.fromfile, f, len(self.example))
476        finally:
477            f.close()
478            os_helper.unlink(os_helper.TESTFN)
479
480    def test_filewrite(self):
481        a = array.array(self.typecode, 2*self.example)
482        f = open(os_helper.TESTFN, 'wb')
483        try:
484            f.write(a)
485            f.close()
486            b = array.array(self.typecode)
487            f = open(os_helper.TESTFN, 'rb')
488            b.fromfile(f, len(self.example))
489            self.assertEqual(b, array.array(self.typecode, self.example))
490            self.assertNotEqual(a, b)
491            b.fromfile(f, len(self.example))
492            self.assertEqual(a, b)
493            f.close()
494        finally:
495            if not f.closed:
496                f.close()
497            os_helper.unlink(os_helper.TESTFN)
498
499    def test_tofromlist(self):
500        a = array.array(self.typecode, 2*self.example)
501        b = array.array(self.typecode)
502        self.assertRaises(TypeError, a.tolist, 42)
503        self.assertRaises(TypeError, b.fromlist)
504        self.assertRaises(TypeError, b.fromlist, 42)
505        self.assertRaises(TypeError, b.fromlist, [None])
506        b.fromlist(a.tolist())
507        self.assertEqual(a, b)
508
509    def test_tofrombytes(self):
510        a = array.array(self.typecode, 2*self.example)
511        b = array.array(self.typecode)
512        self.assertRaises(TypeError, a.tobytes, 42)
513        self.assertRaises(TypeError, b.frombytes)
514        self.assertRaises(TypeError, b.frombytes, 42)
515        b.frombytes(a.tobytes())
516        c = array.array(self.typecode, bytearray(a.tobytes()))
517        self.assertEqual(a, b)
518        self.assertEqual(a, c)
519        if a.itemsize>1:
520            self.assertRaises(ValueError, b.frombytes, b"x")
521
522    def test_fromarray(self):
523        a = array.array(self.typecode, self.example)
524        b = array.array(self.typecode, a)
525        self.assertEqual(a, b)
526
527    def test_repr(self):
528        a = array.array(self.typecode, 2*self.example)
529        self.assertEqual(a, eval(repr(a), {"array": array.array}))
530
531        a = array.array(self.typecode)
532        self.assertEqual(repr(a), "array('%s')" % self.typecode)
533
534    def test_str(self):
535        a = array.array(self.typecode, 2*self.example)
536        str(a)
537
538    def test_cmp(self):
539        a = array.array(self.typecode, self.example)
540        self.assertIs(a == 42, False)
541        self.assertIs(a != 42, True)
542
543        self.assertIs(a == a, True)
544        self.assertIs(a != a, False)
545        self.assertIs(a < a, False)
546        self.assertIs(a <= a, True)
547        self.assertIs(a > a, False)
548        self.assertIs(a >= a, True)
549
550        al = array.array(self.typecode, self.smallerexample)
551        ab = array.array(self.typecode, self.biggerexample)
552
553        self.assertIs(a == 2*a, False)
554        self.assertIs(a != 2*a, True)
555        self.assertIs(a < 2*a, True)
556        self.assertIs(a <= 2*a, True)
557        self.assertIs(a > 2*a, False)
558        self.assertIs(a >= 2*a, False)
559
560        self.assertIs(a == al, False)
561        self.assertIs(a != al, True)
562        self.assertIs(a < al, False)
563        self.assertIs(a <= al, False)
564        self.assertIs(a > al, True)
565        self.assertIs(a >= al, True)
566
567        self.assertIs(a == ab, False)
568        self.assertIs(a != ab, True)
569        self.assertIs(a < ab, True)
570        self.assertIs(a <= ab, True)
571        self.assertIs(a > ab, False)
572        self.assertIs(a >= ab, False)
573
574    def test_add(self):
575        a = array.array(self.typecode, self.example) \
576            + array.array(self.typecode, self.example[::-1])
577        self.assertEqual(
578            a,
579            array.array(self.typecode, self.example + self.example[::-1])
580        )
581
582        b = array.array(self.badtypecode())
583        self.assertRaises(TypeError, a.__add__, b)
584
585        self.assertRaises(TypeError, a.__add__, "bad")
586
587    def test_iadd(self):
588        a = array.array(self.typecode, self.example[::-1])
589        b = a
590        a += array.array(self.typecode, 2*self.example)
591        self.assertIs(a, b)
592        self.assertEqual(
593            a,
594            array.array(self.typecode, self.example[::-1]+2*self.example)
595        )
596        a = array.array(self.typecode, self.example)
597        a += a
598        self.assertEqual(
599            a,
600            array.array(self.typecode, self.example + self.example)
601        )
602
603        b = array.array(self.badtypecode())
604        self.assertRaises(TypeError, a.__add__, b)
605
606        self.assertRaises(TypeError, a.__iadd__, "bad")
607
608    def test_mul(self):
609        a = 5*array.array(self.typecode, self.example)
610        self.assertEqual(
611            a,
612            array.array(self.typecode, 5*self.example)
613        )
614
615        a = array.array(self.typecode, self.example)*5
616        self.assertEqual(
617            a,
618            array.array(self.typecode, self.example*5)
619        )
620
621        a = 0*array.array(self.typecode, self.example)
622        self.assertEqual(
623            a,
624            array.array(self.typecode)
625        )
626
627        a = (-1)*array.array(self.typecode, self.example)
628        self.assertEqual(
629            a,
630            array.array(self.typecode)
631        )
632
633        a = 5 * array.array(self.typecode, self.example[:1])
634        self.assertEqual(
635            a,
636            array.array(self.typecode, [a[0]] * 5)
637        )
638
639        self.assertRaises(TypeError, a.__mul__, "bad")
640
641    def test_imul(self):
642        a = array.array(self.typecode, self.example)
643        b = a
644
645        a *= 5
646        self.assertIs(a, b)
647        self.assertEqual(
648            a,
649            array.array(self.typecode, 5*self.example)
650        )
651
652        a *= 0
653        self.assertIs(a, b)
654        self.assertEqual(a, array.array(self.typecode))
655
656        a *= 1000
657        self.assertIs(a, b)
658        self.assertEqual(a, array.array(self.typecode))
659
660        a *= -1
661        self.assertIs(a, b)
662        self.assertEqual(a, array.array(self.typecode))
663
664        a = array.array(self.typecode, self.example)
665        a *= -1
666        self.assertEqual(a, array.array(self.typecode))
667
668        self.assertRaises(TypeError, a.__imul__, "bad")
669
670    def test_getitem(self):
671        a = array.array(self.typecode, self.example)
672        self.assertEntryEqual(a[0], self.example[0])
673        self.assertEntryEqual(a[0], self.example[0])
674        self.assertEntryEqual(a[-1], self.example[-1])
675        self.assertEntryEqual(a[-1], self.example[-1])
676        self.assertEntryEqual(a[len(self.example)-1], self.example[-1])
677        self.assertEntryEqual(a[-len(self.example)], self.example[0])
678        self.assertRaises(TypeError, a.__getitem__)
679        self.assertRaises(IndexError, a.__getitem__, len(self.example))
680        self.assertRaises(IndexError, a.__getitem__, -len(self.example)-1)
681
682    def test_setitem(self):
683        a = array.array(self.typecode, self.example)
684        a[0] = a[-1]
685        self.assertEntryEqual(a[0], a[-1])
686
687        a = array.array(self.typecode, self.example)
688        a[0] = a[-1]
689        self.assertEntryEqual(a[0], a[-1])
690
691        a = array.array(self.typecode, self.example)
692        a[-1] = a[0]
693        self.assertEntryEqual(a[0], a[-1])
694
695        a = array.array(self.typecode, self.example)
696        a[-1] = a[0]
697        self.assertEntryEqual(a[0], a[-1])
698
699        a = array.array(self.typecode, self.example)
700        a[len(self.example)-1] = a[0]
701        self.assertEntryEqual(a[0], a[-1])
702
703        a = array.array(self.typecode, self.example)
704        a[-len(self.example)] = a[-1]
705        self.assertEntryEqual(a[0], a[-1])
706
707        self.assertRaises(TypeError, a.__setitem__)
708        self.assertRaises(TypeError, a.__setitem__, None)
709        self.assertRaises(TypeError, a.__setitem__, 0, None)
710        self.assertRaises(
711            IndexError,
712            a.__setitem__,
713            len(self.example), self.example[0]
714        )
715        self.assertRaises(
716            IndexError,
717            a.__setitem__,
718            -len(self.example)-1, self.example[0]
719        )
720
721    def test_delitem(self):
722        a = array.array(self.typecode, self.example)
723        del a[0]
724        self.assertEqual(
725            a,
726            array.array(self.typecode, self.example[1:])
727        )
728
729        a = array.array(self.typecode, self.example)
730        del a[-1]
731        self.assertEqual(
732            a,
733            array.array(self.typecode, self.example[:-1])
734        )
735
736        a = array.array(self.typecode, self.example)
737        del a[len(self.example)-1]
738        self.assertEqual(
739            a,
740            array.array(self.typecode, self.example[:-1])
741        )
742
743        a = array.array(self.typecode, self.example)
744        del a[-len(self.example)]
745        self.assertEqual(
746            a,
747            array.array(self.typecode, self.example[1:])
748        )
749
750        self.assertRaises(TypeError, a.__delitem__)
751        self.assertRaises(TypeError, a.__delitem__, None)
752        self.assertRaises(IndexError, a.__delitem__, len(self.example))
753        self.assertRaises(IndexError, a.__delitem__, -len(self.example)-1)
754
755    def test_getslice(self):
756        a = array.array(self.typecode, self.example)
757        self.assertEqual(a[:], a)
758
759        self.assertEqual(
760            a[1:],
761            array.array(self.typecode, self.example[1:])
762        )
763
764        self.assertEqual(
765            a[:1],
766            array.array(self.typecode, self.example[:1])
767        )
768
769        self.assertEqual(
770            a[:-1],
771            array.array(self.typecode, self.example[:-1])
772        )
773
774        self.assertEqual(
775            a[-1:],
776            array.array(self.typecode, self.example[-1:])
777        )
778
779        self.assertEqual(
780            a[-1:-1],
781            array.array(self.typecode)
782        )
783
784        self.assertEqual(
785            a[2:1],
786            array.array(self.typecode)
787        )
788
789        self.assertEqual(
790            a[1000:],
791            array.array(self.typecode)
792        )
793        self.assertEqual(a[-1000:], a)
794        self.assertEqual(a[:1000], a)
795        self.assertEqual(
796            a[:-1000],
797            array.array(self.typecode)
798        )
799        self.assertEqual(a[-1000:1000], a)
800        self.assertEqual(
801            a[2000:1000],
802            array.array(self.typecode)
803        )
804
805    def test_extended_getslice(self):
806        # Test extended slicing by comparing with list slicing
807        # (Assumes list conversion works correctly, too)
808        a = array.array(self.typecode, self.example)
809        indices = (0, None, 1, 3, 19, 100, sys.maxsize, -1, -2, -31, -100)
810        for start in indices:
811            for stop in indices:
812                # Everything except the initial 0 (invalid step)
813                for step in indices[1:]:
814                    self.assertEqual(list(a[start:stop:step]),
815                                     list(a)[start:stop:step])
816
817    def test_setslice(self):
818        a = array.array(self.typecode, self.example)
819        a[:1] = a
820        self.assertEqual(
821            a,
822            array.array(self.typecode, self.example + self.example[1:])
823        )
824
825        a = array.array(self.typecode, self.example)
826        a[:-1] = a
827        self.assertEqual(
828            a,
829            array.array(self.typecode, self.example + self.example[-1:])
830        )
831
832        a = array.array(self.typecode, self.example)
833        a[-1:] = a
834        self.assertEqual(
835            a,
836            array.array(self.typecode, self.example[:-1] + self.example)
837        )
838
839        a = array.array(self.typecode, self.example)
840        a[1:] = a
841        self.assertEqual(
842            a,
843            array.array(self.typecode, self.example[:1] + self.example)
844        )
845
846        a = array.array(self.typecode, self.example)
847        a[1:-1] = a
848        self.assertEqual(
849            a,
850            array.array(
851                self.typecode,
852                self.example[:1] + self.example + self.example[-1:]
853            )
854        )
855
856        a = array.array(self.typecode, self.example)
857        a[1000:] = a
858        self.assertEqual(
859            a,
860            array.array(self.typecode, 2*self.example)
861        )
862
863        a = array.array(self.typecode, self.example)
864        a[-1000:] = a
865        self.assertEqual(
866            a,
867            array.array(self.typecode, self.example)
868        )
869
870        a = array.array(self.typecode, self.example)
871        a[:1000] = a
872        self.assertEqual(
873            a,
874            array.array(self.typecode, self.example)
875        )
876
877        a = array.array(self.typecode, self.example)
878        a[:-1000] = a
879        self.assertEqual(
880            a,
881            array.array(self.typecode, 2*self.example)
882        )
883
884        a = array.array(self.typecode, self.example)
885        a[1:0] = a
886        self.assertEqual(
887            a,
888            array.array(self.typecode, self.example[:1] + self.example + self.example[1:])
889        )
890
891        a = array.array(self.typecode, self.example)
892        a[2000:1000] = a
893        self.assertEqual(
894            a,
895            array.array(self.typecode, 2*self.example)
896        )
897
898        a = array.array(self.typecode, self.example)
899        self.assertRaises(TypeError, a.__setitem__, slice(0, 0), None)
900        self.assertRaises(TypeError, a.__setitem__, slice(0, 1), None)
901
902        b = array.array(self.badtypecode())
903        self.assertRaises(TypeError, a.__setitem__, slice(0, 0), b)
904        self.assertRaises(TypeError, a.__setitem__, slice(0, 1), b)
905
906    def test_extended_set_del_slice(self):
907        indices = (0, None, 1, 3, 19, 100, sys.maxsize, -1, -2, -31, -100)
908        for start in indices:
909            for stop in indices:
910                # Everything except the initial 0 (invalid step)
911                for step in indices[1:]:
912                    a = array.array(self.typecode, self.example)
913                    L = list(a)
914                    # Make sure we have a slice of exactly the right length,
915                    # but with (hopefully) different data.
916                    data = L[start:stop:step]
917                    data.reverse()
918                    L[start:stop:step] = data
919                    a[start:stop:step] = array.array(self.typecode, data)
920                    self.assertEqual(a, array.array(self.typecode, L))
921
922                    del L[start:stop:step]
923                    del a[start:stop:step]
924                    self.assertEqual(a, array.array(self.typecode, L))
925
926    def test_index(self):
927        example = 2*self.example
928        a = array.array(self.typecode, example)
929        self.assertRaises(TypeError, a.index)
930        for x in example:
931            self.assertEqual(a.index(x), example.index(x))
932        self.assertRaises(ValueError, a.index, None)
933        self.assertRaises(ValueError, a.index, self.outside)
934
935        a = array.array('i', [-2, -1, 0, 0, 1, 2])
936        self.assertEqual(a.index(0), 2)
937        self.assertEqual(a.index(0, 2), 2)
938        self.assertEqual(a.index(0, -4), 2)
939        self.assertEqual(a.index(-2, -10), 0)
940        self.assertEqual(a.index(0, 3), 3)
941        self.assertEqual(a.index(0, -3), 3)
942        self.assertEqual(a.index(0, 3, 4), 3)
943        self.assertEqual(a.index(0, -3, -2), 3)
944        self.assertRaises(ValueError, a.index, 2, 0, -10)
945
946    def test_count(self):
947        example = 2*self.example
948        a = array.array(self.typecode, example)
949        self.assertRaises(TypeError, a.count)
950        for x in example:
951            self.assertEqual(a.count(x), example.count(x))
952        self.assertEqual(a.count(self.outside), 0)
953        self.assertEqual(a.count(None), 0)
954
955    def test_remove(self):
956        for x in self.example:
957            example = 2*self.example
958            a = array.array(self.typecode, example)
959            pos = example.index(x)
960            example2 = example[:pos] + example[pos+1:]
961            a.remove(x)
962            self.assertEqual(a, array.array(self.typecode, example2))
963
964        a = array.array(self.typecode, self.example)
965        self.assertRaises(ValueError, a.remove, self.outside)
966
967        self.assertRaises(ValueError, a.remove, None)
968
969    def test_pop(self):
970        a = array.array(self.typecode)
971        self.assertRaises(IndexError, a.pop)
972
973        a = array.array(self.typecode, 2*self.example)
974        self.assertRaises(TypeError, a.pop, 42, 42)
975        self.assertRaises(TypeError, a.pop, None)
976        self.assertRaises(IndexError, a.pop, len(a))
977        self.assertRaises(IndexError, a.pop, -len(a)-1)
978
979        self.assertEntryEqual(a.pop(0), self.example[0])
980        self.assertEqual(
981            a,
982            array.array(self.typecode, self.example[1:]+self.example)
983        )
984        self.assertEntryEqual(a.pop(1), self.example[2])
985        self.assertEqual(
986            a,
987            array.array(self.typecode, self.example[1:2]+self.example[3:]+self.example)
988        )
989        self.assertEntryEqual(a.pop(0), self.example[1])
990        self.assertEntryEqual(a.pop(), self.example[-1])
991        self.assertEqual(
992            a,
993            array.array(self.typecode, self.example[3:]+self.example[:-1])
994        )
995
996    def test_reverse(self):
997        a = array.array(self.typecode, self.example)
998        self.assertRaises(TypeError, a.reverse, 42)
999        a.reverse()
1000        self.assertEqual(
1001            a,
1002            array.array(self.typecode, self.example[::-1])
1003        )
1004
1005    def test_extend(self):
1006        a = array.array(self.typecode, self.example)
1007        self.assertRaises(TypeError, a.extend)
1008        a.extend(array.array(self.typecode, self.example[::-1]))
1009        self.assertEqual(
1010            a,
1011            array.array(self.typecode, self.example+self.example[::-1])
1012        )
1013
1014        a = array.array(self.typecode, self.example)
1015        a.extend(a)
1016        self.assertEqual(
1017            a,
1018            array.array(self.typecode, self.example+self.example)
1019        )
1020
1021        b = array.array(self.badtypecode())
1022        self.assertRaises(TypeError, a.extend, b)
1023
1024        a = array.array(self.typecode, self.example)
1025        a.extend(self.example[::-1])
1026        self.assertEqual(
1027            a,
1028            array.array(self.typecode, self.example+self.example[::-1])
1029        )
1030
1031    def test_constructor_with_iterable_argument(self):
1032        a = array.array(self.typecode, iter(self.example))
1033        b = array.array(self.typecode, self.example)
1034        self.assertEqual(a, b)
1035
1036        # non-iterable argument
1037        self.assertRaises(TypeError, array.array, self.typecode, 10)
1038
1039        # pass through errors raised in __iter__
1040        class A:
1041            def __iter__(self):
1042                raise UnicodeError
1043        self.assertRaises(UnicodeError, array.array, self.typecode, A())
1044
1045        # pass through errors raised in next()
1046        def B():
1047            raise UnicodeError
1048            yield None
1049        self.assertRaises(UnicodeError, array.array, self.typecode, B())
1050
1051    def test_coveritertraverse(self):
1052        try:
1053            import gc
1054        except ImportError:
1055            self.skipTest('gc module not available')
1056        a = array.array(self.typecode)
1057        l = [iter(a)]
1058        l.append(l)
1059        gc.collect()
1060
1061    def test_buffer(self):
1062        a = array.array(self.typecode, self.example)
1063        m = memoryview(a)
1064        expected = m.tobytes()
1065        self.assertEqual(a.tobytes(), expected)
1066        self.assertEqual(a.tobytes()[0], expected[0])
1067        # Resizing is forbidden when there are buffer exports.
1068        # For issue 4509, we also check after each error that
1069        # the array was not modified.
1070        self.assertRaises(BufferError, a.append, a[0])
1071        self.assertEqual(m.tobytes(), expected)
1072        self.assertRaises(BufferError, a.extend, a[0:1])
1073        self.assertEqual(m.tobytes(), expected)
1074        self.assertRaises(BufferError, a.remove, a[0])
1075        self.assertEqual(m.tobytes(), expected)
1076        self.assertRaises(BufferError, a.pop, 0)
1077        self.assertEqual(m.tobytes(), expected)
1078        self.assertRaises(BufferError, a.fromlist, a.tolist())
1079        self.assertEqual(m.tobytes(), expected)
1080        self.assertRaises(BufferError, a.frombytes, a.tobytes())
1081        self.assertEqual(m.tobytes(), expected)
1082        if self.typecode == 'u':
1083            self.assertRaises(BufferError, a.fromunicode, a.tounicode())
1084            self.assertEqual(m.tobytes(), expected)
1085        self.assertRaises(BufferError, operator.imul, a, 2)
1086        self.assertEqual(m.tobytes(), expected)
1087        self.assertRaises(BufferError, operator.imul, a, 0)
1088        self.assertEqual(m.tobytes(), expected)
1089        self.assertRaises(BufferError, operator.setitem, a, slice(0, 0), a)
1090        self.assertEqual(m.tobytes(), expected)
1091        self.assertRaises(BufferError, operator.delitem, a, 0)
1092        self.assertEqual(m.tobytes(), expected)
1093        self.assertRaises(BufferError, operator.delitem, a, slice(0, 1))
1094        self.assertEqual(m.tobytes(), expected)
1095
1096    def test_weakref(self):
1097        s = array.array(self.typecode, self.example)
1098        p = weakref.proxy(s)
1099        self.assertEqual(p.tobytes(), s.tobytes())
1100        s = None
1101        support.gc_collect()  # For PyPy or other GCs.
1102        self.assertRaises(ReferenceError, len, p)
1103
1104    @unittest.skipUnless(hasattr(sys, 'getrefcount'),
1105                         'test needs sys.getrefcount()')
1106    def test_bug_782369(self):
1107        for i in range(10):
1108            b = array.array('B', range(64))
1109        rc = sys.getrefcount(10)
1110        for i in range(10):
1111            b = array.array('B', range(64))
1112        self.assertEqual(rc, sys.getrefcount(10))
1113
1114    def test_subclass_with_kwargs(self):
1115        # SF bug #1486663 -- this used to erroneously raise a TypeError
1116        ArraySubclassWithKwargs('b', newarg=1)
1117
1118    def test_create_from_bytes(self):
1119        # XXX This test probably needs to be moved in a subclass or
1120        # generalized to use self.typecode.
1121        a = array.array('H', b"1234")
1122        self.assertEqual(len(a) * a.itemsize, 4)
1123
1124    @support.cpython_only
1125    def test_sizeof_with_buffer(self):
1126        a = array.array(self.typecode, self.example)
1127        basesize = support.calcvobjsize('Pn2Pi')
1128        buffer_size = a.buffer_info()[1] * a.itemsize
1129        support.check_sizeof(self, a, basesize + buffer_size)
1130
1131    @support.cpython_only
1132    def test_sizeof_without_buffer(self):
1133        a = array.array(self.typecode)
1134        basesize = support.calcvobjsize('Pn2Pi')
1135        support.check_sizeof(self, a, basesize)
1136
1137    def test_initialize_with_unicode(self):
1138        if self.typecode != 'u':
1139            with self.assertRaises(TypeError) as cm:
1140                a = array.array(self.typecode, 'foo')
1141            self.assertIn("cannot use a str", str(cm.exception))
1142            with self.assertRaises(TypeError) as cm:
1143                a = array.array(self.typecode, array.array('u', 'foo'))
1144            self.assertIn("cannot use a unicode array", str(cm.exception))
1145        else:
1146            a = array.array(self.typecode, "foo")
1147            a = array.array(self.typecode, array.array('u', 'foo'))
1148
1149    @support.cpython_only
1150    def test_obsolete_write_lock(self):
1151        _testcapi = import_helper.import_module('_testcapi')
1152        a = array.array('B', b"")
1153        self.assertRaises(BufferError, _testcapi.getbuffer_with_null_view, a)
1154
1155    def test_free_after_iterating(self):
1156        support.check_free_after_iterating(self, iter, array.array,
1157                                           (self.typecode,))
1158        support.check_free_after_iterating(self, reversed, array.array,
1159                                           (self.typecode,))
1160
1161class StringTest(BaseTest):
1162
1163    def test_setitem(self):
1164        super().test_setitem()
1165        a = array.array(self.typecode, self.example)
1166        self.assertRaises(TypeError, a.__setitem__, 0, self.example[:2])
1167
1168class UnicodeTest(StringTest, unittest.TestCase):
1169    typecode = 'u'
1170    example = '\x01\u263a\x00\ufeff'
1171    smallerexample = '\x01\u263a\x00\ufefe'
1172    biggerexample = '\x01\u263a\x01\ufeff'
1173    outside = str('\x33')
1174    minitemsize = 2
1175
1176    def test_unicode(self):
1177        self.assertRaises(TypeError, array.array, 'b', 'foo')
1178
1179        a = array.array('u', '\xa0\xc2\u1234')
1180        a.fromunicode(' ')
1181        a.fromunicode('')
1182        a.fromunicode('')
1183        a.fromunicode('\x11abc\xff\u1234')
1184        s = a.tounicode()
1185        self.assertEqual(s, '\xa0\xc2\u1234 \x11abc\xff\u1234')
1186        self.assertEqual(a.itemsize, sizeof_wchar)
1187
1188        s = '\x00="\'a\\b\x80\xff\u0000\u0001\u1234'
1189        a = array.array('u', s)
1190        self.assertEqual(
1191            repr(a),
1192            "array('u', '\\x00=\"\\'a\\\\b\\x80\xff\\x00\\x01\u1234')")
1193
1194        self.assertRaises(TypeError, a.fromunicode)
1195
1196    def test_issue17223(self):
1197        # this used to crash
1198        if sizeof_wchar == 4:
1199            # U+FFFFFFFF is an invalid code point in Unicode 6.0
1200            invalid_str = b'\xff\xff\xff\xff'
1201        else:
1202            # PyUnicode_FromUnicode() cannot fail with 16-bit wchar_t
1203            self.skipTest("specific to 32-bit wchar_t")
1204        a = array.array('u', invalid_str)
1205        self.assertRaises(ValueError, a.tounicode)
1206        self.assertRaises(ValueError, str, a)
1207
1208class NumberTest(BaseTest):
1209
1210    def test_extslice(self):
1211        a = array.array(self.typecode, range(5))
1212        self.assertEqual(a[::], a)
1213        self.assertEqual(a[::2], array.array(self.typecode, [0,2,4]))
1214        self.assertEqual(a[1::2], array.array(self.typecode, [1,3]))
1215        self.assertEqual(a[::-1], array.array(self.typecode, [4,3,2,1,0]))
1216        self.assertEqual(a[::-2], array.array(self.typecode, [4,2,0]))
1217        self.assertEqual(a[3::-2], array.array(self.typecode, [3,1]))
1218        self.assertEqual(a[-100:100:], a)
1219        self.assertEqual(a[100:-100:-1], a[::-1])
1220        self.assertEqual(a[-100:100:2], array.array(self.typecode, [0,2,4]))
1221        self.assertEqual(a[1000:2000:2], array.array(self.typecode, []))
1222        self.assertEqual(a[-1000:-2000:-2], array.array(self.typecode, []))
1223
1224    def test_delslice(self):
1225        a = array.array(self.typecode, range(5))
1226        del a[::2]
1227        self.assertEqual(a, array.array(self.typecode, [1,3]))
1228        a = array.array(self.typecode, range(5))
1229        del a[1::2]
1230        self.assertEqual(a, array.array(self.typecode, [0,2,4]))
1231        a = array.array(self.typecode, range(5))
1232        del a[1::-2]
1233        self.assertEqual(a, array.array(self.typecode, [0,2,3,4]))
1234        a = array.array(self.typecode, range(10))
1235        del a[::1000]
1236        self.assertEqual(a, array.array(self.typecode, [1,2,3,4,5,6,7,8,9]))
1237        # test issue7788
1238        a = array.array(self.typecode, range(10))
1239        del a[9::1<<333]
1240
1241    def test_assignment(self):
1242        a = array.array(self.typecode, range(10))
1243        a[::2] = array.array(self.typecode, [42]*5)
1244        self.assertEqual(a, array.array(self.typecode, [42, 1, 42, 3, 42, 5, 42, 7, 42, 9]))
1245        a = array.array(self.typecode, range(10))
1246        a[::-4] = array.array(self.typecode, [10]*3)
1247        self.assertEqual(a, array.array(self.typecode, [0, 10, 2, 3, 4, 10, 6, 7, 8 ,10]))
1248        a = array.array(self.typecode, range(4))
1249        a[::-1] = a
1250        self.assertEqual(a, array.array(self.typecode, [3, 2, 1, 0]))
1251        a = array.array(self.typecode, range(10))
1252        b = a[:]
1253        c = a[:]
1254        ins = array.array(self.typecode, range(2))
1255        a[2:3] = ins
1256        b[slice(2,3)] = ins
1257        c[2:3:] = ins
1258
1259    def test_iterationcontains(self):
1260        a = array.array(self.typecode, range(10))
1261        self.assertEqual(list(a), list(range(10)))
1262        b = array.array(self.typecode, [20])
1263        self.assertEqual(a[-1] in a, True)
1264        self.assertEqual(b[0] not in a, True)
1265
1266    def check_overflow(self, lower, upper):
1267        # method to be used by subclasses
1268
1269        # should not overflow assigning lower limit
1270        a = array.array(self.typecode, [lower])
1271        a[0] = lower
1272        # should overflow assigning less than lower limit
1273        self.assertRaises(OverflowError, array.array, self.typecode, [lower-1])
1274        self.assertRaises(OverflowError, a.__setitem__, 0, lower-1)
1275        # should not overflow assigning upper limit
1276        a = array.array(self.typecode, [upper])
1277        a[0] = upper
1278        # should overflow assigning more than upper limit
1279        self.assertRaises(OverflowError, array.array, self.typecode, [upper+1])
1280        self.assertRaises(OverflowError, a.__setitem__, 0, upper+1)
1281
1282    def test_subclassing(self):
1283        typecode = self.typecode
1284        class ExaggeratingArray(array.array):
1285            __slots__ = ['offset']
1286
1287            def __new__(cls, typecode, data, offset):
1288                return array.array.__new__(cls, typecode, data)
1289
1290            def __init__(self, typecode, data, offset):
1291                self.offset = offset
1292
1293            def __getitem__(self, i):
1294                return array.array.__getitem__(self, i) + self.offset
1295
1296        a = ExaggeratingArray(self.typecode, [3, 6, 7, 11], 4)
1297        self.assertEntryEqual(a[0], 7)
1298
1299        self.assertRaises(AttributeError, setattr, a, "color", "blue")
1300
1301    def test_frombytearray(self):
1302        a = array.array('b', range(10))
1303        b = array.array(self.typecode, a)
1304        self.assertEqual(a, b)
1305
1306class IntegerNumberTest(NumberTest):
1307    def test_type_error(self):
1308        a = array.array(self.typecode)
1309        a.append(42)
1310        with self.assertRaises(TypeError):
1311            a.append(42.0)
1312        with self.assertRaises(TypeError):
1313            a[0] = 42.0
1314
1315class Intable:
1316    def __init__(self, num):
1317        self._num = num
1318    def __index__(self):
1319        return self._num
1320    def __int__(self):
1321        return self._num
1322    def __sub__(self, other):
1323        return Intable(int(self) - int(other))
1324    def __add__(self, other):
1325        return Intable(int(self) + int(other))
1326
1327class SignedNumberTest(IntegerNumberTest):
1328    example = [-1, 0, 1, 42, 0x7f]
1329    smallerexample = [-1, 0, 1, 42, 0x7e]
1330    biggerexample = [-1, 0, 1, 43, 0x7f]
1331    outside = 23
1332
1333    def test_overflow(self):
1334        a = array.array(self.typecode)
1335        lower = -1 * int(pow(2, a.itemsize * 8 - 1))
1336        upper = int(pow(2, a.itemsize * 8 - 1)) - 1
1337        self.check_overflow(lower, upper)
1338        self.check_overflow(Intable(lower), Intable(upper))
1339
1340class UnsignedNumberTest(IntegerNumberTest):
1341    example = [0, 1, 17, 23, 42, 0xff]
1342    smallerexample = [0, 1, 17, 23, 42, 0xfe]
1343    biggerexample = [0, 1, 17, 23, 43, 0xff]
1344    outside = 0xaa
1345
1346    def test_overflow(self):
1347        a = array.array(self.typecode)
1348        lower = 0
1349        upper = int(pow(2, a.itemsize * 8)) - 1
1350        self.check_overflow(lower, upper)
1351        self.check_overflow(Intable(lower), Intable(upper))
1352
1353    def test_bytes_extend(self):
1354        s = bytes(self.example)
1355
1356        a = array.array(self.typecode, self.example)
1357        a.extend(s)
1358        self.assertEqual(
1359            a,
1360            array.array(self.typecode, self.example+self.example)
1361        )
1362
1363        a = array.array(self.typecode, self.example)
1364        a.extend(bytearray(reversed(s)))
1365        self.assertEqual(
1366            a,
1367            array.array(self.typecode, self.example+self.example[::-1])
1368        )
1369
1370
1371class ByteTest(SignedNumberTest, unittest.TestCase):
1372    typecode = 'b'
1373    minitemsize = 1
1374
1375class UnsignedByteTest(UnsignedNumberTest, unittest.TestCase):
1376    typecode = 'B'
1377    minitemsize = 1
1378
1379class ShortTest(SignedNumberTest, unittest.TestCase):
1380    typecode = 'h'
1381    minitemsize = 2
1382
1383class UnsignedShortTest(UnsignedNumberTest, unittest.TestCase):
1384    typecode = 'H'
1385    minitemsize = 2
1386
1387class IntTest(SignedNumberTest, unittest.TestCase):
1388    typecode = 'i'
1389    minitemsize = 2
1390
1391class UnsignedIntTest(UnsignedNumberTest, unittest.TestCase):
1392    typecode = 'I'
1393    minitemsize = 2
1394
1395class LongTest(SignedNumberTest, unittest.TestCase):
1396    typecode = 'l'
1397    minitemsize = 4
1398
1399class UnsignedLongTest(UnsignedNumberTest, unittest.TestCase):
1400    typecode = 'L'
1401    minitemsize = 4
1402
1403class LongLongTest(SignedNumberTest, unittest.TestCase):
1404    typecode = 'q'
1405    minitemsize = 8
1406
1407class UnsignedLongLongTest(UnsignedNumberTest, unittest.TestCase):
1408    typecode = 'Q'
1409    minitemsize = 8
1410
1411class FPTest(NumberTest):
1412    example = [-42.0, 0, 42, 1e5, -1e10]
1413    smallerexample = [-42.0, 0, 42, 1e5, -2e10]
1414    biggerexample = [-42.0, 0, 42, 1e5, 1e10]
1415    outside = 23
1416
1417    def assertEntryEqual(self, entry1, entry2):
1418        self.assertAlmostEqual(entry1, entry2)
1419
1420    def test_nan(self):
1421        a = array.array(self.typecode, [float('nan')])
1422        b = array.array(self.typecode, [float('nan')])
1423        self.assertIs(a != b, True)
1424        self.assertIs(a == b, False)
1425        self.assertIs(a > b, False)
1426        self.assertIs(a >= b, False)
1427        self.assertIs(a < b, False)
1428        self.assertIs(a <= b, False)
1429
1430    def test_byteswap(self):
1431        a = array.array(self.typecode, self.example)
1432        self.assertRaises(TypeError, a.byteswap, 42)
1433        if a.itemsize in (1, 2, 4, 8):
1434            b = array.array(self.typecode, self.example)
1435            b.byteswap()
1436            if a.itemsize==1:
1437                self.assertEqual(a, b)
1438            else:
1439                # On alphas treating the byte swapped bit patters as
1440                # floats/doubles results in floating point exceptions
1441                # => compare the 8bit string values instead
1442                self.assertNotEqual(a.tobytes(), b.tobytes())
1443            b.byteswap()
1444            self.assertEqual(a, b)
1445
1446class FloatTest(FPTest, unittest.TestCase):
1447    typecode = 'f'
1448    minitemsize = 4
1449
1450class DoubleTest(FPTest, unittest.TestCase):
1451    typecode = 'd'
1452    minitemsize = 8
1453
1454    def test_alloc_overflow(self):
1455        from sys import maxsize
1456        a = array.array('d', [-1]*65536)
1457        try:
1458            a *= maxsize//65536 + 1
1459        except MemoryError:
1460            pass
1461        else:
1462            self.fail("Array of size > maxsize created - MemoryError expected")
1463        b = array.array('d', [ 2.71828183, 3.14159265, -1])
1464        try:
1465            b * (maxsize//3 + 1)
1466        except MemoryError:
1467            pass
1468        else:
1469            self.fail("Array of size > maxsize created - MemoryError expected")
1470
1471
1472class LargeArrayTest(unittest.TestCase):
1473    typecode = 'b'
1474
1475    def example(self, size):
1476        # We assess a base memuse of <=2.125 for constructing this array
1477        base = array.array(self.typecode, [0, 1, 2, 3, 4, 5, 6, 7]) * (size // 8)
1478        base += array.array(self.typecode, [99]*(size % 8) + [8, 9, 10, 11])
1479        return base
1480
1481    @support.bigmemtest(_2G, memuse=2.125)
1482    def test_example_data(self, size):
1483        example = self.example(size)
1484        self.assertEqual(len(example), size+4)
1485
1486    @support.bigmemtest(_2G, memuse=2.125)
1487    def test_access(self, size):
1488        example = self.example(size)
1489        self.assertEqual(example[0], 0)
1490        self.assertEqual(example[-(size+4)], 0)
1491        self.assertEqual(example[size], 8)
1492        self.assertEqual(example[-4], 8)
1493        self.assertEqual(example[size+3], 11)
1494        self.assertEqual(example[-1], 11)
1495
1496    @support.bigmemtest(_2G, memuse=2.125+1)
1497    def test_slice(self, size):
1498        example = self.example(size)
1499        self.assertEqual(list(example[:4]), [0, 1, 2, 3])
1500        self.assertEqual(list(example[-4:]), [8, 9, 10, 11])
1501        part = example[1:-1]
1502        self.assertEqual(len(part), size+2)
1503        self.assertEqual(part[0], 1)
1504        self.assertEqual(part[-1], 10)
1505        del part
1506        part = example[::2]
1507        self.assertEqual(len(part), (size+5)//2)
1508        self.assertEqual(list(part[:4]), [0, 2, 4, 6])
1509        if size % 2:
1510            self.assertEqual(list(part[-2:]), [9, 11])
1511        else:
1512            self.assertEqual(list(part[-2:]), [8, 10])
1513
1514    @support.bigmemtest(_2G, memuse=2.125)
1515    def test_count(self, size):
1516        example = self.example(size)
1517        self.assertEqual(example.count(0), size//8)
1518        self.assertEqual(example.count(11), 1)
1519
1520    @support.bigmemtest(_2G, memuse=2.125)
1521    def test_append(self, size):
1522        example = self.example(size)
1523        example.append(12)
1524        self.assertEqual(example[-1], 12)
1525
1526    @support.bigmemtest(_2G, memuse=2.125)
1527    def test_extend(self, size):
1528        example = self.example(size)
1529        example.extend(iter([12, 13, 14, 15]))
1530        self.assertEqual(len(example), size+8)
1531        self.assertEqual(list(example[-8:]), [8, 9, 10, 11, 12, 13, 14, 15])
1532
1533    @support.bigmemtest(_2G, memuse=2.125)
1534    def test_frombytes(self, size):
1535        example = self.example(size)
1536        example.frombytes(b'abcd')
1537        self.assertEqual(len(example), size+8)
1538        self.assertEqual(list(example[-8:]), [8, 9, 10, 11] + list(b'abcd'))
1539
1540    @support.bigmemtest(_2G, memuse=2.125)
1541    def test_fromlist(self, size):
1542        example = self.example(size)
1543        example.fromlist([12, 13, 14, 15])
1544        self.assertEqual(len(example), size+8)
1545        self.assertEqual(list(example[-8:]), [8, 9, 10, 11, 12, 13, 14, 15])
1546
1547    @support.bigmemtest(_2G, memuse=2.125)
1548    def test_index(self, size):
1549        example = self.example(size)
1550        self.assertEqual(example.index(0), 0)
1551        self.assertEqual(example.index(1), 1)
1552        self.assertEqual(example.index(7), 7)
1553        self.assertEqual(example.index(11), size+3)
1554
1555    @support.bigmemtest(_2G, memuse=2.125)
1556    def test_insert(self, size):
1557        example = self.example(size)
1558        example.insert(0, 12)
1559        example.insert(10, 13)
1560        example.insert(size+1, 14)
1561        self.assertEqual(len(example), size+7)
1562        self.assertEqual(example[0], 12)
1563        self.assertEqual(example[10], 13)
1564        self.assertEqual(example[size+1], 14)
1565
1566    @support.bigmemtest(_2G, memuse=2.125)
1567    def test_pop(self, size):
1568        example = self.example(size)
1569        self.assertEqual(example.pop(0), 0)
1570        self.assertEqual(example[0], 1)
1571        self.assertEqual(example.pop(size+1), 10)
1572        self.assertEqual(example[size+1], 11)
1573        self.assertEqual(example.pop(1), 2)
1574        self.assertEqual(example[1], 3)
1575        self.assertEqual(len(example), size+1)
1576        self.assertEqual(example.pop(), 11)
1577        self.assertEqual(len(example), size)
1578
1579    @support.bigmemtest(_2G, memuse=2.125)
1580    def test_remove(self, size):
1581        example = self.example(size)
1582        example.remove(0)
1583        self.assertEqual(len(example), size+3)
1584        self.assertEqual(example[0], 1)
1585        example.remove(10)
1586        self.assertEqual(len(example), size+2)
1587        self.assertEqual(example[size], 9)
1588        self.assertEqual(example[size+1], 11)
1589
1590    @support.bigmemtest(_2G, memuse=2.125)
1591    def test_reverse(self, size):
1592        example = self.example(size)
1593        example.reverse()
1594        self.assertEqual(len(example), size+4)
1595        self.assertEqual(example[0], 11)
1596        self.assertEqual(example[3], 8)
1597        self.assertEqual(example[-1], 0)
1598        example.reverse()
1599        self.assertEqual(len(example), size+4)
1600        self.assertEqual(list(example[:4]), [0, 1, 2, 3])
1601        self.assertEqual(list(example[-4:]), [8, 9, 10, 11])
1602
1603    # list takes about 9 bytes per element
1604    @support.bigmemtest(_2G, memuse=2.125+9)
1605    def test_tolist(self, size):
1606        example = self.example(size)
1607        ls = example.tolist()
1608        self.assertEqual(len(ls), len(example))
1609        self.assertEqual(ls[:8], list(example[:8]))
1610        self.assertEqual(ls[-8:], list(example[-8:]))
1611
1612if __name__ == "__main__":
1613    unittest.main()
1614