mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
* 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.
This commit is contained in:
parent
f414fc4004
commit
93677f075d
3 changed files with 64 additions and 31 deletions
|
@ -150,6 +150,23 @@ class TestBugs(unittest.TestCase):
|
|||
L.sort(None)
|
||||
self.assertEqual(L, range(50))
|
||||
|
||||
def test_undetected_mutation(self):
|
||||
# Python 2.4a1 did not always detect mutation
|
||||
memorywaster = []
|
||||
for i in range(20):
|
||||
def mutating_cmp(x, y):
|
||||
L.append(3)
|
||||
L.pop()
|
||||
return cmp(x, y)
|
||||
L = [1,2]
|
||||
self.assertRaises(ValueError, L.sort, mutating_cmp)
|
||||
def mutating_cmp(x, y):
|
||||
L.append(3)
|
||||
del L[:]
|
||||
return cmp(x, y)
|
||||
self.assertRaises(ValueError, L.sort, mutating_cmp)
|
||||
memorywaster = [memorywaster]
|
||||
|
||||
#==============================================================================
|
||||
|
||||
class TestDecorateSortUndecorate(unittest.TestCase):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue