summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_sort.py
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2004-07-29 12:40:23 (GMT)
committerArmin Rigo <arigo@tunes.org>2004-07-29 12:40:23 (GMT)
commit93677f075df9a23c036f4baeb2b9f67c784eadbc (patch)
treea96bfc6ce9b3dc2b976d24a8f2f1b2732888bf96 /Lib/test/test_sort.py
parentf414fc4004fde1118f15efe73f93e2d12d91d82c (diff)
downloadcpython-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.py17
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):