Commit c7d063cc authored by Stefan Behnel's avatar Stefan Behnel

fix negative slice indices

parent 306c3a71
......@@ -427,15 +427,15 @@ static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i,
if (likely(m && m->sq_ass_item)) {
if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
Py_ssize_t l = m->sq_length(o);
if (likely(l >= 0)) {
i += l;
} else {
// if length > max(Py_ssize_t), maybe the object can wrap around itself?
if (PyErr_ExceptionMatches(PyExc_OverflowError))
PyErr_Clear();
else
return -1;
}
if (likely(l >= 0)) {
i += l;
} else {
// if length > max(Py_ssize_t), maybe the object can wrap around itself?
if (PyErr_ExceptionMatches(PyExc_OverflowError))
PyErr_Clear();
else
return -1;
}
}
return m->sq_ass_item(o, i, (PyObject *)NULL);
}
......@@ -476,6 +476,25 @@ static CYTHON_INLINE PyObject* __Pyx_PySequence_GetObjectSlice(
} else
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);
}
#endif
......
def f(obj1, obj2, obj3, obj4):
def test_full(seq):
"""
>>> l = [1,2,3,4]
>>> f(1, l, 2, 3)
>>> test_full(l)
[1, 2, 3, 4]
>>> l == f(1, l, 2, 3)
>>> l == test_full(l)
True
>>> l is f(1, l, 2, 3)
>>> l is test_full(l)
False
>>> try: f(1, 42, 2, 3)
>>> try: test_full(42)
... except TypeError: pass
"""
obj1 = obj2[:]
return obj1
obj = seq[:]
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]
>>> 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
"""
obj1 = obj2[obj3:]
return obj1
obj = seq[start:]
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]
>>> 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
"""
obj1 = obj2[:obj4]
return obj1
obj = seq[:stop]
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]
>>> 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
"""
obj1 = obj2[obj3:obj4]
return obj1
obj = seq[start:stop]
return obj
class A(object):
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