from testutils import assert_raises x = [1, 2, 3] assert x[0] == 1 assert x[1] == 2 # assert x[7] y = [2, *x] assert y == [2, 1, 2, 3] y.extend(x) assert y == [2, 1, 2, 3, 1, 2, 3] a = [] a.extend((1,2,3,4)) assert a == [1, 2, 3, 4] a.extend('abcdefg') assert a == [1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e', 'f', 'g'] a.extend(range(10)) assert a == [1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] a = [] a.extend({1,2,3,4}) assert a == [1, 2, 3, 4] a.extend({'a': 1, 'b': 2, 'z': 51}) assert a == [1, 2, 3, 4, 'a', 'b', 'z'] class Iter: def __iter__(self): yield 12 yield 28 a.extend(Iter()) assert a == [1, 2, 3, 4, 'a', 'b', 'z', 12, 28] a.extend(bytes(b'hello world')) assert a == [1, 2, 3, 4, 'a', 'b', 'z', 12, 28, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] class Next: def __next__(self): yield 12 yield 28 assert_raises(TypeError, lambda: [].extend(3)) assert_raises(TypeError, lambda: [].extend(slice(0, 10, 1))) assert x * 0 == [], "list __mul__ by 0 failed" assert x * -1 == [], "list __mul__ by -1 failed" assert x * 2 == [1, 2, 3, 1, 2, 3], "list __mul__ by 2 failed" y = x x *= 2 assert y is x assert x == [1, 2, 3] * 2 # index() assert ['a', 'b', 'c'].index('b') == 1 assert [5, 6, 7].index(7) == 2 assert_raises(ValueError, lambda: ['a', 'b', 'c'].index('z')) x = [[1,0,-3], 'a', 1] y = [[3,2,1], 'z', 2] assert x < y, "list __lt__ failed" x = [5, 13, 31] y = [1, 10, 29] assert x > y, "list __gt__ failed" x = [0, 1, 2] assert x.pop() == 2 assert x == [0, 1] def test_pop(lst, idx, value, new_lst): assert lst.pop(idx) == value assert lst == new_lst test_pop([0, 1, 2], -1, 2, [0, 1]) test_pop([0, 1, 2], 0, 0, [1, 2]) test_pop([0, 1, 2], 1, 1, [0, 2]) test_pop([0, 1, 2], 2, 2, [0, 1]) assert_raises(IndexError, lambda: [].pop()) assert_raises(IndexError, lambda: [].pop(0)) assert_raises(IndexError, lambda: [].pop(-1)) assert_raises(IndexError, lambda: [0].pop(1)) assert_raises(IndexError, lambda: [0].pop(-2)) recursive = [] recursive.append(recursive) assert repr(recursive) == "[[...]]" # insert() x = ['a', 'b', 'c'] x.insert(0, 'z') # insert is in-place, no return value assert x == ['z', 'a', 'b', 'c'] x = ['a', 'b', 'c'] x.insert(100, 'z') assert x == ['a', 'b', 'c', 'z'] x = ['a', 'b', 'c'] x.insert(-1, 'z') assert x == ['a', 'b', 'z', 'c'] x = ['a', 'b', 'c'] x.insert(-100, 'z') assert x == ['z', 'a', 'b', 'c'] assert_raises(OverflowError, lambda: x.insert(100000000000000000000, 'z')) x = [[], 2, {}] y = x.copy() assert x is not y assert x == y assert all(a is b for a, b in zip(x, y)) y.append(4) assert x != y a = [1, 2, 3] assert len(a) == 3 a.remove(1) assert len(a) == 2 assert not 1 in a assert_raises(ValueError, lambda: a.remove(10), _msg='Remove not exist element') foo = bar = [1] foo += [2] assert (foo, bar) == ([1, 2], [1, 2]) x = [1] x.append(x) assert x in x assert x.index(x) == 1 assert x.count(x) == 1 x.remove(x) assert x not in x class Foo(object): def __eq__(self, x): return False foo = Foo() foo1 = Foo() x = [1, foo, 2, foo, []] assert x == x assert foo in x assert 2 in x assert x.index(foo) == 1 assert x.count(foo) == 2 assert x.index(2) == 2 assert [] in x assert x.index([]) == 4 assert foo1 not in x x.remove(foo) assert x.index(foo) == 2 assert x.count(foo) == 1 x = [] x.append(x) assert x == x a = [1, 2, 3] b = [1, 2, 3] c = [a, b] a.append(c) b.append(c) assert a == b assert [foo] == [foo] for size in [1, 2, 3, 4, 5, 8, 10, 100, 1000]: lst = list(range(size)) orig = lst[:] lst.sort() assert lst == orig assert sorted(lst) == orig assert_raises(ZeroDivisionError, sorted, lst, key=lambda x: 1/x) lst.reverse() assert sorted(lst) == orig assert sorted(lst, reverse=True) == lst assert sorted(lst, key=lambda x: -x) == lst assert sorted(lst, key=lambda x: -x, reverse=True) == orig assert sorted([(1, 2, 3), (0, 3, 6)]) == [(0, 3, 6), (1, 2, 3)] assert sorted([(1, 2, 3), (0, 3, 6)], key=lambda x: x[0]) == [(0, 3, 6), (1, 2, 3)] assert sorted([(1, 2, 3), (0, 3, 6)], key=lambda x: x[1]) == [(1, 2, 3), (0, 3, 6)] assert sorted([(1, 2), (), (5,)], key=len) == [(), (5,), (1, 2)] lst = [3, 1, 5, 2, 4] class C: def __init__(self, x): self.x = x def __lt__(self, other): return self.x < other.x lst.sort(key=C) assert lst == [1, 2, 3, 4, 5] lst = [3, 1, 5, 2, 4] class C: def __init__(self, x): self.x = x def __gt__(self, other): return self.x > other.x lst.sort(key=C) assert lst == [1, 2, 3, 4, 5] lst = [5, 1, 2, 3, 4] def f(x): lst.append(1) return x assert_raises(ValueError, lambda: lst.sort(key=f)) # "list modified during sort" assert lst == [1, 2, 3, 4, 5] # __delitem__ x = ['a', 'b', 'c'] del x[0] assert x == ['b', 'c'] x = ['a', 'b', 'c'] del x[-1] assert x == ['a', 'b'] x = y = [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15] del x[2:14:3] assert x == y assert x == [1, 2, 4, 5, 7, 8, 11, 12, 14, 15] assert y == [1, 2, 4, 5, 7, 8, 11, 12, 14, 15] x = [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15] del x[-5:] assert x == [1, 2, 3, 4, 5, 6, 7, 8, 10] x = list(range(12)) del x[10:2:-2] assert x == [0,1,2,3,5,7,9,11] def bad_del_1(): del ['a', 'b']['a'] assert_raises(TypeError, bad_del_1) def bad_del_2(): del ['a', 'b'][2] assert_raises(IndexError, bad_del_2) # __setitem__ # simple index x = [1, 2, 3, 4, 5] x[0] = 'a' assert x == ['a', 2, 3, 4, 5] x[-1] = 'b' assert x == ['a', 2, 3, 4, 'b'] # make sure refrences are assigned correctly y = [] x[1] = y y.append(100) assert x[1] == y assert x[1] == [100] #index bounds def set_index_out_of_bounds_high(): x = [0, 1, 2, 3, 4] x[5] = 'a' def set_index_out_of_bounds_low(): x = [0, 1, 2, 3, 4] x[-6] = 'a' assert_raises(IndexError, set_index_out_of_bounds_high) assert_raises(IndexError, set_index_out_of_bounds_low) # non stepped slice index a = list(range(10)) x = a[:] y = a[:] assert x == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # replace whole list x[:] = ['a', 'b', 'c'] y[::1] = ['a', 'b', 'c'] assert x == ['a', 'b', 'c'] assert x == y # splice list start x = a[:] y = a[:] z = a[:] zz = a[:] x[:1] = ['a', 'b', 'c'] y[0:1] = ['a', 'b', 'c'] z[:1:1] = ['a', 'b', 'c'] zz[0:1:1] = ['a', 'b', 'c'] assert x == ['a', 'b', 'c', 1, 2, 3, 4, 5, 6, 7, 8, 9] assert x == y assert x == z assert x == zz # splice list end x = a[:] y = a[:] z = a[:] zz = a[:] x[5:] = ['a', 'b', 'c'] y[5::1] = ['a', 'b', 'c'] z[5:10] = ['a', 'b', 'c'] zz[5:10:1] = ['a', 'b', 'c'] assert x == [0, 1, 2, 3, 4, 'a', 'b', 'c'] assert x == y assert x == z assert x == zz # insert sec x = a[:] y = a[:] z = a[:] zz = a[:] x[1:1] = ['a', 'b', 'c'] y[1:0] = ['a', 'b', 'c'] z[1:1:1] = ['a', 'b', 'c'] zz[1:0:1] = ['a', 'b', 'c'] assert x == [0, 'a', 'b', 'c', 1, 2, 3, 4, 5, 6, 7, 8, 9] assert x == y assert x == z assert x == zz # same but negative indexes? x = a[:] y = a[:] z = a[:] zz = a[:] x[-1:-1] = ['a', 'b', 'c'] y[-1:9] = ['a', 'b', 'c'] z[-1:-1:1] = ['a', 'b', 'c'] zz[-1:9:1] = ['a', 'b', 'c'] assert x == [0, 1, 2, 3, 4, 5, 6, 7, 8, 'a', 'b', 'c', 9] assert x == y assert x == z assert x == zz # splice mid x = a[:] y = a[:] x[3:5] = ['a', 'b', 'c', 'd', 'e'] y[3:5:1] = ['a', 'b', 'c', 'd', 'e'] assert x == [0, 1, 2, 'a', 'b', 'c', 'd', 'e', 5, 6, 7, 8, 9] assert x == y x = a[:] x[3:5] = ['a'] assert x == [0, 1, 2, 'a', 5, 6, 7, 8, 9] # assign empty to non stepped empty slice does nothing x = a[:] y = a[:] x[5:2] = [] y[5:2:1] = [] assert x == a assert y == a # assign empty to non stepped slice removes elems x = a[:] y = a[:] x[2:8] = [] y[2:8:1] = [] assert x == [0, 1, 8, 9] assert x == y # make sure refrences are assigned correctly yy = [] x = a[:] y = a[:] x[3:5] = ['a', 'b', 'c', 'd', yy] y[3:5:1] = ['a', 'b', 'c', 'd', yy] assert x == [0, 1, 2, 'a', 'b', 'c', 'd', [], 5, 6, 7, 8, 9] assert x == y yy.append(100) assert x == [0, 1, 2, 'a', 'b', 'c', 'd', [100], 5, 6, 7, 8, 9] assert x == y assert x[7] == yy assert x[7] == [100] assert y[7] == yy assert y[7] == [100] # no zero step def no_zero_step_set(): x = [1, 2, 3, 4, 5] x[0:4:0] = [11, 12, 13, 14, 15] assert_raises(ValueError, no_zero_step_set) # stepped slice index # forward slice x = a[:] x[2:8:2] = ['a', 'b', 'c'] assert x == [0, 1, 'a', 3, 'b', 5, 'c', 7, 8, 9] x = a[:] y = a[:] z = a[:] zz = a[:] c = ['a', 'b', 'c', 'd', 'e'] x[::2] = c y[-10::2] = c z[0:10:2] = c zz[-13:13:2] = c # slice indexes will be truncated to bounds assert x == ['a', 1, 'b', 3, 'c', 5, 'd', 7, 'e', 9] assert x == y assert x == z assert x == zz # backward slice x = a[:] x[8:2:-2] = ['a', 'b', 'c'] assert x == [0, 1, 2, 3, 'c', 5, 'b', 7, 'a', 9] x = a[:] y = a[:] z = a[:] zz = a[:] c = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] x[::-1] = c y[9:-11:-1] = c z[9::-1] = c zz[11:-13:-1] = c # slice indexes will be truncated to bounds assert x == ['j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'] assert x == y assert x == z assert x == zz # step size bigger than len x = a[:] x[::200] = ['a'] assert x == ['a', 1, 2, 3, 4, 5, 6, 7, 8, 9] x = a[:] x[5::200] = ['a'] assert x == [0, 1, 2, 3, 4, 'a', 6, 7, 8, 9] # bad stepped slices def stepped_slice_assign_too_big(): x = [0, 1, 2, 3, 4] x[::2] = ['a', 'b', 'c', 'd'] assert_raises(ValueError, stepped_slice_assign_too_big) def stepped_slice_assign_too_small(): x = [0, 1, 2, 3, 4] x[::2] = ['a', 'b'] assert_raises(ValueError, stepped_slice_assign_too_small) # must assign iter t0 slice def must_assign_iter_to_slice(): x = [0, 1, 2, 3, 4] x[::2] = 42 assert_raises(TypeError, must_assign_iter_to_slice) # other iterables? a = list(range(10)) # string x = a[:] x[3:8] = "abcdefghi" assert x == [0, 1, 2, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 8, 9] # tuple x = a[:] x[3:8] = (11, 12, 13, 14, 15) assert x == [0, 1, 2, 11, 12, 13, 14, 15, 8, 9] # class # __next__ class CIterNext: def __init__(self, sec=(1, 2, 3)): self.sec = sec self.index = 0 def __iter__(self): return self def __next__(self): if self.index >= len(self.sec): raise StopIteration v = self.sec[self.index] self.index += 1 return v x = list(range(10)) x[3:8] = CIterNext() assert x == [0, 1, 2, 1, 2, 3, 8, 9] # __iter__ yield class CIter: def __init__(self, sec=(1, 2, 3)): self.sec = sec def __iter__(self): for n in self.sec: yield n x = list(range(10)) x[3:8] = CIter() assert x == [0, 1, 2, 1, 2, 3, 8, 9] # __getitem but no __iter__ sequence class CGetItem: def __init__(self, sec=(1, 2, 3)): self.sec = sec def __getitem__(self, sub): return self.sec[sub] x = list(range(10)) x[3:8] = CGetItem() assert x == [0, 1, 2, 1, 2, 3, 8, 9] # iter raises error class CIterError: def __iter__(self): for i in range(10): if i > 5: raise RuntimeError yield i def bad_iter_assign(): x = list(range(10)) x[3:8] = CIterError() assert_raises(RuntimeError, bad_iter_assign) # slice assign when step or stop is -1 a = list(range(10)) x = a[:] x[-1:-5:-1] = ['a', 'b', 'c', 'd'] assert x == [0, 1, 2, 3, 4, 5, 'd', 'c', 'b', 'a'] x = a[:] x[-5:-1:-1] = [] assert x == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # is step != 1 and start or stop of slice == -1 x = list(range(10)) del x[-1:-5:-1] assert x == [0, 1, 2, 3, 4, 5] x = list(range(10)) del x[-5:-1:-1] assert [1, 2].__ne__([]) assert [2, 1].__ne__([1, 2]) assert not [1, 2].__ne__([1, 2]) assert [1, 2].__ne__(1) == NotImplemented # list gt, ge, lt, le assert_raises(TypeError, lambda: [0, []] < [0, 0]) assert_raises(TypeError, lambda: [0, []] <= [0, 0]) assert_raises(TypeError, lambda: [0, []] > [0, 0]) assert_raises(TypeError, lambda: [0, []] >= [0, 0]) assert_raises(TypeError, lambda: [0, 0] < [0, []]) assert_raises(TypeError, lambda: [0, 0] <= [0, []]) assert_raises(TypeError, lambda: [0, 0] > [0, []]) assert_raises(TypeError, lambda: [0, 0] >= [0, []]) assert [0, 0] < [1, -1] assert [0, 0] < [0, 0, 1] assert [0, 0] < [0, 0, -1] assert [0, 0] <= [0, 0, -1] assert not [0, 0, 0, 0] <= [0, -1] assert [0, 0] > [-1, 1] assert [0, 0] >= [-1, 1] assert [0, 0, 0] >= [-1, 1] assert [0, 0] <= [0, 1] assert [0, 0] <= [0, 0] assert [0, 0] <= [0, 0] assert not [0, 0] > [0, 0] assert not [0, 0] < [0, 0] assert not [float('nan'), float('nan')] <= [float('nan'), 1] assert not [float('nan'), float('nan')] <= [float('nan'), float('nan')] assert not [float('nan'), float('nan')] >= [float('nan'), float('nan')] assert not [float('nan'), float('nan')] < [float('nan'), float('nan')] assert not [float('nan'), float('nan')] > [float('nan'), float('nan')] assert [float('inf'), float('inf')] >= [float('inf'), 1] assert [float('inf'), float('inf')] <= [float('inf'), float('inf')] assert [float('inf'), float('inf')] >= [float('inf'), float('inf')] assert not [float('inf'), float('inf')] < [float('inf'), float('inf')] assert not [float('inf'), float('inf')] > [float('inf'), float('inf')] # list __iadd__ a = [] a += [1, 2, 3] assert a == [1, 2, 3] a = [] a += (1,2,3,4) assert a == [1, 2, 3, 4] a += 'abcdefg' assert a == [1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e', 'f', 'g'] a += range(10) assert a == [1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] a = [] a += {1,2,3,4} assert a == [1, 2, 3, 4] a += {'a': 1, 'b': 2, 'z': 51} assert a == [1, 2, 3, 4, 'a', 'b', 'z'] class Iter: def __iter__(self): yield 12 yield 28 a += Iter() assert a == [1, 2, 3, 4, 'a', 'b', 'z', 12, 28] a += bytes(b'hello world') assert a == [1, 2, 3, 4, 'a', 'b', 'z', 12, 28, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] class Next: def __next__(self): yield 12 yield 28 def iadd_int(): a = [] a += 3 def iadd_slice(): a = [] a += slice(0, 10, 1) assert_raises(TypeError, iadd_int) assert_raises(TypeError, iadd_slice) it = iter([1,2,3,4]) assert it.__length_hint__() == 4 assert next(it) == 1 assert it.__length_hint__() == 3 assert list(it) == [2,3,4] assert it.__length_hint__() == 0 it = reversed([1,2,3,4]) assert it.__length_hint__() == 4 assert next(it) == 4 assert it.__length_hint__() == 3 assert list(it) == [3,2,1] assert it.__length_hint__() == 0 a = [*[1, 2], 3, *[4, 5]] assert a == [1, 2, 3, 4, 5]