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