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_keywords_in_subclass(self):
50        class subclass(list):
51            pass
52        u = subclass([1, 2])
53        self.assertIs(type(u), subclass)
54        self.assertEqual(list(u), [1, 2])
55        with self.assertRaises(TypeError):
56            subclass(sequence=())
57
58        class subclass_with_init(list):
59            def __init__(self, seq, newarg=None):
60                super().__init__(seq)
61                self.newarg = newarg
62        u = subclass_with_init([1, 2], newarg=3)
63        self.assertIs(type(u), subclass_with_init)
64        self.assertEqual(list(u), [1, 2])
65        self.assertEqual(u.newarg, 3)
66
67        class subclass_with_new(list):
68            def __new__(cls, seq, newarg=None):
69                self = super().__new__(cls, seq)
70                self.newarg = newarg
71                return self
72        u = subclass_with_new([1, 2], newarg=3)
73        self.assertIs(type(u), subclass_with_new)
74        self.assertEqual(list(u), [1, 2])
75        self.assertEqual(u.newarg, 3)
76
77    def test_truth(self):
78        super().test_truth()
79        self.assertTrue(not [])
80        self.assertTrue([42])
81
82    def test_identity(self):
83        self.assertTrue([] is not [])
84
85    def test_len(self):
86        super().test_len()
87        self.assertEqual(len([]), 0)
88        self.assertEqual(len([0]), 1)
89        self.assertEqual(len([0, 1, 2]), 3)
90
91    def test_overflow(self):
92        lst = [4, 5, 6, 7]
93        n = int((sys.maxsize*2+2) // len(lst))
94        def mul(a, b): return a * b
95        def imul(a, b): a *= b
96        self.assertRaises((MemoryError, OverflowError), mul, lst, n)
97        self.assertRaises((MemoryError, OverflowError), imul, lst, n)
98
99    def test_list_resize_overflow(self):
100        # gh-97616: test new_allocated * sizeof(PyObject*) overflow
101        # check in list_resize()
102        lst = [0] * 65
103        del lst[1:]
104        self.assertEqual(len(lst), 1)
105
106        size = ((2 ** (tuple.__itemsize__ * 8) - 1) // 2)
107        with self.assertRaises((MemoryError, OverflowError)):
108            lst * size
109        with self.assertRaises((MemoryError, OverflowError)):
110            lst *= size
111
112    def test_repr_large(self):
113        # Check the repr of large list objects
114        def check(n):
115            l = [0] * n
116            s = repr(l)
117            self.assertEqual(s,
118                '[' + ', '.join(['0'] * n) + ']')
119        check(10)       # check our checking code
120        check(1000000)
121
122    def test_iterator_pickle(self):
123        orig = self.type2test([4, 5, 6, 7])
124        data = [10, 11, 12, 13, 14, 15]
125        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
126            # initial iterator
127            itorig = iter(orig)
128            d = pickle.dumps((itorig, orig), proto)
129            it, a = pickle.loads(d)
130            a[:] = data
131            self.assertEqual(type(it), type(itorig))
132            self.assertEqual(list(it), data)
133
134            # running iterator
135            next(itorig)
136            d = pickle.dumps((itorig, orig), proto)
137            it, a = pickle.loads(d)
138            a[:] = data
139            self.assertEqual(type(it), type(itorig))
140            self.assertEqual(list(it), data[1:])
141
142            # empty iterator
143            for i in range(1, len(orig)):
144                next(itorig)
145            d = pickle.dumps((itorig, orig), proto)
146            it, a = pickle.loads(d)
147            a[:] = data
148            self.assertEqual(type(it), type(itorig))
149            self.assertEqual(list(it), data[len(orig):])
150
151            # exhausted iterator
152            self.assertRaises(StopIteration, next, itorig)
153            d = pickle.dumps((itorig, orig), proto)
154            it, a = pickle.loads(d)
155            a[:] = data
156            self.assertEqual(list(it), [])
157
158    def test_reversed_pickle(self):
159        orig = self.type2test([4, 5, 6, 7])
160        data = [10, 11, 12, 13, 14, 15]
161        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
162            # initial iterator
163            itorig = reversed(orig)
164            d = pickle.dumps((itorig, orig), proto)
165            it, a = pickle.loads(d)
166            a[:] = data
167            self.assertEqual(type(it), type(itorig))
168            self.assertEqual(list(it), data[len(orig)-1::-1])
169
170            # running iterator
171            next(itorig)
172            d = pickle.dumps((itorig, orig), proto)
173            it, a = pickle.loads(d)
174            a[:] = data
175            self.assertEqual(type(it), type(itorig))
176            self.assertEqual(list(it), data[len(orig)-2::-1])
177
178            # empty iterator
179            for i in range(1, len(orig)):
180                next(itorig)
181            d = pickle.dumps((itorig, orig), proto)
182            it, a = pickle.loads(d)
183            a[:] = data
184            self.assertEqual(type(it), type(itorig))
185            self.assertEqual(list(it), [])
186
187            # exhausted iterator
188            self.assertRaises(StopIteration, next, itorig)
189            d = pickle.dumps((itorig, orig), proto)
190            it, a = pickle.loads(d)
191            a[:] = data
192            self.assertEqual(list(it), [])
193
194    def test_step_overflow(self):
195        a = [0, 1, 2, 3, 4]
196        a[1::sys.maxsize] = [0]
197        self.assertEqual(a[3::sys.maxsize], [3])
198
199    def test_no_comdat_folding(self):
200        # Issue 8847: In the PGO build, the MSVC linker's COMDAT folding
201        # optimization causes failures in code that relies on distinct
202        # function addresses.
203        class L(list): pass
204        with self.assertRaises(TypeError):
205            (3,) + L([1,2])
206
207    def test_equal_operator_modifying_operand(self):
208        # test fix for seg fault reported in bpo-38588 part 2.
209        class X:
210            def __eq__(self,other) :
211                list2.clear()
212                return NotImplemented
213
214        class Y:
215            def __eq__(self, other):
216                list1.clear()
217                return NotImplemented
218
219        class Z:
220            def __eq__(self, other):
221                list3.clear()
222                return NotImplemented
223
224        list1 = [X()]
225        list2 = [Y()]
226        self.assertTrue(list1 == list2)
227
228        list3 = [Z()]
229        list4 = [1]
230        self.assertFalse(list3 == list4)
231
232    @cpython_only
233    def test_preallocation(self):
234        iterable = [0] * 10
235        iter_size = sys.getsizeof(iterable)
236
237        self.assertEqual(iter_size, sys.getsizeof(list([0] * 10)))
238        self.assertEqual(iter_size, sys.getsizeof(list(range(10))))
239
240    def test_count_index_remove_crashes(self):
241        # bpo-38610: The count(), index(), and remove() methods were not
242        # holding strong references to list elements while calling
243        # PyObject_RichCompareBool().
244        class X:
245            def __eq__(self, other):
246                lst.clear()
247                return NotImplemented
248
249        lst = [X()]
250        with self.assertRaises(ValueError):
251            lst.index(lst)
252
253        class L(list):
254            def __eq__(self, other):
255                str(other)
256                return NotImplemented
257
258        lst = L([X()])
259        lst.count(lst)
260
261        lst = L([X()])
262        with self.assertRaises(ValueError):
263            lst.remove(lst)
264
265        # bpo-39453: list.__contains__ was not holding strong references
266        # to list elements while calling PyObject_RichCompareBool().
267        lst = [X(), X()]
268        3 in lst
269        lst = [X(), X()]
270        X() in lst
271
272
273if __name__ == "__main__":
274    unittest.main()
275