This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author connelly
Recipients
Date 2004-06-17.10:22:29
SpamBayes Score
Marked as misclassified
Message-id
In-reply-to
Content
Hi,

When a slice is passed to __getitem__, the indices for
the slice are wrapped by the length of the object
(adding len(self) once to both start index if < 0 and
the end index if < 0).

class C:
  def __getitem__(self, item): print item
  def __len__(self): return 10

>>> x = C()
>>> x[-3]
-3
>>> x[-3:-2]
slice(7, 8, None)

This seems to be incorrect (at least inconsistent).

However, it truly becomes a BUG when one tries to
emulate a list type:

class C:                      # Emulated list type
  def __init__(self, d):
    self.data = d
  def __len__(self):
    return len(self.data)
  def __getitem__(self, item):
    if isinstance(item, slice):
      indices = item.indices(len(self))
      return [self[i] for i in range(*indices)]
    else:
      return self.data[item]

x = [1, 2, 3]
y = C([1, 2, 3])

>>> x[-7:-5]
[]
>>> print y[-7:-5]
[1]                         (incorrect behavior)

Here the item.indices method does the exact same
wrapping process AGAIN.  So indices are wrapped once as
the slice index is constructed and passed to
__getitem__, and again when item.indices is called. 
This makes it impossible to implement a correctly
behaving list data type without using hacks to suppress
this Python bug.

I would advise that you make the slices object passed
to __getitem__ not have its start/end indexes wrapped.

Thanks,
Connelly Barnes
E-mail:
'636f6e6e656c6c796261726e6573407961686f6f2e636f6d'.decode('hex')
History
Date User Action Args
2008-01-20 09:56:57adminlinkissue974635 messages
2008-01-20 09:56:57admincreate