bpo-36218: Fix handling of heterogeneous values in list.sort (GH-12209)
This commit is contained in:
parent
9dcc095f45
commit
dd5417afcf
|
@ -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__":
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix a segfault occuring when sorting a list of heterogeneous values. Patch
|
||||||
|
contributed by Rémi Lapeyre and Elliot Gorokhovsky.
|
|
@ -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;
|
||||||
break;
|
/* 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key_type == &PyLong_Type) {
|
if (keys_are_all_same_type) {
|
||||||
if (ints_are_bounded && Py_ABS(Py_SIZE(key)) > 1)
|
if (key_type == &PyLong_Type &&
|
||||||
|
ints_are_bounded &&
|
||||||
|
Py_ABS(Py_SIZE(key)) > 1) {
|
||||||
|
|
||||||
ints_are_bounded = 0;
|
ints_are_bounded = 0;
|
||||||
|
}
|
||||||
|
else if (key_type == &PyUnicode_Type &&
|
||||||
|
strings_are_latin &&
|
||||||
|
PyUnicode_KIND(key) != PyUnicode_1BYTE_KIND) {
|
||||||
|
|
||||||
|
strings_are_latin = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (key_type == &PyUnicode_Type){
|
|
||||||
if (strings_are_latin &&
|
|
||||||
PyUnicode_KIND(key) != PyUnicode_1BYTE_KIND)
|
|
||||||
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)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue