This very simple snippet fails on python 2 but passes with python 3:
class A:
    def __init__(self, value):
        self.value = value
    def __setitem__(self, key, value):
        pass
r = A(1)
r[80:-10] = list(range(10))
On python2, the interpreter make a call to __len__ which does not exist and therefore fails with:
Traceback (most recent call last):
  File "prog.py", line 9, in <module>
AttributeError: A instance has no attribute '__len__'
Where is this behaviour documented? It doesn't make sense to force a container to have a size.
That's an old-style class quirk. Old-style classes have a lot of poorly-documented quirks, mostly old behavior that hasn't kept up with changes to Python.
Here, types.InstanceType has a __setslice__, which is responsible for looking up the old-style class __setitem__ and __setslice__. Since this __setslice__ exists, Python tries to go through __setslice__, which requires a len call first for negative slice indexes. Your (old-style) class doesn't have __len__, so the call fails.
Use a new-style class:
class A(object):
    ...
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With