mirror of
https://github.com/python/cpython
synced 2026-09-29 10:15:30 +03:00
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).
This commit is contained in:
parent
c0cbc8611b
commit
8fc4a91665
1 changed files with 16 additions and 8 deletions
|
|
@ -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. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue