Re: [Cython] PATCH: fix delitem for index nodes
author"Lisandro Dalcin" <dalcinl@gmail.com>
Mon, 27 Oct 2008 16:22:00 +0000 (09:22 -0700)
committer"Lisandro Dalcin" <dalcinl@gmail.com>
Mon, 27 Oct 2008 16:22:00 +0000 (09:22 -0700)
Cython/Compiler/ExprNodes.py
tests/run/dictintindex.pyx

index 8bf34fa49058da3f21b8fb7ea6e981abd3e7e717..8613c0cfa97e56d90453d39f3a955f77f4dae1fb 100644 (file)
@@ -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);
index d9bec0e54c288b50e9414875f16e28055ca59f59..797f929ba44954400db5e54ecd8b84d523192700 100644 (file)
 __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]