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