self.start.analyse_types(env)
if self.stop:
self.stop.analyse_types(env)
- self.base = self.base.coerce_to_pyobject(env)
+ if self.base.type.is_array or self.base.type.is_ptr:
+ # we need a ptr type here instead of an array type, as
+ # array types can result in invalid type casts in the C
+ # code
+ self.type = PyrexTypes.CPtrType(self.base.type.base_type)
+ else:
+ self.base = self.base.coerce_to_pyobject(env)
+ self.type = py_object_type
c_int = PyrexTypes.c_py_ssize_t_type
if self.start:
self.start = self.start.coerce_to(c_int, env)
if self.stop:
self.stop = self.stop.coerce_to(c_int, env)
- self.type = py_object_type
self.gil_check(env)
self.is_temp = 1
gil_message = "Slicing Python object"
def generate_result_code(self, code):
+ if not self.type.is_pyobject:
+ error(self.pos,
+ "Slicing is not currently supported for '%s'." % self.type)
+ return
code.putln(
"%s = PySequence_GetSlice(%s, %s, %s); %s" % (
self.result(),
def generate_assignment_code(self, rhs, code):
self.generate_subexpr_evaluation_code(code)
- code.put_error_if_neg(self.pos,
- "PySequence_SetSlice(%s, %s, %s, %s)" % (
- self.base.py_result(),
- self.start_code(),
- self.stop_code(),
- rhs.result()))
+ if self.type.is_pyobject:
+ code.put_error_if_neg(self.pos,
+ "PySequence_SetSlice(%s, %s, %s, %s)" % (
+ self.base.py_result(),
+ self.start_code(),
+ self.stop_code(),
+ rhs.result()))
+ else:
+ if rhs.type.is_array:
+ # FIXME: we should check both array sizes here
+ array_length = rhs.type.size
+ else:
+ array_length = self.base.type.size
+ start_offset = ''
+ if self.start:
+ start_offset = self.start_code()
+ if start_offset == '0':
+ start_offset = ''
+ else:
+ start_offset += '+'
+ for i in range(array_length):
+ code.putln("%s[%s%s] = %s[%d];" % (
+ self.base.result(), start_offset, i,
+ rhs.result(), i))
self.generate_subexpr_disposal_code(code)
rhs.generate_disposal_code(code)
def generate_deletion_code(self, code):
+ if not self.type.is_pyobject:
+ error(self.pos,
+ "Deleting slices is only supported for Python types, not '%s'." % self.type)
+ return
self.generate_subexpr_evaluation_code(code)
code.put_error_if_neg(self.pos,
"PySequence_DelSlice(%s, %s, %s)" % (
def stop_code(self):
if self.stop:
return self.stop.result()
+ elif self.base.type.is_array:
+ return self.base.type.size
else:
return "PY_SSIZE_T_MAX"