* drop the unreasonable list invariant that ob_item should never come back
to NULL during the lifetime of the object.
* listobject.c nevertheless did not conform to the other invariants,
either; fixed.
* listobject.c now uses list_clear() as the obvious internal way to clear
a list, instead of abusing list_ass_slice() for that. It makes it easier
to enforce the invariant about ob_item == NULL.
* listsort() sets allocated to -1 during sort; any mutation will set it
to a value >= 0, so it is a safe way to detect mutation. A negative
value for allocated does not cause a problem elsewhere currently.
test_sort.py has a new test for this fix.
* listsort() leak: if items were added to the list during the sort, AND if
these items had a __del__ that puts still more stuff into the list,
then this more stuff (and the PyObject** array to hold them) were
overridden at the end of listsort() and never released.
diff --git a/Include/listobject.h b/Include/listobject.h
index ffce029..43048d3 100644
--- a/Include/listobject.h
+++ b/Include/listobject.h
@@ -30,9 +30,7 @@
* 0 <= ob_size <= allocated
* len(list) == ob_size
* ob_item == NULL implies ob_size == allocated == 0
- * If ob_item ever becomes non-NULL, it remains non-NULL for the
- * life of the list object. The check for mutation in list.sort()
- * relies on this odd detail.
+ * list.sort() temporarily sets allocated to -1 to detect mutations.
*/
int allocated;
} PyListObject;