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.

classification
Title: slice object uses -1 as exclusive end-bound
Type: behavior Stage: test needed
Components: Interpreter Core Versions: Python 2.6
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: mwh Nosy List: ajaksu2, bryango, georg.brandl, mwh
Priority: normal Keywords:

Created on 2005-08-11 15:08 by bryango, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (5)
msg26023 - (view) Author: Bryan G. Olson (bryango) Date: 2005-08-11 15:08
The slice object passed to __getitem__ or __setitem__
reports an 
incorrect 'stop' value when the step is negative and
the slice 
includes the 0 index. If one then actually tries to
slice with 
what slice.indices returns, the result is wrong. Here's
a demo:

    class BuggerAll:

        def __init__(self, somelist):
            self.sequence = somelist[:]

        def __getitem__(self, key):
            if isinstance(key, slice):
                start, stop, step =
key.indices(len(self.sequence))
                # print 'Slice says start, stop, step
are:', start, stop, step
                return self.sequence[start : stop : step]


    print           range(10) [None : None : -2]
    print BuggerAll(range(10))[None : None : -2]


The above should print the same sequence twice, but
actually 
prints:

    [9, 7, 5, 3, 1]
    []

Un-commenting the print statement in __getitem__ shows:

    Slice says start, stop, step are: 9 -1 -2

The problem is the stop value of -1. The slice object
seems to 
think that -1 is a valid exclusive-end-bound, but when
slicing, 
Python interprets negative numbers as an offset from
the high 
end of the sequence. That is,

    range(10)[9 : -1 : -2]

is the same as,

    range(10)[[9 : 9 : -2]

which is the empty list.


So what should the slice.indices return in this case,
so that 
slicing with the returned values will work correctly? My 
experiments indicate:

    The start value can be any of:  None,  any integer
>= 9, -1
    The stop value can be either:   None, any integer
<= -11
    Step is correct; it must be:    -2

My favorite choice here is (9, None, -2).  The doc for 
slice.indices currently says:

    This method takes a single integer argument
/length/ and
    computes information about the extended slice that
the slice
    object would describe if applied to a sequence of
length
    items. It returns a tuple of three integers;
respectively
    these are the /start/ and /stop/ indices and the
/step/ or
    stride length of the slice. Missing or
out-of-bounds indices
    are handled in a manner consistent with regular slices.

    http://docs.python.org/ref/types.html

So using (9, None, -2) would require changing both the
code and 
the doc (because None is not an integer). A stop value
of -11 
(or less) would require changing only the code.


msg26024 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2005-08-12 13:02
Logged In: YES 
user_id=6656

This is clearly in my area.
msg26025 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2005-08-14 19:07
Logged In: YES 
user_id=6656

Did you see my follow up on clpy?
msg82197 - (view) Author: Daniel Diniz (ajaksu2) * (Python triager) Date: 2009-02-16 00:49
Closing suggested. FWIW, Micheal's reply is at
http://mail.python.org/pipermail/python-list/2005-August/335846.html
msg85531 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2009-04-05 17:27
Closing as "won't fix".  There's another issue that deals with better
documentation for slicing semantics.
History
Date User Action Args
2022-04-11 14:56:12adminsetgithub: 42268
2009-04-05 17:27:21georg.brandlsetstatus: open -> closed

nosy: + georg.brandl
messages: + msg85531

resolution: wont fix
2009-02-16 00:49:38ajaksu2setnosy: + ajaksu2
stage: test needed
type: behavior
messages: + msg82197
versions: + Python 2.6, - Python 2.4
2005-08-11 15:08:00bryangocreate