New submission from Konstantin Tretyakov:
Consider the following example:
class A:
def __getitem__(self, index):
return True
If you invoke A()[-1], everything is fine. However, if you invoke A()[-1:2],
you get an "AttributeError: A instance has no attribute '__len__'".
Moreover, if you define __len__ for your class, you will discover that
__getitem__ will act "smart" and modify slice you are passing into the
function. Check this out:
class A:
def __getitem__(self, index):
return index.start
def __len__(self):
return 10
Now A()[-1:10] outputs "9". The same kind of argument-mangling happens within
__setitem__.
This is completely unintuitive and contrary to what I read in the docs
(https://docs.python.org/2/reference/datamodel.html#object.__getitem__):
"Note that the special interpretation of negative indexes (if the class wishes
to emulate a sequence type) is up to the __getitem__() method.".
Especially intuitive is the fact that if you do A()[slice(-1,10)] or
A().__getitem__(slice(-1,10)), no special treatment is done for the -1,
everything works fine and the __len__ method is not invoked.
As far as I understand, the root cause is the behaviour of STORE_SLICE+3
command, which tries to be too smart.
I have discovered this within code where slice indexing was used to insert
arbitrary intervals into a data structure (hence using negative numbers would
be totally fine), and obviuosly such behaviour broke the whole idea, albeit it
was nontrivial to debug and discover.
This does not seem to be a problem for Python 3.3, however I believe fixing
this in Python 2.7 is important as well.
----------
components: Interpreter Core
messages: 220792
nosy: kt
priority: normal
severity: normal
status: open
title: __getitem__ and __setitem__ try to be smart when invoked with negative
slice indices
type: behavior
versions: Python 2.7
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue21785>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com