diff options
author | Tim Peters <tim.peters@gmail.com> | 2004-07-31 21:53:19 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2004-07-31 21:53:19 (GMT) |
commit | 8fc4a916658aa4a24f29a6e1b438f910465cc22b (patch) | |
tree | a07574fecca021074488ead07a33d579a0a6b58c | |
parent | c0cbc8611b5d9633796ade4b1cd37f332fa0b12f (diff) | |
download | cpython-8fc4a916658aa4a24f29a6e1b438f910465cc22b.zip cpython-8fc4a916658aa4a24f29a6e1b438f910465cc22b.tar.gz cpython-8fc4a916658aa4a24f29a6e1b438f910465cc22b.tar.bz2 |
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).
-rw-r--r-- | Objects/listobject.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/Objects/listobject.c b/Objects/listobject.c index 91c0a1c..72b2356 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -519,6 +519,12 @@ list_clear(PyListObject *a) 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 list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v) { @@ -823,6 +829,7 @@ listpop(PyListObject *self, PyObject *args) { int i = -1; PyObject *v, *arg = NULL; + int status; if (!PyArg_UnpackTuple(args, "pop", 0, 1, &arg)) return NULL; @@ -845,16 +852,17 @@ listpop(PyListObject *self, PyObject *args) } v = self->ob_item[i]; if (i == self->ob_size - 1) { - if (list_resize(self, self->ob_size - 1) == -1) - return NULL; - return v; + status = list_resize(self, self->ob_size - 1); + assert(status >= 0); + return v; /* and v now owns the reference the list had */ } Py_INCREF(v); - if (list_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) { - Py_DECREF(v); - return NULL; - } - return v; + status = list_ass_slice(self, i, i+1, (PyObject *)NULL); + assert(status >= 0); + /* Use status, so that in a release build compilers don't + * complain about the unused name. + */ + return status, v; } /* Reverse a slice of a list in place, from lo up to (exclusive) hi. */ |