From 37e136373e0d9ab3bdf25ecd9c42b86281ed21d3 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 28 Nov 2003 21:43:02 +0000 Subject: [PATCH] Make sure the list.sort's decorate step unwinds itself before returning an exception raised by the key function. (Suggested by Michael Hudson.) --- Lib/test/test_sort.py | 7 +++++++ Objects/listobject.c | 11 +++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_sort.py b/Lib/test/test_sort.py index 053b3381d5..2659a9088d 100644 --- a/Lib/test/test_sort.py +++ b/Lib/test/test_sort.py @@ -186,6 +186,13 @@ class TestDecorateSortUndecorate(unittest.TestCase): data = 'The quick Brown fox Jumped over The lazy Dog'.split() self.assertRaises(TypeError, data.sort, "bad", str.lower) + def test_key_with_exception(self): + # Verify that the wrapper has been removed + data = range(-2,2) + dup = data[:] + self.assertRaises(ZeroDivisionError, data.sort, None, lambda x: 1/x) + self.assertEqual(data, dup) + def test_reverse(self): data = range(100) random.shuffle(data) diff --git a/Objects/listobject.c b/Objects/listobject.c index 3782c3baac..95aa484f2b 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1876,8 +1876,15 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) value = PyList_GET_ITEM(self, i); key = PyObject_CallFunctionObjArgs(keyfunc, value, NULL); - if (key == NULL) + if (key == NULL) { + for (i=i-1 ; i>=0 ; i--) { + kvpair = PyList_GET_ITEM(self, i); + value = sortwrapper_getvalue(kvpair); + PyList_SET_ITEM(self, i, value); + Py_DECREF(kvpair); + } goto dsu_fail; + } kvpair = build_sortwrapper(key, value); if (kvpair == NULL) goto dsu_fail; @@ -1885,7 +1892,7 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) } } - /* Reverse sort stability achieved by initialially reversing the list, + /* Reverse sort stability achieved by initially reversing the list, applying a stable forward sort, then reversing the final result. */ if (reverse && self->ob_size > 1) reverse_slice(self->ob_item, self->ob_item + self->ob_size); -- 2.50.1