Commit 8fc4a916 authored by Tim Peters's avatar Tim Peters

list_ass_slice(): Document the obscure new intent that deleting a slice

of no more than 8 elements cannot fail.

listpop():  Take advantage of that its calls to list_resize() and
list_ass_slice() can't fail.  This is assert'ed in a debug build now, but
in an icky way.  That is, you can't say:

	assert(some_call() >= 0);

because then some_call() won't occur at all in a release build.  So it
has to be a big pile of #ifdefs on Py_DEBUG (yuck), or the pleasant:

        status = some_call();
        assert(status >= 0);

But in that case, compilers may whine in a release build, because status
appears unused then.  I'm not certain the ugly trick I used here will
convince all compilers to shut up about status (status is always "used" now,
as the first (ignored) clause in a comma expression).
parent c0cbc861
...@@ -519,6 +519,12 @@ list_clear(PyListObject *a) ...@@ -519,6 +519,12 @@ list_clear(PyListObject *a)
return 0; return 0;
} }
/* a[ilow:ihigh] = v if v != NULL.
* del a[ilow:ihigh] if v == NULL.
*
* Special speed gimmick: when v is NULL and ihigh - ilow <= 8, it's
* guaranteed the call cannot fail.
*/
static int static int
list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v) list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
{ {
...@@ -823,6 +829,7 @@ listpop(PyListObject *self, PyObject *args) ...@@ -823,6 +829,7 @@ listpop(PyListObject *self, PyObject *args)
{ {
int i = -1; int i = -1;
PyObject *v, *arg = NULL; PyObject *v, *arg = NULL;
int status;
if (!PyArg_UnpackTuple(args, "pop", 0, 1, &arg)) if (!PyArg_UnpackTuple(args, "pop", 0, 1, &arg))
return NULL; return NULL;
...@@ -845,16 +852,17 @@ listpop(PyListObject *self, PyObject *args) ...@@ -845,16 +852,17 @@ listpop(PyListObject *self, PyObject *args)
} }
v = self->ob_item[i]; v = self->ob_item[i];
if (i == self->ob_size - 1) { if (i == self->ob_size - 1) {
if (list_resize(self, self->ob_size - 1) == -1) status = list_resize(self, self->ob_size - 1);
return NULL; assert(status >= 0);
return v; return v; /* and v now owns the reference the list had */
} }
Py_INCREF(v); Py_INCREF(v);
if (list_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) { status = list_ass_slice(self, i, i+1, (PyObject *)NULL);
Py_DECREF(v); assert(status >= 0);
return NULL; /* Use status, so that in a release build compilers don't
} * complain about the unused name.
return v; */
return status, v;
} }
/* Reverse a slice of a list in place, from lo up to (exclusive) hi. */ /* Reverse a slice of a list in place, from lo up to (exclusive) hi. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment