• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2007 Google, Inc. All Rights Reserved.
2# Licensed to PSF under a Contributor Agreement.
3
4"""Abstract Base Classes (ABCs) for collections, according to PEP 3119.
5
6Unit tests are in test_collections.
7"""
8
9from abc import ABCMeta, abstractmethod
10import sys
11
12GenericAlias = type(list[int])
13
14__all__ = ["Awaitable", "Coroutine",
15           "AsyncIterable", "AsyncIterator", "AsyncGenerator",
16           "Hashable", "Iterable", "Iterator", "Generator", "Reversible",
17           "Sized", "Container", "Callable", "Collection",
18           "Set", "MutableSet",
19           "Mapping", "MutableMapping",
20           "MappingView", "KeysView", "ItemsView", "ValuesView",
21           "Sequence", "MutableSequence",
22           "ByteString",
23           ]
24
25# This module has been renamed from collections.abc to _collections_abc to
26# speed up interpreter startup. Some of the types such as MutableMapping are
27# required early but collections module imports a lot of other modules.
28# See issue #19218
29__name__ = "collections.abc"
30
31# Private list of types that we want to register with the various ABCs
32# so that they will pass tests like:
33#       it = iter(somebytearray)
34#       assert isinstance(it, Iterable)
35# Note:  in other implementations, these types might not be distinct
36# and they may have their own implementation specific types that
37# are not included on this list.
38bytes_iterator = type(iter(b''))
39bytearray_iterator = type(iter(bytearray()))
40#callable_iterator = ???
41dict_keyiterator = type(iter({}.keys()))
42dict_valueiterator = type(iter({}.values()))
43dict_itemiterator = type(iter({}.items()))
44list_iterator = type(iter([]))
45list_reverseiterator = type(iter(reversed([])))
46range_iterator = type(iter(range(0)))
47longrange_iterator = type(iter(range(1 << 1000)))
48set_iterator = type(iter(set()))
49str_iterator = type(iter(""))
50tuple_iterator = type(iter(()))
51zip_iterator = type(iter(zip()))
52## views ##
53dict_keys = type({}.keys())
54dict_values = type({}.values())
55dict_items = type({}.items())
56## misc ##
57mappingproxy = type(type.__dict__)
58generator = type((lambda: (yield))())
59## coroutine ##
60async def _coro(): pass
61_coro = _coro()
62coroutine = type(_coro)
63_coro.close()  # Prevent ResourceWarning
64del _coro
65## asynchronous generator ##
66async def _ag(): yield
67_ag = _ag()
68async_generator = type(_ag)
69del _ag
70
71
72### ONE-TRICK PONIES ###
73
74def _check_methods(C, *methods):
75    mro = C.__mro__
76    for method in methods:
77        for B in mro:
78            if method in B.__dict__:
79                if B.__dict__[method] is None:
80                    return NotImplemented
81                break
82        else:
83            return NotImplemented
84    return True
85
86class Hashable(metaclass=ABCMeta):
87
88    __slots__ = ()
89
90    @abstractmethod
91    def __hash__(self):
92        return 0
93
94    @classmethod
95    def __subclasshook__(cls, C):
96        if cls is Hashable:
97            return _check_methods(C, "__hash__")
98        return NotImplemented
99
100
101class Awaitable(metaclass=ABCMeta):
102
103    __slots__ = ()
104
105    @abstractmethod
106    def __await__(self):
107        yield
108
109    @classmethod
110    def __subclasshook__(cls, C):
111        if cls is Awaitable:
112            return _check_methods(C, "__await__")
113        return NotImplemented
114
115    __class_getitem__ = classmethod(GenericAlias)
116
117
118class Coroutine(Awaitable):
119
120    __slots__ = ()
121
122    @abstractmethod
123    def send(self, value):
124        """Send a value into the coroutine.
125        Return next yielded value or raise StopIteration.
126        """
127        raise StopIteration
128
129    @abstractmethod
130    def throw(self, typ, val=None, tb=None):
131        """Raise an exception in the coroutine.
132        Return next yielded value or raise StopIteration.
133        """
134        if val is None:
135            if tb is None:
136                raise typ
137            val = typ()
138        if tb is not None:
139            val = val.with_traceback(tb)
140        raise val
141
142    def close(self):
143        """Raise GeneratorExit inside coroutine.
144        """
145        try:
146            self.throw(GeneratorExit)
147        except (GeneratorExit, StopIteration):
148            pass
149        else:
150            raise RuntimeError("coroutine ignored GeneratorExit")
151
152    @classmethod
153    def __subclasshook__(cls, C):
154        if cls is Coroutine:
155            return _check_methods(C, '__await__', 'send', 'throw', 'close')
156        return NotImplemented
157
158
159Coroutine.register(coroutine)
160
161
162class AsyncIterable(metaclass=ABCMeta):
163
164    __slots__ = ()
165
166    @abstractmethod
167    def __aiter__(self):
168        return AsyncIterator()
169
170    @classmethod
171    def __subclasshook__(cls, C):
172        if cls is AsyncIterable:
173            return _check_methods(C, "__aiter__")
174        return NotImplemented
175
176    __class_getitem__ = classmethod(GenericAlias)
177
178
179class AsyncIterator(AsyncIterable):
180
181    __slots__ = ()
182
183    @abstractmethod
184    async def __anext__(self):
185        """Return the next item or raise StopAsyncIteration when exhausted."""
186        raise StopAsyncIteration
187
188    def __aiter__(self):
189        return self
190
191    @classmethod
192    def __subclasshook__(cls, C):
193        if cls is AsyncIterator:
194            return _check_methods(C, "__anext__", "__aiter__")
195        return NotImplemented
196
197
198class AsyncGenerator(AsyncIterator):
199
200    __slots__ = ()
201
202    async def __anext__(self):
203        """Return the next item from the asynchronous generator.
204        When exhausted, raise StopAsyncIteration.
205        """
206        return await self.asend(None)
207
208    @abstractmethod
209    async def asend(self, value):
210        """Send a value into the asynchronous generator.
211        Return next yielded value or raise StopAsyncIteration.
212        """
213        raise StopAsyncIteration
214
215    @abstractmethod
216    async def athrow(self, typ, val=None, tb=None):
217        """Raise an exception in the asynchronous generator.
218        Return next yielded value or raise StopAsyncIteration.
219        """
220        if val is None:
221            if tb is None:
222                raise typ
223            val = typ()
224        if tb is not None:
225            val = val.with_traceback(tb)
226        raise val
227
228    async def aclose(self):
229        """Raise GeneratorExit inside coroutine.
230        """
231        try:
232            await self.athrow(GeneratorExit)
233        except (GeneratorExit, StopAsyncIteration):
234            pass
235        else:
236            raise RuntimeError("asynchronous generator ignored GeneratorExit")
237
238    @classmethod
239    def __subclasshook__(cls, C):
240        if cls is AsyncGenerator:
241            return _check_methods(C, '__aiter__', '__anext__',
242                                  'asend', 'athrow', 'aclose')
243        return NotImplemented
244
245
246AsyncGenerator.register(async_generator)
247
248
249class Iterable(metaclass=ABCMeta):
250
251    __slots__ = ()
252
253    @abstractmethod
254    def __iter__(self):
255        while False:
256            yield None
257
258    @classmethod
259    def __subclasshook__(cls, C):
260        if cls is Iterable:
261            return _check_methods(C, "__iter__")
262        return NotImplemented
263
264    __class_getitem__ = classmethod(GenericAlias)
265
266
267class Iterator(Iterable):
268
269    __slots__ = ()
270
271    @abstractmethod
272    def __next__(self):
273        'Return the next item from the iterator. When exhausted, raise StopIteration'
274        raise StopIteration
275
276    def __iter__(self):
277        return self
278
279    @classmethod
280    def __subclasshook__(cls, C):
281        if cls is Iterator:
282            return _check_methods(C, '__iter__', '__next__')
283        return NotImplemented
284
285
286Iterator.register(bytes_iterator)
287Iterator.register(bytearray_iterator)
288#Iterator.register(callable_iterator)
289Iterator.register(dict_keyiterator)
290Iterator.register(dict_valueiterator)
291Iterator.register(dict_itemiterator)
292Iterator.register(list_iterator)
293Iterator.register(list_reverseiterator)
294Iterator.register(range_iterator)
295Iterator.register(longrange_iterator)
296Iterator.register(set_iterator)
297Iterator.register(str_iterator)
298Iterator.register(tuple_iterator)
299Iterator.register(zip_iterator)
300
301
302class Reversible(Iterable):
303
304    __slots__ = ()
305
306    @abstractmethod
307    def __reversed__(self):
308        while False:
309            yield None
310
311    @classmethod
312    def __subclasshook__(cls, C):
313        if cls is Reversible:
314            return _check_methods(C, "__reversed__", "__iter__")
315        return NotImplemented
316
317
318class Generator(Iterator):
319
320    __slots__ = ()
321
322    def __next__(self):
323        """Return the next item from the generator.
324        When exhausted, raise StopIteration.
325        """
326        return self.send(None)
327
328    @abstractmethod
329    def send(self, value):
330        """Send a value into the generator.
331        Return next yielded value or raise StopIteration.
332        """
333        raise StopIteration
334
335    @abstractmethod
336    def throw(self, typ, val=None, tb=None):
337        """Raise an exception in the generator.
338        Return next yielded value or raise StopIteration.
339        """
340        if val is None:
341            if tb is None:
342                raise typ
343            val = typ()
344        if tb is not None:
345            val = val.with_traceback(tb)
346        raise val
347
348    def close(self):
349        """Raise GeneratorExit inside generator.
350        """
351        try:
352            self.throw(GeneratorExit)
353        except (GeneratorExit, StopIteration):
354            pass
355        else:
356            raise RuntimeError("generator ignored GeneratorExit")
357
358    @classmethod
359    def __subclasshook__(cls, C):
360        if cls is Generator:
361            return _check_methods(C, '__iter__', '__next__',
362                                  'send', 'throw', 'close')
363        return NotImplemented
364
365
366Generator.register(generator)
367
368
369class Sized(metaclass=ABCMeta):
370
371    __slots__ = ()
372
373    @abstractmethod
374    def __len__(self):
375        return 0
376
377    @classmethod
378    def __subclasshook__(cls, C):
379        if cls is Sized:
380            return _check_methods(C, "__len__")
381        return NotImplemented
382
383
384class Container(metaclass=ABCMeta):
385
386    __slots__ = ()
387
388    @abstractmethod
389    def __contains__(self, x):
390        return False
391
392    @classmethod
393    def __subclasshook__(cls, C):
394        if cls is Container:
395            return _check_methods(C, "__contains__")
396        return NotImplemented
397
398    __class_getitem__ = classmethod(GenericAlias)
399
400
401class Collection(Sized, Iterable, Container):
402
403    __slots__ = ()
404
405    @classmethod
406    def __subclasshook__(cls, C):
407        if cls is Collection:
408            return _check_methods(C,  "__len__", "__iter__", "__contains__")
409        return NotImplemented
410
411
412class Callable(metaclass=ABCMeta):
413
414    __slots__ = ()
415
416    @abstractmethod
417    def __call__(self, *args, **kwds):
418        return False
419
420    @classmethod
421    def __subclasshook__(cls, C):
422        if cls is Callable:
423            return _check_methods(C, "__call__")
424        return NotImplemented
425
426    __class_getitem__ = classmethod(GenericAlias)
427
428
429### SETS ###
430
431
432class Set(Collection):
433
434    """A set is a finite, iterable container.
435
436    This class provides concrete generic implementations of all
437    methods except for __contains__, __iter__ and __len__.
438
439    To override the comparisons (presumably for speed, as the
440    semantics are fixed), redefine __le__ and __ge__,
441    then the other operations will automatically follow suit.
442    """
443
444    __slots__ = ()
445
446    def __le__(self, other):
447        if not isinstance(other, Set):
448            return NotImplemented
449        if len(self) > len(other):
450            return False
451        for elem in self:
452            if elem not in other:
453                return False
454        return True
455
456    def __lt__(self, other):
457        if not isinstance(other, Set):
458            return NotImplemented
459        return len(self) < len(other) and self.__le__(other)
460
461    def __gt__(self, other):
462        if not isinstance(other, Set):
463            return NotImplemented
464        return len(self) > len(other) and self.__ge__(other)
465
466    def __ge__(self, other):
467        if not isinstance(other, Set):
468            return NotImplemented
469        if len(self) < len(other):
470            return False
471        for elem in other:
472            if elem not in self:
473                return False
474        return True
475
476    def __eq__(self, other):
477        if not isinstance(other, Set):
478            return NotImplemented
479        return len(self) == len(other) and self.__le__(other)
480
481    @classmethod
482    def _from_iterable(cls, it):
483        '''Construct an instance of the class from any iterable input.
484
485        Must override this method if the class constructor signature
486        does not accept an iterable for an input.
487        '''
488        return cls(it)
489
490    def __and__(self, other):
491        if not isinstance(other, Iterable):
492            return NotImplemented
493        return self._from_iterable(value for value in other if value in self)
494
495    __rand__ = __and__
496
497    def isdisjoint(self, other):
498        'Return True if two sets have a null intersection.'
499        for value in other:
500            if value in self:
501                return False
502        return True
503
504    def __or__(self, other):
505        if not isinstance(other, Iterable):
506            return NotImplemented
507        chain = (e for s in (self, other) for e in s)
508        return self._from_iterable(chain)
509
510    __ror__ = __or__
511
512    def __sub__(self, other):
513        if not isinstance(other, Set):
514            if not isinstance(other, Iterable):
515                return NotImplemented
516            other = self._from_iterable(other)
517        return self._from_iterable(value for value in self
518                                   if value not in other)
519
520    def __rsub__(self, other):
521        if not isinstance(other, Set):
522            if not isinstance(other, Iterable):
523                return NotImplemented
524            other = self._from_iterable(other)
525        return self._from_iterable(value for value in other
526                                   if value not in self)
527
528    def __xor__(self, other):
529        if not isinstance(other, Set):
530            if not isinstance(other, Iterable):
531                return NotImplemented
532            other = self._from_iterable(other)
533        return (self - other) | (other - self)
534
535    __rxor__ = __xor__
536
537    def _hash(self):
538        """Compute the hash value of a set.
539
540        Note that we don't define __hash__: not all sets are hashable.
541        But if you define a hashable set type, its __hash__ should
542        call this function.
543
544        This must be compatible __eq__.
545
546        All sets ought to compare equal if they contain the same
547        elements, regardless of how they are implemented, and
548        regardless of the order of the elements; so there's not much
549        freedom for __eq__ or __hash__.  We match the algorithm used
550        by the built-in frozenset type.
551        """
552        MAX = sys.maxsize
553        MASK = 2 * MAX + 1
554        n = len(self)
555        h = 1927868237 * (n + 1)
556        h &= MASK
557        for x in self:
558            hx = hash(x)
559            h ^= (hx ^ (hx << 16) ^ 89869747)  * 3644798167
560            h &= MASK
561        h = h * 69069 + 907133923
562        h &= MASK
563        if h > MAX:
564            h -= MASK + 1
565        if h == -1:
566            h = 590923713
567        return h
568
569
570Set.register(frozenset)
571
572
573class MutableSet(Set):
574    """A mutable set is a finite, iterable container.
575
576    This class provides concrete generic implementations of all
577    methods except for __contains__, __iter__, __len__,
578    add(), and discard().
579
580    To override the comparisons (presumably for speed, as the
581    semantics are fixed), all you have to do is redefine __le__ and
582    then the other operations will automatically follow suit.
583    """
584
585    __slots__ = ()
586
587    @abstractmethod
588    def add(self, value):
589        """Add an element."""
590        raise NotImplementedError
591
592    @abstractmethod
593    def discard(self, value):
594        """Remove an element.  Do not raise an exception if absent."""
595        raise NotImplementedError
596
597    def remove(self, value):
598        """Remove an element. If not a member, raise a KeyError."""
599        if value not in self:
600            raise KeyError(value)
601        self.discard(value)
602
603    def pop(self):
604        """Return the popped value.  Raise KeyError if empty."""
605        it = iter(self)
606        try:
607            value = next(it)
608        except StopIteration:
609            raise KeyError from None
610        self.discard(value)
611        return value
612
613    def clear(self):
614        """This is slow (creates N new iterators!) but effective."""
615        try:
616            while True:
617                self.pop()
618        except KeyError:
619            pass
620
621    def __ior__(self, it):
622        for value in it:
623            self.add(value)
624        return self
625
626    def __iand__(self, it):
627        for value in (self - it):
628            self.discard(value)
629        return self
630
631    def __ixor__(self, it):
632        if it is self:
633            self.clear()
634        else:
635            if not isinstance(it, Set):
636                it = self._from_iterable(it)
637            for value in it:
638                if value in self:
639                    self.discard(value)
640                else:
641                    self.add(value)
642        return self
643
644    def __isub__(self, it):
645        if it is self:
646            self.clear()
647        else:
648            for value in it:
649                self.discard(value)
650        return self
651
652
653MutableSet.register(set)
654
655
656### MAPPINGS ###
657
658
659class Mapping(Collection):
660
661    __slots__ = ()
662
663    """A Mapping is a generic container for associating key/value
664    pairs.
665
666    This class provides concrete generic implementations of all
667    methods except for __getitem__, __iter__, and __len__.
668
669    """
670
671    @abstractmethod
672    def __getitem__(self, key):
673        raise KeyError
674
675    def get(self, key, default=None):
676        'D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.'
677        try:
678            return self[key]
679        except KeyError:
680            return default
681
682    def __contains__(self, key):
683        try:
684            self[key]
685        except KeyError:
686            return False
687        else:
688            return True
689
690    def keys(self):
691        "D.keys() -> a set-like object providing a view on D's keys"
692        return KeysView(self)
693
694    def items(self):
695        "D.items() -> a set-like object providing a view on D's items"
696        return ItemsView(self)
697
698    def values(self):
699        "D.values() -> an object providing a view on D's values"
700        return ValuesView(self)
701
702    def __eq__(self, other):
703        if not isinstance(other, Mapping):
704            return NotImplemented
705        return dict(self.items()) == dict(other.items())
706
707    __reversed__ = None
708
709
710Mapping.register(mappingproxy)
711
712
713class MappingView(Sized):
714
715    __slots__ = '_mapping',
716
717    def __init__(self, mapping):
718        self._mapping = mapping
719
720    def __len__(self):
721        return len(self._mapping)
722
723    def __repr__(self):
724        return '{0.__class__.__name__}({0._mapping!r})'.format(self)
725
726    __class_getitem__ = classmethod(GenericAlias)
727
728
729class KeysView(MappingView, Set):
730
731    __slots__ = ()
732
733    @classmethod
734    def _from_iterable(self, it):
735        return set(it)
736
737    def __contains__(self, key):
738        return key in self._mapping
739
740    def __iter__(self):
741        yield from self._mapping
742
743
744KeysView.register(dict_keys)
745
746
747class ItemsView(MappingView, Set):
748
749    __slots__ = ()
750
751    @classmethod
752    def _from_iterable(self, it):
753        return set(it)
754
755    def __contains__(self, item):
756        key, value = item
757        try:
758            v = self._mapping[key]
759        except KeyError:
760            return False
761        else:
762            return v is value or v == value
763
764    def __iter__(self):
765        for key in self._mapping:
766            yield (key, self._mapping[key])
767
768
769ItemsView.register(dict_items)
770
771
772class ValuesView(MappingView, Collection):
773
774    __slots__ = ()
775
776    def __contains__(self, value):
777        for key in self._mapping:
778            v = self._mapping[key]
779            if v is value or v == value:
780                return True
781        return False
782
783    def __iter__(self):
784        for key in self._mapping:
785            yield self._mapping[key]
786
787
788ValuesView.register(dict_values)
789
790
791class MutableMapping(Mapping):
792
793    __slots__ = ()
794
795    """A MutableMapping is a generic container for associating
796    key/value pairs.
797
798    This class provides concrete generic implementations of all
799    methods except for __getitem__, __setitem__, __delitem__,
800    __iter__, and __len__.
801
802    """
803
804    @abstractmethod
805    def __setitem__(self, key, value):
806        raise KeyError
807
808    @abstractmethod
809    def __delitem__(self, key):
810        raise KeyError
811
812    __marker = object()
813
814    def pop(self, key, default=__marker):
815        '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
816          If key is not found, d is returned if given, otherwise KeyError is raised.
817        '''
818        try:
819            value = self[key]
820        except KeyError:
821            if default is self.__marker:
822                raise
823            return default
824        else:
825            del self[key]
826            return value
827
828    def popitem(self):
829        '''D.popitem() -> (k, v), remove and return some (key, value) pair
830           as a 2-tuple; but raise KeyError if D is empty.
831        '''
832        try:
833            key = next(iter(self))
834        except StopIteration:
835            raise KeyError from None
836        value = self[key]
837        del self[key]
838        return key, value
839
840    def clear(self):
841        'D.clear() -> None.  Remove all items from D.'
842        try:
843            while True:
844                self.popitem()
845        except KeyError:
846            pass
847
848    def update(self, other=(), /, **kwds):
849        ''' D.update([E, ]**F) -> None.  Update D from mapping/iterable E and F.
850            If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
851            If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
852            In either case, this is followed by: for k, v in F.items(): D[k] = v
853        '''
854        if isinstance(other, Mapping):
855            for key in other:
856                self[key] = other[key]
857        elif hasattr(other, "keys"):
858            for key in other.keys():
859                self[key] = other[key]
860        else:
861            for key, value in other:
862                self[key] = value
863        for key, value in kwds.items():
864            self[key] = value
865
866    def setdefault(self, key, default=None):
867        'D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D'
868        try:
869            return self[key]
870        except KeyError:
871            self[key] = default
872        return default
873
874
875MutableMapping.register(dict)
876
877
878### SEQUENCES ###
879
880
881class Sequence(Reversible, Collection):
882
883    """All the operations on a read-only sequence.
884
885    Concrete subclasses must override __new__ or __init__,
886    __getitem__, and __len__.
887    """
888
889    __slots__ = ()
890
891    @abstractmethod
892    def __getitem__(self, index):
893        raise IndexError
894
895    def __iter__(self):
896        i = 0
897        try:
898            while True:
899                v = self[i]
900                yield v
901                i += 1
902        except IndexError:
903            return
904
905    def __contains__(self, value):
906        for v in self:
907            if v is value or v == value:
908                return True
909        return False
910
911    def __reversed__(self):
912        for i in reversed(range(len(self))):
913            yield self[i]
914
915    def index(self, value, start=0, stop=None):
916        '''S.index(value, [start, [stop]]) -> integer -- return first index of value.
917           Raises ValueError if the value is not present.
918
919           Supporting start and stop arguments is optional, but
920           recommended.
921        '''
922        if start is not None and start < 0:
923            start = max(len(self) + start, 0)
924        if stop is not None and stop < 0:
925            stop += len(self)
926
927        i = start
928        while stop is None or i < stop:
929            try:
930                v = self[i]
931                if v is value or v == value:
932                    return i
933            except IndexError:
934                break
935            i += 1
936        raise ValueError
937
938    def count(self, value):
939        'S.count(value) -> integer -- return number of occurrences of value'
940        return sum(1 for v in self if v is value or v == value)
941
942
943Sequence.register(tuple)
944Sequence.register(str)
945Sequence.register(range)
946Sequence.register(memoryview)
947
948
949class ByteString(Sequence):
950
951    """This unifies bytes and bytearray.
952
953    XXX Should add all their methods.
954    """
955
956    __slots__ = ()
957
958ByteString.register(bytes)
959ByteString.register(bytearray)
960
961
962class MutableSequence(Sequence):
963
964    __slots__ = ()
965
966    """All the operations on a read-write sequence.
967
968    Concrete subclasses must provide __new__ or __init__,
969    __getitem__, __setitem__, __delitem__, __len__, and insert().
970
971    """
972
973    @abstractmethod
974    def __setitem__(self, index, value):
975        raise IndexError
976
977    @abstractmethod
978    def __delitem__(self, index):
979        raise IndexError
980
981    @abstractmethod
982    def insert(self, index, value):
983        'S.insert(index, value) -- insert value before index'
984        raise IndexError
985
986    def append(self, value):
987        'S.append(value) -- append value to the end of the sequence'
988        self.insert(len(self), value)
989
990    def clear(self):
991        'S.clear() -> None -- remove all items from S'
992        try:
993            while True:
994                self.pop()
995        except IndexError:
996            pass
997
998    def reverse(self):
999        'S.reverse() -- reverse *IN PLACE*'
1000        n = len(self)
1001        for i in range(n//2):
1002            self[i], self[n-i-1] = self[n-i-1], self[i]
1003
1004    def extend(self, values):
1005        'S.extend(iterable) -- extend sequence by appending elements from the iterable'
1006        if values is self:
1007            values = list(values)
1008        for v in values:
1009            self.append(v)
1010
1011    def pop(self, index=-1):
1012        '''S.pop([index]) -> item -- remove and return item at index (default last).
1013           Raise IndexError if list is empty or index is out of range.
1014        '''
1015        v = self[index]
1016        del self[index]
1017        return v
1018
1019    def remove(self, value):
1020        '''S.remove(value) -- remove first occurrence of value.
1021           Raise ValueError if the value is not present.
1022        '''
1023        del self[self.index(value)]
1024
1025    def __iadd__(self, values):
1026        self.extend(values)
1027        return self
1028
1029
1030MutableSequence.register(list)
1031MutableSequence.register(bytearray)  # Multiply inheriting, see ByteString
1032