Commit fee84f22 authored by Stefan Behnel's avatar Stefan Behnel

fix ticket #578 by working around CPython bug 9834: crash in Py3.[0-1.2] when...

fix ticket #578 by working around CPython bug 9834: crash in Py3.[0-1.2] when slicing non-sliceable objects
parent d4fefe87
...@@ -2459,7 +2459,7 @@ class SliceIndexNode(ExprNode): ...@@ -2459,7 +2459,7 @@ class SliceIndexNode(ExprNode):
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
else: else:
code.putln( code.putln(
"%s = PySequence_GetSlice(%s, %s, %s); %s" % ( "%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % (
self.result(), self.result(),
self.base.py_result(), self.base.py_result(),
self.start_code(), self.start_code(),
...@@ -2471,7 +2471,7 @@ class SliceIndexNode(ExprNode): ...@@ -2471,7 +2471,7 @@ class SliceIndexNode(ExprNode):
self.generate_subexpr_evaluation_code(code) self.generate_subexpr_evaluation_code(code)
if self.type.is_pyobject: if self.type.is_pyobject:
code.put_error_if_neg(self.pos, 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.base.py_result(),
self.start_code(), self.start_code(),
self.stop_code(), self.stop_code(),
...@@ -2508,7 +2508,7 @@ class SliceIndexNode(ExprNode): ...@@ -2508,7 +2508,7 @@ class SliceIndexNode(ExprNode):
return return
self.generate_subexpr_evaluation_code(code) self.generate_subexpr_evaluation_code(code)
code.put_error_if_neg(self.pos, code.put_error_if_neg(self.pos,
"PySequence_DelSlice(%s, %s, %s)" % ( "__Pyx_PySequence_DelSlice(%s, %s, %s)" % (
self.base.py_result(), self.base.py_result(),
self.start_code(), self.start_code(),
self.stop_code())) self.stop_code()))
......
...@@ -593,6 +593,25 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -593,6 +593,25 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("#endif") code.putln("#endif")
code.put(""" 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 #if PY_MAJOR_VERSION >= 3
#define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
#endif #endif
......
...@@ -7,6 +7,9 @@ def f(obj1, obj2, obj3, obj4): ...@@ -7,6 +7,9 @@ def f(obj1, obj2, obj3, obj4):
True True
>>> l is f(1, l, 2, 3) >>> l is f(1, l, 2, 3)
False False
>>> f(1, 42, 2, 3)
Traceback (most recent call last):
TypeError: 'int' object is unsliceable
""" """
obj1 = obj2[:] obj1 = obj2[:]
return obj1 return obj1
...@@ -15,6 +18,9 @@ def g(obj1, obj2, obj3, obj4): ...@@ -15,6 +18,9 @@ def g(obj1, obj2, obj3, obj4):
""" """
>>> g(1, [1,2,3,4], 2, 3) >>> g(1, [1,2,3,4], 2, 3)
[3, 4] [3, 4]
>>> g(1, 42, 2, 3)
Traceback (most recent call last):
TypeError: 'int' object is unsliceable
""" """
obj1 = obj2[obj3:] obj1 = obj2[obj3:]
return obj1 return obj1
...@@ -23,6 +29,9 @@ def h(obj1, obj2, obj3, obj4): ...@@ -23,6 +29,9 @@ def h(obj1, obj2, obj3, obj4):
""" """
>>> h(1, [1,2,3,4], 2, 3) >>> h(1, [1,2,3,4], 2, 3)
[1, 2, 3] [1, 2, 3]
>>> h(1, 42, 2, 3)
Traceback (most recent call last):
TypeError: 'int' object is unsliceable
""" """
obj1 = obj2[:obj4] obj1 = obj2[:obj4]
return obj1 return obj1
...@@ -31,6 +40,9 @@ def j(obj1, obj2, obj3, obj4): ...@@ -31,6 +40,9 @@ def j(obj1, obj2, obj3, obj4):
""" """
>>> j(1, [1,2,3,4], 2, 3) >>> j(1, [1,2,3,4], 2, 3)
[3] [3]
>>> j(1, 42, 2, 3)
Traceback (most recent call last):
TypeError: 'int' object is unsliceable
""" """
obj1 = obj2[obj3:obj4] obj1 = obj2[obj3:obj4]
return obj1 return obj1
......
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