Skip to content

Commit f10eb37

Browse files
committed
keylist arg
1 parent 714d0a7 commit f10eb37

File tree

7 files changed

+62
-22
lines changed

7 files changed

+62
-22
lines changed

Include/internal/pycore_global_objects_fini_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ struct _Py_global_strings {
561561
STRUCT_FOR_ID(keepends)
562562
STRUCT_FOR_ID(key)
563563
STRUCT_FOR_ID(keyfile)
564+
STRUCT_FOR_ID(keylist)
564565
STRUCT_FOR_ID(keys)
565566
STRUCT_FOR_ID(kind)
566567
STRUCT_FOR_ID(kw)

Include/internal/pycore_runtime_init_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_unicodeobject_generated.h

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/clinic/listobject.c.h

Lines changed: 17 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/listobject.c

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2882,6 +2882,7 @@ list.sort
28822882
28832883
*
28842884
key as keyfunc: object = None
2885+
keylist: object = None
28852886
reverse: bool = False
28862887
28872888
Sort the list in ascending order and return None.
@@ -2896,8 +2897,9 @@ The reverse flag can be set to sort in descending order.
28962897
[clinic start generated code]*/
28972898

28982899
static PyObject *
2899-
list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
2900-
/*[clinic end generated code: output=57b9f9c5e23fbe42 input=e4f6b6069181ad7d]*/
2900+
list_sort_impl(PyListObject *self, PyObject *keyfunc, PyObject *keylist,
2901+
int reverse)
2902+
/*[clinic end generated code: output=ebb99a3e19f35128 input=466d6923f1e8913d]*/
29012903
{
29022904
MergeState ms;
29032905
Py_ssize_t nremaining;
@@ -2915,6 +2917,23 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
29152917
if (keyfunc == Py_None)
29162918
keyfunc = NULL;
29172919

2920+
if (keylist == Py_None) {
2921+
keylist = NULL;
2922+
}
2923+
else if (keylist != NULL) {
2924+
if (keyfunc != NULL) {
2925+
PyErr_SetString(PyExc_ValueError,
2926+
"Only one of key and keylist can be provided.");
2927+
return result;
2928+
}
2929+
if (!PyList_Check(keylist)) {
2930+
PyErr_Format(PyExc_TypeError,
2931+
"'%.200s' object is not list",
2932+
Py_TYPE(keylist)->tp_name);
2933+
return result;
2934+
}
2935+
}
2936+
29182937
/* The list is temporarily made empty, so that mutations performed
29192938
* by comparison functions can't affect the slice of memory we're
29202939
* sorting (allowing mutations during sorting is a core-dump
@@ -2926,9 +2945,8 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
29262945
Py_SET_SIZE(self, 0);
29272946
FT_ATOMIC_STORE_PTR_RELEASE(self->ob_item, NULL);
29282947
self->allocated = -1; /* any operation will reset it to >= 0 */
2929-
2930-
PyObject **keylist;
2931-
if (keyfunc == NULL) {
2948+
PyObject **keylist_ob_item;
2949+
if (keyfunc == NULL && keylist == NULL) {
29322950
keys = NULL;
29332951
lo.keys = saved_ob_item;
29342952
lo.values = NULL;
@@ -2944,10 +2962,16 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
29442962
goto keyfunc_fail;
29452963
}
29462964
}
2947-
if (PyList_CheckExact(keyfunc)) {
2948-
keylist = ((PyListObject *) keyfunc)->ob_item;
2949-
for (i = 0; i < saved_ob_size ; i++) {
2950-
keys[i] = keylist[i];
2965+
2966+
if (keylist != NULL) {
2967+
if (saved_ob_size != Py_SIZE(keylist)) {
2968+
PyErr_SetString(PyExc_ValueError,
2969+
"Lengths of input list and keylist differ.");
2970+
goto keyfunc_fail;
2971+
}
2972+
keylist_ob_item = ((PyListObject *) keylist)->ob_item;
2973+
for (i = 0; i < saved_ob_size; i++) {
2974+
keys[i] = keylist_ob_item[i];
29512975
}
29522976
}
29532977
else {
@@ -3125,9 +3149,9 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
31253149
result = Py_None;
31263150
fail:
31273151
if (keys != NULL) {
3128-
if (PyList_CheckExact(keyfunc)) {
3152+
if (keylist != NULL) {
31293153
for (i = 0; i < saved_ob_size ; i++) {
3130-
keylist[i] = keys[i];
3154+
keylist_ob_item[i] = keys[i];
31313155
}
31323156
}
31333157
else {
@@ -3184,7 +3208,7 @@ PyList_Sort(PyObject *v)
31843208
return -1;
31853209
}
31863210
Py_BEGIN_CRITICAL_SECTION(v);
3187-
v = list_sort_impl((PyListObject *)v, NULL, 0);
3211+
v = list_sort_impl((PyListObject *)v, NULL, NULL, 0);
31883212
Py_END_CRITICAL_SECTION();
31893213
if (v == NULL)
31903214
return -1;

Python/bltinmodule.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2638,6 +2638,7 @@ sorted as builtin_sorted
26382638
26392639
iterable as seq: object
26402640
key as keyfunc: object = None
2641+
keylist: object = None
26412642
reverse: object = False
26422643
26432644
Return a new list containing all items from the iterable in ascending order.
@@ -2647,7 +2648,7 @@ reverse flag can be set to request the result in descending order.
26472648
[end disabled clinic input]*/
26482649

26492650
PyDoc_STRVAR(builtin_sorted__doc__,
2650-
"sorted($module, iterable, /, *, key=None, reverse=False)\n"
2651+
"sorted($module, iterable, /, *, key=None, keylist=None, reverse=False)\n"
26512652
"--\n"
26522653
"\n"
26532654
"Return a new list containing all items from the iterable in ascending order.\n"

0 commit comments

Comments
 (0)