fix ticket #578 by working around CPython bug 9834: crash in Py3.[0-1.2] when slicing...
authorStefan Behnel <scoder@users.berlios.de>
Mon, 1 Nov 2010 18:33:18 +0000 (19:33 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Mon, 1 Nov 2010 18:33:18 +0000 (19:33 +0100)
Cython/Compiler/ExprNodes.py
Cython/Compiler/ModuleNode.py
tests/run/slice2.pyx

index 50ee5a74dc9c1bfb5dd15a6496d20f70bb37655a..72e7b5e3b58ad9377ee1fd23a1ff5d5ed11d5e8d 100755 (executable)
@@ -2459,7 +2459,7 @@ class SliceIndexNode(ExprNode):
                         code.error_goto_if_null(self.result(), self.pos)))
         else:
             code.putln(
-                "%s = PySequence_GetSlice(%s, %s, %s); %s" % (
+                "%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % (
                     self.result(),
                     self.base.py_result(),
                     self.start_code(),
@@ -2471,7 +2471,7 @@ class SliceIndexNode(ExprNode):
         self.generate_subexpr_evaluation_code(code)
         if self.type.is_pyobject:
             code.put_error_if_neg(self.pos, 
-                "PySequence_SetSlice(%s, %s, %s, %s)" % (
+                "__Pyx_PySequence_SetSlice(%s, %s, %s, %s)" % (
                     self.base.py_result(),
                     self.start_code(),
                     self.stop_code(),
@@ -2508,7 +2508,7 @@ class SliceIndexNode(ExprNode):
             return
         self.generate_subexpr_evaluation_code(code)
         code.put_error_if_neg(self.pos,
-            "PySequence_DelSlice(%s, %s, %s)" % (
+            "__Pyx_PySequence_DelSlice(%s, %s, %s)" % (
                 self.base.py_result(),
                 self.start_code(),
                 self.stop_code()))
index a3650396d5ef2048755b08ab13b4b0dec6839fbd..e00ccd07406e03e8bcfdec2c7570c31b94903ec1 100644 (file)
@@ -593,6 +593,25 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("#endif")
 
         code.put("""
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) ((!(obj)) ? \\
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \\
+        (((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \\
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) ((!(obj)) ? \\
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \\
+        (((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \\
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) ((!(obj)) ? \\
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \\
+        (((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \\
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+
 #if PY_MAJOR_VERSION >= 3
   #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
 #endif
index 29e3f9994a891732b077d975f9b6cb2695745adf..0b510bd9cbc421645cdc471c4f65d58b3e341526 100644 (file)
@@ -7,6 +7,9 @@ def f(obj1, obj2, obj3, obj4):
     True
     >>> l is f(1, l, 2, 3)
     False
+    >>> f(1, 42, 2, 3)
+    Traceback (most recent call last):
+    TypeError: 'int' object is unsliceable
     """
     obj1 = obj2[:]
     return obj1
@@ -15,6 +18,9 @@ def g(obj1, obj2, obj3, obj4):
     """
     >>> g(1, [1,2,3,4], 2, 3)
     [3, 4]
+    >>> g(1, 42, 2, 3)
+    Traceback (most recent call last):
+    TypeError: 'int' object is unsliceable
     """
     obj1 = obj2[obj3:]
     return obj1
@@ -23,6 +29,9 @@ def h(obj1, obj2, obj3, obj4):
     """
     >>> h(1, [1,2,3,4], 2, 3)
     [1, 2, 3]
+    >>> h(1, 42, 2, 3)
+    Traceback (most recent call last):
+    TypeError: 'int' object is unsliceable
     """
     obj1 = obj2[:obj4]
     return obj1
@@ -31,6 +40,9 @@ def j(obj1, obj2, obj3, obj4):
     """
     >>> j(1, [1,2,3,4], 2, 3)
     [3]
+    >>> j(1, 42, 2, 3)
+    Traceback (most recent call last):
+    TypeError: 'int' object is unsliceable
     """
     obj1 = obj2[obj3:obj4]
     return obj1