1from collections.abc import MutableSequence
2from functools import total_ordering
3
4from .helpers import NO_EXTENSIONS
5
6
7@total_ordering
8class FrozenList(MutableSequence):
9
10    __slots__ = ("_frozen", "_items")
11
12    def __init__(self, items=None):
13        self._frozen = False
14        if items is not None:
15            items = list(items)
16        else:
17            items = []
18        self._items = items
19
20    @property
21    def frozen(self):
22        return self._frozen
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        if self._frozen:
32            raise RuntimeError("Cannot modify frozen list.")
33        self._items[index] = value
34
35    def __delitem__(self, index):
36        if self._frozen:
37            raise RuntimeError("Cannot modify frozen list.")
38        del self._items[index]
39
40    def __len__(self):
41        return self._items.__len__()
42
43    def __iter__(self):
44        return self._items.__iter__()
45
46    def __reversed__(self):
47        return self._items.__reversed__()
48
49    def __eq__(self, other):
50        return list(self) == other
51
52    def __le__(self, other):
53        return list(self) <= other
54
55    def insert(self, pos, item):
56        if self._frozen:
57            raise RuntimeError("Cannot modify frozen list.")
58        self._items.insert(pos, item)
59
60    def __repr__(self):
61        return f"<FrozenList(frozen={self._frozen}, {self._items!r})>"
62
63
64PyFrozenList = FrozenList
65
66try:
67    from aiohttp._frozenlist import FrozenList as CFrozenList  # type: ignore
68
69    if not NO_EXTENSIONS:
70        FrozenList = CFrozenList  # type: ignore
71except ImportError:  # pragma: no cover
72    pass
73