Issue 974635: Slice indexes passed to getitem are wrapped (original) (raw)

Created on 2004-06-17 10:22 by connelly, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (6)

msg60511 - (view)

Author: Connelly (connelly)

Date: 2004-06-17 10:22

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')

msg60512 - (view)

Author: Michael Hudson (mwh) (Python committer)

Date: 2004-06-17 11:23

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 :-)

msg60513 - (view)

Author: Connelly (connelly)

Date: 2004-06-17 21:50

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 [].

msg60514 - (view)

Author: Michael Hudson (mwh) (Python committer)

Date: 2004-06-18 10:46

Logged In: YES user_id=6656

'make your classes new-style' == subclass object.

class C(object): ... def getitem(self, item): print item ... def len(self): return 10 ... C()[-3:-2] slice(-3, -2, None)

msg64309 - (view)

Author: Alexander Belopolsky (belopolsky) * (Python committer)

Date: 2008-03-22 01:19

This looks like a duplicate of which was closed as "won't fix."

msg82057 - (view)

Author: Daniel Diniz (ajaksu2) * (Python triager)

Date: 2009-02-14 13:58

Will close this one as a duplicate of #723806 unless someone springs to its defense.

History

Date

User

Action

Args

2022-04-11 14:56:04

admin

set

github: 40411

2009-02-16 20:54:49

brett.cannon

set

status: open -> closed
resolution: wont fix

2009-02-14 13:58:37

ajaksu2

set

nosy: + ajaksu2
dependencies: + overintelligent slice() behavior on integers
messages: +

2008-03-22 01:19:06

belopolsky

set

nosy: + belopolsky
type: behavior
messages: +
components: + Interpreter Core, - None

2004-06-17 10:22:29

connelly

create