[Python-Dev] Slicing

David Abrahams David Abrahams" <david.abrahams@rcn.com
Wed, 19 Jun 2002 07:57:22 -0400


----- Original Message -----
From: "Michael Hudson" <mwh@python.net>

> > This seems to indicate that I can't, in general, pass a slice object to
> > PyObject_GetItem in order to do slicing.** Correct?
>
> No.  The time machine has got you here; update to CVS and try again.

While that result is of interest, I think I need to support 2.2.1, so maybe
it doesn't make too much difference what the current CVS is doing.

> This comes down to the (slightly odd, IMHO) distinction between
> sequences and mappings, which doesn't really appear at the Python
> level.
>
> type_pointer->tp_as_sequence->sq_item
>
> takes a single int as a parameter
>
> type_pointer->tp_as_mapping->mp_subscr
>
> takes a PyObject*.

I know about those details, but of course they aren't really a cause: as
the current CVS shows, it *can* be handled.

> Builtin sequences (as of last week) have mp_subscr
> methods that handle slices.  I haven't checked, but would be amazed if
> PyObject_GetItem can't now be used with sliceobjects.

Good to know.

> > So Python is doing some dispatching internally based on the types of
the

> > >>> class subint(int): pass
> > ...
> > >>> subint()
> > 0
> > >>> Z[subint():5]
> > Traceback (most recent call last):
> >   File "<stdin>", line 1, in ?
> > TypeError: unsubscriptable object
>
> This last one is easy: you're trying to subscript the class object!

Oops, nice catch!

>>> Z()[subint():5]
getslice 0 5

> > I want to make a generalized getslice function in C which can operate
on a
> > triple of arbitrary objects. Here's the python version I came up with:
> >
> >     def getslice(x,start,finish):
> >         if (type(start) is type(finish) is int
> >             and hasattr(type(x), '__getslice__')):
> >             return x.__getslice__(start, finish)
> >         else:
> >             return x.__getitem__(slice(start,finish))
> >
> > Have I got the logic right here?
>
> You can't do this logic from Python, AFAIK.

Why do you say that? Are you saying I should be looking at slots and not
attributes, plus special handling for classic classes (ick)?

> I think PyObject_GetItem is your best bet.

Well, not if I care about versions < 2.2.2. So, I'm modifying my logic
slightly:

     def getslice(x,start,finish):
         if (isinstance(start,int) and isinstance(finish,int)
             and hasattr(type(x), '__getslice__')):
             return x.__getslice__(start, finish)
         else:
             return x.__getitem__(slice(start,finish))

-Dave