Commit c7d063cc authored by Stefan Behnel's avatar Stefan Behnel

fix negative slice indices

parent 306c3a71
...@@ -476,6 +476,25 @@ static CYTHON_INLINE PyObject* __Pyx_PySequence_GetObjectSlice( ...@@ -476,6 +476,25 @@ static CYTHON_INLINE PyObject* __Pyx_PySequence_GetObjectSlice(
} else } else
cstop = PY_SSIZE_T_MAX; cstop = PY_SSIZE_T_MAX;
} }
if (unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
Py_ssize_t l = ms->sq_length(obj);
if (likely(l >= 0)) {
if (cstop < 0) {
cstop += l;
if (cstop < 0) cstop = 0;
}
if (cstart < 0) {
cstart += l;
if (cstart < 0) cstart = 0;
}
} else {
// if length > max(Py_ssize_t), maybe the object can wrap around itself?
if (PyErr_ExceptionMatches(PyExc_OverflowError))
PyErr_Clear();
else
return NULL;
}
}
return ms->sq_slice(obj, cstart, cstop); return ms->sq_slice(obj, cstart, cstop);
} }
#endif #endif
......
def f(obj1, obj2, obj3, obj4): def test_full(seq):
""" """
>>> l = [1,2,3,4] >>> l = [1,2,3,4]
>>> f(1, l, 2, 3) >>> test_full(l)
[1, 2, 3, 4] [1, 2, 3, 4]
>>> l == f(1, l, 2, 3) >>> l == test_full(l)
True True
>>> l is f(1, l, 2, 3) >>> l is test_full(l)
False False
>>> try: f(1, 42, 2, 3) >>> try: test_full(42)
... except TypeError: pass ... except TypeError: pass
""" """
obj1 = obj2[:] obj = seq[:]
return obj1 return obj
def g(obj1, obj2, obj3, obj4): def test_start(seq, start):
""" """
>>> g(1, [1,2,3,4], 2, 3) >>> test_start([1,2,3,4], 2)
[3, 4] [3, 4]
>>> try: g(1, 42, 2, 3) >>> test_start([1,2,3,4], 3)
[4]
>>> test_start([1,2,3,4], 4)
[]
>>> test_start([1,2,3,4], 8)
[]
>>> test_start([1,2,3,4], -3)
[2, 3, 4]
>>> test_start([1,2,3,4], -4)
[1, 2, 3, 4]
>>> test_start([1,2,3,4], -8)
[1, 2, 3, 4]
>>> test_start([1,2,3,4], 0)
[1, 2, 3, 4]
>>> try: test_start(42, 2, 3)
... except TypeError: pass ... except TypeError: pass
""" """
obj1 = obj2[obj3:] obj = seq[start:]
return obj1 return obj
def h(obj1, obj2, obj3, obj4): def test_stop(seq, stop):
""" """
>>> h(1, [1,2,3,4], 2, 3) >>> test_stop([1,2,3,4], 3)
[1, 2, 3] [1, 2, 3]
>>> try: h(1, 42, 2, 3) >>> test_stop([1,2,3,4], -1)
[1, 2, 3]
>>> test_stop([1,2,3,4], -3)
[1]
>>> test_stop([1,2,3,4], -4)
[]
>>> test_stop([1,2,3,4], -8)
[]
>>> test_stop([1,2,3,4], 0)
[]
>>> try: test_stop(42, 3)
... except TypeError: pass ... except TypeError: pass
""" """
obj1 = obj2[:obj4] obj = seq[:stop]
return obj1 return obj
def j(obj1, obj2, obj3, obj4): def test_start_and_stop(seq, start, stop):
""" """
>>> j(1, [1,2,3,4], 2, 3) >>> l = [1,2,3,4]
>>> test_start_and_stop(l, 2, 3)
[3] [3]
>>> try: j(1, 42, 2, 3) >>> test_start_and_stop(l, -3, -1)
[2, 3]
>>> try: test_start_and_stop(42, 2, 3)
... except TypeError: pass ... except TypeError: pass
""" """
obj1 = obj2[obj3:obj4] obj = seq[start:stop]
return obj1 return obj
class A(object): class A(object):
pass pass
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment