I am studying ways to forward object methods in order to modify some of them and leave the rest as they are.
I thought that if it is possible to get __getitem__ as a field, it should be possible to use square brackets and len as well, but apparently it is not:
class Wrapper:
    def __init__(self, x):
        self.__dict__['__wrapped_obj'] = x
    def __getattribute__(self, item):
        if item == '__dict__':
            return super().__getattribute__(item)
        print('They be gettin "{}"'.format(item))
        return self.__dict__['__wrapped_obj'].__getattribute__(item)
    def __setattribute__(self, item, v):
        print('They be settin "{}"'.format(item))
        return setattr(self.__dict__['__wrapped_obj'], item, v)
class Wrapper2:  # gives same results
    def __init__(self, x):
        for k in dir(x):
            if k not in ('__class__', ):
                setattr(self, k, getattr(x, k))
        self.__dict__['__wrapped_obj'] = x
a = Wrapper([])
a.append(5)
print(a.__getitem__(0))  # 5
len(a)                   # TypeError: object of type 'Wrapper' has no len()
a[0]                     # TypeError: 'Wrapper' object does not support indexing
So Python internally uses something else than item's __dict__ to find magic methods?
