1#include "Python.h"
2#include "pycore_call.h"          // _PyObject_CallNoArgs()
3#include "pycore_long.h"          // _PyLong_GetZero()
4#include "pycore_moduleobject.h"  // _PyModule_GetState()
5#include "pycore_object.h"        // _PyObject_GC_TRACK
6#include "pycore_pystate.h"       // _PyThreadState_GET()
7#include "pycore_tuple.h"         // _PyTuple_ITEMS()
8#include "structmember.h"         // PyMemberDef
9
10/* _functools module written and maintained
11   by Hye-Shik Chang <perky@FreeBSD.org>
12   with adaptations by Raymond Hettinger <python@rcn.com>
13   Copyright (c) 2004, 2005, 2006 Python Software Foundation.
14   All rights reserved.
15*/
16
17typedef struct _functools_state {
18    /* this object is used delimit args and keywords in the cache keys */
19    PyObject *kwd_mark;
20    PyTypeObject *partial_type;
21    PyTypeObject *keyobject_type;
22    PyTypeObject *lru_list_elem_type;
23} _functools_state;
24
25static inline _functools_state *
26get_functools_state(PyObject *module)
27{
28    void *state = _PyModule_GetState(module);
29    assert(state != NULL);
30    return (_functools_state *)state;
31}
32
33
34/* partial object **********************************************************/
35
36typedef struct {
37    PyObject_HEAD
38    PyObject *fn;
39    PyObject *args;
40    PyObject *kw;
41    PyObject *dict;        /* __dict__ */
42    PyObject *weakreflist; /* List of weak references */
43    vectorcallfunc vectorcall;
44} partialobject;
45
46static void partial_setvectorcall(partialobject *pto);
47static struct PyModuleDef _functools_module;
48static PyObject *
49partial_call(partialobject *pto, PyObject *args, PyObject *kwargs);
50
51static inline _functools_state *
52get_functools_state_by_type(PyTypeObject *type)
53{
54    PyObject *module = PyType_GetModuleByDef(type, &_functools_module);
55    if (module == NULL) {
56        return NULL;
57    }
58    return get_functools_state(module);
59}
60
61static PyObject *
62partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
63{
64    PyObject *func, *pargs, *nargs, *pkw;
65    partialobject *pto;
66
67    if (PyTuple_GET_SIZE(args) < 1) {
68        PyErr_SetString(PyExc_TypeError,
69                        "type 'partial' takes at least one argument");
70        return NULL;
71    }
72
73    pargs = pkw = NULL;
74    func = PyTuple_GET_ITEM(args, 0);
75    if (Py_TYPE(func)->tp_call == (ternaryfunc)partial_call) {
76        // The type of "func" might not be exactly the same type object
77        // as "type", but if it is called using partial_call, it must have the
78        // same memory layout (fn, args and kw members).
79        // We can use its underlying function directly and merge the arguments.
80        partialobject *part = (partialobject *)func;
81        if (part->dict == NULL) {
82            pargs = part->args;
83            pkw = part->kw;
84            func = part->fn;
85            assert(PyTuple_Check(pargs));
86            assert(PyDict_Check(pkw));
87        }
88    }
89    if (!PyCallable_Check(func)) {
90        PyErr_SetString(PyExc_TypeError,
91                        "the first argument must be callable");
92        return NULL;
93    }
94
95    /* create partialobject structure */
96    pto = (partialobject *)type->tp_alloc(type, 0);
97    if (pto == NULL)
98        return NULL;
99
100    pto->fn = func;
101    Py_INCREF(func);
102
103    nargs = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX);
104    if (nargs == NULL) {
105        Py_DECREF(pto);
106        return NULL;
107    }
108    if (pargs == NULL) {
109        pto->args = nargs;
110    }
111    else {
112        pto->args = PySequence_Concat(pargs, nargs);
113        Py_DECREF(nargs);
114        if (pto->args == NULL) {
115            Py_DECREF(pto);
116            return NULL;
117        }
118        assert(PyTuple_Check(pto->args));
119    }
120
121    if (pkw == NULL || PyDict_GET_SIZE(pkw) == 0) {
122        if (kw == NULL) {
123            pto->kw = PyDict_New();
124        }
125        else if (Py_REFCNT(kw) == 1) {
126            Py_INCREF(kw);
127            pto->kw = kw;
128        }
129        else {
130            pto->kw = PyDict_Copy(kw);
131        }
132    }
133    else {
134        pto->kw = PyDict_Copy(pkw);
135        if (kw != NULL && pto->kw != NULL) {
136            if (PyDict_Merge(pto->kw, kw, 1) != 0) {
137                Py_DECREF(pto);
138                return NULL;
139            }
140        }
141    }
142    if (pto->kw == NULL) {
143        Py_DECREF(pto);
144        return NULL;
145    }
146
147    partial_setvectorcall(pto);
148    return (PyObject *)pto;
149}
150
151static int
152partial_clear(partialobject *pto)
153{
154    Py_CLEAR(pto->fn);
155    Py_CLEAR(pto->args);
156    Py_CLEAR(pto->kw);
157    Py_CLEAR(pto->dict);
158    return 0;
159}
160
161static int
162partial_traverse(partialobject *pto, visitproc visit, void *arg)
163{
164    Py_VISIT(Py_TYPE(pto));
165    Py_VISIT(pto->fn);
166    Py_VISIT(pto->args);
167    Py_VISIT(pto->kw);
168    Py_VISIT(pto->dict);
169    return 0;
170}
171
172static void
173partial_dealloc(partialobject *pto)
174{
175    PyTypeObject *tp = Py_TYPE(pto);
176    /* bpo-31095: UnTrack is needed before calling any callbacks */
177    PyObject_GC_UnTrack(pto);
178    if (pto->weakreflist != NULL) {
179        PyObject_ClearWeakRefs((PyObject *) pto);
180    }
181    (void)partial_clear(pto);
182    tp->tp_free(pto);
183    Py_DECREF(tp);
184}
185
186
187/* Merging keyword arguments using the vectorcall convention is messy, so
188 * if we would need to do that, we stop using vectorcall and fall back
189 * to using partial_call() instead. */
190Py_NO_INLINE static PyObject *
191partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto,
192                            PyObject *const *args, size_t nargsf,
193                            PyObject *kwnames)
194{
195    pto->vectorcall = NULL;
196    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
197    return _PyObject_MakeTpCall(tstate, (PyObject *)pto,
198                                args, nargs, kwnames);
199}
200
201static PyObject *
202partial_vectorcall(partialobject *pto, PyObject *const *args,
203                   size_t nargsf, PyObject *kwnames)
204{
205    PyThreadState *tstate = _PyThreadState_GET();
206
207    /* pto->kw is mutable, so need to check every time */
208    if (PyDict_GET_SIZE(pto->kw)) {
209        return partial_vectorcall_fallback(tstate, pto, args, nargsf, kwnames);
210    }
211
212    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
213    Py_ssize_t nargs_total = nargs;
214    if (kwnames != NULL) {
215        nargs_total += PyTuple_GET_SIZE(kwnames);
216    }
217
218    PyObject **pto_args = _PyTuple_ITEMS(pto->args);
219    Py_ssize_t pto_nargs = PyTuple_GET_SIZE(pto->args);
220
221    /* Fast path if we're called without arguments */
222    if (nargs_total == 0) {
223        return _PyObject_VectorcallTstate(tstate, pto->fn,
224                                          pto_args, pto_nargs, NULL);
225    }
226
227    /* Fast path using PY_VECTORCALL_ARGUMENTS_OFFSET to prepend a single
228     * positional argument */
229    if (pto_nargs == 1 && (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET)) {
230        PyObject **newargs = (PyObject **)args - 1;
231        PyObject *tmp = newargs[0];
232        newargs[0] = pto_args[0];
233        PyObject *ret = _PyObject_VectorcallTstate(tstate, pto->fn,
234                                                   newargs, nargs + 1, kwnames);
235        newargs[0] = tmp;
236        return ret;
237    }
238
239    Py_ssize_t newnargs_total = pto_nargs + nargs_total;
240
241    PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
242    PyObject *ret;
243    PyObject **stack;
244
245    if (newnargs_total <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
246        stack = small_stack;
247    }
248    else {
249        stack = PyMem_Malloc(newnargs_total * sizeof(PyObject *));
250        if (stack == NULL) {
251            PyErr_NoMemory();
252            return NULL;
253        }
254    }
255
256    /* Copy to new stack, using borrowed references */
257    memcpy(stack, pto_args, pto_nargs * sizeof(PyObject*));
258    memcpy(stack + pto_nargs, args, nargs_total * sizeof(PyObject*));
259
260    ret = _PyObject_VectorcallTstate(tstate, pto->fn,
261                                     stack, pto_nargs + nargs, kwnames);
262    if (stack != small_stack) {
263        PyMem_Free(stack);
264    }
265    return ret;
266}
267
268/* Set pto->vectorcall depending on the parameters of the partial object */
269static void
270partial_setvectorcall(partialobject *pto)
271{
272    if (_PyVectorcall_Function(pto->fn) == NULL) {
273        /* Don't use vectorcall if the underlying function doesn't support it */
274        pto->vectorcall = NULL;
275    }
276    /* We could have a special case if there are no arguments,
277     * but that is unlikely (why use partial without arguments?),
278     * so we don't optimize that */
279    else {
280        pto->vectorcall = (vectorcallfunc)partial_vectorcall;
281    }
282}
283
284
285static PyObject *
286partial_call(partialobject *pto, PyObject *args, PyObject *kwargs)
287{
288    assert(PyCallable_Check(pto->fn));
289    assert(PyTuple_Check(pto->args));
290    assert(PyDict_Check(pto->kw));
291
292    /* Merge keywords */
293    PyObject *kwargs2;
294    if (PyDict_GET_SIZE(pto->kw) == 0) {
295        /* kwargs can be NULL */
296        kwargs2 = kwargs;
297        Py_XINCREF(kwargs2);
298    }
299    else {
300        /* bpo-27840, bpo-29318: dictionary of keyword parameters must be
301           copied, because a function using "**kwargs" can modify the
302           dictionary. */
303        kwargs2 = PyDict_Copy(pto->kw);
304        if (kwargs2 == NULL) {
305            return NULL;
306        }
307
308        if (kwargs != NULL) {
309            if (PyDict_Merge(kwargs2, kwargs, 1) != 0) {
310                Py_DECREF(kwargs2);
311                return NULL;
312            }
313        }
314    }
315
316    /* Merge positional arguments */
317    /* Note: tupleconcat() is optimized for empty tuples */
318    PyObject *args2 = PySequence_Concat(pto->args, args);
319    if (args2 == NULL) {
320        Py_XDECREF(kwargs2);
321        return NULL;
322    }
323
324    PyObject *res = PyObject_Call(pto->fn, args2, kwargs2);
325    Py_DECREF(args2);
326    Py_XDECREF(kwargs2);
327    return res;
328}
329
330PyDoc_STRVAR(partial_doc,
331"partial(func, *args, **keywords) - new function with partial application\n\
332    of the given arguments and keywords.\n");
333
334#define OFF(x) offsetof(partialobject, x)
335static PyMemberDef partial_memberlist[] = {
336    {"func",            T_OBJECT,       OFF(fn),        READONLY,
337     "function object to use in future partial calls"},
338    {"args",            T_OBJECT,       OFF(args),      READONLY,
339     "tuple of arguments to future partial calls"},
340    {"keywords",        T_OBJECT,       OFF(kw),        READONLY,
341     "dictionary of keyword arguments to future partial calls"},
342    {"__weaklistoffset__", T_PYSSIZET,
343     offsetof(partialobject, weakreflist), READONLY},
344    {"__dictoffset__", T_PYSSIZET,
345     offsetof(partialobject, dict), READONLY},
346    {"__vectorcalloffset__", T_PYSSIZET,
347     offsetof(partialobject, vectorcall), READONLY},
348    {NULL}  /* Sentinel */
349};
350
351static PyGetSetDef partial_getsetlist[] = {
352    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
353    {NULL} /* Sentinel */
354};
355
356static PyObject *
357partial_repr(partialobject *pto)
358{
359    PyObject *result = NULL;
360    PyObject *arglist;
361    Py_ssize_t i, n;
362    PyObject *key, *value;
363    int status;
364
365    status = Py_ReprEnter((PyObject *)pto);
366    if (status != 0) {
367        if (status < 0)
368            return NULL;
369        return PyUnicode_FromString("...");
370    }
371
372    arglist = PyUnicode_FromString("");
373    if (arglist == NULL)
374        goto done;
375    /* Pack positional arguments */
376    assert (PyTuple_Check(pto->args));
377    n = PyTuple_GET_SIZE(pto->args);
378    for (i = 0; i < n; i++) {
379        Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist,
380                                        PyTuple_GET_ITEM(pto->args, i)));
381        if (arglist == NULL)
382            goto done;
383    }
384    /* Pack keyword arguments */
385    assert (PyDict_Check(pto->kw));
386    for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) {
387        /* Prevent key.__str__ from deleting the value. */
388        Py_INCREF(value);
389        Py_SETREF(arglist, PyUnicode_FromFormat("%U, %S=%R", arglist,
390                                                key, value));
391        Py_DECREF(value);
392        if (arglist == NULL)
393            goto done;
394    }
395    result = PyUnicode_FromFormat("%s(%R%U)", Py_TYPE(pto)->tp_name,
396                                  pto->fn, arglist);
397    Py_DECREF(arglist);
398
399 done:
400    Py_ReprLeave((PyObject *)pto);
401    return result;
402}
403
404/* Pickle strategy:
405   __reduce__ by itself doesn't support getting kwargs in the unpickle
406   operation so we define a __setstate__ that replaces all the information
407   about the partial.  If we only replaced part of it someone would use
408   it as a hook to do strange things.
409 */
410
411static PyObject *
412partial_reduce(partialobject *pto, PyObject *unused)
413{
414    return Py_BuildValue("O(O)(OOOO)", Py_TYPE(pto), pto->fn, pto->fn,
415                         pto->args, pto->kw,
416                         pto->dict ? pto->dict : Py_None);
417}
418
419static PyObject *
420partial_setstate(partialobject *pto, PyObject *state)
421{
422    PyObject *fn, *fnargs, *kw, *dict;
423
424    if (!PyTuple_Check(state) ||
425        !PyArg_ParseTuple(state, "OOOO", &fn, &fnargs, &kw, &dict) ||
426        !PyCallable_Check(fn) ||
427        !PyTuple_Check(fnargs) ||
428        (kw != Py_None && !PyDict_Check(kw)))
429    {
430        PyErr_SetString(PyExc_TypeError, "invalid partial state");
431        return NULL;
432    }
433
434    if(!PyTuple_CheckExact(fnargs))
435        fnargs = PySequence_Tuple(fnargs);
436    else
437        Py_INCREF(fnargs);
438    if (fnargs == NULL)
439        return NULL;
440
441    if (kw == Py_None)
442        kw = PyDict_New();
443    else if(!PyDict_CheckExact(kw))
444        kw = PyDict_Copy(kw);
445    else
446        Py_INCREF(kw);
447    if (kw == NULL) {
448        Py_DECREF(fnargs);
449        return NULL;
450    }
451
452    if (dict == Py_None)
453        dict = NULL;
454    else
455        Py_INCREF(dict);
456
457    Py_INCREF(fn);
458    Py_SETREF(pto->fn, fn);
459    Py_SETREF(pto->args, fnargs);
460    Py_SETREF(pto->kw, kw);
461    Py_XSETREF(pto->dict, dict);
462    partial_setvectorcall(pto);
463    Py_RETURN_NONE;
464}
465
466static PyMethodDef partial_methods[] = {
467    {"__reduce__", (PyCFunction)partial_reduce, METH_NOARGS},
468    {"__setstate__", (PyCFunction)partial_setstate, METH_O},
469    {"__class_getitem__",    Py_GenericAlias,
470    METH_O|METH_CLASS,       PyDoc_STR("See PEP 585")},
471    {NULL,              NULL}           /* sentinel */
472};
473
474static PyType_Slot partial_type_slots[] = {
475    {Py_tp_dealloc, partial_dealloc},
476    {Py_tp_repr, partial_repr},
477    {Py_tp_call, partial_call},
478    {Py_tp_getattro, PyObject_GenericGetAttr},
479    {Py_tp_setattro, PyObject_GenericSetAttr},
480    {Py_tp_doc, (void *)partial_doc},
481    {Py_tp_traverse, partial_traverse},
482    {Py_tp_clear, partial_clear},
483    {Py_tp_methods, partial_methods},
484    {Py_tp_members, partial_memberlist},
485    {Py_tp_getset, partial_getsetlist},
486    {Py_tp_new, partial_new},
487    {Py_tp_free, PyObject_GC_Del},
488    {0, 0}
489};
490
491static PyType_Spec partial_type_spec = {
492    .name = "functools.partial",
493    .basicsize = sizeof(partialobject),
494    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
495             Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL |
496             Py_TPFLAGS_IMMUTABLETYPE,
497    .slots = partial_type_slots
498};
499
500
501/* cmp_to_key ***************************************************************/
502
503typedef struct {
504    PyObject_HEAD
505    PyObject *cmp;
506    PyObject *object;
507} keyobject;
508
509static int
510keyobject_clear(keyobject *ko)
511{
512    Py_CLEAR(ko->cmp);
513    Py_CLEAR(ko->object);
514    return 0;
515}
516
517static void
518keyobject_dealloc(keyobject *ko)
519{
520    PyTypeObject *tp = Py_TYPE(ko);
521    PyObject_GC_UnTrack(ko);
522    (void)keyobject_clear(ko);
523    tp->tp_free(ko);
524    Py_DECREF(tp);
525}
526
527static int
528keyobject_traverse(keyobject *ko, visitproc visit, void *arg)
529{
530    Py_VISIT(Py_TYPE(ko));
531    Py_VISIT(ko->cmp);
532    Py_VISIT(ko->object);
533    return 0;
534}
535
536static PyMemberDef keyobject_members[] = {
537    {"obj", T_OBJECT,
538     offsetof(keyobject, object), 0,
539     PyDoc_STR("Value wrapped by a key function.")},
540    {NULL}
541};
542
543static PyObject *
544keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds);
545
546static PyObject *
547keyobject_richcompare(PyObject *ko, PyObject *other, int op);
548
549static PyType_Slot keyobject_type_slots[] = {
550    {Py_tp_dealloc, keyobject_dealloc},
551    {Py_tp_call, keyobject_call},
552    {Py_tp_getattro, PyObject_GenericGetAttr},
553    {Py_tp_traverse, keyobject_traverse},
554    {Py_tp_clear, keyobject_clear},
555    {Py_tp_richcompare, keyobject_richcompare},
556    {Py_tp_members, keyobject_members},
557    {0, 0}
558};
559
560static PyType_Spec keyobject_type_spec = {
561    .name = "functools.KeyWrapper",
562    .basicsize = sizeof(keyobject),
563    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
564              Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE),
565    .slots = keyobject_type_slots
566};
567
568static PyObject *
569keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds)
570{
571    PyObject *object;
572    keyobject *result;
573    static char *kwargs[] = {"obj", NULL};
574
575    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:K", kwargs, &object))
576        return NULL;
577
578    result = PyObject_GC_New(keyobject, Py_TYPE(ko));
579    if (result == NULL) {
580        return NULL;
581    }
582    Py_INCREF(ko->cmp);
583    result->cmp = ko->cmp;
584    Py_INCREF(object);
585    result->object = object;
586    PyObject_GC_Track(result);
587    return (PyObject *)result;
588}
589
590static PyObject *
591keyobject_richcompare(PyObject *ko, PyObject *other, int op)
592{
593    PyObject *res;
594    PyObject *x;
595    PyObject *y;
596    PyObject *compare;
597    PyObject *answer;
598    PyObject* stack[2];
599
600    if (!Py_IS_TYPE(other, Py_TYPE(ko))) {
601        PyErr_Format(PyExc_TypeError, "other argument must be K instance");
602        return NULL;
603    }
604    compare = ((keyobject *) ko)->cmp;
605    assert(compare != NULL);
606    x = ((keyobject *) ko)->object;
607    y = ((keyobject *) other)->object;
608    if (!x || !y){
609        PyErr_Format(PyExc_AttributeError, "object");
610        return NULL;
611    }
612
613    /* Call the user's comparison function and translate the 3-way
614     * result into true or false (or error).
615     */
616    stack[0] = x;
617    stack[1] = y;
618    res = _PyObject_FastCall(compare, stack, 2);
619    if (res == NULL) {
620        return NULL;
621    }
622
623    answer = PyObject_RichCompare(res, _PyLong_GetZero(), op);
624    Py_DECREF(res);
625    return answer;
626}
627
628static PyObject *
629functools_cmp_to_key(PyObject *self, PyObject *args, PyObject *kwds)
630{
631    PyObject *cmp;
632    static char *kwargs[] = {"mycmp", NULL};
633    keyobject *object;
634    _functools_state *state;
635
636    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:cmp_to_key", kwargs, &cmp))
637        return NULL;
638
639    state = get_functools_state(self);
640    object = PyObject_GC_New(keyobject, state->keyobject_type);
641    if (!object)
642        return NULL;
643    Py_INCREF(cmp);
644    object->cmp = cmp;
645    object->object = NULL;
646    PyObject_GC_Track(object);
647    return (PyObject *)object;
648}
649
650PyDoc_STRVAR(functools_cmp_to_key_doc,
651"Convert a cmp= function into a key= function.");
652
653/* reduce (used to be a builtin) ********************************************/
654
655static PyObject *
656functools_reduce(PyObject *self, PyObject *args)
657{
658    PyObject *seq, *func, *result = NULL, *it;
659
660    if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result))
661        return NULL;
662    if (result != NULL)
663        Py_INCREF(result);
664
665    it = PyObject_GetIter(seq);
666    if (it == NULL) {
667        if (PyErr_ExceptionMatches(PyExc_TypeError))
668            PyErr_SetString(PyExc_TypeError,
669                            "reduce() arg 2 must support iteration");
670        Py_XDECREF(result);
671        return NULL;
672    }
673
674    if ((args = PyTuple_New(2)) == NULL)
675        goto Fail;
676
677    for (;;) {
678        PyObject *op2;
679
680        if (Py_REFCNT(args) > 1) {
681            Py_DECREF(args);
682            if ((args = PyTuple_New(2)) == NULL)
683                goto Fail;
684        }
685
686        op2 = PyIter_Next(it);
687        if (op2 == NULL) {
688            if (PyErr_Occurred())
689                goto Fail;
690            break;
691        }
692
693        if (result == NULL)
694            result = op2;
695        else {
696            /* Update the args tuple in-place */
697            assert(Py_REFCNT(args) == 1);
698            Py_XSETREF(_PyTuple_ITEMS(args)[0], result);
699            Py_XSETREF(_PyTuple_ITEMS(args)[1], op2);
700            if ((result = PyObject_Call(func, args, NULL)) == NULL) {
701                goto Fail;
702            }
703            // bpo-42536: The GC may have untracked this args tuple. Since we're
704            // recycling it, make sure it's tracked again:
705            if (!_PyObject_GC_IS_TRACKED(args)) {
706                _PyObject_GC_TRACK(args);
707            }
708        }
709    }
710
711    Py_DECREF(args);
712
713    if (result == NULL)
714        PyErr_SetString(PyExc_TypeError,
715                   "reduce() of empty iterable with no initial value");
716
717    Py_DECREF(it);
718    return result;
719
720Fail:
721    Py_XDECREF(args);
722    Py_XDECREF(result);
723    Py_DECREF(it);
724    return NULL;
725}
726
727PyDoc_STRVAR(functools_reduce_doc,
728"reduce(function, iterable[, initial]) -> value\n\
729\n\
730Apply a function of two arguments cumulatively to the items of a sequence\n\
731or iterable, from left to right, so as to reduce the iterable to a single\n\
732value.  For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\
733((((1+2)+3)+4)+5).  If initial is present, it is placed before the items\n\
734of the iterable in the calculation, and serves as a default when the\n\
735iterable is empty.");
736
737/* lru_cache object **********************************************************/
738
739/* There are four principal algorithmic differences from the pure python version:
740
741   1). The C version relies on the GIL instead of having its own reentrant lock.
742
743   2). The prev/next link fields use borrowed references.
744
745   3). For a full cache, the pure python version rotates the location of the
746       root entry so that it never has to move individual links and it can
747       limit updates to just the key and result fields.  However, in the C
748       version, links are temporarily removed while the cache dict updates are
749       occurring. Afterwards, they are appended or prepended back into the
750       doubly-linked lists.
751
752   4)  In the Python version, the _HashSeq class is used to prevent __hash__
753       from being called more than once.  In the C version, the "known hash"
754       variants of dictionary calls as used to the same effect.
755
756*/
757
758struct lru_list_elem;
759struct lru_cache_object;
760
761typedef struct lru_list_elem {
762    PyObject_HEAD
763    struct lru_list_elem *prev, *next;  /* borrowed links */
764    Py_hash_t hash;
765    PyObject *key, *result;
766} lru_list_elem;
767
768static void
769lru_list_elem_dealloc(lru_list_elem *link)
770{
771    PyTypeObject *tp = Py_TYPE(link);
772    Py_XDECREF(link->key);
773    Py_XDECREF(link->result);
774    tp->tp_free(link);
775    Py_DECREF(tp);
776}
777
778static PyType_Slot lru_list_elem_type_slots[] = {
779    {Py_tp_dealloc, lru_list_elem_dealloc},
780    {0, 0}
781};
782
783static PyType_Spec lru_list_elem_type_spec = {
784    .name = "functools._lru_list_elem",
785    .basicsize = sizeof(lru_list_elem),
786    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
787             Py_TPFLAGS_IMMUTABLETYPE,
788    .slots = lru_list_elem_type_slots
789};
790
791
792typedef PyObject *(*lru_cache_ternaryfunc)(struct lru_cache_object *, PyObject *, PyObject *);
793
794typedef struct lru_cache_object {
795    lru_list_elem root;  /* includes PyObject_HEAD */
796    lru_cache_ternaryfunc wrapper;
797    int typed;
798    PyObject *cache;
799    Py_ssize_t hits;
800    PyObject *func;
801    Py_ssize_t maxsize;
802    Py_ssize_t misses;
803    /* the kwd_mark is used delimit args and keywords in the cache keys */
804    PyObject *kwd_mark;
805    PyTypeObject *lru_list_elem_type;
806    PyObject *cache_info_type;
807    PyObject *dict;
808    PyObject *weakreflist;
809} lru_cache_object;
810
811static PyObject *
812lru_cache_make_key(PyObject *kwd_mark, PyObject *args,
813                   PyObject *kwds, int typed)
814{
815    PyObject *key, *keyword, *value;
816    Py_ssize_t key_size, pos, key_pos, kwds_size;
817
818    kwds_size = kwds ? PyDict_GET_SIZE(kwds) : 0;
819
820    /* short path, key will match args anyway, which is a tuple */
821    if (!typed && !kwds_size) {
822        if (PyTuple_GET_SIZE(args) == 1) {
823            key = PyTuple_GET_ITEM(args, 0);
824            if (PyUnicode_CheckExact(key) || PyLong_CheckExact(key)) {
825                /* For common scalar keys, save space by
826                   dropping the enclosing args tuple  */
827                Py_INCREF(key);
828                return key;
829            }
830        }
831        Py_INCREF(args);
832        return args;
833    }
834
835    key_size = PyTuple_GET_SIZE(args);
836    if (kwds_size)
837        key_size += kwds_size * 2 + 1;
838    if (typed)
839        key_size += PyTuple_GET_SIZE(args) + kwds_size;
840
841    key = PyTuple_New(key_size);
842    if (key == NULL)
843        return NULL;
844
845    key_pos = 0;
846    for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) {
847        PyObject *item = PyTuple_GET_ITEM(args, pos);
848        Py_INCREF(item);
849        PyTuple_SET_ITEM(key, key_pos++, item);
850    }
851    if (kwds_size) {
852        Py_INCREF(kwd_mark);
853        PyTuple_SET_ITEM(key, key_pos++, kwd_mark);
854        for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) {
855            Py_INCREF(keyword);
856            PyTuple_SET_ITEM(key, key_pos++, keyword);
857            Py_INCREF(value);
858            PyTuple_SET_ITEM(key, key_pos++, value);
859        }
860        assert(key_pos == PyTuple_GET_SIZE(args) + kwds_size * 2 + 1);
861    }
862    if (typed) {
863        for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) {
864            PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(args, pos));
865            Py_INCREF(item);
866            PyTuple_SET_ITEM(key, key_pos++, item);
867        }
868        if (kwds_size) {
869            for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) {
870                PyObject *item = (PyObject *)Py_TYPE(value);
871                Py_INCREF(item);
872                PyTuple_SET_ITEM(key, key_pos++, item);
873            }
874        }
875    }
876    assert(key_pos == key_size);
877    return key;
878}
879
880static PyObject *
881uncached_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
882{
883    PyObject *result;
884
885    self->misses++;
886    result = PyObject_Call(self->func, args, kwds);
887    if (!result)
888        return NULL;
889    return result;
890}
891
892static PyObject *
893infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
894{
895    PyObject *result;
896    Py_hash_t hash;
897    PyObject *key = lru_cache_make_key(self->kwd_mark, args, kwds, self->typed);
898    if (!key)
899        return NULL;
900    hash = PyObject_Hash(key);
901    if (hash == -1) {
902        Py_DECREF(key);
903        return NULL;
904    }
905    result = _PyDict_GetItem_KnownHash(self->cache, key, hash);
906    if (result) {
907        Py_INCREF(result);
908        self->hits++;
909        Py_DECREF(key);
910        return result;
911    }
912    if (PyErr_Occurred()) {
913        Py_DECREF(key);
914        return NULL;
915    }
916    self->misses++;
917    result = PyObject_Call(self->func, args, kwds);
918    if (!result) {
919        Py_DECREF(key);
920        return NULL;
921    }
922    if (_PyDict_SetItem_KnownHash(self->cache, key, result, hash) < 0) {
923        Py_DECREF(result);
924        Py_DECREF(key);
925        return NULL;
926    }
927    Py_DECREF(key);
928    return result;
929}
930
931static void
932lru_cache_extract_link(lru_list_elem *link)
933{
934    lru_list_elem *link_prev = link->prev;
935    lru_list_elem *link_next = link->next;
936    link_prev->next = link->next;
937    link_next->prev = link->prev;
938}
939
940static void
941lru_cache_append_link(lru_cache_object *self, lru_list_elem *link)
942{
943    lru_list_elem *root = &self->root;
944    lru_list_elem *last = root->prev;
945    last->next = root->prev = link;
946    link->prev = last;
947    link->next = root;
948}
949
950static void
951lru_cache_prepend_link(lru_cache_object *self, lru_list_elem *link)
952{
953    lru_list_elem *root = &self->root;
954    lru_list_elem *first = root->next;
955    first->prev = root->next = link;
956    link->prev = root;
957    link->next = first;
958}
959
960/* General note on reentrancy:
961
962   There are four dictionary calls in the bounded_lru_cache_wrapper():
963   1) The initial check for a cache match.  2) The post user-function
964   check for a cache match.  3) The deletion of the oldest entry.
965   4) The addition of the newest entry.
966
967   In all four calls, we have a known hash which lets use avoid a call
968   to __hash__().  That leaves only __eq__ as a possible source of a
969   reentrant call.
970
971   The __eq__ method call is always made for a cache hit (dict access #1).
972   Accordingly, we have make sure not modify the cache state prior to
973   this call.
974
975   The __eq__ method call is never made for the deletion (dict access #3)
976   because it is an identity match.
977
978   For the other two accesses (#2 and #4), calls to __eq__ only occur
979   when some other entry happens to have an exactly matching hash (all
980   64-bits).  Though rare, this can happen, so we have to make sure to
981   either call it at the top of its code path before any cache
982   state modifications (dict access #2) or be prepared to restore
983   invariants at the end of the code path (dict access #4).
984
985   Another possible source of reentrancy is a decref which can trigger
986   arbitrary code execution.  To make the code easier to reason about,
987   the decrefs are deferred to the end of the each possible code path
988   so that we know the cache is a consistent state.
989 */
990
991static PyObject *
992bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
993{
994    lru_list_elem *link;
995    PyObject *key, *result, *testresult;
996    Py_hash_t hash;
997
998    key = lru_cache_make_key(self->kwd_mark, args, kwds, self->typed);
999    if (!key)
1000        return NULL;
1001    hash = PyObject_Hash(key);
1002    if (hash == -1) {
1003        Py_DECREF(key);
1004        return NULL;
1005    }
1006    link  = (lru_list_elem *)_PyDict_GetItem_KnownHash(self->cache, key, hash);
1007    if (link != NULL) {
1008        lru_cache_extract_link(link);
1009        lru_cache_append_link(self, link);
1010        result = link->result;
1011        self->hits++;
1012        Py_INCREF(result);
1013        Py_DECREF(key);
1014        return result;
1015    }
1016    if (PyErr_Occurred()) {
1017        Py_DECREF(key);
1018        return NULL;
1019    }
1020    self->misses++;
1021    result = PyObject_Call(self->func, args, kwds);
1022    if (!result) {
1023        Py_DECREF(key);
1024        return NULL;
1025    }
1026    testresult = _PyDict_GetItem_KnownHash(self->cache, key, hash);
1027    if (testresult != NULL) {
1028        /* Getting here means that this same key was added to the cache
1029           during the PyObject_Call().  Since the link update is already
1030           done, we need only return the computed result. */
1031        Py_DECREF(key);
1032        return result;
1033    }
1034    if (PyErr_Occurred()) {
1035        /* This is an unusual case since this same lookup
1036           did not previously trigger an error during lookup.
1037           Treat it the same as an error in user function
1038           and return with the error set. */
1039        Py_DECREF(key);
1040        Py_DECREF(result);
1041        return NULL;
1042    }
1043    /* This is the normal case.  The new key wasn't found before
1044       user function call and it is still not there.  So we
1045       proceed normally and update the cache with the new result. */
1046
1047    assert(self->maxsize > 0);
1048    if (PyDict_GET_SIZE(self->cache) < self->maxsize ||
1049        self->root.next == &self->root)
1050    {
1051        /* Cache is not full, so put the result in a new link */
1052        link = (lru_list_elem *)PyObject_New(lru_list_elem,
1053                                             self->lru_list_elem_type);
1054        if (link == NULL) {
1055            Py_DECREF(key);
1056            Py_DECREF(result);
1057            return NULL;
1058        }
1059
1060        link->hash = hash;
1061        link->key = key;
1062        link->result = result;
1063        /* What is really needed here is a SetItem variant with a "no clobber"
1064           option.  If the __eq__ call triggers a reentrant call that adds
1065           this same key, then this setitem call will update the cache dict
1066           with this new link, leaving the old link as an orphan (i.e. not
1067           having a cache dict entry that refers to it). */
1068        if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
1069                                      hash) < 0) {
1070            Py_DECREF(link);
1071            return NULL;
1072        }
1073        lru_cache_append_link(self, link);
1074        Py_INCREF(result); /* for return */
1075        return result;
1076    }
1077    /* Since the cache is full, we need to evict an old key and add
1078       a new key.  Rather than free the old link and allocate a new
1079       one, we reuse the link for the new key and result and move it
1080       to front of the cache to mark it as recently used.
1081
1082       We try to assure all code paths (including errors) leave all
1083       of the links in place.  Either the link is successfully
1084       updated and moved or it is restored to its old position.
1085       However if an unrecoverable error is found, it doesn't
1086       make sense to reinsert the link, so we leave it out
1087       and the cache will no longer register as full.
1088    */
1089    PyObject *oldkey, *oldresult, *popresult;
1090
1091    /* Extract the oldest item. */
1092    assert(self->root.next != &self->root);
1093    link = self->root.next;
1094    lru_cache_extract_link(link);
1095    /* Remove it from the cache.
1096       The cache dict holds one reference to the link.
1097       We created one other reference when the link was created.
1098       The linked list only has borrowed references. */
1099    popresult = _PyDict_Pop_KnownHash(self->cache, link->key,
1100                                      link->hash, Py_None);
1101    if (popresult == Py_None) {
1102        /* Getting here means that the user function call or another
1103           thread has already removed the old key from the dictionary.
1104           This link is now an orphan.  Since we don't want to leave the
1105           cache in an inconsistent state, we don't restore the link. */
1106        Py_DECREF(popresult);
1107        Py_DECREF(link);
1108        Py_DECREF(key);
1109        return result;
1110    }
1111    if (popresult == NULL) {
1112        /* An error arose while trying to remove the oldest key (the one
1113           being evicted) from the cache.  We restore the link to its
1114           original position as the oldest link.  Then we allow the
1115           error propagate upward; treating it the same as an error
1116           arising in the user function. */
1117        lru_cache_prepend_link(self, link);
1118        Py_DECREF(key);
1119        Py_DECREF(result);
1120        return NULL;
1121    }
1122    /* Keep a reference to the old key and old result to prevent their
1123       ref counts from going to zero during the update. That will
1124       prevent potentially arbitrary object clean-up code (i.e. __del__)
1125       from running while we're still adjusting the links. */
1126    oldkey = link->key;
1127    oldresult = link->result;
1128
1129    link->hash = hash;
1130    link->key = key;
1131    link->result = result;
1132    /* Note:  The link is being added to the cache dict without the
1133       prev and next fields set to valid values.   We have to wait
1134       for successful insertion in the cache dict before adding the
1135       link to the linked list.  Otherwise, the potentially reentrant
1136       __eq__ call could cause the then orphan link to be visited. */
1137    if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
1138                                  hash) < 0) {
1139        /* Somehow the cache dict update failed.  We no longer can
1140           restore the old link.  Let the error propagate upward and
1141           leave the cache short one link. */
1142        Py_DECREF(popresult);
1143        Py_DECREF(link);
1144        Py_DECREF(oldkey);
1145        Py_DECREF(oldresult);
1146        return NULL;
1147    }
1148    lru_cache_append_link(self, link);
1149    Py_INCREF(result); /* for return */
1150    Py_DECREF(popresult);
1151    Py_DECREF(oldkey);
1152    Py_DECREF(oldresult);
1153    return result;
1154}
1155
1156static PyObject *
1157lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1158{
1159    PyObject *func, *maxsize_O, *cache_info_type, *cachedict;
1160    int typed;
1161    lru_cache_object *obj;
1162    Py_ssize_t maxsize;
1163    PyObject *(*wrapper)(lru_cache_object *, PyObject *, PyObject *);
1164    _functools_state *state;
1165    static char *keywords[] = {"user_function", "maxsize", "typed",
1166                               "cache_info_type", NULL};
1167
1168    if (!PyArg_ParseTupleAndKeywords(args, kw, "OOpO:lru_cache", keywords,
1169                                     &func, &maxsize_O, &typed,
1170                                     &cache_info_type)) {
1171        return NULL;
1172    }
1173
1174    if (!PyCallable_Check(func)) {
1175        PyErr_SetString(PyExc_TypeError,
1176                        "the first argument must be callable");
1177        return NULL;
1178    }
1179
1180    state = get_functools_state_by_type(type);
1181    if (state == NULL) {
1182        return NULL;
1183    }
1184
1185    /* select the caching function, and make/inc maxsize_O */
1186    if (maxsize_O == Py_None) {
1187        wrapper = infinite_lru_cache_wrapper;
1188        /* use this only to initialize lru_cache_object attribute maxsize */
1189        maxsize = -1;
1190    } else if (PyIndex_Check(maxsize_O)) {
1191        maxsize = PyNumber_AsSsize_t(maxsize_O, PyExc_OverflowError);
1192        if (maxsize == -1 && PyErr_Occurred())
1193            return NULL;
1194        if (maxsize < 0) {
1195            maxsize = 0;
1196        }
1197        if (maxsize == 0)
1198            wrapper = uncached_lru_cache_wrapper;
1199        else
1200            wrapper = bounded_lru_cache_wrapper;
1201    } else {
1202        PyErr_SetString(PyExc_TypeError, "maxsize should be integer or None");
1203        return NULL;
1204    }
1205
1206    if (!(cachedict = PyDict_New()))
1207        return NULL;
1208
1209    obj = (lru_cache_object *)type->tp_alloc(type, 0);
1210    if (obj == NULL) {
1211        Py_DECREF(cachedict);
1212        return NULL;
1213    }
1214
1215    obj->root.prev = &obj->root;
1216    obj->root.next = &obj->root;
1217    obj->wrapper = wrapper;
1218    obj->typed = typed;
1219    obj->cache = cachedict;
1220    Py_INCREF(func);
1221    obj->func = func;
1222    obj->misses = obj->hits = 0;
1223    obj->maxsize = maxsize;
1224    Py_INCREF(state->kwd_mark);
1225    obj->kwd_mark = state->kwd_mark;
1226    Py_INCREF(state->lru_list_elem_type);
1227    obj->lru_list_elem_type = state->lru_list_elem_type;
1228    Py_INCREF(cache_info_type);
1229    obj->cache_info_type = cache_info_type;
1230    obj->dict = NULL;
1231    obj->weakreflist = NULL;
1232    return (PyObject *)obj;
1233}
1234
1235static lru_list_elem *
1236lru_cache_unlink_list(lru_cache_object *self)
1237{
1238    lru_list_elem *root = &self->root;
1239    lru_list_elem *link = root->next;
1240    if (link == root)
1241        return NULL;
1242    root->prev->next = NULL;
1243    root->next = root->prev = root;
1244    return link;
1245}
1246
1247static void
1248lru_cache_clear_list(lru_list_elem *link)
1249{
1250    while (link != NULL) {
1251        lru_list_elem *next = link->next;
1252        Py_DECREF(link);
1253        link = next;
1254    }
1255}
1256
1257static int
1258lru_cache_tp_clear(lru_cache_object *self)
1259{
1260    lru_list_elem *list = lru_cache_unlink_list(self);
1261    Py_CLEAR(self->cache);
1262    Py_CLEAR(self->func);
1263    Py_CLEAR(self->kwd_mark);
1264    Py_CLEAR(self->lru_list_elem_type);
1265    Py_CLEAR(self->cache_info_type);
1266    Py_CLEAR(self->dict);
1267    lru_cache_clear_list(list);
1268    return 0;
1269}
1270
1271static void
1272lru_cache_dealloc(lru_cache_object *obj)
1273{
1274    PyTypeObject *tp = Py_TYPE(obj);
1275    /* bpo-31095: UnTrack is needed before calling any callbacks */
1276    PyObject_GC_UnTrack(obj);
1277    if (obj->weakreflist != NULL) {
1278        PyObject_ClearWeakRefs((PyObject*)obj);
1279    }
1280
1281    (void)lru_cache_tp_clear(obj);
1282    tp->tp_free(obj);
1283    Py_DECREF(tp);
1284}
1285
1286static PyObject *
1287lru_cache_call(lru_cache_object *self, PyObject *args, PyObject *kwds)
1288{
1289    return self->wrapper(self, args, kwds);
1290}
1291
1292static PyObject *
1293lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1294{
1295    if (obj == Py_None || obj == NULL) {
1296        Py_INCREF(self);
1297        return self;
1298    }
1299    return PyMethod_New(self, obj);
1300}
1301
1302static PyObject *
1303lru_cache_cache_info(lru_cache_object *self, PyObject *unused)
1304{
1305    if (self->maxsize == -1) {
1306        return PyObject_CallFunction(self->cache_info_type, "nnOn",
1307                                     self->hits, self->misses, Py_None,
1308                                     PyDict_GET_SIZE(self->cache));
1309    }
1310    return PyObject_CallFunction(self->cache_info_type, "nnnn",
1311                                 self->hits, self->misses, self->maxsize,
1312                                 PyDict_GET_SIZE(self->cache));
1313}
1314
1315static PyObject *
1316lru_cache_cache_clear(lru_cache_object *self, PyObject *unused)
1317{
1318    lru_list_elem *list = lru_cache_unlink_list(self);
1319    self->hits = self->misses = 0;
1320    PyDict_Clear(self->cache);
1321    lru_cache_clear_list(list);
1322    Py_RETURN_NONE;
1323}
1324
1325static PyObject *
1326lru_cache_reduce(PyObject *self, PyObject *unused)
1327{
1328    return PyObject_GetAttrString(self, "__qualname__");
1329}
1330
1331static PyObject *
1332lru_cache_copy(PyObject *self, PyObject *unused)
1333{
1334    Py_INCREF(self);
1335    return self;
1336}
1337
1338static PyObject *
1339lru_cache_deepcopy(PyObject *self, PyObject *unused)
1340{
1341    Py_INCREF(self);
1342    return self;
1343}
1344
1345static int
1346lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
1347{
1348    Py_VISIT(Py_TYPE(self));
1349    lru_list_elem *link = self->root.next;
1350    while (link != &self->root) {
1351        lru_list_elem *next = link->next;
1352        Py_VISIT(link->key);
1353        Py_VISIT(link->result);
1354        Py_VISIT(Py_TYPE(link));
1355        link = next;
1356    }
1357    Py_VISIT(self->cache);
1358    Py_VISIT(self->func);
1359    Py_VISIT(self->kwd_mark);
1360    Py_VISIT(self->lru_list_elem_type);
1361    Py_VISIT(self->cache_info_type);
1362    Py_VISIT(self->dict);
1363    return 0;
1364}
1365
1366
1367PyDoc_STRVAR(lru_cache_doc,
1368"Create a cached callable that wraps another function.\n\
1369\n\
1370user_function:      the function being cached\n\
1371\n\
1372maxsize:  0         for no caching\n\
1373          None      for unlimited cache size\n\
1374          n         for a bounded cache\n\
1375\n\
1376typed:    False     cache f(3) and f(3.0) as identical calls\n\
1377          True      cache f(3) and f(3.0) as distinct calls\n\
1378\n\
1379cache_info_type:    namedtuple class with the fields:\n\
1380                        hits misses currsize maxsize\n"
1381);
1382
1383static PyMethodDef lru_cache_methods[] = {
1384    {"cache_info", (PyCFunction)lru_cache_cache_info, METH_NOARGS},
1385    {"cache_clear", (PyCFunction)lru_cache_cache_clear, METH_NOARGS},
1386    {"__reduce__", (PyCFunction)lru_cache_reduce, METH_NOARGS},
1387    {"__copy__", (PyCFunction)lru_cache_copy, METH_VARARGS},
1388    {"__deepcopy__", (PyCFunction)lru_cache_deepcopy, METH_VARARGS},
1389    {NULL}
1390};
1391
1392static PyGetSetDef lru_cache_getsetlist[] = {
1393    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
1394    {NULL}
1395};
1396
1397static PyMemberDef lru_cache_memberlist[] = {
1398    {"__dictoffset__", T_PYSSIZET,
1399     offsetof(lru_cache_object, dict), READONLY},
1400    {"__weaklistoffset__", T_PYSSIZET,
1401     offsetof(lru_cache_object, weakreflist), READONLY},
1402    {NULL}  /* Sentinel */
1403};
1404
1405static PyType_Slot lru_cache_type_slots[] = {
1406    {Py_tp_dealloc, lru_cache_dealloc},
1407    {Py_tp_call, lru_cache_call},
1408    {Py_tp_doc, (void *)lru_cache_doc},
1409    {Py_tp_traverse, lru_cache_tp_traverse},
1410    {Py_tp_clear, lru_cache_tp_clear},
1411    {Py_tp_methods, lru_cache_methods},
1412    {Py_tp_members, lru_cache_memberlist},
1413    {Py_tp_getset, lru_cache_getsetlist},
1414    {Py_tp_descr_get, lru_cache_descr_get},
1415    {Py_tp_new, lru_cache_new},
1416    {0, 0}
1417};
1418
1419static PyType_Spec lru_cache_type_spec = {
1420    .name = "functools._lru_cache_wrapper",
1421    .basicsize = sizeof(lru_cache_object),
1422    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1423             Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_IMMUTABLETYPE,
1424    .slots = lru_cache_type_slots
1425};
1426
1427
1428/* module level code ********************************************************/
1429
1430PyDoc_STRVAR(_functools_doc,
1431"Tools that operate on functions.");
1432
1433static PyMethodDef _functools_methods[] = {
1434    {"reduce",          functools_reduce,     METH_VARARGS, functools_reduce_doc},
1435    {"cmp_to_key",      _PyCFunction_CAST(functools_cmp_to_key),
1436     METH_VARARGS | METH_KEYWORDS, functools_cmp_to_key_doc},
1437    {NULL,              NULL}           /* sentinel */
1438};
1439
1440static int
1441_functools_exec(PyObject *module)
1442{
1443    _functools_state *state = get_functools_state(module);
1444    state->kwd_mark = _PyObject_CallNoArgs((PyObject *)&PyBaseObject_Type);
1445    if (state->kwd_mark == NULL) {
1446        return -1;
1447    }
1448
1449    state->partial_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
1450        &partial_type_spec, NULL);
1451    if (state->partial_type == NULL) {
1452        return -1;
1453    }
1454    if (PyModule_AddType(module, state->partial_type) < 0) {
1455        return -1;
1456    }
1457
1458    PyObject *lru_cache_type = PyType_FromModuleAndSpec(module,
1459        &lru_cache_type_spec, NULL);
1460    if (lru_cache_type == NULL) {
1461        return -1;
1462    }
1463    if (PyModule_AddType(module, (PyTypeObject *)lru_cache_type) < 0) {
1464        Py_DECREF(lru_cache_type);
1465        return -1;
1466    }
1467    Py_DECREF(lru_cache_type);
1468
1469    state->keyobject_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
1470        &keyobject_type_spec, NULL);
1471    if (state->keyobject_type == NULL) {
1472        return -1;
1473    }
1474    // keyobject_type is used only internally.
1475    // So we don't expose it in module namespace.
1476
1477    state->lru_list_elem_type = (PyTypeObject *)PyType_FromModuleAndSpec(
1478        module, &lru_list_elem_type_spec, NULL);
1479    if (state->lru_list_elem_type == NULL) {
1480        return -1;
1481    }
1482    // lru_list_elem is used only in _lru_cache_wrapper.
1483    // So we don't expose it in module namespace.
1484
1485    return 0;
1486}
1487
1488static int
1489_functools_traverse(PyObject *module, visitproc visit, void *arg)
1490{
1491    _functools_state *state = get_functools_state(module);
1492    Py_VISIT(state->kwd_mark);
1493    Py_VISIT(state->partial_type);
1494    Py_VISIT(state->keyobject_type);
1495    Py_VISIT(state->lru_list_elem_type);
1496    return 0;
1497}
1498
1499static int
1500_functools_clear(PyObject *module)
1501{
1502    _functools_state *state = get_functools_state(module);
1503    Py_CLEAR(state->kwd_mark);
1504    Py_CLEAR(state->partial_type);
1505    Py_CLEAR(state->keyobject_type);
1506    Py_CLEAR(state->lru_list_elem_type);
1507    return 0;
1508}
1509
1510static void
1511_functools_free(void *module)
1512{
1513    _functools_clear((PyObject *)module);
1514}
1515
1516static struct PyModuleDef_Slot _functools_slots[] = {
1517    {Py_mod_exec, _functools_exec},
1518    {0, NULL}
1519};
1520
1521static struct PyModuleDef _functools_module = {
1522    PyModuleDef_HEAD_INIT,
1523    .m_name = "_functools",
1524    .m_doc = _functools_doc,
1525    .m_size = sizeof(_functools_state),
1526    .m_methods = _functools_methods,
1527    .m_slots = _functools_slots,
1528    .m_traverse = _functools_traverse,
1529    .m_clear = _functools_clear,
1530    .m_free = _functools_free,
1531};
1532
1533PyMODINIT_FUNC
1534PyInit__functools(void)
1535{
1536    return PyModuleDef_Init(&_functools_module);
1537}
1538