[ python-Bugs-974635 ] Slice indexes passed to __getitem__ are
wrapped
SourceForge.net
noreply at sourceforge.net
Thu Jun 17 17:50:16 EDT 2004
Bugs item #974635, was opened at 2004-06-17 10:22
Message generated for change (Comment added) made by connelly
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=974635&group_id=5470
Category: None
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Connelly (connelly)
Assigned to: Nobody/Anonymous (nobody)
Summary: Slice indexes passed to __getitem__ are wrapped
Initial Comment:
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')
----------------------------------------------------------------------
>Comment By: Connelly (connelly)
Date: 2004-06-17 21:50
Message:
Logged In: YES
user_id=1039782
I'm not sure what you mean by 'make your classes new-style'.
According to
http://www.python.org/doc/2.3.4/ref/specialnames.html, the
__getitem__ method should be used, and the __getslice__
method is deprecated.
If you subclass the built-in list type, then the __getitem__
method is *not* called when subscripting with a slice.
Instead, the __getslice__ method is called. Try it out.
So I can't see any reasonable way to get around this bug.
You can try and modify the class C shown above, so that it
behaves correctly. I don't think you will be able to do it
without putting in special "workaround" code to avoid this
Python bug.
y = C([1, 2, 3])
>>> print y[-7:-5] # should be [].
----------------------------------------------------------------------
Comment By: Michael Hudson (mwh)
Date: 2004-06-17 11:23
Message:
Logged In: YES
user_id=6656
You'll be happier if you make your classes new-style.
I don't know if it's worth changing old-style classes at
this point. Personally, I'm trying to forget about them
just as quickly as possible :-)
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=974635&group_id=5470
More information about the Python-bugs-list
mailing list