1import sys
2from test import list_tests
3from test.support import cpython_only
4import pickle
5import unittest
6
7class ListTest(list_tests.CommonTest):
8    type2test = list
9
10    def test_basic(self):
11        self.assertEqual(list([]), [])
12        l0_3 = [0, 1, 2, 3]
13        l0_3_bis = list(l0_3)
14        self.assertEqual(l0_3, l0_3_bis)
15        self.assertTrue(l0_3 is not l0_3_bis)
16        self.assertEqual(list(()), [])
17        self.assertEqual(list((0, 1, 2, 3)), [0, 1, 2, 3])
18        self.assertEqual(list(''), [])
19        self.assertEqual(list('spam'), ['s', 'p', 'a', 'm'])
20        self.assertEqual(list(x for x in range(10) if x % 2),
21                         [1, 3, 5, 7, 9])
22
23        if sys.maxsize == 0x7fffffff:
24            # This test can currently only work on 32-bit machines.
25            # XXX If/when PySequence_Length() returns a ssize_t, it should be
26            # XXX re-enabled.
27            # Verify clearing of bug #556025.
28            # This assumes that the max data size (sys.maxint) == max
29            # address size this also assumes that the address size is at
30            # least 4 bytes with 8 byte addresses, the bug is not well
31            # tested
32            #
33            # Note: This test is expected to SEGV under Cygwin 1.3.12 or
34            # earlier due to a newlib bug.  See the following mailing list
35            # thread for the details:
36
37            #     http://sources.redhat.com/ml/newlib/2002/msg00369.html
38            self.assertRaises(MemoryError, list, range(sys.maxsize // 2))
39
40        # This code used to segfault in Py2.4a3
41        x = []
42        x.extend(-y for y in x)
43        self.assertEqual(x, [])
44
45    def test_keyword_args(self):
46        with self.assertRaisesRegex(TypeError, 'keyword argument'):
47            list(sequence=[])
48
49    def test_truth(self):
50        super().test_truth()
51        self.assertTrue(not [])
52        self.assertTrue([42])
53
54    def test_identity(self):
55        self.assertTrue([] is not [])
56
57    def test_len(self):
58        super().test_len()
59        self.assertEqual(len([]), 0)
60        self.assertEqual(len([0]), 1)
61        self.assertEqual(len([0, 1, 2]), 3)
62
63    def test_overflow(self):
64        lst = [4, 5, 6, 7]
65        n = int((sys.maxsize*2+2) // len(lst))
66        def mul(a, b): return a * b
67        def imul(a, b): a *= b
68        self.assertRaises((MemoryError, OverflowError), mul, lst, n)
69        self.assertRaises((MemoryError, OverflowError), imul, lst, n)
70
71    def test_repr_large(self):
72        # Check the repr of large list objects
73        def check(n):
74            l = [0] * n
75            s = repr(l)
76            self.assertEqual(s,
77                '[' + ', '.join(['0'] * n) + ']')
78        check(10)       # check our checking code
79        check(1000000)
80
81    def test_iterator_pickle(self):
82        orig = self.type2test([4, 5, 6, 7])
83        data = [10, 11, 12, 13, 14, 15]
84        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
85            # initial iterator
86            itorig = iter(orig)
87            d = pickle.dumps((itorig, orig), proto)
88            it, a = pickle.loads(d)
89            a[:] = data
90            self.assertEqual(type(it), type(itorig))
91            self.assertEqual(list(it), data)
92
93            # running iterator
94            next(itorig)
95            d = pickle.dumps((itorig, orig), proto)
96            it, a = pickle.loads(d)
97            a[:] = data
98            self.assertEqual(type(it), type(itorig))
99            self.assertEqual(list(it), data[1:])
100
101            # empty iterator
102            for i in range(1, len(orig)):
103                next(itorig)
104            d = pickle.dumps((itorig, orig), proto)
105            it, a = pickle.loads(d)
106            a[:] = data
107            self.assertEqual(type(it), type(itorig))
108            self.assertEqual(list(it), data[len(orig):])
109
110            # exhausted iterator
111            self.assertRaises(StopIteration, next, itorig)
112            d = pickle.dumps((itorig, orig), proto)
113            it, a = pickle.loads(d)
114            a[:] = data
115            self.assertEqual(list(it), [])
116
117    def test_reversed_pickle(self):
118        orig = self.type2test([4, 5, 6, 7])
119        data = [10, 11, 12, 13, 14, 15]
120        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
121            # initial iterator
122            itorig = reversed(orig)
123            d = pickle.dumps((itorig, orig), proto)
124            it, a = pickle.loads(d)
125            a[:] = data
126            self.assertEqual(type(it), type(itorig))
127            self.assertEqual(list(it), data[len(orig)-1::-1])
128
129            # running iterator
130            next(itorig)
131            d = pickle.dumps((itorig, orig), proto)
132            it, a = pickle.loads(d)
133            a[:] = data
134            self.assertEqual(type(it), type(itorig))
135            self.assertEqual(list(it), data[len(orig)-2::-1])
136
137            # empty iterator
138            for i in range(1, len(orig)):
139                next(itorig)
140            d = pickle.dumps((itorig, orig), proto)
141            it, a = pickle.loads(d)
142            a[:] = data
143            self.assertEqual(type(it), type(itorig))
144            self.assertEqual(list(it), [])
145
146            # exhausted iterator
147            self.assertRaises(StopIteration, next, itorig)
148            d = pickle.dumps((itorig, orig), proto)
149            it, a = pickle.loads(d)
150            a[:] = data
151            self.assertEqual(list(it), [])
152
153    def test_step_overflow(self):
154        a = [0, 1, 2, 3, 4]
155        a[1::sys.maxsize] = [0]
156        self.assertEqual(a[3::sys.maxsize], [3])
157
158    def test_no_comdat_folding(self):
159        # Issue 8847: In the PGO build, the MSVC linker's COMDAT folding
160        # optimization causes failures in code that relies on distinct
161        # function addresses.
162        class L(list): pass
163        with self.assertRaises(TypeError):
164            (3,) + L([1,2])
165
166    def test_equal_operator_modifying_operand(self):
167        # test fix for seg fault reported in bpo-38588 part 2.
168        class X:
169            def __eq__(self,other) :
170                list2.clear()
171                return NotImplemented
172
173        class Y:
174            def __eq__(self, other):
175                list1.clear()
176                return NotImplemented
177
178        class Z:
179            def __eq__(self, other):
180                list3.clear()
181                return NotImplemented
182
183        list1 = [X()]
184        list2 = [Y()]
185        self.assertTrue(list1 == list2)
186
187        list3 = [Z()]
188        list4 = [1]
189        self.assertFalse(list3 == list4)
190
191    @cpython_only
192    def test_preallocation(self):
193        iterable = [0] * 10
194        iter_size = sys.getsizeof(iterable)
195
196        self.assertEqual(iter_size, sys.getsizeof(list([0] * 10)))
197        self.assertEqual(iter_size, sys.getsizeof(list(range(10))))
198
199    def test_count_index_remove_crashes(self):
200        # bpo-38610: The count(), index(), and remove() methods were not
201        # holding strong references to list elements while calling
202        # PyObject_RichCompareBool().
203        class X:
204            def __eq__(self, other):
205                lst.clear()
206                return NotImplemented
207
208        lst = [X()]
209        with self.assertRaises(ValueError):
210            lst.index(lst)
211
212        class L(list):
213            def __eq__(self, other):
214                str(other)
215                return NotImplemented
216
217        lst = L([X()])
218        lst.count(lst)
219
220        lst = L([X()])
221        with self.assertRaises(ValueError):
222            lst.remove(lst)
223
224        # bpo-39453: list.__contains__ was not holding strong references
225        # to list elements while calling PyObject_RichCompareBool().
226        lst = [X(), X()]
227        3 in lst
228        lst = [X(), X()]
229        X() in lst
230
231
232if __name__ == "__main__":
233    unittest.main()
234