Commit 13dff283 authored by Lisandro Dalcin's avatar Lisandro Dalcin

Re: [Cython] PATCH: fix delitem for index nodes

parent a823cf5e
......@@ -1557,10 +1557,6 @@ class IndexNode(ExprNode):
if self.index.type.is_int and not self.index.type.is_longlong:
self.original_index_type = self.index.type
self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
if getting:
env.use_utility_code(getitem_int_utility_code)
if setting:
env.use_utility_code(setitem_int_utility_code)
else:
self.index = self.index.coerce_to_pyobject(env)
self.type = py_object_type
......@@ -1636,6 +1632,7 @@ class IndexNode(ExprNode):
if self.index.type.is_int:
function = "__Pyx_GetItemInt"
index_code = self.index.result()
code.globalstate.use_utility_code(getitem_int_utility_code)
else:
function = "PyObject_GetItem"
index_code = self.index.py_result()
......@@ -1654,6 +1651,7 @@ class IndexNode(ExprNode):
if self.index.type.is_int:
function = "__Pyx_SetItemInt"
index_code = self.index.result()
code.globalstate.use_utility_code(setitem_int_utility_code)
else:
function = "PyObject_SetItem"
index_code = self.index.py_result()
......@@ -1708,16 +1706,18 @@ class IndexNode(ExprNode):
self.generate_subexpr_evaluation_code(code)
#if self.type.is_pyobject:
if self.index.type.is_int:
function = "PySequence_DelItem"
function = "__Pyx_DelItemInt"
index_code = self.index.result()
code.globalstate.use_utility_code(delitem_int_utility_code)
else:
function = "PyObject_DelItem"
index_code = self.index.py_result()
code.putln(
"if (%s(%s, %s) < 0) %s" % (
"if (%s(%s, %s%s) < 0) %s" % (
function,
self.base.py_result(),
index_code,
self.index_unsigned_parameter(),
code.error_goto(self.pos)))
self.generate_subexpr_disposal_code(code)
......@@ -4930,6 +4930,27 @@ impl = """
#------------------------------------------------------------------------------------
delitem_int_utility_code = UtilityCode(
proto = """
static INLINE int __Pyx_DelItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) {
int r;
if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0) || !is_unsigned))
r = PySequence_DelItem(o, i);
else {
PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i);
if (!j)
return -1;
r = PyObject_DelItem(o, j);
Py_DECREF(j);
}
return r;
}
""",
impl = """
""")
#------------------------------------------------------------------------------------
raise_noneattr_error_utility_code = UtilityCode(
proto = """
static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname);
......
__doc__ = u"""
>>> test_index()
>>> test_get_char_neg()
0
>>> test_get_char_zero()
1
>>> test_del()
>>> test_get_char_pos()
2
>>> test_get_uchar_zero()
1
>>> test_get_uchar_pos()
2
>>> test_get_int_neg()
0
>>> test_get_int_zero()
1
>>> test_get_int_pos()
2
>>> test_get_uint_zero()
1
>>> test_get_uint_pos()
2
>>> test_get_longlong_neg()
0
>>> test_get_longlong_zero()
1
>>> test_get_longlong_pos()
2
>>> test_get_ulonglong_zero()
1
>>> test_get_ulonglong_pos()
2
>>> test_del_char()
Traceback (most recent call last):
KeyError: 0
>>> test_del_uchar()
Traceback (most recent call last):
KeyError: 0
>>> test_del_int()
Traceback (most recent call last):
KeyError: 0
>>> test_del_uint()
Traceback (most recent call last):
KeyError: 0
>>> test_del_longlong() #doctest: +ELLIPSIS
Traceback (most recent call last):
KeyError: 0...
>>> test_del_ulonglong() #doctest: +ELLIPSIS
Traceback (most recent call last):
KeyError: 0...
"""
def test_index():
def test_get_char_neg():
cdef char key = -1
d = {-1:0}
return d[key]
def test_get_char_zero():
cdef char key = 0
d = {0:1}
return d[key]
def test_get_char_pos():
cdef char key = 1
d = {1:2}
return d[key]
def test_get_uchar_zero():
cdef unsigned char key = 0
d = {0:1}
return d[key]
def test_get_uchar_pos():
cdef unsigned char key = 1
d = {1:2}
return d[key]
def test_get_int_neg():
cdef int key = -1
d = {-1:0}
return d[key]
def test_get_int_zero():
cdef int key = 0
d = {0:1}
return d[key]
def test_get_int_pos():
cdef int key = 1
d = {1:2}
return d[key]
def test_get_uint_zero():
cdef unsigned int key = 0
d = {0:1}
return d[key]
def test_get_uint_pos():
cdef unsigned int key = 1
d = {1:2}
return d[key]
def test_get_longlong_neg():
cdef long long key = -1
d = {-1:0}
return d[key]
def test_get_longlong_zero():
cdef long long key = 0
d = {0:1}
return d[key]
def test_get_longlong_pos():
cdef long long key = 1
d = {1:2}
return d[key]
def test_get_ulonglong_zero():
cdef unsigned long long key = 0
d = {0:1}
return d[key]
def test_get_ulonglong_pos():
cdef unsigned long long key = 1
d = {1:2}
return d[key]
def test_del_char():
cdef char key = 0
d = {0:1}
del d[key]
return d[key]
def test_del():
def test_del_uchar():
cdef unsigned char key = 0
d = {0:1}
del d[key]
return d[key]
def test_del_int():
cdef int key = 0
d = {0:1}
del d[key]
return d[key]
def test_del_uint():
cdef unsigned int key = 0
d = {0:1}
del d[key]
return d[key]
def test_del_longlong():
cdef long long key = 0
d = {0:1}
del d[key]
return d[key]
def test_del_ulonglong():
cdef unsigned long long key = 0
d = {0:1}
del d[key]
return d[key]
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