blob: 88c02d82dca0a2b516cf8ce492fe1675bdbf3ed5 [file] [log] [blame]
Raymond Hettinger9c323f82005-02-28 19:39:44 +00001#include "Python.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01002#include "pycore_pymem.h"
3#include "pycore_pystate.h"
Victor Stinnerec13b932018-11-25 23:56:17 +01004#include "pycore_tupleobject.h"
Raymond Hettinger9c323f82005-02-28 19:39:44 +00005#include "structmember.h"
6
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00007/* _functools module written and maintained
Raymond Hettinger9c323f82005-02-28 19:39:44 +00008 by Hye-Shik Chang <perky@FreeBSD.org>
9 with adaptations by Raymond Hettinger <python@rcn.com>
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000010 Copyright (c) 2004, 2005, 2006 Python Software Foundation.
Raymond Hettinger9c323f82005-02-28 19:39:44 +000011 All rights reserved.
12*/
13
14/* partial object **********************************************************/
15
16typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000017 PyObject_HEAD
18 PyObject *fn;
19 PyObject *args;
20 PyObject *kw;
Jeroen Demeyered184c02019-07-13 16:39:18 +020021 PyObject *dict; /* __dict__ */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000022 PyObject *weakreflist; /* List of weak references */
Jeroen Demeyered184c02019-07-13 16:39:18 +020023 vectorcallfunc vectorcall;
Raymond Hettinger9c323f82005-02-28 19:39:44 +000024} partialobject;
25
26static PyTypeObject partial_type;
27
Jeroen Demeyered184c02019-07-13 16:39:18 +020028static void partial_setvectorcall(partialobject *pto);
29
Raymond Hettinger9c323f82005-02-28 19:39:44 +000030static PyObject *
31partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
32{
Alexander Belopolskye49af342015-03-01 15:08:17 -050033 PyObject *func, *pargs, *nargs, *pkw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000034 partialobject *pto;
Raymond Hettinger9c323f82005-02-28 19:39:44 +000035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000036 if (PyTuple_GET_SIZE(args) < 1) {
37 PyErr_SetString(PyExc_TypeError,
38 "type 'partial' takes at least one argument");
39 return NULL;
40 }
Raymond Hettinger9c323f82005-02-28 19:39:44 +000041
Serhiy Storchaka38741282016-02-02 18:45:17 +020042 pargs = pkw = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043 func = PyTuple_GET_ITEM(args, 0);
Alexander Belopolskye49af342015-03-01 15:08:17 -050044 if (Py_TYPE(func) == &partial_type && type == &partial_type) {
45 partialobject *part = (partialobject *)func;
46 if (part->dict == NULL) {
47 pargs = part->args;
48 pkw = part->kw;
49 func = part->fn;
Serhiy Storchaka38741282016-02-02 18:45:17 +020050 assert(PyTuple_Check(pargs));
51 assert(PyDict_Check(pkw));
Alexander Belopolskye49af342015-03-01 15:08:17 -050052 }
53 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000054 if (!PyCallable_Check(func)) {
55 PyErr_SetString(PyExc_TypeError,
56 "the first argument must be callable");
57 return NULL;
58 }
Raymond Hettinger9c323f82005-02-28 19:39:44 +000059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 /* create partialobject structure */
61 pto = (partialobject *)type->tp_alloc(type, 0);
62 if (pto == NULL)
63 return NULL;
Raymond Hettinger9c323f82005-02-28 19:39:44 +000064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 pto->fn = func;
66 Py_INCREF(func);
Alexander Belopolskye49af342015-03-01 15:08:17 -050067
68 nargs = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX);
69 if (nargs == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070 Py_DECREF(pto);
71 return NULL;
72 }
Serhiy Storchaka3c749fc2017-03-25 12:10:16 +020073 if (pargs == NULL) {
Alexander Belopolskye49af342015-03-01 15:08:17 -050074 pto->args = nargs;
Alexander Belopolskye49af342015-03-01 15:08:17 -050075 }
76 else {
77 pto->args = PySequence_Concat(pargs, nargs);
Serhiy Storchaka3c749fc2017-03-25 12:10:16 +020078 Py_DECREF(nargs);
Alexander Belopolskye49af342015-03-01 15:08:17 -050079 if (pto->args == NULL) {
Alexander Belopolskye49af342015-03-01 15:08:17 -050080 Py_DECREF(pto);
81 return NULL;
82 }
Serhiy Storchaka38741282016-02-02 18:45:17 +020083 assert(PyTuple_Check(pto->args));
Alexander Belopolskye49af342015-03-01 15:08:17 -050084 }
Alexander Belopolskye49af342015-03-01 15:08:17 -050085
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +020086 if (pkw == NULL || PyDict_GET_SIZE(pkw) == 0) {
Serhiy Storchaka38741282016-02-02 18:45:17 +020087 if (kw == NULL) {
88 pto->kw = PyDict_New();
Alexander Belopolskye49af342015-03-01 15:08:17 -050089 }
Serhiy Storchaka9639e4a2017-02-20 14:04:30 +020090 else if (Py_REFCNT(kw) == 1) {
Serhiy Storchaka38741282016-02-02 18:45:17 +020091 Py_INCREF(kw);
92 pto->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 }
Serhiy Storchaka9639e4a2017-02-20 14:04:30 +020094 else {
95 pto->kw = PyDict_Copy(kw);
96 }
Alexander Belopolskye49af342015-03-01 15:08:17 -050097 }
98 else {
Serhiy Storchaka38741282016-02-02 18:45:17 +020099 pto->kw = PyDict_Copy(pkw);
100 if (kw != NULL && pto->kw != NULL) {
101 if (PyDict_Merge(pto->kw, kw, 1) != 0) {
Benjamin Petersondae2ef12015-05-09 00:29:08 -0400102 Py_DECREF(pto);
103 return NULL;
104 }
105 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 }
Serhiy Storchaka38741282016-02-02 18:45:17 +0200107 if (pto->kw == NULL) {
108 Py_DECREF(pto);
109 return NULL;
110 }
Raymond Hettingerc8b6d1b2005-03-08 06:14:50 +0000111
Jeroen Demeyered184c02019-07-13 16:39:18 +0200112 partial_setvectorcall(pto);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 return (PyObject *)pto;
Raymond Hettinger9c323f82005-02-28 19:39:44 +0000114}
115
116static void
117partial_dealloc(partialobject *pto)
118{
INADA Naokia6296d32017-08-24 14:55:17 +0900119 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 PyObject_GC_UnTrack(pto);
121 if (pto->weakreflist != NULL)
122 PyObject_ClearWeakRefs((PyObject *) pto);
123 Py_XDECREF(pto->fn);
124 Py_XDECREF(pto->args);
125 Py_XDECREF(pto->kw);
126 Py_XDECREF(pto->dict);
127 Py_TYPE(pto)->tp_free(pto);
Raymond Hettinger9c323f82005-02-28 19:39:44 +0000128}
129
Jeroen Demeyered184c02019-07-13 16:39:18 +0200130
131/* Merging keyword arguments using the vectorcall convention is messy, so
132 * if we would need to do that, we stop using vectorcall and fall back
133 * to using partial_call() instead. */
134_Py_NO_INLINE static PyObject *
Victor Stinner7e433732019-11-08 10:05:17 +0100135partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto,
136 PyObject *const *args, size_t nargsf,
137 PyObject *kwnames)
Raymond Hettinger9c323f82005-02-28 19:39:44 +0000138{
Jeroen Demeyered184c02019-07-13 16:39:18 +0200139 pto->vectorcall = NULL;
140 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
Victor Stinner7e433732019-11-08 10:05:17 +0100141 return _PyObject_MakeTpCall(tstate, (PyObject *)pto,
142 args, nargs, kwnames);
Jeroen Demeyered184c02019-07-13 16:39:18 +0200143}
144
145static PyObject *
146partial_vectorcall(partialobject *pto, PyObject *const *args,
147 size_t nargsf, PyObject *kwnames)
148{
Victor Stinner7e433732019-11-08 10:05:17 +0100149 PyThreadState *tstate = _PyThreadState_GET();
150
Jeroen Demeyered184c02019-07-13 16:39:18 +0200151 /* pto->kw is mutable, so need to check every time */
152 if (PyDict_GET_SIZE(pto->kw)) {
Victor Stinner7e433732019-11-08 10:05:17 +0100153 return partial_vectorcall_fallback(tstate, pto, args, nargsf, kwnames);
Jeroen Demeyered184c02019-07-13 16:39:18 +0200154 }
155
156 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
157 Py_ssize_t nargs_total = nargs;
158 if (kwnames != NULL) {
159 nargs_total += PyTuple_GET_SIZE(kwnames);
160 }
161
162 PyObject **pto_args = _PyTuple_ITEMS(pto->args);
163 Py_ssize_t pto_nargs = PyTuple_GET_SIZE(pto->args);
164
165 /* Fast path if we're called without arguments */
166 if (nargs_total == 0) {
Victor Stinner7e433732019-11-08 10:05:17 +0100167 return _PyObject_VectorcallTstate(tstate, pto->fn,
168 pto_args, pto_nargs, NULL);
Jeroen Demeyered184c02019-07-13 16:39:18 +0200169 }
170
171 /* Fast path using PY_VECTORCALL_ARGUMENTS_OFFSET to prepend a single
172 * positional argument */
173 if (pto_nargs == 1 && (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET)) {
174 PyObject **newargs = (PyObject **)args - 1;
175 PyObject *tmp = newargs[0];
176 newargs[0] = pto_args[0];
Victor Stinner7e433732019-11-08 10:05:17 +0100177 PyObject *ret = _PyObject_VectorcallTstate(tstate, pto->fn,
178 newargs, nargs + 1, kwnames);
Jeroen Demeyered184c02019-07-13 16:39:18 +0200179 newargs[0] = tmp;
180 return ret;
181 }
182
183 Py_ssize_t newnargs_total = pto_nargs + nargs_total;
184
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100185 PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 PyObject *ret;
Jeroen Demeyered184c02019-07-13 16:39:18 +0200187 PyObject **stack;
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100188
Jeroen Demeyered184c02019-07-13 16:39:18 +0200189 if (newnargs_total <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
190 stack = small_stack;
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100191 }
192 else {
Jeroen Demeyered184c02019-07-13 16:39:18 +0200193 stack = PyMem_Malloc(newnargs_total * sizeof(PyObject *));
194 if (stack == NULL) {
195 PyErr_NoMemory();
196 return NULL;
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100197 }
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100198 }
199
Jeroen Demeyered184c02019-07-13 16:39:18 +0200200 /* Copy to new stack, using borrowed references */
201 memcpy(stack, pto_args, pto_nargs * sizeof(PyObject*));
202 memcpy(stack + pto_nargs, args, nargs_total * sizeof(PyObject*));
203
Victor Stinner7e433732019-11-08 10:05:17 +0100204 ret = _PyObject_VectorcallTstate(tstate, pto->fn,
205 stack, pto_nargs + nargs, kwnames);
Jeroen Demeyered184c02019-07-13 16:39:18 +0200206 if (stack != small_stack) {
207 PyMem_Free(stack);
208 }
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100209 return ret;
210}
211
Jeroen Demeyered184c02019-07-13 16:39:18 +0200212/* Set pto->vectorcall depending on the parameters of the partial object */
213static void
214partial_setvectorcall(partialobject *pto)
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100215{
Petr Viktorinffd97532020-02-11 17:46:57 +0100216 if (PyVectorcall_Function(pto->fn) == NULL) {
Jeroen Demeyered184c02019-07-13 16:39:18 +0200217 /* Don't use vectorcall if the underlying function doesn't support it */
218 pto->vectorcall = NULL;
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100219 }
Jeroen Demeyered184c02019-07-13 16:39:18 +0200220 /* We could have a special case if there are no arguments,
221 * but that is unlikely (why use partial without arguments?),
222 * so we don't optimize that */
223 else {
224 pto->vectorcall = (vectorcallfunc)partial_vectorcall;
225 }
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100226}
227
Jeroen Demeyered184c02019-07-13 16:39:18 +0200228
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100229static PyObject *
230partial_call(partialobject *pto, PyObject *args, PyObject *kwargs)
231{
Jeroen Demeyered184c02019-07-13 16:39:18 +0200232 assert(PyCallable_Check(pto->fn));
233 assert(PyTuple_Check(pto->args));
234 assert(PyDict_Check(pto->kw));
Raymond Hettinger9c323f82005-02-28 19:39:44 +0000235
Jeroen Demeyered184c02019-07-13 16:39:18 +0200236 /* Merge keywords */
237 PyObject *kwargs2;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200238 if (PyDict_GET_SIZE(pto->kw) == 0) {
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100239 /* kwargs can be NULL */
240 kwargs2 = kwargs;
241 Py_XINCREF(kwargs2);
Victor Stinnerf4d28d42016-08-23 16:22:35 +0200242 }
243 else {
Victor Stinner561ca802017-02-23 18:26:43 +0100244 /* bpo-27840, bpo-29318: dictionary of keyword parameters must be
245 copied, because a function using "**kwargs" can modify the
246 dictionary. */
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100247 kwargs2 = PyDict_Copy(pto->kw);
248 if (kwargs2 == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 return NULL;
250 }
Victor Stinnerf4d28d42016-08-23 16:22:35 +0200251
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100252 if (kwargs != NULL) {
253 if (PyDict_Merge(kwargs2, kwargs, 1) != 0) {
254 Py_DECREF(kwargs2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 return NULL;
256 }
257 }
258 }
Raymond Hettinger9c323f82005-02-28 19:39:44 +0000259
Jeroen Demeyered184c02019-07-13 16:39:18 +0200260 /* Merge positional arguments */
261 /* Note: tupleconcat() is optimized for empty tuples */
262 PyObject *args2 = PySequence_Concat(pto->args, args);
263 if (args2 == NULL) {
264 Py_XDECREF(kwargs2);
265 return NULL;
266 }
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100267
Jeroen Demeyered184c02019-07-13 16:39:18 +0200268 PyObject *res = PyObject_Call(pto->fn, args2, kwargs2);
269 Py_DECREF(args2);
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100270 Py_XDECREF(kwargs2);
271 return res;
Raymond Hettinger9c323f82005-02-28 19:39:44 +0000272}
273
274static int
275partial_traverse(partialobject *pto, visitproc visit, void *arg)
276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 Py_VISIT(pto->fn);
278 Py_VISIT(pto->args);
279 Py_VISIT(pto->kw);
280 Py_VISIT(pto->dict);
281 return 0;
Raymond Hettinger9c323f82005-02-28 19:39:44 +0000282}
283
284PyDoc_STRVAR(partial_doc,
285"partial(func, *args, **keywords) - new function with partial application\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 of the given arguments and keywords.\n");
Raymond Hettinger9c323f82005-02-28 19:39:44 +0000287
288#define OFF(x) offsetof(partialobject, x)
289static PyMemberDef partial_memberlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 {"func", T_OBJECT, OFF(fn), READONLY,
291 "function object to use in future partial calls"},
292 {"args", T_OBJECT, OFF(args), READONLY,
293 "tuple of arguments to future partial calls"},
294 {"keywords", T_OBJECT, OFF(kw), READONLY,
295 "dictionary of keyword arguments to future partial calls"},
296 {NULL} /* Sentinel */
Raymond Hettinger9c323f82005-02-28 19:39:44 +0000297};
298
Georg Brandlc2fb6c72006-02-21 17:49:57 +0000299static PyGetSetDef partial_getsetlist[] = {
Benjamin Peterson23d7f122012-02-19 20:02:57 -0500300 {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 {NULL} /* Sentinel */
Raymond Hettingerc8b6d1b2005-03-08 06:14:50 +0000302};
303
Alexander Belopolsky41e422a2010-12-01 20:05:49 +0000304static PyObject *
305partial_repr(partialobject *pto)
306{
Serhiy Storchaka179f9602016-06-12 11:44:06 +0300307 PyObject *result = NULL;
Alexander Belopolsky41e422a2010-12-01 20:05:49 +0000308 PyObject *arglist;
Alexander Belopolsky41e422a2010-12-01 20:05:49 +0000309 Py_ssize_t i, n;
Serhiy Storchaka38741282016-02-02 18:45:17 +0200310 PyObject *key, *value;
Serhiy Storchaka179f9602016-06-12 11:44:06 +0300311 int status;
312
313 status = Py_ReprEnter((PyObject *)pto);
314 if (status != 0) {
315 if (status < 0)
316 return NULL;
Nick Coghlan457fc9a2016-09-10 20:00:02 +1000317 return PyUnicode_FromString("...");
Serhiy Storchaka179f9602016-06-12 11:44:06 +0300318 }
Alexander Belopolsky41e422a2010-12-01 20:05:49 +0000319
320 arglist = PyUnicode_FromString("");
Serhiy Storchaka179f9602016-06-12 11:44:06 +0300321 if (arglist == NULL)
322 goto done;
Alexander Belopolsky41e422a2010-12-01 20:05:49 +0000323 /* Pack positional arguments */
324 assert (PyTuple_Check(pto->args));
325 n = PyTuple_GET_SIZE(pto->args);
326 for (i = 0; i < n; i++) {
Serhiy Storchaka179f9602016-06-12 11:44:06 +0300327 Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist,
328 PyTuple_GET_ITEM(pto->args, i)));
329 if (arglist == NULL)
330 goto done;
Alexander Belopolsky41e422a2010-12-01 20:05:49 +0000331 }
332 /* Pack keyword arguments */
Serhiy Storchaka38741282016-02-02 18:45:17 +0200333 assert (PyDict_Check(pto->kw));
334 for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) {
Michael Seifert6c3d5272017-03-15 06:26:33 +0100335 /* Prevent key.__str__ from deleting the value. */
336 Py_INCREF(value);
337 Py_SETREF(arglist, PyUnicode_FromFormat("%U, %S=%R", arglist,
Serhiy Storchaka179f9602016-06-12 11:44:06 +0300338 key, value));
Michael Seifert6c3d5272017-03-15 06:26:33 +0100339 Py_DECREF(value);
Serhiy Storchaka179f9602016-06-12 11:44:06 +0300340 if (arglist == NULL)
341 goto done;
Alexander Belopolsky41e422a2010-12-01 20:05:49 +0000342 }
343 result = PyUnicode_FromFormat("%s(%R%U)", Py_TYPE(pto)->tp_name,
344 pto->fn, arglist);
345 Py_DECREF(arglist);
Serhiy Storchaka179f9602016-06-12 11:44:06 +0300346
347 done:
348 Py_ReprLeave((PyObject *)pto);
Alexander Belopolsky41e422a2010-12-01 20:05:49 +0000349 return result;
350}
351
Jack Diederiche0cbd692009-04-01 04:27:09 +0000352/* Pickle strategy:
353 __reduce__ by itself doesn't support getting kwargs in the unpickle
354 operation so we define a __setstate__ that replaces all the information
355 about the partial. If we only replaced part of it someone would use
Ezio Melotti13925002011-03-16 11:05:33 +0200356 it as a hook to do strange things.
Jack Diederiche0cbd692009-04-01 04:27:09 +0000357 */
358
Antoine Pitrou69f71142009-05-24 21:25:49 +0000359static PyObject *
Jack Diederiche0cbd692009-04-01 04:27:09 +0000360partial_reduce(partialobject *pto, PyObject *unused)
361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 return Py_BuildValue("O(O)(OOOO)", Py_TYPE(pto), pto->fn, pto->fn,
363 pto->args, pto->kw,
364 pto->dict ? pto->dict : Py_None);
Jack Diederiche0cbd692009-04-01 04:27:09 +0000365}
366
Antoine Pitrou69f71142009-05-24 21:25:49 +0000367static PyObject *
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +0200368partial_setstate(partialobject *pto, PyObject *state)
Jack Diederiche0cbd692009-04-01 04:27:09 +0000369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 PyObject *fn, *fnargs, *kw, *dict;
Serhiy Storchaka38741282016-02-02 18:45:17 +0200371
372 if (!PyTuple_Check(state) ||
373 !PyArg_ParseTuple(state, "OOOO", &fn, &fnargs, &kw, &dict) ||
374 !PyCallable_Check(fn) ||
375 !PyTuple_Check(fnargs) ||
376 (kw != Py_None && !PyDict_Check(kw)))
377 {
378 PyErr_SetString(PyExc_TypeError, "invalid partial state");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 }
Serhiy Storchaka38741282016-02-02 18:45:17 +0200381
382 if(!PyTuple_CheckExact(fnargs))
383 fnargs = PySequence_Tuple(fnargs);
384 else
385 Py_INCREF(fnargs);
386 if (fnargs == NULL)
387 return NULL;
388
389 if (kw == Py_None)
390 kw = PyDict_New();
391 else if(!PyDict_CheckExact(kw))
392 kw = PyDict_Copy(kw);
393 else
394 Py_INCREF(kw);
395 if (kw == NULL) {
396 Py_DECREF(fnargs);
397 return NULL;
398 }
399
Serhiy Storchaka38741282016-02-02 18:45:17 +0200400 if (dict == Py_None)
401 dict = NULL;
402 else
403 Py_INCREF(dict);
404
Victor Stinner0f7b0b32017-03-14 21:37:20 +0100405 Py_INCREF(fn);
Serhiy Storchaka864b63c2016-04-11 09:53:37 +0300406 Py_SETREF(pto->fn, fn);
407 Py_SETREF(pto->args, fnargs);
408 Py_SETREF(pto->kw, kw);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300409 Py_XSETREF(pto->dict, dict);
Jeroen Demeyered184c02019-07-13 16:39:18 +0200410 partial_setvectorcall(pto);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 Py_RETURN_NONE;
Jack Diederiche0cbd692009-04-01 04:27:09 +0000412}
413
414static PyMethodDef partial_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 {"__reduce__", (PyCFunction)partial_reduce, METH_NOARGS},
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +0200416 {"__setstate__", (PyCFunction)partial_setstate, METH_O},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 {NULL, NULL} /* sentinel */
Jack Diederiche0cbd692009-04-01 04:27:09 +0000418};
419
Raymond Hettinger9c323f82005-02-28 19:39:44 +0000420static PyTypeObject partial_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 PyVarObject_HEAD_INIT(NULL, 0)
422 "functools.partial", /* tp_name */
423 sizeof(partialobject), /* tp_basicsize */
424 0, /* tp_itemsize */
425 /* methods */
426 (destructor)partial_dealloc, /* tp_dealloc */
Jeroen Demeyered184c02019-07-13 16:39:18 +0200427 offsetof(partialobject, vectorcall),/* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 0, /* tp_getattr */
429 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200430 0, /* tp_as_async */
Alexander Belopolsky41e422a2010-12-01 20:05:49 +0000431 (reprfunc)partial_repr, /* tp_repr */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 0, /* tp_as_number */
433 0, /* tp_as_sequence */
434 0, /* tp_as_mapping */
435 0, /* tp_hash */
436 (ternaryfunc)partial_call, /* tp_call */
437 0, /* tp_str */
438 PyObject_GenericGetAttr, /* tp_getattro */
439 PyObject_GenericSetAttr, /* tp_setattro */
440 0, /* tp_as_buffer */
441 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Jeroen Demeyered184c02019-07-13 16:39:18 +0200442 Py_TPFLAGS_BASETYPE |
Petr Viktorinffd97532020-02-11 17:46:57 +0100443 Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 partial_doc, /* tp_doc */
445 (traverseproc)partial_traverse, /* tp_traverse */
446 0, /* tp_clear */
447 0, /* tp_richcompare */
448 offsetof(partialobject, weakreflist), /* tp_weaklistoffset */
449 0, /* tp_iter */
450 0, /* tp_iternext */
451 partial_methods, /* tp_methods */
452 partial_memberlist, /* tp_members */
453 partial_getsetlist, /* tp_getset */
454 0, /* tp_base */
455 0, /* tp_dict */
456 0, /* tp_descr_get */
457 0, /* tp_descr_set */
458 offsetof(partialobject, dict), /* tp_dictoffset */
459 0, /* tp_init */
460 0, /* tp_alloc */
461 partial_new, /* tp_new */
462 PyObject_GC_Del, /* tp_free */
Raymond Hettinger9c323f82005-02-28 19:39:44 +0000463};
464
465
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700466/* cmp_to_key ***************************************************************/
467
468typedef struct {
Victor Stinner446c8d52011-04-05 12:21:35 +0200469 PyObject_HEAD
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700470 PyObject *cmp;
471 PyObject *object;
472} keyobject;
473
474static void
475keyobject_dealloc(keyobject *ko)
476{
477 Py_DECREF(ko->cmp);
478 Py_XDECREF(ko->object);
479 PyObject_FREE(ko);
480}
481
482static int
483keyobject_traverse(keyobject *ko, visitproc visit, void *arg)
484{
485 Py_VISIT(ko->cmp);
486 if (ko->object)
487 Py_VISIT(ko->object);
488 return 0;
489}
490
Benjamin Peterson3bd97292011-04-05 17:25:14 -0500491static int
492keyobject_clear(keyobject *ko)
493{
494 Py_CLEAR(ko->cmp);
495 if (ko->object)
496 Py_CLEAR(ko->object);
497 return 0;
498}
499
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700500static PyMemberDef keyobject_members[] = {
501 {"obj", T_OBJECT,
502 offsetof(keyobject, object), 0,
503 PyDoc_STR("Value wrapped by a key function.")},
504 {NULL}
505};
506
507static PyObject *
Raymond Hettingera5632862011-04-09 12:57:00 -0700508keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds);
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700509
510static PyObject *
511keyobject_richcompare(PyObject *ko, PyObject *other, int op);
512
513static PyTypeObject keyobject_type = {
514 PyVarObject_HEAD_INIT(&PyType_Type, 0)
515 "functools.KeyWrapper", /* tp_name */
516 sizeof(keyobject), /* tp_basicsize */
517 0, /* tp_itemsize */
518 /* methods */
519 (destructor)keyobject_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200520 0, /* tp_vectorcall_offset */
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700521 0, /* tp_getattr */
522 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200523 0, /* tp_as_async */
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700524 0, /* tp_repr */
525 0, /* tp_as_number */
526 0, /* tp_as_sequence */
527 0, /* tp_as_mapping */
528 0, /* tp_hash */
529 (ternaryfunc)keyobject_call, /* tp_call */
530 0, /* tp_str */
531 PyObject_GenericGetAttr, /* tp_getattro */
532 0, /* tp_setattro */
533 0, /* tp_as_buffer */
534 Py_TPFLAGS_DEFAULT, /* tp_flags */
535 0, /* tp_doc */
536 (traverseproc)keyobject_traverse, /* tp_traverse */
Benjamin Peterson3bd97292011-04-05 17:25:14 -0500537 (inquiry)keyobject_clear, /* tp_clear */
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700538 keyobject_richcompare, /* tp_richcompare */
539 0, /* tp_weaklistoffset */
540 0, /* tp_iter */
541 0, /* tp_iternext */
542 0, /* tp_methods */
543 keyobject_members, /* tp_members */
544 0, /* tp_getset */
545};
546
547static PyObject *
548keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds)
549{
550 PyObject *object;
551 keyobject *result;
552 static char *kwargs[] = {"obj", NULL};
553
554 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:K", kwargs, &object))
555 return NULL;
556 result = PyObject_New(keyobject, &keyobject_type);
557 if (!result)
558 return NULL;
559 Py_INCREF(ko->cmp);
560 result->cmp = ko->cmp;
561 Py_INCREF(object);
562 result->object = object;
563 return (PyObject *)result;
564}
565
566static PyObject *
567keyobject_richcompare(PyObject *ko, PyObject *other, int op)
568{
569 PyObject *res;
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700570 PyObject *x;
571 PyObject *y;
572 PyObject *compare;
573 PyObject *answer;
Victor Stinnerf7a4c482016-08-19 18:52:35 +0200574 PyObject* stack[2];
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700575
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700576 if (Py_TYPE(other) != &keyobject_type){
577 PyErr_Format(PyExc_TypeError, "other argument must be K instance");
578 return NULL;
579 }
580 compare = ((keyobject *) ko)->cmp;
581 assert(compare != NULL);
582 x = ((keyobject *) ko)->object;
583 y = ((keyobject *) other)->object;
584 if (!x || !y){
585 PyErr_Format(PyExc_AttributeError, "object");
586 return NULL;
587 }
588
589 /* Call the user's comparison function and translate the 3-way
590 * result into true or false (or error).
591 */
Victor Stinnerf7a4c482016-08-19 18:52:35 +0200592 stack[0] = x;
593 stack[1] = y;
Victor Stinner559bb6a2016-08-22 22:48:54 +0200594 res = _PyObject_FastCall(compare, stack, 2);
Victor Stinnerf7a4c482016-08-19 18:52:35 +0200595 if (res == NULL) {
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700596 return NULL;
Victor Stinnerf7a4c482016-08-19 18:52:35 +0200597 }
598
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300599 answer = PyObject_RichCompare(res, _PyLong_Zero, op);
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700600 Py_DECREF(res);
601 return answer;
602}
603
604static PyObject *
Victor Stinner446c8d52011-04-05 12:21:35 +0200605functools_cmp_to_key(PyObject *self, PyObject *args, PyObject *kwds)
606{
607 PyObject *cmp;
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700608 static char *kwargs[] = {"mycmp", NULL};
Victor Stinner446c8d52011-04-05 12:21:35 +0200609 keyobject *object;
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700610
611 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:cmp_to_key", kwargs, &cmp))
612 return NULL;
Victor Stinner446c8d52011-04-05 12:21:35 +0200613 object = PyObject_New(keyobject, &keyobject_type);
Raymond Hettinger7ab9e222011-04-05 02:33:54 -0700614 if (!object)
615 return NULL;
616 Py_INCREF(cmp);
617 object->cmp = cmp;
618 object->object = NULL;
619 return (PyObject *)object;
620}
621
622PyDoc_STRVAR(functools_cmp_to_key_doc,
623"Convert a cmp= function into a key= function.");
624
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000625/* reduce (used to be a builtin) ********************************************/
626
627static PyObject *
628functools_reduce(PyObject *self, PyObject *args)
629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 PyObject *seq, *func, *result = NULL, *it;
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result))
633 return NULL;
634 if (result != NULL)
635 Py_INCREF(result);
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 it = PyObject_GetIter(seq);
638 if (it == NULL) {
Alexander Belopolskye29e6bf2010-08-16 18:55:46 +0000639 if (PyErr_ExceptionMatches(PyExc_TypeError))
640 PyErr_SetString(PyExc_TypeError,
641 "reduce() arg 2 must support iteration");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 Py_XDECREF(result);
643 return NULL;
644 }
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000646 if ((args = PyTuple_New(2)) == NULL)
647 goto Fail;
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000649 for (;;) {
650 PyObject *op2;
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000651
Victor Stinnera93c51e2020-02-07 00:38:59 +0100652 if (Py_REFCNT(args) > 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000653 Py_DECREF(args);
654 if ((args = PyTuple_New(2)) == NULL)
655 goto Fail;
656 }
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 op2 = PyIter_Next(it);
659 if (op2 == NULL) {
660 if (PyErr_Occurred())
661 goto Fail;
662 break;
663 }
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 if (result == NULL)
666 result = op2;
667 else {
Sergey Fedoseeve5f62072019-06-02 01:32:18 +0500668 /* Update the args tuple in-place */
Victor Stinnera93c51e2020-02-07 00:38:59 +0100669 assert(Py_REFCNT(args) == 1);
Sergey Fedoseeve5f62072019-06-02 01:32:18 +0500670 Py_XSETREF(_PyTuple_ITEMS(args)[0], result);
671 Py_XSETREF(_PyTuple_ITEMS(args)[1], op2);
672 if ((result = PyObject_Call(func, args, NULL)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 goto Fail;
Sergey Fedoseeve5f62072019-06-02 01:32:18 +0500674 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 }
676 }
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 Py_DECREF(args);
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 if (result == NULL)
681 PyErr_SetString(PyExc_TypeError,
682 "reduce() of empty sequence with no initial value");
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000684 Py_DECREF(it);
685 return result;
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000686
687Fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 Py_XDECREF(args);
689 Py_XDECREF(result);
690 Py_DECREF(it);
691 return NULL;
Guido van Rossum0919a1a2006-08-26 20:49:04 +0000692}
693
694PyDoc_STRVAR(functools_reduce_doc,
695"reduce(function, sequence[, initial]) -> value\n\
696\n\
697Apply a function of two arguments cumulatively to the items of a sequence,\n\
698from left to right, so as to reduce the sequence to a single value.\n\
699For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\
700((((1+2)+3)+4)+5). If initial is present, it is placed before the items\n\
701of the sequence in the calculation, and serves as a default when the\n\
702sequence is empty.");
703
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300704/* lru_cache object **********************************************************/
705
Raymond Hettinger2dda72a2019-02-08 18:55:02 -0800706/* There are four principal algorithmic differences from the pure python version:
707
708 1). The C version relies on the GIL instead of having its own reentrant lock.
709
710 2). The prev/next link fields use borrowed references.
711
712 3). For a full cache, the pure python version rotates the location of the
713 root entry so that it never has to move individual links and it can
714 limit updates to just the key and result fields. However, in the C
715 version, links are temporarily removed while the cache dict updates are
716 occurring. Afterwards, they are appended or prepended back into the
717 doubly-linked lists.
718
719 4) In the Python version, the _HashSeq class is used to prevent __hash__
720 from being called more than once. In the C version, the "known hash"
721 variants of dictionary calls as used to the same effect.
722
723*/
724
725
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300726/* this object is used delimit args and keywords in the cache keys */
727static PyObject *kwd_mark = NULL;
728
729struct lru_list_elem;
730struct lru_cache_object;
731
732typedef struct lru_list_elem {
733 PyObject_HEAD
734 struct lru_list_elem *prev, *next; /* borrowed links */
Serhiy Storchakab9d98d52015-10-02 12:47:11 +0300735 Py_hash_t hash;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300736 PyObject *key, *result;
737} lru_list_elem;
738
739static void
740lru_list_elem_dealloc(lru_list_elem *link)
741{
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300742 Py_XDECREF(link->key);
743 Py_XDECREF(link->result);
INADA Naoki3070b712017-12-26 02:03:24 +0900744 PyObject_Del(link);
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300745}
746
747static PyTypeObject lru_list_elem_type = {
748 PyVarObject_HEAD_INIT(&PyType_Type, 0)
749 "functools._lru_list_elem", /* tp_name */
750 sizeof(lru_list_elem), /* tp_basicsize */
751 0, /* tp_itemsize */
752 /* methods */
753 (destructor)lru_list_elem_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200754 0, /* tp_vectorcall_offset */
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300755 0, /* tp_getattr */
756 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200757 0, /* tp_as_async */
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300758 0, /* tp_repr */
759 0, /* tp_as_number */
760 0, /* tp_as_sequence */
761 0, /* tp_as_mapping */
762 0, /* tp_hash */
763 0, /* tp_call */
764 0, /* tp_str */
765 0, /* tp_getattro */
766 0, /* tp_setattro */
767 0, /* tp_as_buffer */
INADA Naoki3070b712017-12-26 02:03:24 +0900768 Py_TPFLAGS_DEFAULT, /* tp_flags */
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300769};
770
771
772typedef PyObject *(*lru_cache_ternaryfunc)(struct lru_cache_object *, PyObject *, PyObject *);
773
774typedef struct lru_cache_object {
775 lru_list_elem root; /* includes PyObject_HEAD */
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300776 lru_cache_ternaryfunc wrapper;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300777 int typed;
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500778 PyObject *cache;
779 Py_ssize_t hits;
780 PyObject *func;
781 Py_ssize_t maxsize;
782 Py_ssize_t misses;
783 PyObject *cache_info_type;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300784 PyObject *dict;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300785} lru_cache_object;
786
787static PyTypeObject lru_cache_type;
788
789static PyObject *
790lru_cache_make_key(PyObject *args, PyObject *kwds, int typed)
791{
Raymond Hettingerdda44682017-01-08 18:04:30 -0800792 PyObject *key, *keyword, *value;
793 Py_ssize_t key_size, pos, key_pos, kwds_size;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300794
Raymond Hettinger14adbd42019-04-20 07:20:44 -1000795 kwds_size = kwds ? PyDict_GET_SIZE(kwds) : 0;
796
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300797 /* short path, key will match args anyway, which is a tuple */
Raymond Hettinger14adbd42019-04-20 07:20:44 -1000798 if (!typed && !kwds_size) {
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500799 if (PyTuple_GET_SIZE(args) == 1) {
800 key = PyTuple_GET_ITEM(args, 0);
801 if (PyUnicode_CheckExact(key) || PyLong_CheckExact(key)) {
802 /* For common scalar keys, save space by
803 dropping the enclosing args tuple */
804 Py_INCREF(key);
805 return key;
806 }
807 }
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300808 Py_INCREF(args);
809 return args;
810 }
811
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300812 key_size = PyTuple_GET_SIZE(args);
Raymond Hettingerdda44682017-01-08 18:04:30 -0800813 if (kwds_size)
814 key_size += kwds_size * 2 + 1;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300815 if (typed)
Raymond Hettingerdda44682017-01-08 18:04:30 -0800816 key_size += PyTuple_GET_SIZE(args) + kwds_size;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300817
818 key = PyTuple_New(key_size);
819 if (key == NULL)
Raymond Hettingerdda44682017-01-08 18:04:30 -0800820 return NULL;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300821
822 key_pos = 0;
823 for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) {
824 PyObject *item = PyTuple_GET_ITEM(args, pos);
825 Py_INCREF(item);
826 PyTuple_SET_ITEM(key, key_pos++, item);
827 }
Raymond Hettingerdda44682017-01-08 18:04:30 -0800828 if (kwds_size) {
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300829 Py_INCREF(kwd_mark);
830 PyTuple_SET_ITEM(key, key_pos++, kwd_mark);
Raymond Hettingerdda44682017-01-08 18:04:30 -0800831 for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) {
832 Py_INCREF(keyword);
833 PyTuple_SET_ITEM(key, key_pos++, keyword);
834 Py_INCREF(value);
835 PyTuple_SET_ITEM(key, key_pos++, value);
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300836 }
Raymond Hettingerdda44682017-01-08 18:04:30 -0800837 assert(key_pos == PyTuple_GET_SIZE(args) + kwds_size * 2 + 1);
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300838 }
839 if (typed) {
840 for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) {
841 PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(args, pos));
842 Py_INCREF(item);
843 PyTuple_SET_ITEM(key, key_pos++, item);
844 }
Raymond Hettingerdda44682017-01-08 18:04:30 -0800845 if (kwds_size) {
846 for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) {
847 PyObject *item = (PyObject *)Py_TYPE(value);
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300848 Py_INCREF(item);
849 PyTuple_SET_ITEM(key, key_pos++, item);
850 }
851 }
852 }
853 assert(key_pos == key_size);
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300854 return key;
855}
856
857static PyObject *
858uncached_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
859{
Raymond Hettingerffdf1c32019-01-31 15:03:38 -0800860 PyObject *result;
861
862 self->misses++;
863 result = PyObject_Call(self->func, args, kwds);
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300864 if (!result)
865 return NULL;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300866 return result;
867}
868
869static PyObject *
870infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
871{
872 PyObject *result;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +0300873 Py_hash_t hash;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300874 PyObject *key = lru_cache_make_key(args, kwds, self->typed);
875 if (!key)
876 return NULL;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +0300877 hash = PyObject_Hash(key);
Yury Selivanov46a02db2016-11-09 18:55:45 -0500878 if (hash == -1) {
879 Py_DECREF(key);
Serhiy Storchakab9d98d52015-10-02 12:47:11 +0300880 return NULL;
Yury Selivanov46a02db2016-11-09 18:55:45 -0500881 }
Serhiy Storchakab9d98d52015-10-02 12:47:11 +0300882 result = _PyDict_GetItem_KnownHash(self->cache, key, hash);
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300883 if (result) {
884 Py_INCREF(result);
885 self->hits++;
886 Py_DECREF(key);
887 return result;
888 }
889 if (PyErr_Occurred()) {
890 Py_DECREF(key);
891 return NULL;
892 }
Raymond Hettingerffdf1c32019-01-31 15:03:38 -0800893 self->misses++;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300894 result = PyObject_Call(self->func, args, kwds);
895 if (!result) {
896 Py_DECREF(key);
897 return NULL;
898 }
Serhiy Storchakab9d98d52015-10-02 12:47:11 +0300899 if (_PyDict_SetItem_KnownHash(self->cache, key, result, hash) < 0) {
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300900 Py_DECREF(result);
901 Py_DECREF(key);
902 return NULL;
903 }
904 Py_DECREF(key);
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300905 return result;
906}
907
908static void
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500909lru_cache_extract_link(lru_list_elem *link)
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300910{
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500911 lru_list_elem *link_prev = link->prev;
912 lru_list_elem *link_next = link->next;
913 link_prev->next = link->next;
914 link_next->prev = link->prev;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300915}
916
917static void
918lru_cache_append_link(lru_cache_object *self, lru_list_elem *link)
919{
920 lru_list_elem *root = &self->root;
921 lru_list_elem *last = root->prev;
922 last->next = root->prev = link;
923 link->prev = last;
924 link->next = root;
925}
926
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500927static void
928lru_cache_prepend_link(lru_cache_object *self, lru_list_elem *link)
929{
930 lru_list_elem *root = &self->root;
931 lru_list_elem *first = root->next;
932 first->prev = root->next = link;
933 link->prev = root;
934 link->next = first;
935}
936
937/* General note on reentrancy:
938
939 There are four dictionary calls in the bounded_lru_cache_wrapper():
940 1) The initial check for a cache match. 2) The post user-function
941 check for a cache match. 3) The deletion of the oldest entry.
942 4) The addition of the newest entry.
943
944 In all four calls, we have a known hash which lets use avoid a call
945 to __hash__(). That leaves only __eq__ as a possible source of a
946 reentrant call.
947
948 The __eq__ method call is always made for a cache hit (dict access #1).
949 Accordingly, we have make sure not modify the cache state prior to
950 this call.
951
952 The __eq__ method call is never made for the deletion (dict access #3)
953 because it is an identity match.
954
955 For the other two accesses (#2 and #4), calls to __eq__ only occur
956 when some other entry happens to have an exactly matching hash (all
957 64-bits). Though rare, this can happen, so we have to make sure to
958 either call it at the top of its code path before any cache
959 state modifications (dict access #2) or be prepared to restore
960 invariants at the end of the code path (dict access #4).
961
962 Another possible source of reentrancy is a decref which can trigger
963 arbitrary code execution. To make the code easier to reason about,
964 the decrefs are deferred to the end of the each possible code path
965 so that we know the cache is a consistent state.
966 */
967
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300968static PyObject *
969bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
970{
971 lru_list_elem *link;
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500972 PyObject *key, *result, *testresult;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +0300973 Py_hash_t hash;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300974
975 key = lru_cache_make_key(args, kwds, self->typed);
976 if (!key)
977 return NULL;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +0300978 hash = PyObject_Hash(key);
Yury Selivanov46a02db2016-11-09 18:55:45 -0500979 if (hash == -1) {
980 Py_DECREF(key);
Serhiy Storchakab9d98d52015-10-02 12:47:11 +0300981 return NULL;
Yury Selivanov46a02db2016-11-09 18:55:45 -0500982 }
Serhiy Storchakab9d98d52015-10-02 12:47:11 +0300983 link = (lru_list_elem *)_PyDict_GetItem_KnownHash(self->cache, key, hash);
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500984 if (link != NULL) {
985 lru_cache_extract_link(link);
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300986 lru_cache_append_link(self, link);
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300987 result = link->result;
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500988 self->hits++;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300989 Py_INCREF(result);
990 Py_DECREF(key);
991 return result;
992 }
993 if (PyErr_Occurred()) {
994 Py_DECREF(key);
995 return NULL;
996 }
Raymond Hettingerd8080c02019-01-26 03:02:00 -0500997 self->misses++;
Serhiy Storchaka46c56112015-05-24 21:53:49 +0300998 result = PyObject_Call(self->func, args, kwds);
999 if (!result) {
1000 Py_DECREF(key);
1001 return NULL;
1002 }
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001003 testresult = _PyDict_GetItem_KnownHash(self->cache, key, hash);
1004 if (testresult != NULL) {
1005 /* Getting here means that this same key was added to the cache
1006 during the PyObject_Call(). Since the link update is already
1007 done, we need only return the computed result. */
1008 Py_DECREF(key);
1009 return result;
1010 }
1011 if (PyErr_Occurred()) {
1012 /* This is an unusual case since this same lookup
1013 did not previously trigger an error during lookup.
1014 Treat it the same as an error in user function
1015 and return with the error set. */
1016 Py_DECREF(key);
1017 Py_DECREF(result);
1018 return NULL;
1019 }
1020 /* This is the normal case. The new key wasn't found before
1021 user function call and it is still not there. So we
1022 proceed normally and update the cache with the new result. */
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001023
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001024 assert(self->maxsize > 0);
1025 if (PyDict_GET_SIZE(self->cache) < self->maxsize ||
1026 self->root.next == &self->root)
1027 {
1028 /* Cache is not full, so put the result in a new link */
INADA Naoki3070b712017-12-26 02:03:24 +09001029 link = (lru_list_elem *)PyObject_New(lru_list_elem,
1030 &lru_list_elem_type);
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001031 if (link == NULL) {
1032 Py_DECREF(key);
1033 Py_DECREF(result);
1034 return NULL;
1035 }
1036
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001037 link->hash = hash;
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001038 link->key = key;
1039 link->result = result;
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001040 /* What is really needed here is a SetItem variant with a "no clobber"
1041 option. If the __eq__ call triggers a reentrant call that adds
1042 this same key, then this setitem call will update the cache dict
1043 with this new link, leaving the old link as an orphan (i.e. not
1044 having a cache dict entry that refers to it). */
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001045 if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
1046 hash) < 0) {
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001047 Py_DECREF(link);
1048 return NULL;
1049 }
1050 lru_cache_append_link(self, link);
1051 Py_INCREF(result); /* for return */
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001052 return result;
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001053 }
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001054 /* Since the cache is full, we need to evict an old key and add
1055 a new key. Rather than free the old link and allocate a new
1056 one, we reuse the link for the new key and result and move it
1057 to front of the cache to mark it as recently used.
1058
1059 We try to assure all code paths (including errors) leave all
1060 of the links in place. Either the link is successfully
1061 updated and moved or it is restored to its old position.
1062 However if an unrecoverable error is found, it doesn't
1063 make sense to reinsert the link, so we leave it out
1064 and the cache will no longer register as full.
1065 */
1066 PyObject *oldkey, *oldresult, *popresult;
1067
1068 /* Extract the oldest item. */
1069 assert(self->root.next != &self->root);
1070 link = self->root.next;
1071 lru_cache_extract_link(link);
1072 /* Remove it from the cache.
Raymond Hettinger2dda72a2019-02-08 18:55:02 -08001073 The cache dict holds one reference to the link.
1074 We created one other reference when the link was created.
1075 The linked list only has borrowed references. */
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001076 popresult = _PyDict_Pop_KnownHash(self->cache, link->key,
1077 link->hash, Py_None);
1078 if (popresult == Py_None) {
1079 /* Getting here means that the user function call or another
1080 thread has already removed the old key from the dictionary.
Raymond Hettinger2dda72a2019-02-08 18:55:02 -08001081 This link is now an orphan. Since we don't want to leave the
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001082 cache in an inconsistent state, we don't restore the link. */
1083 Py_DECREF(popresult);
1084 Py_DECREF(link);
1085 Py_DECREF(key);
1086 return result;
1087 }
1088 if (popresult == NULL) {
1089 /* An error arose while trying to remove the oldest key (the one
1090 being evicted) from the cache. We restore the link to its
1091 original position as the oldest link. Then we allow the
1092 error propagate upward; treating it the same as an error
1093 arising in the user function. */
1094 lru_cache_prepend_link(self, link);
1095 Py_DECREF(key);
1096 Py_DECREF(result);
1097 return NULL;
1098 }
1099 /* Keep a reference to the old key and old result to prevent their
1100 ref counts from going to zero during the update. That will
1101 prevent potentially arbitrary object clean-up code (i.e. __del__)
1102 from running while we're still adjusting the links. */
1103 oldkey = link->key;
1104 oldresult = link->result;
1105
1106 link->hash = hash;
1107 link->key = key;
1108 link->result = result;
1109 /* Note: The link is being added to the cache dict without the
1110 prev and next fields set to valid values. We have to wait
1111 for successful insertion in the cache dict before adding the
1112 link to the linked list. Otherwise, the potentially reentrant
Raymond Hettinger2dda72a2019-02-08 18:55:02 -08001113 __eq__ call could cause the then orphan link to be visited. */
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001114 if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
1115 hash) < 0) {
1116 /* Somehow the cache dict update failed. We no longer can
1117 restore the old link. Let the error propagate upward and
1118 leave the cache short one link. */
1119 Py_DECREF(popresult);
1120 Py_DECREF(link);
1121 Py_DECREF(oldkey);
1122 Py_DECREF(oldresult);
1123 return NULL;
1124 }
1125 lru_cache_append_link(self, link);
1126 Py_INCREF(result); /* for return */
1127 Py_DECREF(popresult);
1128 Py_DECREF(oldkey);
1129 Py_DECREF(oldresult);
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001130 return result;
1131}
1132
1133static PyObject *
1134lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1135{
Serhiy Storchaka374164c2015-07-25 12:10:21 +03001136 PyObject *func, *maxsize_O, *cache_info_type, *cachedict;
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001137 int typed;
1138 lru_cache_object *obj;
1139 Py_ssize_t maxsize;
1140 PyObject *(*wrapper)(lru_cache_object *, PyObject *, PyObject *);
1141 static char *keywords[] = {"user_function", "maxsize", "typed",
1142 "cache_info_type", NULL};
1143
1144 if (!PyArg_ParseTupleAndKeywords(args, kw, "OOpO:lru_cache", keywords,
1145 &func, &maxsize_O, &typed,
1146 &cache_info_type)) {
1147 return NULL;
1148 }
1149
1150 if (!PyCallable_Check(func)) {
1151 PyErr_SetString(PyExc_TypeError,
1152 "the first argument must be callable");
1153 return NULL;
1154 }
1155
1156 /* select the caching function, and make/inc maxsize_O */
1157 if (maxsize_O == Py_None) {
1158 wrapper = infinite_lru_cache_wrapper;
1159 /* use this only to initialize lru_cache_object attribute maxsize */
1160 maxsize = -1;
1161 } else if (PyIndex_Check(maxsize_O)) {
1162 maxsize = PyNumber_AsSsize_t(maxsize_O, PyExc_OverflowError);
1163 if (maxsize == -1 && PyErr_Occurred())
1164 return NULL;
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001165 if (maxsize < 0) {
1166 maxsize = 0;
1167 }
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001168 if (maxsize == 0)
1169 wrapper = uncached_lru_cache_wrapper;
1170 else
1171 wrapper = bounded_lru_cache_wrapper;
1172 } else {
1173 PyErr_SetString(PyExc_TypeError, "maxsize should be integer or None");
1174 return NULL;
1175 }
1176
Serhiy Storchaka374164c2015-07-25 12:10:21 +03001177 if (!(cachedict = PyDict_New()))
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001178 return NULL;
1179
Serhiy Storchaka374164c2015-07-25 12:10:21 +03001180 obj = (lru_cache_object *)type->tp_alloc(type, 0);
1181 if (obj == NULL) {
1182 Py_DECREF(cachedict);
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001183 return NULL;
1184 }
1185
1186 obj->root.prev = &obj->root;
1187 obj->root.next = &obj->root;
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001188 obj->wrapper = wrapper;
1189 obj->typed = typed;
1190 obj->cache = cachedict;
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001191 Py_INCREF(func);
1192 obj->func = func;
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001193 obj->misses = obj->hits = 0;
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001194 obj->maxsize = maxsize;
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001195 Py_INCREF(cache_info_type);
1196 obj->cache_info_type = cache_info_type;
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001197 return (PyObject *)obj;
1198}
1199
1200static lru_list_elem *
1201lru_cache_unlink_list(lru_cache_object *self)
1202{
1203 lru_list_elem *root = &self->root;
1204 lru_list_elem *link = root->next;
1205 if (link == root)
1206 return NULL;
1207 root->prev->next = NULL;
1208 root->next = root->prev = root;
1209 return link;
1210}
1211
1212static void
1213lru_cache_clear_list(lru_list_elem *link)
1214{
1215 while (link != NULL) {
1216 lru_list_elem *next = link->next;
1217 Py_DECREF(link);
1218 link = next;
1219 }
1220}
1221
1222static void
1223lru_cache_dealloc(lru_cache_object *obj)
1224{
INADA Naokia6296d32017-08-24 14:55:17 +09001225 lru_list_elem *list;
1226 /* bpo-31095: UnTrack is needed before calling any callbacks */
1227 PyObject_GC_UnTrack(obj);
1228
1229 list = lru_cache_unlink_list(obj);
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001230 Py_XDECREF(obj->cache);
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001231 Py_XDECREF(obj->func);
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001232 Py_XDECREF(obj->cache_info_type);
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001233 Py_XDECREF(obj->dict);
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001234 lru_cache_clear_list(list);
1235 Py_TYPE(obj)->tp_free(obj);
1236}
1237
1238static PyObject *
1239lru_cache_call(lru_cache_object *self, PyObject *args, PyObject *kwds)
1240{
1241 return self->wrapper(self, args, kwds);
1242}
1243
1244static PyObject *
Serhiy Storchakae7070f02015-06-08 11:19:24 +03001245lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1246{
1247 if (obj == Py_None || obj == NULL) {
1248 Py_INCREF(self);
1249 return self;
1250 }
1251 return PyMethod_New(self, obj);
1252}
1253
1254static PyObject *
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001255lru_cache_cache_info(lru_cache_object *self, PyObject *unused)
1256{
Raymond Hettingerd8080c02019-01-26 03:02:00 -05001257 if (self->maxsize == -1) {
1258 return PyObject_CallFunction(self->cache_info_type, "nnOn",
1259 self->hits, self->misses, Py_None,
1260 PyDict_GET_SIZE(self->cache));
1261 }
1262 return PyObject_CallFunction(self->cache_info_type, "nnnn",
1263 self->hits, self->misses, self->maxsize,
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02001264 PyDict_GET_SIZE(self->cache));
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001265}
1266
1267static PyObject *
1268lru_cache_cache_clear(lru_cache_object *self, PyObject *unused)
1269{
1270 lru_list_elem *list = lru_cache_unlink_list(self);
1271 self->hits = self->misses = 0;
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001272 PyDict_Clear(self->cache);
1273 lru_cache_clear_list(list);
1274 Py_RETURN_NONE;
1275}
1276
Serhiy Storchaka45120f22015-10-24 09:49:56 +03001277static PyObject *
1278lru_cache_reduce(PyObject *self, PyObject *unused)
1279{
1280 return PyObject_GetAttrString(self, "__qualname__");
1281}
1282
Serhiy Storchakae4d65e32015-12-28 23:58:07 +02001283static PyObject *
1284lru_cache_copy(PyObject *self, PyObject *unused)
1285{
1286 Py_INCREF(self);
1287 return self;
1288}
1289
1290static PyObject *
1291lru_cache_deepcopy(PyObject *self, PyObject *unused)
1292{
1293 Py_INCREF(self);
1294 return self;
1295}
1296
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001297static int
1298lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
1299{
1300 lru_list_elem *link = self->root.next;
1301 while (link != &self->root) {
1302 lru_list_elem *next = link->next;
INADA Naoki3070b712017-12-26 02:03:24 +09001303 Py_VISIT(link->key);
1304 Py_VISIT(link->result);
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001305 link = next;
1306 }
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001307 Py_VISIT(self->func);
1308 Py_VISIT(self->cache);
1309 Py_VISIT(self->cache_info_type);
1310 Py_VISIT(self->dict);
1311 return 0;
1312}
1313
1314static int
1315lru_cache_tp_clear(lru_cache_object *self)
1316{
1317 lru_list_elem *list = lru_cache_unlink_list(self);
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001318 Py_CLEAR(self->func);
1319 Py_CLEAR(self->cache);
1320 Py_CLEAR(self->cache_info_type);
1321 Py_CLEAR(self->dict);
1322 lru_cache_clear_list(list);
1323 return 0;
1324}
1325
1326
1327PyDoc_STRVAR(lru_cache_doc,
1328"Create a cached callable that wraps another function.\n\
1329\n\
1330user_function: the function being cached\n\
1331\n\
1332maxsize: 0 for no caching\n\
1333 None for unlimited cache size\n\
1334 n for a bounded cache\n\
1335\n\
1336typed: False cache f(3) and f(3.0) as identical calls\n\
1337 True cache f(3) and f(3.0) as distinct calls\n\
1338\n\
1339cache_info_type: namedtuple class with the fields:\n\
1340 hits misses currsize maxsize\n"
1341);
1342
1343static PyMethodDef lru_cache_methods[] = {
1344 {"cache_info", (PyCFunction)lru_cache_cache_info, METH_NOARGS},
1345 {"cache_clear", (PyCFunction)lru_cache_cache_clear, METH_NOARGS},
Serhiy Storchaka45120f22015-10-24 09:49:56 +03001346 {"__reduce__", (PyCFunction)lru_cache_reduce, METH_NOARGS},
Serhiy Storchakae4d65e32015-12-28 23:58:07 +02001347 {"__copy__", (PyCFunction)lru_cache_copy, METH_VARARGS},
1348 {"__deepcopy__", (PyCFunction)lru_cache_deepcopy, METH_VARARGS},
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001349 {NULL}
1350};
1351
1352static PyGetSetDef lru_cache_getsetlist[] = {
1353 {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
1354 {NULL}
1355};
1356
1357static PyTypeObject lru_cache_type = {
1358 PyVarObject_HEAD_INIT(NULL, 0)
1359 "functools._lru_cache_wrapper", /* tp_name */
1360 sizeof(lru_cache_object), /* tp_basicsize */
1361 0, /* tp_itemsize */
1362 /* methods */
1363 (destructor)lru_cache_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001364 0, /* tp_vectorcall_offset */
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001365 0, /* tp_getattr */
1366 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001367 0, /* tp_as_async */
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001368 0, /* tp_repr */
1369 0, /* tp_as_number */
1370 0, /* tp_as_sequence */
1371 0, /* tp_as_mapping */
1372 0, /* tp_hash */
1373 (ternaryfunc)lru_cache_call, /* tp_call */
1374 0, /* tp_str */
1375 0, /* tp_getattro */
1376 0, /* tp_setattro */
1377 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +02001378 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1379 Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_METHOD_DESCRIPTOR,
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001380 /* tp_flags */
1381 lru_cache_doc, /* tp_doc */
1382 (traverseproc)lru_cache_tp_traverse,/* tp_traverse */
1383 (inquiry)lru_cache_tp_clear, /* tp_clear */
1384 0, /* tp_richcompare */
1385 0, /* tp_weaklistoffset */
1386 0, /* tp_iter */
1387 0, /* tp_iternext */
1388 lru_cache_methods, /* tp_methods */
1389 0, /* tp_members */
1390 lru_cache_getsetlist, /* tp_getset */
1391 0, /* tp_base */
1392 0, /* tp_dict */
Serhiy Storchakae7070f02015-06-08 11:19:24 +03001393 lru_cache_descr_get, /* tp_descr_get */
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001394 0, /* tp_descr_set */
1395 offsetof(lru_cache_object, dict), /* tp_dictoffset */
1396 0, /* tp_init */
1397 0, /* tp_alloc */
1398 lru_cache_new, /* tp_new */
1399};
1400
Raymond Hettinger9c323f82005-02-28 19:39:44 +00001401/* module level code ********************************************************/
1402
1403PyDoc_STRVAR(module_doc,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001404"Tools that operate on functions.");
Raymond Hettinger9c323f82005-02-28 19:39:44 +00001405
1406static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 {"reduce", functools_reduce, METH_VARARGS, functools_reduce_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001408 {"cmp_to_key", (PyCFunction)(void(*)(void))functools_cmp_to_key,
Victor Stinner446c8d52011-04-05 12:21:35 +02001409 METH_VARARGS | METH_KEYWORDS, functools_cmp_to_key_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 {NULL, NULL} /* sentinel */
Raymond Hettinger9c323f82005-02-28 19:39:44 +00001411};
1412
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001413static void
1414module_free(void *m)
1415{
1416 Py_CLEAR(kwd_mark);
1417}
Martin v. Löwis1a214512008-06-11 05:26:20 +00001418
1419static struct PyModuleDef _functoolsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 PyModuleDef_HEAD_INIT,
1421 "_functools",
1422 module_doc,
1423 -1,
1424 module_methods,
1425 NULL,
1426 NULL,
1427 NULL,
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001428 module_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +00001429};
1430
Raymond Hettinger9c323f82005-02-28 19:39:44 +00001431PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001432PyInit__functools(void)
Raymond Hettinger9c323f82005-02-28 19:39:44 +00001433{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 int i;
1435 PyObject *m;
Serhiy Storchaka4ab46d72017-09-17 21:11:04 +03001436 const char *name;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 PyTypeObject *typelist[] = {
1438 &partial_type,
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001439 &lru_cache_type,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 NULL
1441 };
Raymond Hettinger9c323f82005-02-28 19:39:44 +00001442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 m = PyModule_Create(&_functoolsmodule);
1444 if (m == NULL)
1445 return NULL;
Raymond Hettinger9c323f82005-02-28 19:39:44 +00001446
Victor Stinnera5ed5f02016-12-06 18:45:50 +01001447 kwd_mark = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type);
Serhiy Storchaka46c56112015-05-24 21:53:49 +03001448 if (!kwd_mark) {
1449 Py_DECREF(m);
1450 return NULL;
1451 }
1452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 for (i=0 ; typelist[i] != NULL ; i++) {
1454 if (PyType_Ready(typelist[i]) < 0) {
1455 Py_DECREF(m);
1456 return NULL;
1457 }
Serhiy Storchaka4ab46d72017-09-17 21:11:04 +03001458 name = _PyType_Name(typelist[i]);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 Py_INCREF(typelist[i]);
Serhiy Storchaka4ab46d72017-09-17 21:11:04 +03001460 PyModule_AddObject(m, name, (PyObject *)typelist[i]);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 }
1462 return m;
Raymond Hettinger9c323f82005-02-28 19:39:44 +00001463}