I used collections.MutableSequence
instead of subclassing Python's list()**
The resulting code... posting here in case, it helps someone...
from collections.abc import MutableSequence
class MyList(MutableSequence):
"""
An extensive user-defined wrapper around list objects.
Inspiration:
https://github.com/python/cpython/blob/208a7e957b812ad3b3733791845447677a704f3e/Lib/collections/__init__.py#L1174https://github.com/python/cpython/blob/208a7e957b812ad3b3733791845447677a704f3e/Lib/collections/__init__.py#L1174
"""
def __init__(self, initlist=None):
self.data = []
if initlist is not None:
if isinstance(initlist, list):
self.data[:] = initlist
elif isinstance(initlist, MyList):
self.data[:] = initlist.data[:]
else:
self.data = list(initlist)
def __repr__(self):
return """<{} data: {}>""".format(self.__class__.__name__, repr(self.data))
def __lt__(self, other):
return self.data < self.__cast(other)
def __le__(self, other):
return self.data <= self.__cast(other)
def __eq__(self, other):
return self.data == self.__cast(other)
def __gt__(self, other):
return self.data > self.__cast(other)
def __ge__(self, other):
return self.data >= self.__cast(other)
def __cast(self, other):
return other.data if isinstance(other, MyList) else other
def __contains__(self, value):
return value in self.data
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
if isinstance(i, slice):
return self.__class__(self.data[idx])
else:
return self.data[idx]
def __setitem__(self, idx, value):
# optional: self._acl_check(val)
self.data[idx] = value
def __delitem__(self, idx):
del self.data[idx]
def __add__(self, other):
if isinstance(other, MyList):
return self.__class__(self.data + other.data)
elif isinstance(other, type(self.data)):
return self.__class__(self.data + other)
return self.__class__(self.data + list(other))
def __radd__(self, other):
if isinstance(other, MyList):
return self.__class__(other.data + self.data)
elif isinstance(other, type(self.data)):
return self.__class__(other + self.data)
return self.__class__(list(other) + self.data)
def __iadd__(self, other):
if isinstance(other, MyList):
self.data += other.data
elif isinstance(other, type(self.data)):
self.data += other
else:
self.data += list(other)
return self
def __mul__(self, nn):
return self.__class__(self.data * nn)
__rmul__ = __mul__
def __imul__(self, nn):
self.data *= nn
return self
def __copy__(self):
inst = self.__class__.__new__(self.__class__)
inst.__dict__.update(self.__dict__)
# Create a copy and avoid triggering descriptors
inst.__dict__["data"] = self.__dict__["data"][:]
return inst
def append(self, value):
self.data.append(value)
def insert(self, idx, value):
self.data.insert(idx, value)
def pop(self, idx=-1):
return self.data.pop(idx)
def remove(self, value):
self.data.remove(value)
def clear(self):
self.data.clear()
def copy(self):
return self.__class__(self)
def count(self, value):
return self.data.count(value)
def index(self, idx, *args):
return self.data.index(idx, *args)
def reverse(self):
self.data.reverse()
def sort(self, /, *args, **kwds):
self.data.sort(*args, **kwds)
def extend(self, other):
if isinstance(other, MyList):
self.data.extend(other.data)
else:
self.data.extend(other)