Skip to content

Commit 5da854f

Browse files
author
Michael W. Hudson
committed
This is Alex Martelli's patch
[ 633870 ] allow any seq assignment to a list slice plus a very silly little test case of my own.
1 parent cc6cc5d commit 5da854f

File tree

2 files changed

+16
-9
lines changed

2 files changed

+16
-9
lines changed

Lib/test/test_types.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ def f():
297297
if a != []:
298298
raise TestFailed, "list inplace repeat"
299299

300+
a = []
301+
a[:] = tuple(range(10))
302+
if a != range(10):
303+
raise TestFailed, "assigning tuple to slice"
300304

301305
print '6.5.3a Additional list operations'
302306
a = [0,1,2,3,4]

Objects/listobject.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -448,14 +448,22 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
448448
list. :-( */
449449
PyObject **recycle, **p;
450450
PyObject **item;
451+
PyObject *v_as_SF = NULL; /* PySequence_Fast(v) */
451452
int n; /* Size of replacement list */
452453
int d; /* Change in size */
453454
int k; /* Loop index */
454455
#define b ((PyListObject *)v)
455456
if (v == NULL)
456457
n = 0;
457-
else if (PyList_Check(v)) {
458-
n = b->ob_size;
458+
else {
459+
char msg[256];
460+
sprintf(msg, "must assign sequence (not \"%.200s\") to slice",
461+
v->ob_type->tp_name);
462+
v_as_SF = PySequence_Fast(v, msg);
463+
if(v_as_SF == NULL)
464+
return -1;
465+
n = PySequence_Fast_GET_SIZE(v_as_SF);
466+
459467
if (a == b) {
460468
/* Special case "a[i:j] = a" -- copy b first */
461469
int ret;
@@ -465,12 +473,6 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
465473
return ret;
466474
}
467475
}
468-
else {
469-
PyErr_Format(PyExc_TypeError,
470-
"must assign list (not \"%.200s\") to slice",
471-
v->ob_type->tp_name);
472-
return -1;
473-
}
474476
if (ilow < 0)
475477
ilow = 0;
476478
else if (ilow > a->ob_size)
@@ -512,7 +514,7 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
512514
a->ob_size += d;
513515
}
514516
for (k = 0; k < n; k++, ilow++) {
515-
PyObject *w = b->ob_item[k];
517+
PyObject *w = PySequence_Fast_GET_ITEM(v_as_SF, k);
516518
Py_XINCREF(w);
517519
item[ilow] = w;
518520
}
@@ -525,6 +527,7 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
525527
PyMem_FREE(a->ob_item);
526528
a->ob_item = NULL;
527529
}
530+
Py_XDECREF(v_as_SF);
528531
return 0;
529532
#undef b
530533
}

0 commit comments

Comments
 (0)