diff options
author | Armin Rigo <arigo@tunes.org> | 2004-07-29 12:40:23 (GMT) |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2004-07-29 12:40:23 (GMT) |
commit | 93677f075df9a23c036f4baeb2b9f67c784eadbc (patch) | |
tree | a96bfc6ce9b3dc2b976d24a8f2f1b2732888bf96 /Lib/test/test_sort.py | |
parent | f414fc4004fde1118f15efe73f93e2d12d91d82c (diff) | |
download | cpython-93677f075df9a23c036f4baeb2b9f67c784eadbc.zip cpython-93677f075df9a23c036f4baeb2b9f67c784eadbc.tar.gz cpython-93677f075df9a23c036f4baeb2b9f67c784eadbc.tar.bz2 |
* 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.
Diffstat (limited to 'Lib/test/test_sort.py')
-rw-r--r-- | Lib/test/test_sort.py | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/Lib/test/test_sort.py b/Lib/test/test_sort.py index 5d670a8..09dc649 100644 --- a/Lib/test/test_sort.py +++ b/Lib/test/test_sort.py @@ -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): |