nogil_check = Node.gil_error
gil_message = "Slicing Python object"
+ get_slice_utility_code = TempitaUtilityCode.load(
+ "SliceObject", "ObjectHandling.c", context={'access': 'Get'})
+
+ set_slice_utility_code = TempitaUtilityCode.load(
+ "SliceObject", "ObjectHandling.c", context={'access': 'Set'})
+
def coerce_to(self, dst_type, env):
if ((self.base.type.is_string or self.base.type.is_cpp_string)
and dst_type in (bytes_type, str_type, unicode_type)):
stop_code,
code.error_goto_if_null(result, self.pos)))
elif self.type is py_object_type:
- code.globalstate.use_utility_code(
- UtilityCode.load_cached("GetObjectSlice", "ObjectHandling.c"))
+ code.globalstate.use_utility_code(self.get_slice_utility_code)
(has_c_start, has_c_stop, c_start, c_stop,
py_start, py_stop, py_slice) = self.get_slice_config()
code.putln(
- "%s = __Pyx_PySequence_GetObjectSlice(%s, %s, %s, %s, %s, %s, %d, %d); %s" % (
+ "%s = __Pyx_PyObject_GetSlice(%s, %s, %s, %s, %s, %s, %d, %d); %s" % (
result,
self.base.py_result(),
c_start, c_stop,
def generate_assignment_code(self, rhs, code):
self.generate_subexpr_evaluation_code(code)
if self.type.is_pyobject:
- code.globalstate.use_utility_code(
- UtilityCode.load_cached("SetObjectSlice", "ObjectHandling.c"))
+ code.globalstate.use_utility_code(self.set_slice_utility_code)
(has_c_start, has_c_stop, c_start, c_stop,
py_start, py_stop, py_slice) = self.get_slice_config()
code.put_error_if_neg(self.pos,
- "__Pyx_PySequence_SetObjectSlice(%s, %s, %s, %s, %s, %s, %s, %d, %d)" % (
+ "__Pyx_PyObject_SetSlice(%s, %s, %s, %s, %s, %s, %s, %d, %d)" % (
self.base.py_result(),
rhs.py_result(),
c_start, c_stop,
"Deleting slices is only supported for Python types, not '%s'." % self.type)
return
self.generate_subexpr_evaluation_code(code)
- code.globalstate.use_utility_code(
- UtilityCode.load_cached("SetObjectSlice", "ObjectHandling.c"))
+ code.globalstate.use_utility_code(self.set_slice_utility_code)
(has_c_start, has_c_stop, c_start, c_stop,
py_start, py_stop, py_slice) = self.get_slice_config()
code.put_error_if_neg(self.pos,
- "__Pyx_PySequence_DelObjectSlice(%s, %s, %s, %s, %s, %s, %d, %d)" % (
+ "__Pyx_PyObject_DelSlice(%s, %s, %s, %s, %s, %s, %d, %d)" % (
self.base.py_result(),
c_start, c_stop,
py_start, py_stop, py_slice,
}
-/////////////// GetObjectSlice.proto ///////////////
+/////////////// SliceObject.proto ///////////////
// we pass pointer addresses to show the C compiler what is NULL and what isn't
-static CYTHON_INLINE PyObject* __Pyx_PySequence_GetObjectSlice(
+{{if access == 'Get'}}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
int has_cstart, int has_cstop);
-
-/////////////// GetObjectSlice ///////////////
-
-static CYTHON_INLINE PyObject* __Pyx_PySequence_GetObjectSlice(
- PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
- PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
- int has_cstart, int has_cstop) {
- PyMappingMethods* mp;
-#if PY_MAJOR_VERSION < 3
- PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
- if (likely(ms && ms->sq_slice)) {
- if (!has_cstart) {
- if (_py_start && (*_py_start != Py_None)) {
- cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
- if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) return NULL;
- } else
- cstart = 0;
- }
- if (!has_cstop) {
- if (_py_stop && (*_py_stop != Py_None)) {
- cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
- if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) return NULL;
- } else
- cstop = PY_SSIZE_T_MAX;
- }
- if (unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
- Py_ssize_t l = ms->sq_length(obj);
- if (likely(l >= 0)) {
- if (cstop < 0) {
- cstop += l;
- if (cstop < 0) cstop = 0;
- }
- if (cstart < 0) {
- cstart += l;
- if (cstart < 0) cstart = 0;
- }
- } else {
- // if length > max(Py_ssize_t), maybe the object can wrap around itself?
- if (PyErr_ExceptionMatches(PyExc_OverflowError))
- PyErr_Clear();
- else
- return NULL;
- }
- }
- return ms->sq_slice(obj, cstart, cstop);
- }
-#endif
- mp = Py_TYPE(obj)->tp_as_mapping;
- if (likely(mp && mp->mp_subscript)) {
- PyObject *result, *py_slice, *py_start, *py_stop;
- if (_py_slice) {
- py_slice = *_py_slice;
- } else {
- PyObject* owned_start = NULL;
- PyObject* owned_stop = NULL;
- if (_py_start) {
- py_start = *_py_start;
- } else {
- if (has_cstart) {
- owned_start = py_start = PyInt_FromSsize_t(cstart);
- if (unlikely(!py_start)) return NULL;
- } else
- py_start = Py_None;
- }
- if (_py_stop) {
- py_stop = *_py_stop;
- } else {
- if (has_cstop) {
- owned_stop = py_stop = PyInt_FromSsize_t(cstop);
- if (unlikely(!py_stop)) {
- Py_XDECREF(owned_start);
- return NULL;
- }
- } else
- py_stop = Py_None;
- }
- py_slice = PySlice_New(py_start, py_stop, Py_None);
- Py_XDECREF(owned_start);
- Py_XDECREF(owned_stop);
- if (unlikely(!py_slice)) return NULL;
- }
- result = mp->mp_subscript(obj, py_slice);
- if (!_py_slice) {
- Py_DECREF(py_slice);
- }
- return result;
- }
- PyErr_Format(PyExc_TypeError,
- "'%.200s' object is unsliceable", Py_TYPE(obj)->tp_name);
- return NULL;
-}
-
-/////////////// SetObjectSlice.proto ///////////////
-
-#define __Pyx_PySequence_DelObjectSlice(obj, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop) \
- __Pyx_PySequence_SetObjectSlice(obj, (PyObject*)NULL, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop)
+{{else}}
+#define __Pyx_PyObject_DelSlice(obj, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop) \
+ __Pyx_PyObject_SetSlice(obj, (PyObject*)NULL, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop)
// we pass pointer addresses to show the C compiler what is NULL and what isn't
-static CYTHON_INLINE int __Pyx_PySequence_SetObjectSlice(
+static CYTHON_INLINE int __Pyx_PyObject_SetSlice(
PyObject* obj, PyObject* value, Py_ssize_t cstart, Py_ssize_t cstop,
PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
int has_cstart, int has_cstop);
+{{endif}}
-/////////////// SetObjectSlice ///////////////
+/////////////// SliceObject ///////////////
-static CYTHON_INLINE int __Pyx_PySequence_SetObjectSlice(
+{{if access == 'Get'}}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
+ PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
+{{else}}
+static CYTHON_INLINE int __Pyx_PyObject_SetSlice(
PyObject* obj, PyObject* value, Py_ssize_t cstart, Py_ssize_t cstop,
+{{endif}}
PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
int has_cstart, int has_cstop) {
PyMappingMethods* mp;
#if PY_MAJOR_VERSION < 3
PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
- if (likely(ms && ms->sq_ass_slice)) {
+ if (likely(ms && ms->sq_{{if access == 'Set'}}ass_{{endif}}slice)) {
if (!has_cstart) {
if (_py_start && (*_py_start != Py_None)) {
cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
- if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) return -1;
+ if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
} else
cstart = 0;
}
if (!has_cstop) {
if (_py_stop && (*_py_stop != Py_None)) {
cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
- if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) return -1;
+ if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
} else
cstop = PY_SSIZE_T_MAX;
}
if (PyErr_ExceptionMatches(PyExc_OverflowError))
PyErr_Clear();
else
- return -1;
+ goto bad;
}
}
+{{if access == 'Get'}}
+ return ms->sq_slice(obj, cstart, cstop);
+{{else}}
return ms->sq_ass_slice(obj, cstart, cstop, value);
+{{endif}}
}
#endif
+
mp = Py_TYPE(obj)->tp_as_mapping;
+{{if access == 'Get'}}
+ if (likely(mp && mp->mp_subscript)) {
+ PyObject *result;
+{{else}}
if (likely(mp && mp->mp_ass_subscript)) {
- PyObject *py_slice, *py_start, *py_stop;
int result;
+{{endif}}
+ PyObject *py_slice, *py_start, *py_stop;
if (_py_slice) {
py_slice = *_py_slice;
} else {
} else {
if (has_cstart) {
owned_start = py_start = PyInt_FromSsize_t(cstart);
- if (unlikely(!py_start)) return -1;
+ if (unlikely(!py_start)) goto bad;
} else
py_start = Py_None;
}
owned_stop = py_stop = PyInt_FromSsize_t(cstop);
if (unlikely(!py_stop)) {
Py_XDECREF(owned_start);
- return -1;
+ goto bad;
}
} else
py_stop = Py_None;
py_slice = PySlice_New(py_start, py_stop, Py_None);
Py_XDECREF(owned_start);
Py_XDECREF(owned_stop);
- if (unlikely(!py_slice)) return -1;
+ if (unlikely(!py_slice)) goto bad;
}
+{{if access == 'Get'}}
+ result = mp->mp_subscript(obj, py_slice);
+{{else}}
result = mp->mp_ass_subscript(obj, py_slice, value);
+{{endif}}
if (!_py_slice) {
Py_DECREF(py_slice);
}
return result;
}
PyErr_Format(PyExc_TypeError,
+{{if access == 'Get'}}
"'%.200s' object is unsliceable", Py_TYPE(obj)->tp_name);
- return -1;
+{{else}}
+ "'%.200s' object does not support slice assignment", Py_TYPE(obj)->tp_name);
+{{endif}}
+
+bad:
+ return {{if access == 'Get'}}NULL{{else}}-1{{endif}};
}
+
/////////////// SliceTupleAndList.proto ///////////////
#if CYTHON_COMPILING_IN_CPYTHON