From 13dff2831d4709f3a9ad414d21239a37b4b3a0d8 Mon Sep 17 00:00:00 2001 From: "\"Lisandro Dalcin\"" Date: Mon, 27 Oct 2008 09:22:00 -0700 Subject: [PATCH] Re: [Cython] PATCH: fix delitem for index nodes --- Cython/Compiler/ExprNodes.py | 33 ++++++-- tests/run/dictintindex.pyx | 147 ++++++++++++++++++++++++++++++++++- 2 files changed, 170 insertions(+), 10 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 8bf34fa4..8613c0cf 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -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); diff --git a/tests/run/dictintindex.pyx b/tests/run/dictintindex.pyx index d9bec0e5..797f929b 100644 --- a/tests/run/dictintindex.pyx +++ b/tests/run/dictintindex.pyx @@ -1,18 +1,157 @@ __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] -- 2.26.2