Commit dd5417af authored by Rémi Lapeyre's avatar Rémi Lapeyre Committed by Raymond Hettinger

bpo-36218: Fix handling of heterogeneous values in list.sort (GH-12209)

parent 9dcc095f
...@@ -373,6 +373,11 @@ class TestOptimizedCompares(unittest.TestCase): ...@@ -373,6 +373,11 @@ class TestOptimizedCompares(unittest.TestCase):
check_against_PyObject_RichCompareBool(self, [float('nan')]*100) check_against_PyObject_RichCompareBool(self, [float('nan')]*100)
check_against_PyObject_RichCompareBool(self, [float('nan') for check_against_PyObject_RichCompareBool(self, [float('nan') for
_ in range(100)]) _ in range(100)])
def test_not_all_tuples(self):
self.assertRaises(TypeError, [(1.0, 1.0), (False, "A"), 6].sort)
self.assertRaises(TypeError, [('a', 1), (1, 'a')].sort)
self.assertRaises(TypeError, [(1, 'a'), ('a', 1)].sort)
#============================================================================== #==============================================================================
if __name__ == "__main__": if __name__ == "__main__":
......
Fix a segfault occuring when sorting a list of heterogeneous values. Patch
contributed by Rémi Lapeyre and Elliot Gorokhovsky.
\ No newline at end of file
...@@ -2306,19 +2306,28 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) ...@@ -2306,19 +2306,28 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
if (key->ob_type != key_type) { if (key->ob_type != key_type) {
keys_are_all_same_type = 0; keys_are_all_same_type = 0;
/* If keys are in tuple we must loop over the whole list to make
sure all items are tuples */
if (!keys_are_in_tuples) {
break; break;
} }
}
if (keys_are_all_same_type) {
if (key_type == &PyLong_Type &&
ints_are_bounded &&
Py_ABS(Py_SIZE(key)) > 1) {
if (key_type == &PyLong_Type) {
if (ints_are_bounded && Py_ABS(Py_SIZE(key)) > 1)
ints_are_bounded = 0; ints_are_bounded = 0;
} }
else if (key_type == &PyUnicode_Type){ else if (key_type == &PyUnicode_Type &&
if (strings_are_latin && strings_are_latin &&
PyUnicode_KIND(key) != PyUnicode_1BYTE_KIND) PyUnicode_KIND(key) != PyUnicode_1BYTE_KIND) {
strings_are_latin = 0; strings_are_latin = 0;
} }
} }
}
/* Choose the best compare, given what we now know about the keys. */ /* Choose the best compare, given what we now know about the keys. */
if (keys_are_all_same_type) { if (keys_are_all_same_type) {
...@@ -2346,10 +2355,12 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) ...@@ -2346,10 +2355,12 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
if (keys_are_in_tuples) { if (keys_are_in_tuples) {
/* Make sure we're not dealing with tuples of tuples /* Make sure we're not dealing with tuples of tuples
* (remember: here, key_type refers list [key[0] for key in keys]) */ * (remember: here, key_type refers list [key[0] for key in keys]) */
if (key_type == &PyTuple_Type) if (key_type == &PyTuple_Type) {
ms.tuple_elem_compare = safe_object_compare; ms.tuple_elem_compare = safe_object_compare;
else }
else {
ms.tuple_elem_compare = ms.key_compare; ms.tuple_elem_compare = ms.key_compare;
}
ms.key_compare = unsafe_tuple_compare; ms.key_compare = unsafe_tuple_compare;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment