diff -r 2a18f6b85da2 Doc/library/stdtypes.rst --- a/Doc/library/stdtypes.rst Sun Apr 12 18:47:56 2015 -0400 +++ b/Doc/library/stdtypes.rst Mon Apr 13 10:13:03 2015 -0400 @@ -1082,7 +1082,7 @@ Notes: (1) - *t* must have the same length as the slice it is replacing. + *t* must have the same length as the slice it is replacing or be empty. (2) The optional argument *i* defaults to ``-1``, so that by default the last diff -r 2a18f6b85da2 Lib/test/list_tests.py --- a/Lib/test/list_tests.py Sun Apr 12 18:47:56 2015 -0400 +++ b/Lib/test/list_tests.py Mon Apr 13 10:13:03 2015 -0400 @@ -562,6 +562,13 @@ a = self.type2test(range(10)) del a[::1000] self.assertEqual(a, self.type2test([1, 2, 3, 4, 5, 6, 7, 8, 9])) + # deletion via assignment (issue #12606) + b = self.type2test([0,1,2,3,4,5]) + b[1:5:2] = [] + self.assertEqual(b, self.type2test([0, 2, 4, 5])) + b[::-2] = () + self.assertEqual(b, self.type2test([0, 4])) + self.assertRaises(TypeError, b.__setitem__, slice(None, None, 2), None) # assignment a = self.type2test(range(10)) a[::2] = [-1]*5 diff -r 2a18f6b85da2 Lib/test/test_bytes.py --- a/Lib/test/test_bytes.py Sun Apr 12 18:47:56 2015 -0400 +++ b/Lib/test/test_bytes.py Mon Apr 13 10:13:03 2015 -0400 @@ -13,6 +13,7 @@ import pickle import tempfile import unittest +import itertools import test.support import test.string_tests @@ -990,7 +991,8 @@ for start in indices: for stop in indices: # Skip invalid step 0 - for step in indices[1:]: + bool_states = itertools.cycle((True, False)) + for step, using_del in zip(indices[1:], bool_states): L = list(range(255)) b = bytearray(L) # Make sure we have a slice of exactly the right length, @@ -1001,9 +1003,14 @@ b[start:stop:step] = data self.assertEqual(b, bytearray(L)) - del L[start:stop:step] - del b[start:stop:step] - self.assertEqual(b, bytearray(L)) + if using_del: + del L[start:stop:step] + del b[start:stop:step] + self.assertEqual(b, bytearray(L)) + else: + L[start:stop:step] = [] + b[start:stop:step] = [] + self.assertEqual(b, bytearray(L)) def test_setslice_trap(self): # This test verifies that we correctly handle assigning self diff -r 2a18f6b85da2 Objects/listobject.c --- a/Objects/listobject.c Sun Apr 12 18:47:56 2015 -0400 +++ b/Objects/listobject.c Mon Apr 13 10:13:03 2015 -0400 @@ -2479,7 +2479,23 @@ (step > 0 && start > stop)) stop = start; - if (value == NULL) { + PyObject *seq; + if (value) { + /* protect against a[::-1] = a */ + if (self == (PyListObject*)value) { + seq = list_slice((PyListObject*)value, 0, + PyList_GET_SIZE(value)); + } + else { + seq = PySequence_Fast(value, + "must assign iterable " + "to extended slice"); + } + if (!seq) + return -1; + } + + if (value == NULL || PySequence_Fast_GET_SIZE(seq) == 0) { /* delete slice */ PyObject **garbage; size_t cur; @@ -2546,23 +2562,10 @@ } else { /* assign slice */ - PyObject *ins, *seq; + PyObject *ins; PyObject **garbage, **seqitems, **selfitems; Py_ssize_t cur, i; - /* protect against a[::-1] = a */ - if (self == (PyListObject*)value) { - seq = list_slice((PyListObject*)value, 0, - PyList_GET_SIZE(value)); - } - else { - seq = PySequence_Fast(value, - "must assign iterable " - "to extended slice"); - } - if (!seq) - return -1; - if (PySequence_Fast_GET_SIZE(seq) != slicelength) { PyErr_Format(PyExc_ValueError, "attempt to assign sequence of "