Skip to content

Commit 588d0cb

Browse files
pablogsalmiss-islington
authored andcommitted
gh-95173: Revert commit 51ed2c5 (GH-95176)
(cherry picked from commit 9007dec) Co-authored-by: Pablo Galindo Salgado <[email protected]>
1 parent 687dd50 commit 588d0cb

File tree

2 files changed

+13
-71
lines changed

2 files changed

+13
-71
lines changed

Doc/whatsnew/3.11.rst

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,13 +1478,6 @@ Changes in the Python API
14781478
the ``'utf-8'`` encoding.
14791479
(Contributed by Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి) in :issue:`41137`.)
14801480

1481-
* When sorting using tuples as keys, the order of the result may differ
1482-
from earlier releases if the tuple elements don't define a total
1483-
ordering (see :ref:`expressions-value-comparisons` for
1484-
information on total ordering). It's generally true that the result
1485-
of sorting simply isn't well-defined in the absence of a total ordering
1486-
on list elements.
1487-
14881481
* :mod:`calendar`: The :class:`calendar.LocaleTextCalendar` and
14891482
:class:`calendar.LocaleHTMLCalendar` classes now use
14901483
:func:`locale.getlocale`, instead of using :func:`locale.getdefaultlocale`,

Objects/listobject.c

Lines changed: 13 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,13 +1226,6 @@ struct s_MergeState {
12261226
* of tuples. It may be set to safe_object_compare, but the idea is that hopefully
12271227
* we can assume more, and use one of the special-case compares. */
12281228
int (*tuple_elem_compare)(PyObject *, PyObject *, MergeState *);
1229-
1230-
/* Used by unsafe_tuple_compare to record whether the very first tuple
1231-
* elements resolved the last comparison attempt. If so, next time a
1232-
* method that may avoid PyObject_RichCompareBool() entirely is tried.
1233-
* 0 for false, 1 for true.
1234-
*/
1235-
int first_tuple_items_resolved_it;
12361229
};
12371230

12381231
/* binarysort is the best method for sorting small arrays: it does
@@ -2205,24 +2198,7 @@ unsafe_float_compare(PyObject *v, PyObject *w, MergeState *ms)
22052198
* using the same pre-sort check as we use for ms->key_compare,
22062199
* but run on the list [x[0] for x in L]. This allows us to optimize compares
22072200
* on two levels (as long as [x[0] for x in L] is type-homogeneous.) The idea is
2208-
* that most tuple compares don't involve x[1:].
2209-
* However, that may not be right. When it is right, we can win by calling the
2210-
* relatively cheap ms->tuple_elem_compare on the first pair of elements, to
2211-
* see whether v[0] < w[0] or w[0] < v[0]. If either are so, we're done.
2212-
* Else we proceed as in the tuple compare, comparing the remaining pairs via
2213-
* the probably more expensive PyObject_RichCompareBool(..., Py_EQ) until (if
2214-
* ever) that says "no, not equal!". Then, if we're still on the first pair,
2215-
* ms->tuple_elem_compare can resolve it, else PyObject_RichCompareBool(...,
2216-
* Py_LT) finishes the job.
2217-
* In any case, ms->first_tuple_items_resolved_it keeps track of whether the
2218-
* most recent tuple comparison was resolved by the first pair. If so, the
2219-
* next attempt starts by trying the cheap tests on the first pair again, else
2220-
* PyObject_RichCompareBool(..., Py_EQ) is used from the start.
2221-
* There are cases where PyObject_RichCompareBool(..., Py_EQ) is much cheaper!
2222-
* For example, that can return "almost immediately" if passed the same
2223-
* object twice (it special-cases object identity for Py_EQ), which can,
2224-
* potentially, be unboundedly faster than ms->tuple_elem_compare.
2225-
*/
2201+
* that most tuple compares don't involve x[1:]. */
22262202
static int
22272203
unsafe_tuple_compare(PyObject *v, PyObject *w, MergeState *ms)
22282204
{
@@ -2238,52 +2214,26 @@ unsafe_tuple_compare(PyObject *v, PyObject *w, MergeState *ms)
22382214

22392215
vt = (PyTupleObject *)v;
22402216
wt = (PyTupleObject *)w;
2241-
i = 0;
2242-
if (ms->first_tuple_items_resolved_it) {
2243-
/* See whether fast compares of the first elements settle it. */
2244-
k = ms->tuple_elem_compare(vt->ob_item[0], wt->ob_item[0], ms);
2245-
if (k) /* error, or v < w */
2246-
return k;
2247-
k = ms->tuple_elem_compare(wt->ob_item[0], vt->ob_item[0], ms);
2248-
if (k > 0) /* w < v */
2249-
return 0;
2250-
if (k < 0) /* error */
2251-
return -1;
2252-
/* We have
2253-
* not (v[0] < w[0]) and not (w[0] < v[0])
2254-
* which implies, for a total order, that the first elements are
2255-
* equal. So skip them in the loop.
2256-
*/
2257-
i = 1;
2258-
ms->first_tuple_items_resolved_it = 0;
2259-
}
2260-
/* Now first_tuple_items_resolved_it was 0 on entry, or was forced to 0
2261-
* at the end of the `if` block just above.
2262-
*/
2263-
assert(! ms->first_tuple_items_resolved_it);
22642217

22652218
vlen = Py_SIZE(vt);
22662219
wlen = Py_SIZE(wt);
2267-
for (; i < vlen && i < wlen; i++) {
2220+
2221+
for (i = 0; i < vlen && i < wlen; i++) {
22682222
k = PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i], Py_EQ);
2269-
if (!k) { /* not equal */
2270-
if (i) {
2271-
return PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i],
2272-
Py_LT);
2273-
}
2274-
else {
2275-
ms->first_tuple_items_resolved_it = 1;
2276-
return ms->tuple_elem_compare(vt->ob_item[0], wt->ob_item[0],
2277-
ms);
2278-
}
2279-
}
22802223
if (k < 0)
22812224
return -1;
2225+
if (!k)
2226+
break;
22822227
}
2283-
/* all equal until we fell off the end */
2284-
return vlen < wlen;
22852228

2286-
}
2229+
if (i >= vlen || i >= wlen)
2230+
return vlen < wlen;
2231+
2232+
if (i == 0)
2233+
return ms->tuple_elem_compare(vt->ob_item[i], wt->ob_item[i], ms);
2234+
else
2235+
return PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i], Py_LT);
2236+
}
22872237

22882238
/* An adaptive, stable, natural mergesort. See listsort.txt.
22892239
* Returns Py_None on success, NULL on error. Even in case of error, the
@@ -2466,7 +2416,6 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
24662416
}
24672417

24682418
ms.key_compare = unsafe_tuple_compare;
2469-
ms.first_tuple_items_resolved_it = 1; /* be optimistic */
24702419
}
24712420
}
24722421
/* End of pre-sort check: ms is now set properly! */

0 commit comments

Comments
 (0)