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 <rep...@bugs.python.org>
<http://bugs.python.org/issue21785>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to