if rhs.type.is_array:
# FIXME: we should check both array sizes here
array_length = rhs.type.size
+ self.generate_slice_guard_code(code, array_length)
else:
# FIXME: fix the array size according to start/stop
array_length = self.base.type.size
self.start_code(),
self.stop_code()))
self.generate_subexpr_disposal_code(code)
+
+ def generate_slice_guard_code(self, code, target_size):
+ if not self.base.type.is_array:
+ return
+ slice_size = self.base.type.size
+ start = stop = None
+ if self.stop:
+ stop = self.stop.result()
+ try:
+ stop = int(stop)
+ if stop > 0:
+ slice_size = stop
+ else:
+ slice_size = self.base.type.size + stop
+ stop = None
+ except ValueError:
+ pass
+ if self.start:
+ start = self.start.result()
+ try:
+ start = int(start)
+ if start < 0:
+ start = self.base.type.size + start
+ slice_size -= start
+ start = None
+ except ValueError:
+ pass
+ check = None
+ if slice_size < 0:
+ if target_size > 0:
+ error(self.pos, "Assignment to empty slice.")
+ elif start is None and stop is None:
+ # we know the exact slice length
+ if target_size != slice_size:
+ error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
+ slice_size, target_size))
+ elif start is not None:
+ if stop is None:
+ stop = slice_size
+ check = "(%s)-(%s)" % (stop, start)
+ else: # stop is not None:
+ check = stop
+ if check:
+ code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
+ code.putln('PyErr_Format(PyExc_ValueError, "Assignment to slice of wrong length, expected %%d, got %%d", %d, (%s));' % (
+ target_size, check))
+ code.putln(code.error_goto(self.pos))
+ code.putln("}")
def start_code(self):
if self.start:
>>> test_literal_list_slice_start_end()
(1, 2, 3, 4, 5)
->>> test_literal_list_slice_start_param(2)
+>>> test_literal_list_slice_start_param(4)
(1, 2, 3, 4, 5)
->>> test_literal_list_slice_end_param(4)
+>>> test_literal_list_slice_start_param(3)
+Traceback (most recent call last):
+ValueError: Assignment to slice of wrong length, expected 5, got 6
+>>> test_literal_list_slice_start_param(5)
+Traceback (most recent call last):
+ValueError: Assignment to slice of wrong length, expected 5, got 4
+
+>>> test_literal_list_slice_end_param(5)
(1, 2, 3, 4, 5)
+>>> test_literal_list_slice_end_param(4)
+Traceback (most recent call last):
+ValueError: Assignment to slice of wrong length, expected 5, got 4
+>>> test_literal_list_slice_end_param(6)
+Traceback (most recent call last):
+ValueError: Assignment to slice of wrong length, expected 5, got 6
+
>>> test_literal_list_slice_start_end_param(2,7)
(1, 2, 3, 4, 5)
+>>> test_literal_list_slice_start_end_param(3,7)
+Traceback (most recent call last):
+ValueError: Assignment to slice of wrong length, expected 5, got 4
+>>> test_literal_list_slice_start_end_param(1,7)
+Traceback (most recent call last):
+ValueError: Assignment to slice of wrong length, expected 5, got 6
+>>> test_literal_list_slice_start_end_param(2,6)
+Traceback (most recent call last):
+ValueError: Assignment to slice of wrong length, expected 5, got 4
+>>> test_literal_list_slice_start_end_param(2,8)
+Traceback (most recent call last):
+ValueError: Assignment to slice of wrong length, expected 5, got 6
+>>> test_literal_list_slice_start_end_param(3,6)
+Traceback (most recent call last):
+ValueError: Assignment to slice of wrong length, expected 5, got 3
+>>> test_literal_list_slice_start_end_param(1,8)
+Traceback (most recent call last):
+ValueError: Assignment to slice of wrong length, expected 5, got 7
>>> test_ptr_literal_list_slice_all()
(1, 2, 3, 4, 5)
def test_literal_list_slice_start_param(s):
cdef int a[9] # = [9,8,7,6,5,4,3,2,1]
a[s:] = [1,2,3,4,5]
- return (a[2], a[3], a[4], a[5], a[6])
+ return (a[4], a[5], a[6], a[7], a[8])
# return a[s:]
def test_literal_list_slice_end_param(e):