1from collections.abc import MutableSequence
2
3
4cdef class FrozenList:
5
6    cdef readonly bint frozen
7    cdef list _items
8
9    def __init__(self, items=None):
10        self.frozen = False
11        if items is not None:
12            items = list(items)
13        else:
14            items = []
15        self._items = items
16
17    cdef object _check_frozen(self):
18        if self.frozen:
19            raise RuntimeError("Cannot modify frozen list.")
20
21    cdef inline object _fast_len(self):
22        return len(self._items)
23
24    def freeze(self):
25        self.frozen = True
26
27    def __getitem__(self, index):
28        return self._items[index]
29
30    def __setitem__(self, index, value):
31        self._check_frozen()
32        self._items[index] = value
33
34    def __delitem__(self, index):
35        self._check_frozen()
36        del self._items[index]
37
38    def __len__(self):
39        return self._fast_len()
40
41    def __iter__(self):
42        return self._items.__iter__()
43
44    def __reversed__(self):
45        return self._items.__reversed__()
46
47    def __richcmp__(self, other, op):
48        if op == 0:  # <
49            return list(self) < other
50        if op == 1:  # <=
51            return list(self) <= other
52        if op == 2:  # ==
53            return list(self) == other
54        if op == 3:  # !=
55            return list(self) != other
56        if op == 4:  # >
57            return list(self) > other
58        if op == 5:  # =>
59            return list(self) >= other
60
61    def insert(self, pos, item):
62        self._check_frozen()
63        self._items.insert(pos, item)
64
65    def __contains__(self, item):
66        return item in self._items
67
68    def __iadd__(self, items):
69        self._check_frozen()
70        self._items += list(items)
71        return self
72
73    def index(self, item):
74        return self._items.index(item)
75
76    def remove(self, item):
77        self._check_frozen()
78        self._items.remove(item)
79
80    def clear(self):
81        self._check_frozen()
82        self._items.clear()
83
84    def extend(self, items):
85        self._check_frozen()
86        self._items += list(items)
87
88    def reverse(self):
89        self._check_frozen()
90        self._items.reverse()
91
92    def pop(self, index=-1):
93        self._check_frozen()
94        return self._items.pop(index)
95
96    def append(self, item):
97        self._check_frozen()
98        return self._items.append(item)
99
100    def count(self, item):
101        return self._items.count(item)
102
103    def __repr__(self):
104        return '<FrozenList(frozen={}, {!r})>'.format(self.frozen,
105                                                      self._items)
106
107
108MutableSequence.register(FrozenList)
109