summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2004-07-31 21:53:19 (GMT)
committerTim Peters <tim.peters@gmail.com>2004-07-31 21:53:19 (GMT)
commit8fc4a916658aa4a24f29a6e1b438f910465cc22b (patch)
treea07574fecca021074488ead07a33d579a0a6b58c
parentc0cbc8611b5d9633796ade4b1cd37f332fa0b12f (diff)
downloadcpython-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.c24
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. */