#include "Python.h"
#include "pycore_call.h"          // _PyObject_CallNoArgs()
#include "pycore_dict.h"          // _PyDict_Pop_KnownHash()
#include "pycore_long.h"          // _PyLong_GetZero()
#include "pycore_moduleobject.h"  // _PyModule_GetState()
#include "pycore_object.h"        // _PyObject_GC_TRACK
#include "pycore_pyatomic_ft_wrappers.h"
#include "pycore_pystate.h"       // _PyThreadState_GET()
#include "pycore_tuple.h"         // _PyTuple_ITEMS()


#include "clinic/_functoolsmodule.c.h"
/*[clinic input]
module _functools
class _functools._lru_cache_wrapper "PyObject *" "&lru_cache_type_spec"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bece4053896b09c0]*/

/* _functools module written and maintained
   by Hye-Shik Chang <perky@FreeBSD.org>
   with adaptations by Raymond Hettinger <python@rcn.com>
   Copyright (c) 2004 Python Software Foundation.
   All rights reserved.
*/

typedef struct _functools_state {
    /* this object is used delimit args and keywords in the cache keys */
    PyObject *kwd_mark;
    PyTypeObject *placeholder_type;
    PyObject *placeholder;  // strong reference (singleton)
    PyTypeObject *partial_type;
    PyTypeObject *keyobject_type;
    PyTypeObject *lru_list_elem_type;
} _functools_state;

static inline _functools_state *
get_functools_state(PyObject *module)
{
    void *state = _PyModule_GetState(module);
    assert(state != NULL);
    return (_functools_state *)state;
}

/* partial object **********************************************************/


// The 'Placeholder' singleton indicates which formal positional
// parameters are to be bound first when using a 'partial' object.

typedef struct {
    PyObject_HEAD
} placeholderobject;

static inline _functools_state *
get_functools_state_by_type(PyTypeObject *type);

PyDoc_STRVAR(placeholder_doc,
"The type of the Placeholder singleton.\n\n"
"Used as a placeholder for partial arguments.");

static PyObject *
placeholder_repr(PyObject *op)
{
    return PyUnicode_FromString("Placeholder");
}

static PyObject *
placeholder_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
{
    return PyUnicode_FromString("Placeholder");
}

static PyMethodDef placeholder_methods[] = {
    {"__reduce__", placeholder_reduce, METH_NOARGS, NULL},
    {NULL, NULL}
};

static void
placeholder_dealloc(PyObject* self)
{
    PyObject_GC_UnTrack(self);
    PyTypeObject *tp = Py_TYPE(self);
    tp->tp_free((PyObject*)self);
    Py_DECREF(tp);
}

static PyObject *
placeholder_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
    if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) {
        PyErr_SetString(PyExc_TypeError, "PlaceholderType takes no arguments");
        return NULL;
    }
    _functools_state *state = get_functools_state_by_type(type);
    if (state->placeholder != NULL) {
        return Py_NewRef(state->placeholder);
    }

    PyObject *placeholder = PyType_GenericNew(type, NULL, NULL);
    if (placeholder == NULL) {
        return NULL;
    }

    if (state->placeholder == NULL) {
        state->placeholder = Py_NewRef(placeholder);
    }
    return placeholder;
}

static int
placeholder_traverse(PyObject *self, visitproc visit, void *arg)
{
    Py_VISIT(Py_TYPE(self));
    return 0;
}

static PyType_Slot placeholder_type_slots[] = {
    {Py_tp_dealloc, placeholder_dealloc},
    {Py_tp_repr, placeholder_repr},
    {Py_tp_doc, (void *)placeholder_doc},
    {Py_tp_methods, placeholder_methods},
    {Py_tp_new, placeholder_new},
    {Py_tp_traverse, placeholder_traverse},
    {0, 0}
};

static PyType_Spec placeholder_type_spec = {
    .name = "functools._PlaceholderType",
    .basicsize = sizeof(placeholderobject),
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC,
    .slots = placeholder_type_slots
};


typedef struct {
    PyObject_HEAD
    PyObject *fn;
    PyObject *args;
    PyObject *kw;
    PyObject *dict;        /* __dict__ */
    PyObject *weakreflist; /* List of weak references */
    PyObject *placeholder; /* Placeholder for positional arguments */
    Py_ssize_t phcount;    /* Number of placeholders */
    vectorcallfunc vectorcall;
} partialobject;

// cast a PyObject pointer PTR to a partialobject pointer (no type checks)
#define partialobject_CAST(op)  ((partialobject *)(op))

static void partial_setvectorcall(partialobject *pto);
static struct PyModuleDef _functools_module;
static PyObject *
partial_call(PyObject *pto, PyObject *args, PyObject *kwargs);

static inline _functools_state *
get_functools_state_by_type(PyTypeObject *type)
{
    PyObject *module = PyType_GetModuleByDef(type, &_functools_module);
    if (module == NULL) {
        return NULL;
    }
    return get_functools_state(module);
}

// Not converted to argument clinic, because of `*args, **kwargs` arguments.
static PyObject *
partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
    PyObject *func, *pto_args, *new_args, *pto_kw, *phold;
    partialobject *pto;
    Py_ssize_t pto_phcount = 0;
    Py_ssize_t new_nargs = PyTuple_GET_SIZE(args) - 1;

    if (new_nargs < 0) {
        PyErr_SetString(PyExc_TypeError,
                        "type 'partial' takes at least one argument");
        return NULL;
    }
    func = PyTuple_GET_ITEM(args, 0);
    if (!PyCallable_Check(func)) {
        PyErr_SetString(PyExc_TypeError,
                        "the first argument must be callable");
        return NULL;
    }

    _functools_state *state = get_functools_state_by_type(type);
    if (state == NULL) {
        return NULL;
    }
    phold = state->placeholder;

    /* Placeholder restrictions */
    if (new_nargs && PyTuple_GET_ITEM(args, new_nargs) == phold) {
        PyErr_SetString(PyExc_TypeError,
                        "trailing Placeholders are not allowed");
        return NULL;
    }

    /* keyword Placeholder prohibition */
    if (kw != NULL) {
        PyObject *key, *val;
        Py_ssize_t pos = 0;
        while (PyDict_Next(kw, &pos, &key, &val)) {
            if (val == phold) {
                PyErr_SetString(PyExc_TypeError,
                                "Placeholder cannot be passed as a keyword argument");
                return NULL;
            }
        }
    }

    /* check wrapped function / object */
    pto_args = pto_kw = NULL;
    int res = PyObject_TypeCheck(func, state->partial_type);
    if (res == -1) {
        return NULL;
    }
    if (res == 1) {
        // We can use its underlying function directly and merge the arguments.
        partialobject *part = (partialobject *)func;
        if (part->dict == NULL) {
            pto_args = part->args;
            pto_kw = part->kw;
            func = part->fn;
            pto_phcount = part->phcount;
            assert(PyTuple_Check(pto_args));
            assert(PyDict_Check(pto_kw));
        }
    }

    /* create partialobject structure */
    pto = (partialobject *)type->tp_alloc(type, 0);
    if (pto == NULL)
        return NULL;

    pto->fn = Py_NewRef(func);
    pto->placeholder = phold;

    new_args = PyTuple_GetSlice(args, 1, new_nargs + 1);
    if (new_args == NULL) {
        Py_DECREF(pto);
        return NULL;
    }

    /* Count placeholders */
    Py_ssize_t phcount = 0;
    for (Py_ssize_t i = 0; i < new_nargs - 1; i++) {
        if (PyTuple_GET_ITEM(new_args, i) == phold) {
            phcount++;
        }
    }
    /* merge args with args of `func` which is `partial` */
    if (pto_phcount > 0 && new_nargs > 0) {
        Py_ssize_t npargs = PyTuple_GET_SIZE(pto_args);
        Py_ssize_t tot_nargs = npargs;
        if (new_nargs > pto_phcount) {
            tot_nargs += new_nargs - pto_phcount;
        }
        PyObject *item;
        PyObject *tot_args = PyTuple_New(tot_nargs);
        for (Py_ssize_t i = 0, j = 0; i < tot_nargs; i++) {
            if (i < npargs) {
                item = PyTuple_GET_ITEM(pto_args, i);
                if (j < new_nargs && item == phold) {
                    item = PyTuple_GET_ITEM(new_args, j);
                    j++;
                    pto_phcount--;
                }
            }
            else {
                item = PyTuple_GET_ITEM(new_args, j);
                j++;
            }
            Py_INCREF(item);
            PyTuple_SET_ITEM(tot_args, i, item);
        }
        pto->args = tot_args;
        pto->phcount = pto_phcount + phcount;
        Py_DECREF(new_args);
    }
    else if (pto_args == NULL) {
        pto->args = new_args;
        pto->phcount = phcount;
    }
    else {
        pto->args = PySequence_Concat(pto_args, new_args);
        pto->phcount = pto_phcount + phcount;
        Py_DECREF(new_args);
        if (pto->args == NULL) {
            Py_DECREF(pto);
            return NULL;
        }
        assert(PyTuple_Check(pto->args));
    }

    if (pto_kw == NULL || PyDict_GET_SIZE(pto_kw) == 0) {
        if (kw == NULL) {
            pto->kw = PyDict_New();
        }
        else if (Py_REFCNT(kw) == 1) {
            pto->kw = Py_NewRef(kw);
        }
        else {
            pto->kw = PyDict_Copy(kw);
        }
    }
    else {
        pto->kw = PyDict_Copy(pto_kw);
        if (kw != NULL && pto->kw != NULL) {
            if (PyDict_Merge(pto->kw, kw, 1) != 0) {
                Py_DECREF(pto);
                return NULL;
            }
        }
    }
    if (pto->kw == NULL) {
        Py_DECREF(pto);
        return NULL;
    }

    partial_setvectorcall(pto);
    return (PyObject *)pto;
}

static int
partial_clear(PyObject *self)
{
    partialobject *pto = partialobject_CAST(self);
    Py_CLEAR(pto->fn);
    Py_CLEAR(pto->args);
    Py_CLEAR(pto->kw);
    Py_CLEAR(pto->dict);
    return 0;
}

static int
partial_traverse(PyObject *self, visitproc visit, void *arg)
{
    partialobject *pto = partialobject_CAST(self);
    Py_VISIT(Py_TYPE(pto));
    Py_VISIT(pto->fn);
    Py_VISIT(pto->args);
    Py_VISIT(pto->kw);
    Py_VISIT(pto->dict);
    return 0;
}

static void
partial_dealloc(PyObject *self)
{
    PyTypeObject *tp = Py_TYPE(self);
    /* bpo-31095: UnTrack is needed before calling any callbacks */
    PyObject_GC_UnTrack(self);
    if (partialobject_CAST(self)->weakreflist != NULL) {
        PyObject_ClearWeakRefs(self);
    }
    (void)partial_clear(self);
    tp->tp_free(self);
    Py_DECREF(tp);
}

static PyObject *
partial_descr_get(PyObject *self, PyObject *obj, PyObject *type)
{
    if (obj == Py_None || obj == NULL) {
        return Py_NewRef(self);
    }
    return PyMethod_New(self, obj);
}

/* Merging keyword arguments using the vectorcall convention is messy, so
 * if we would need to do that, we stop using vectorcall and fall back
 * to using partial_call() instead. */
Py_NO_INLINE static PyObject *
partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto,
                            PyObject *const *args, size_t nargsf,
                            PyObject *kwnames)
{
    pto->vectorcall = NULL;
    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
    return _PyObject_MakeTpCall(tstate, (PyObject *)pto, args, nargs, kwnames);
}

static PyObject *
partial_vectorcall(PyObject *self, PyObject *const *args,
                   size_t nargsf, PyObject *kwnames)
{
    partialobject *pto = partialobject_CAST(self);;
    PyThreadState *tstate = _PyThreadState_GET();
    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);

    /* pto->kw is mutable, so need to check every time */
    if (PyDict_GET_SIZE(pto->kw)) {
        return partial_vectorcall_fallback(tstate, pto, args, nargsf, kwnames);
    }
    Py_ssize_t pto_phcount = pto->phcount;
    if (nargs < pto_phcount) {
        PyErr_Format(PyExc_TypeError,
                     "missing positional arguments in 'partial' call; "
                     "expected at least %zd, got %zd", pto_phcount, nargs);
        return NULL;
    }

    Py_ssize_t nargskw = nargs;
    if (kwnames != NULL) {
        nargskw += PyTuple_GET_SIZE(kwnames);
    }

    PyObject **pto_args = _PyTuple_ITEMS(pto->args);
    Py_ssize_t pto_nargs = PyTuple_GET_SIZE(pto->args);

    /* Fast path if we're called without arguments */
    if (nargskw == 0) {
        return _PyObject_VectorcallTstate(tstate, pto->fn,
                                          pto_args, pto_nargs, NULL);
    }

    /* Fast path using PY_VECTORCALL_ARGUMENTS_OFFSET to prepend a single
     * positional argument */
    if (pto_nargs == 1 && (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET)) {
        PyObject **newargs = (PyObject **)args - 1;
        PyObject *tmp = newargs[0];
        newargs[0] = pto_args[0];
        PyObject *ret = _PyObject_VectorcallTstate(tstate, pto->fn,
                                                   newargs, nargs + 1, kwnames);
        newargs[0] = tmp;
        return ret;
    }

    PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
    PyObject **stack;

    Py_ssize_t tot_nargskw = pto_nargs + nargskw - pto_phcount;
    if (tot_nargskw <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
        stack = small_stack;
    }
    else {
        stack = PyMem_Malloc(tot_nargskw * sizeof(PyObject *));
        if (stack == NULL) {
            PyErr_NoMemory();
            return NULL;
        }
    }

    Py_ssize_t tot_nargs;
    if (pto_phcount) {
        tot_nargs = pto_nargs + nargs - pto_phcount;
        Py_ssize_t j = 0;       // New args index
        for (Py_ssize_t i = 0; i < pto_nargs; i++) {
            if (pto_args[i] == pto->placeholder) {
                stack[i] = args[j];
                j += 1;
            }
            else {
                stack[i] = pto_args[i];
            }
        }
        assert(j == pto_phcount);
        if (nargskw > pto_phcount) {
            memcpy(stack + pto_nargs, args + j, (nargskw - j) * sizeof(PyObject*));
        }
    }
    else {
        tot_nargs = pto_nargs + nargs;
        /* Copy to new stack, using borrowed references */
        memcpy(stack, pto_args, pto_nargs * sizeof(PyObject*));
        memcpy(stack + pto_nargs, args, nargskw * sizeof(PyObject*));
    }
    PyObject *ret = _PyObject_VectorcallTstate(tstate, pto->fn,
                                               stack, tot_nargs, kwnames);
    if (stack != small_stack) {
        PyMem_Free(stack);
    }
    return ret;
}

/* Set pto->vectorcall depending on the parameters of the partial object */
static void
partial_setvectorcall(partialobject *pto)
{
    if (PyVectorcall_Function(pto->fn) == NULL) {
        /* Don't use vectorcall if the underlying function doesn't support it */
        pto->vectorcall = NULL;
    }
    /* We could have a special case if there are no arguments,
     * but that is unlikely (why use partial without arguments?),
     * so we don't optimize that */
    else {
        pto->vectorcall = partial_vectorcall;
    }
}


// Not converted to argument clinic, because of `*args, **kwargs` arguments.
static PyObject *
partial_call(PyObject *self, PyObject *args, PyObject *kwargs)
{
    partialobject *pto = partialobject_CAST(self);
    assert(PyCallable_Check(pto->fn));
    assert(PyTuple_Check(pto->args));
    assert(PyDict_Check(pto->kw));

    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
    Py_ssize_t pto_phcount = pto->phcount;
    if (nargs < pto_phcount) {
        PyErr_Format(PyExc_TypeError,
                     "missing positional arguments in 'partial' call; "
                     "expected at least %zd, got %zd", pto_phcount, nargs);
        return NULL;
    }

    /* Merge keywords */
    PyObject *tot_kw;
    if (PyDict_GET_SIZE(pto->kw) == 0) {
        /* kwargs can be NULL */
        tot_kw = Py_XNewRef(kwargs);
    }
    else {
        /* bpo-27840, bpo-29318: dictionary of keyword parameters must be
           copied, because a function using "**kwargs" can modify the
           dictionary. */
        tot_kw = PyDict_Copy(pto->kw);
        if (tot_kw == NULL) {
            return NULL;
        }

        if (kwargs != NULL) {
            if (PyDict_Merge(tot_kw, kwargs, 1) != 0) {
                Py_DECREF(tot_kw);
                return NULL;
            }
        }
    }

    /* Merge positional arguments */
    PyObject *tot_args;
    if (pto_phcount) {
        Py_ssize_t pto_nargs = PyTuple_GET_SIZE(pto->args);
        Py_ssize_t tot_nargs = pto_nargs + nargs - pto_phcount;
        assert(tot_nargs >= 0);
        tot_args = PyTuple_New(tot_nargs);
        if (tot_args == NULL) {
            Py_XDECREF(tot_kw);
            return NULL;
        }
        PyObject *pto_args = pto->args;
        PyObject *item;
        Py_ssize_t j = 0;   // New args index
        for (Py_ssize_t i = 0; i < pto_nargs; i++) {
            item = PyTuple_GET_ITEM(pto_args, i);
            if (item == pto->placeholder) {
                item = PyTuple_GET_ITEM(args, j);
                j += 1;
            }
            Py_INCREF(item);
            PyTuple_SET_ITEM(tot_args, i, item);
        }
        assert(j == pto_phcount);
        for (Py_ssize_t i = pto_nargs; i < tot_nargs; i++) {
            item = PyTuple_GET_ITEM(args, j);
            Py_INCREF(item);
            PyTuple_SET_ITEM(tot_args, i, item);
            j += 1;
        }
    }
    else {
        /* Note: tupleconcat() is optimized for empty tuples */
        tot_args = PySequence_Concat(pto->args, args);
        if (tot_args == NULL) {
            Py_XDECREF(tot_kw);
            return NULL;
        }
    }

    PyObject *res = PyObject_Call(pto->fn, tot_args, tot_kw);
    Py_DECREF(tot_args);
    Py_XDECREF(tot_kw);
    return res;
}

PyDoc_STRVAR(partial_doc,
"partial(func, /, *args, **keywords)\n--\n\n\
Create a new function with partial application of the given arguments\n\
and keywords.");

#define OFF(x) offsetof(partialobject, x)
static PyMemberDef partial_memberlist[] = {
    {"func",            _Py_T_OBJECT,       OFF(fn),        Py_READONLY,
     "function object to use in future partial calls"},
    {"args",            _Py_T_OBJECT,       OFF(args),      Py_READONLY,
     "tuple of arguments to future partial calls"},
    {"keywords",        _Py_T_OBJECT,       OFF(kw),        Py_READONLY,
     "dictionary of keyword arguments to future partial calls"},
    {"__weaklistoffset__", Py_T_PYSSIZET,
     offsetof(partialobject, weakreflist), Py_READONLY},
    {"__dictoffset__", Py_T_PYSSIZET,
     offsetof(partialobject, dict), Py_READONLY},
    {"__vectorcalloffset__", Py_T_PYSSIZET,
     offsetof(partialobject, vectorcall), Py_READONLY},
    {NULL}  /* Sentinel */
};

static PyGetSetDef partial_getsetlist[] = {
    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
    {NULL} /* Sentinel */
};

static PyObject *
partial_repr(PyObject *self)
{
    partialobject *pto = partialobject_CAST(self);
    PyObject *result = NULL;
    PyObject *arglist;
    PyObject *mod;
    PyObject *name;
    Py_ssize_t i, n;
    PyObject *key, *value;
    int status;

    status = Py_ReprEnter(self);
    if (status != 0) {
        if (status < 0)
            return NULL;
        return PyUnicode_FromString("...");
    }

    arglist = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
    if (arglist == NULL)
        goto done;
    /* Pack positional arguments */
    assert(PyTuple_Check(pto->args));
    n = PyTuple_GET_SIZE(pto->args);
    for (i = 0; i < n; i++) {
        Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist,
                                        PyTuple_GET_ITEM(pto->args, i)));
        if (arglist == NULL)
            goto done;
    }
    /* Pack keyword arguments */
    assert (PyDict_Check(pto->kw));
    for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) {
        /* Prevent key.__str__ from deleting the value. */
        Py_INCREF(value);
        Py_SETREF(arglist, PyUnicode_FromFormat("%U, %S=%R", arglist,
                                                key, value));
        Py_DECREF(value);
        if (arglist == NULL)
            goto done;
    }

    mod = PyType_GetModuleName(Py_TYPE(pto));
    if (mod == NULL) {
        goto error;
    }
    name = PyType_GetQualName(Py_TYPE(pto));
    if (name == NULL) {
        Py_DECREF(mod);
        goto error;
    }
    result = PyUnicode_FromFormat("%S.%S(%R%U)", mod, name, pto->fn, arglist);
    Py_DECREF(mod);
    Py_DECREF(name);
    Py_DECREF(arglist);

 done:
    Py_ReprLeave(self);
    return result;
 error:
    Py_DECREF(arglist);
    Py_ReprLeave(self);
    return NULL;
}

/* Pickle strategy:
   __reduce__ by itself doesn't support getting kwargs in the unpickle
   operation so we define a __setstate__ that replaces all the information
   about the partial.  If we only replaced part of it someone would use
   it as a hook to do strange things.
 */

static PyObject *
partial_reduce(PyObject *self, PyObject *Py_UNUSED(args))
{
    partialobject *pto = partialobject_CAST(self);
    return Py_BuildValue("O(O)(OOOO)", Py_TYPE(pto), pto->fn, pto->fn,
                         pto->args, pto->kw,
                         pto->dict ? pto->dict : Py_None);
}

static PyObject *
partial_setstate(PyObject *self, PyObject *state)
{
    partialobject *pto = partialobject_CAST(self);
    PyObject *fn, *fnargs, *kw, *dict;

    if (!PyTuple_Check(state)) {
        PyErr_SetString(PyExc_TypeError, "invalid partial state");
        return NULL;
    }
    if (!PyArg_ParseTuple(state, "OOOO", &fn, &fnargs, &kw, &dict) ||
        !PyCallable_Check(fn) ||
        !PyTuple_Check(fnargs) ||
        (kw != Py_None && !PyDict_Check(kw)))
    {
        PyErr_SetString(PyExc_TypeError, "invalid partial state");
        return NULL;
    }

    Py_ssize_t nargs = PyTuple_GET_SIZE(fnargs);
    if (nargs && PyTuple_GET_ITEM(fnargs, nargs - 1) == pto->placeholder) {
        PyErr_SetString(PyExc_TypeError,
                        "trailing Placeholders are not allowed");
        return NULL;
    }
    /* Count placeholders */
    Py_ssize_t phcount = 0;
    for (Py_ssize_t i = 0; i < nargs - 1; i++) {
        if (PyTuple_GET_ITEM(fnargs, i) == pto->placeholder) {
            phcount++;
        }
    }

    if(!PyTuple_CheckExact(fnargs))
        fnargs = PySequence_Tuple(fnargs);
    else
        Py_INCREF(fnargs);
    if (fnargs == NULL)
        return NULL;

    if (kw == Py_None)
        kw = PyDict_New();
    else if(!PyDict_CheckExact(kw))
        kw = PyDict_Copy(kw);
    else
        Py_INCREF(kw);
    if (kw == NULL) {
        Py_DECREF(fnargs);
        return NULL;
    }

    if (dict == Py_None)
        dict = NULL;
    else
        Py_INCREF(dict);
    Py_SETREF(pto->fn, Py_NewRef(fn));
    Py_SETREF(pto->args, fnargs);
    Py_SETREF(pto->kw, kw);
    pto->phcount = phcount;
    Py_XSETREF(pto->dict, dict);
    partial_setvectorcall(pto);
    Py_RETURN_NONE;
}

static PyMethodDef partial_methods[] = {
    {"__reduce__", partial_reduce, METH_NOARGS},
    {"__setstate__", partial_setstate, METH_O},
    {"__class_getitem__",    Py_GenericAlias,
    METH_O|METH_CLASS,       PyDoc_STR("See PEP 585")},
    {NULL,              NULL}           /* sentinel */
};

static PyType_Slot partial_type_slots[] = {
    {Py_tp_dealloc, partial_dealloc},
    {Py_tp_repr, partial_repr},
    {Py_tp_call, partial_call},
    {Py_tp_getattro, PyObject_GenericGetAttr},
    {Py_tp_setattro, PyObject_GenericSetAttr},
    {Py_tp_doc, (void *)partial_doc},
    {Py_tp_traverse, partial_traverse},
    {Py_tp_clear, partial_clear},
    {Py_tp_methods, partial_methods},
    {Py_tp_members, partial_memberlist},
    {Py_tp_getset, partial_getsetlist},
    {Py_tp_descr_get, partial_descr_get},
    {Py_tp_new, partial_new},
    {Py_tp_free, PyObject_GC_Del},
    {0, 0}
};

static PyType_Spec partial_type_spec = {
    .name = "functools.partial",
    .basicsize = sizeof(partialobject),
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
             Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL |
             Py_TPFLAGS_IMMUTABLETYPE,
    .slots = partial_type_slots
};


/* cmp_to_key ***************************************************************/

typedef struct {
    PyObject_HEAD
    PyObject *cmp;
    PyObject *object;
} keyobject;

#define keyobject_CAST(op)  ((keyobject *)(op))

static int
keyobject_clear(PyObject *op)
{
    keyobject *ko = keyobject_CAST(op);
    Py_CLEAR(ko->cmp);
    Py_CLEAR(ko->object);
    return 0;
}

static void
keyobject_dealloc(PyObject *ko)
{
    PyTypeObject *tp = Py_TYPE(ko);
    PyObject_GC_UnTrack(ko);
    (void)keyobject_clear(ko);
    tp->tp_free(ko);
    Py_DECREF(tp);
}

static int
keyobject_traverse(PyObject *op, visitproc visit, void *arg)
{
    keyobject *ko = keyobject_CAST(op);
    Py_VISIT(Py_TYPE(ko));
    Py_VISIT(ko->cmp);
    Py_VISIT(ko->object);
    return 0;
}

static PyMemberDef keyobject_members[] = {
    {"obj", _Py_T_OBJECT,
     offsetof(keyobject, object), 0,
     PyDoc_STR("Value wrapped by a key function.")},
    {NULL}
};

static PyObject *
keyobject_text_signature(PyObject *Py_UNUSED(self), void *Py_UNUSED(ignored))
{
    return PyUnicode_FromString("(obj)");
}

static PyGetSetDef keyobject_getset[] = {
    {"__text_signature__", keyobject_text_signature, NULL},
    {NULL}
};

static PyObject *
keyobject_call(PyObject *ko, PyObject *args, PyObject *kwds);

static PyObject *
keyobject_richcompare(PyObject *ko, PyObject *other, int op);

static PyType_Slot keyobject_type_slots[] = {
    {Py_tp_dealloc, keyobject_dealloc},
    {Py_tp_call, keyobject_call},
    {Py_tp_getattro, PyObject_GenericGetAttr},
    {Py_tp_traverse, keyobject_traverse},
    {Py_tp_clear, keyobject_clear},
    {Py_tp_richcompare, keyobject_richcompare},
    {Py_tp_members, keyobject_members},
    {Py_tp_getset, keyobject_getset},
    {0, 0}
};

static PyType_Spec keyobject_type_spec = {
    .name = "functools.KeyWrapper",
    .basicsize = sizeof(keyobject),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
              Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE),
    .slots = keyobject_type_slots
};

static PyObject *
keyobject_call(PyObject *self, PyObject *args, PyObject *kwds)
{
    PyObject *object;
    keyobject *result;
    static char *kwargs[] = {"obj", NULL};
    keyobject *ko = keyobject_CAST(self);

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:K", kwargs, &object))
        return NULL;

    result = PyObject_GC_New(keyobject, Py_TYPE(ko));
    if (result == NULL) {
        return NULL;
    }
    result->cmp = Py_NewRef(ko->cmp);
    result->object = Py_NewRef(object);
    PyObject_GC_Track(result);
    return (PyObject *)result;
}

static PyObject *
keyobject_richcompare(PyObject *self, PyObject *other, int op)
{
    if (!Py_IS_TYPE(other, Py_TYPE(self))) {
        PyErr_Format(PyExc_TypeError, "other argument must be K instance");
        return NULL;
    }

    keyobject *lhs = keyobject_CAST(self);
    keyobject *rhs = keyobject_CAST(other);

    PyObject *compare = lhs->cmp;
    assert(compare != NULL);
    PyObject *x = lhs->object;
    PyObject *y = rhs->object;
    if (!x || !y){
        PyErr_Format(PyExc_AttributeError, "object");
        return NULL;
    }

    /* Call the user's comparison function and translate the 3-way
     * result into true or false (or error).
     */
    PyObject* args[2] = {x, y};
    PyObject *res = PyObject_Vectorcall(compare, args, 2, NULL);
    if (res == NULL) {
        return NULL;
    }

    PyObject *answer = PyObject_RichCompare(res, _PyLong_GetZero(), op);
    Py_DECREF(res);
    return answer;
}

/*[clinic input]
_functools.cmp_to_key

    mycmp: object
        Function that compares two objects.

Convert a cmp= function into a key= function.
[clinic start generated code]*/

static PyObject *
_functools_cmp_to_key_impl(PyObject *module, PyObject *mycmp)
/*[clinic end generated code: output=71eaad0f4fc81f33 input=d1b76f231c0dfeb3]*/
{
    keyobject *object;
    _functools_state *state;

    state = get_functools_state(module);
    object = PyObject_GC_New(keyobject, state->keyobject_type);
    if (!object)
        return NULL;
    object->cmp = Py_NewRef(mycmp);
    object->object = NULL;
    PyObject_GC_Track(object);
    return (PyObject *)object;
}

/* reduce (used to be a builtin) ********************************************/

/*[clinic input]
_functools.reduce

    function as func: object
    iterable as seq: object
    /
    initial as result: object = NULL

Apply a function of two arguments cumulatively to the items of an iterable, from left to right.

This effectively reduces the iterable to a single value.  If initial is present,
it is placed before the items of the iterable in the calculation, and serves as
a default when the iterable is empty.

For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
calculates ((((1 + 2) + 3) + 4) + 5).
[clinic start generated code]*/

static PyObject *
_functools_reduce_impl(PyObject *module, PyObject *func, PyObject *seq,
                       PyObject *result)
/*[clinic end generated code: output=30d898fe1267c79d input=1511e9a8c38581ac]*/
{
    PyObject *args, *it;

    if (result != NULL)
        Py_INCREF(result);

    it = PyObject_GetIter(seq);
    if (it == NULL) {
        if (PyErr_ExceptionMatches(PyExc_TypeError))
            PyErr_SetString(PyExc_TypeError,
                            "reduce() arg 2 must support iteration");
        Py_XDECREF(result);
        return NULL;
    }

    if ((args = PyTuple_New(2)) == NULL)
        goto Fail;

    for (;;) {
        PyObject *op2;

        if (Py_REFCNT(args) > 1) {
            Py_DECREF(args);
            if ((args = PyTuple_New(2)) == NULL)
                goto Fail;
        }

        op2 = PyIter_Next(it);
        if (op2 == NULL) {
            if (PyErr_Occurred())
                goto Fail;
            break;
        }

        if (result == NULL)
            result = op2;
        else {
            /* Update the args tuple in-place */
            assert(Py_REFCNT(args) == 1);
            Py_XSETREF(_PyTuple_ITEMS(args)[0], result);
            Py_XSETREF(_PyTuple_ITEMS(args)[1], op2);
            if ((result = PyObject_Call(func, args, NULL)) == NULL) {
                goto Fail;
            }
            // bpo-42536: The GC may have untracked this args tuple. Since we're
            // recycling it, make sure it's tracked again:
            _PyTuple_Recycle(args);
        }
    }

    Py_DECREF(args);

    if (result == NULL)
        PyErr_SetString(PyExc_TypeError,
                        "reduce() of empty iterable with no initial value");

    Py_DECREF(it);
    return result;

Fail:
    Py_XDECREF(args);
    Py_XDECREF(result);
    Py_DECREF(it);
    return NULL;
}

/* lru_cache object **********************************************************/

/* There are four principal algorithmic differences from the pure python version:

   1). The C version relies on the GIL instead of having its own reentrant lock.

   2). The prev/next link fields use borrowed references.

   3). For a full cache, the pure python version rotates the location of the
       root entry so that it never has to move individual links and it can
       limit updates to just the key and result fields.  However, in the C
       version, links are temporarily removed while the cache dict updates are
       occurring. Afterwards, they are appended or prepended back into the
       doubly-linked lists.

   4)  In the Python version, the _HashSeq class is used to prevent __hash__
       from being called more than once.  In the C version, the "known hash"
       variants of dictionary calls as used to the same effect.

*/

struct lru_list_elem;
struct lru_cache_object;

typedef struct lru_list_elem {
    PyObject_HEAD
    struct lru_list_elem *prev, *next;  /* borrowed links */
    Py_hash_t hash;
    PyObject *key, *result;
} lru_list_elem;

#define lru_list_elem_CAST(op)  ((lru_list_elem *)(op))

static void
lru_list_elem_dealloc(PyObject *op)
{
    lru_list_elem *link = lru_list_elem_CAST(op);
    PyTypeObject *tp = Py_TYPE(link);
    Py_XDECREF(link->key);
    Py_XDECREF(link->result);
    tp->tp_free(link);
    Py_DECREF(tp);
}

static PyType_Slot lru_list_elem_type_slots[] = {
    {Py_tp_dealloc, lru_list_elem_dealloc},
    {0, 0}
};

static PyType_Spec lru_list_elem_type_spec = {
    .name = "functools._lru_list_elem",
    .basicsize = sizeof(lru_list_elem),
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
             Py_TPFLAGS_IMMUTABLETYPE,
    .slots = lru_list_elem_type_slots
};


typedef PyObject *(*lru_cache_ternaryfunc)(struct lru_cache_object *, PyObject *, PyObject *);

typedef struct lru_cache_object {
    lru_list_elem root;  /* includes PyObject_HEAD */
    lru_cache_ternaryfunc wrapper;
    int typed;
    PyObject *cache;
    Py_ssize_t hits;
    PyObject *func;
    Py_ssize_t maxsize;
    Py_ssize_t misses;
    /* the kwd_mark is used delimit args and keywords in the cache keys */
    PyObject *kwd_mark;
    PyTypeObject *lru_list_elem_type;
    PyObject *cache_info_type;
    PyObject *dict;
    PyObject *weakreflist;
} lru_cache_object;

#define lru_cache_object_CAST(op)   ((lru_cache_object *)(op))

static PyObject *
lru_cache_make_key(PyObject *kwd_mark, PyObject *args,
                   PyObject *kwds, int typed)
{
    PyObject *key, *keyword, *value;
    Py_ssize_t key_size, pos, key_pos, kwds_size;

    kwds_size = kwds ? PyDict_GET_SIZE(kwds) : 0;

    /* short path, key will match args anyway, which is a tuple */
    if (!typed && !kwds_size) {
        if (PyTuple_GET_SIZE(args) == 1) {
            key = PyTuple_GET_ITEM(args, 0);
            if (PyUnicode_CheckExact(key) || PyLong_CheckExact(key)) {
                /* For common scalar keys, save space by
                   dropping the enclosing args tuple  */
                return Py_NewRef(key);
            }
        }
        return Py_NewRef(args);
    }

    key_size = PyTuple_GET_SIZE(args);
    if (kwds_size)
        key_size += kwds_size * 2 + 1;
    if (typed)
        key_size += PyTuple_GET_SIZE(args) + kwds_size;

    key = PyTuple_New(key_size);
    if (key == NULL)
        return NULL;

    key_pos = 0;
    for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) {
        PyObject *item = PyTuple_GET_ITEM(args, pos);
        PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(item));
    }
    if (kwds_size) {
        PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(kwd_mark));
        for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) {
            PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(keyword));
            PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(value));
        }
        assert(key_pos == PyTuple_GET_SIZE(args) + kwds_size * 2 + 1);
    }
    if (typed) {
        for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) {
            PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(args, pos));
            PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(item));
        }
        if (kwds_size) {
            for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) {
                PyObject *item = (PyObject *)Py_TYPE(value);
                PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(item));
            }
        }
    }
    assert(key_pos == key_size);
    return key;
}

static PyObject *
uncached_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
{
    PyObject *result;

    FT_ATOMIC_ADD_SSIZE(self->misses, 1);
    result = PyObject_Call(self->func, args, kwds);
    if (!result)
        return NULL;
    return result;
}

static PyObject *
infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
{
    PyObject *result;
    Py_hash_t hash;
    PyObject *key = lru_cache_make_key(self->kwd_mark, args, kwds, self->typed);
    if (!key)
        return NULL;
    hash = PyObject_Hash(key);
    if (hash == -1) {
        Py_DECREF(key);
        return NULL;
    }
    int res = _PyDict_GetItemRef_KnownHash((PyDictObject *)self->cache, key, hash, &result);
    if (res > 0) {
        FT_ATOMIC_ADD_SSIZE(self->hits, 1);
        Py_DECREF(key);
        return result;
    }
    if (res < 0) {
        Py_DECREF(key);
        return NULL;
    }
    FT_ATOMIC_ADD_SSIZE(self->misses, 1);
    result = PyObject_Call(self->func, args, kwds);
    if (!result) {
        Py_DECREF(key);
        return NULL;
    }
    if (_PyDict_SetItem_KnownHash(self->cache, key, result, hash) < 0) {
        Py_DECREF(result);
        Py_DECREF(key);
        return NULL;
    }
    Py_DECREF(key);
    return result;
}

static void
lru_cache_extract_link(lru_list_elem *link)
{
    lru_list_elem *link_prev = link->prev;
    lru_list_elem *link_next = link->next;
    link_prev->next = link->next;
    link_next->prev = link->prev;
}

static void
lru_cache_append_link(lru_cache_object *self, lru_list_elem *link)
{
    lru_list_elem *root = &self->root;
    lru_list_elem *last = root->prev;
    last->next = root->prev = link;
    link->prev = last;
    link->next = root;
}

static void
lru_cache_prepend_link(lru_cache_object *self, lru_list_elem *link)
{
    lru_list_elem *root = &self->root;
    lru_list_elem *first = root->next;
    first->prev = root->next = link;
    link->prev = root;
    link->next = first;
}

/* General note on reentrancy:

   There are four dictionary calls in the bounded_lru_cache_wrapper():
   1) The initial check for a cache match.  2) The post user-function
   check for a cache match.  3) The deletion of the oldest entry.
   4) The addition of the newest entry.

   In all four calls, we have a known hash which lets use avoid a call
   to __hash__().  That leaves only __eq__ as a possible source of a
   reentrant call.

   The __eq__ method call is always made for a cache hit (dict access #1).
   Accordingly, we have make sure not modify the cache state prior to
   this call.

   The __eq__ method call is never made for the deletion (dict access #3)
   because it is an identity match.

   For the other two accesses (#2 and #4), calls to __eq__ only occur
   when some other entry happens to have an exactly matching hash (all
   64-bits).  Though rare, this can happen, so we have to make sure to
   either call it at the top of its code path before any cache
   state modifications (dict access #2) or be prepared to restore
   invariants at the end of the code path (dict access #4).

   Another possible source of reentrancy is a decref which can trigger
   arbitrary code execution.  To make the code easier to reason about,
   the decrefs are deferred to the end of the each possible code path
   so that we know the cache is a consistent state.
 */

static int
bounded_lru_cache_get_lock_held(lru_cache_object *self, PyObject *args, PyObject *kwds,
                                PyObject **result, PyObject **key, Py_hash_t *hash)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
    lru_list_elem *link;

    PyObject *key_ = *key = lru_cache_make_key(self->kwd_mark, args, kwds, self->typed);
    if (!key_)
        return -1;
    Py_hash_t hash_ = *hash = PyObject_Hash(key_);
    if (hash_ == -1) {
        Py_DECREF(key_);  /* dead reference left in *key, is not used */
        return -1;
    }
    int res = _PyDict_GetItemRef_KnownHash_LockHeld((PyDictObject *)self->cache, key_, hash_,
                                                    (PyObject **)&link);
    if (res > 0) {
        lru_cache_extract_link(link);
        lru_cache_append_link(self, link);
        *result = link->result;
        FT_ATOMIC_ADD_SSIZE(self->hits, 1);
        Py_INCREF(link->result);
        Py_DECREF(link);
        Py_DECREF(key_);
        return 1;
    }
    if (res < 0) {
        Py_DECREF(key_);
        return -1;
    }
    FT_ATOMIC_ADD_SSIZE(self->misses, 1);
    return 0;
}

static PyObject *
bounded_lru_cache_update_lock_held(lru_cache_object *self,
                                   PyObject *result, PyObject *key, Py_hash_t hash)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
    lru_list_elem *link;
    PyObject *testresult;
    int res;

    if (!result) {
        Py_DECREF(key);
        return NULL;
    }
    res = _PyDict_GetItemRef_KnownHash_LockHeld((PyDictObject *)self->cache, key, hash,
                                                &testresult);
    if (res > 0) {
        /* Getting here means that this same key was added to the cache
           during the PyObject_Call().  Since the link update is already
           done, we need only return the computed result. */
        Py_DECREF(testresult);
        Py_DECREF(key);
        return result;
    }
    if (res < 0) {
        /* This is an unusual case since this same lookup
           did not previously trigger an error during lookup.
           Treat it the same as an error in user function
           and return with the error set. */
        Py_DECREF(key);
        Py_DECREF(result);
        return NULL;
    }
    /* This is the normal case.  The new key wasn't found before
       user function call and it is still not there.  So we
       proceed normally and update the cache with the new result. */

    assert(self->maxsize > 0);
    if (PyDict_GET_SIZE(self->cache) < self->maxsize ||
        self->root.next == &self->root)
    {
        /* Cache is not full, so put the result in a new link */
        link = (lru_list_elem *)PyObject_New(lru_list_elem,
                                             self->lru_list_elem_type);
        if (link == NULL) {
            Py_DECREF(key);
            Py_DECREF(result);
            return NULL;
        }

        link->hash = hash;
        link->key = key;
        link->result = result;
        /* What is really needed here is a SetItem variant with a "no clobber"
           option.  If the __eq__ call triggers a reentrant call that adds
           this same key, then this setitem call will update the cache dict
           with this new link, leaving the old link as an orphan (i.e. not
           having a cache dict entry that refers to it). */
        if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
                                      hash) < 0) {
            Py_DECREF(link);
            return NULL;
        }
        lru_cache_append_link(self, link);
        return Py_NewRef(result);
    }
    /* Since the cache is full, we need to evict an old key and add
       a new key.  Rather than free the old link and allocate a new
       one, we reuse the link for the new key and result and move it
       to front of the cache to mark it as recently used.

       We try to assure all code paths (including errors) leave all
       of the links in place.  Either the link is successfully
       updated and moved or it is restored to its old position.
       However if an unrecoverable error is found, it doesn't
       make sense to reinsert the link, so we leave it out
       and the cache will no longer register as full.
    */
    PyObject *oldkey, *oldresult, *popresult;

    /* Extract the oldest item. */
    assert(self->root.next != &self->root);
    link = self->root.next;
    lru_cache_extract_link(link);
    /* Remove it from the cache.
       The cache dict holds one reference to the link.
       We created one other reference when the link was created.
       The linked list only has borrowed references. */
    res = _PyDict_Pop_KnownHash((PyDictObject*)self->cache, link->key,
                                link->hash, &popresult);
    if (res < 0) {
        /* An error arose while trying to remove the oldest key (the one
           being evicted) from the cache.  We restore the link to its
           original position as the oldest link.  Then we allow the
           error propagate upward; treating it the same as an error
           arising in the user function. */
        lru_cache_prepend_link(self, link);
        Py_DECREF(key);
        Py_DECREF(result);
        return NULL;
    }
    if (res == 0) {
        /* Getting here means that the user function call or another
           thread has already removed the old key from the dictionary.
           This link is now an orphan.  Since we don't want to leave the
           cache in an inconsistent state, we don't restore the link. */
        assert(popresult == NULL);
        Py_DECREF(link);
        Py_DECREF(key);
        return result;
    }

    /* Keep a reference to the old key and old result to prevent their
       ref counts from going to zero during the update. That will
       prevent potentially arbitrary object clean-up code (i.e. __del__)
       from running while we're still adjusting the links. */
    assert(popresult != NULL);
    oldkey = link->key;
    oldresult = link->result;

    link->hash = hash;
    link->key = key;
    link->result = result;
    /* Note:  The link is being added to the cache dict without the
       prev and next fields set to valid values.   We have to wait
       for successful insertion in the cache dict before adding the
       link to the linked list.  Otherwise, the potentially reentrant
       __eq__ call could cause the then orphan link to be visited. */
    if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
                                  hash) < 0) {
        /* Somehow the cache dict update failed.  We no longer can
           restore the old link.  Let the error propagate upward and
           leave the cache short one link. */
        Py_DECREF(popresult);
        Py_DECREF(link);
        Py_DECREF(oldkey);
        Py_DECREF(oldresult);
        return NULL;
    }
    lru_cache_append_link(self, link);
    Py_INCREF(result); /* for return */
    Py_DECREF(popresult);
    Py_DECREF(oldkey);
    Py_DECREF(oldresult);
    return result;
}

static PyObject *
bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
{
    PyObject *key, *result;
    Py_hash_t hash;
    int res;

    Py_BEGIN_CRITICAL_SECTION(self);
    res = bounded_lru_cache_get_lock_held(self, args, kwds, &result, &key, &hash);
    Py_END_CRITICAL_SECTION();

    if (res < 0) {
        return NULL;
    }
    if (res > 0) {
        return result;
    }

    result = PyObject_Call(self->func, args, kwds);

    Py_BEGIN_CRITICAL_SECTION(self);
    /* Note:  key will be stolen in the below function, and
       result may be stolen or sometimes re-returned as a passthrough.
       Treat both as being stolen.
     */
    result = bounded_lru_cache_update_lock_held(self, result, key, hash);
    Py_END_CRITICAL_SECTION();

    return result;
}

static PyObject *
lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
    PyObject *func, *maxsize_O, *cache_info_type, *cachedict;
    int typed;
    lru_cache_object *obj;
    Py_ssize_t maxsize;
    PyObject *(*wrapper)(lru_cache_object *, PyObject *, PyObject *);
    _functools_state *state;
    static char *keywords[] = {"user_function", "maxsize", "typed",
                               "cache_info_type", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kw, "OOpO:lru_cache", keywords,
                                     &func, &maxsize_O, &typed,
                                     &cache_info_type)) {
        return NULL;
    }

    if (!PyCallable_Check(func)) {
        PyErr_SetString(PyExc_TypeError,
                        "the first argument must be callable");
        return NULL;
    }

    state = get_functools_state_by_type(type);
    if (state == NULL) {
        return NULL;
    }

    /* select the caching function, and make/inc maxsize_O */
    if (maxsize_O == Py_None) {
        wrapper = infinite_lru_cache_wrapper;
        /* use this only to initialize lru_cache_object attribute maxsize */
        maxsize = -1;
    } else if (PyIndex_Check(maxsize_O)) {
        maxsize = PyNumber_AsSsize_t(maxsize_O, PyExc_OverflowError);
        if (maxsize == -1 && PyErr_Occurred())
            return NULL;
        if (maxsize < 0) {
            maxsize = 0;
        }
        if (maxsize == 0)
            wrapper = uncached_lru_cache_wrapper;
        else
            wrapper = bounded_lru_cache_wrapper;
    } else {
        PyErr_SetString(PyExc_TypeError, "maxsize should be integer or None");
        return NULL;
    }

    if (!(cachedict = PyDict_New()))
        return NULL;

    obj = (lru_cache_object *)type->tp_alloc(type, 0);
    if (obj == NULL) {
        Py_DECREF(cachedict);
        return NULL;
    }

    obj->root.prev = &obj->root;
    obj->root.next = &obj->root;
    obj->wrapper = wrapper;
    obj->typed = typed;
    obj->cache = cachedict;
    obj->func = Py_NewRef(func);
    obj->misses = obj->hits = 0;
    obj->maxsize = maxsize;
    obj->kwd_mark = Py_NewRef(state->kwd_mark);
    obj->lru_list_elem_type = (PyTypeObject*)Py_NewRef(state->lru_list_elem_type);
    obj->cache_info_type = Py_NewRef(cache_info_type);
    obj->dict = NULL;
    obj->weakreflist = NULL;
    return (PyObject *)obj;
}

static lru_list_elem *
lru_cache_unlink_list(lru_cache_object *self)
{
    lru_list_elem *root = &self->root;
    lru_list_elem *link = root->next;
    if (link == root)
        return NULL;
    root->prev->next = NULL;
    root->next = root->prev = root;
    return link;
}

static void
lru_cache_clear_list(lru_list_elem *link)
{
    while (link != NULL) {
        lru_list_elem *next = link->next;
        Py_SETREF(link, next);
    }
}

static int
lru_cache_tp_clear(PyObject *op)
{
    lru_cache_object *self = lru_cache_object_CAST(op);
    lru_list_elem *list = lru_cache_unlink_list(self);
    Py_CLEAR(self->cache);
    Py_CLEAR(self->func);
    Py_CLEAR(self->kwd_mark);
    Py_CLEAR(self->lru_list_elem_type);
    Py_CLEAR(self->cache_info_type);
    Py_CLEAR(self->dict);
    lru_cache_clear_list(list);
    return 0;
}

static void
lru_cache_dealloc(PyObject *op)
{
    lru_cache_object *obj = lru_cache_object_CAST(op);
    PyTypeObject *tp = Py_TYPE(obj);
    /* bpo-31095: UnTrack is needed before calling any callbacks */
    PyObject_GC_UnTrack(obj);
    if (obj->weakreflist != NULL) {
        PyObject_ClearWeakRefs(op);
    }

    (void)lru_cache_tp_clear(op);
    tp->tp_free(obj);
    Py_DECREF(tp);
}

static PyObject *
lru_cache_call(PyObject *op, PyObject *args, PyObject *kwds)
{
    lru_cache_object *self = lru_cache_object_CAST(op);
    PyObject *result;
    result = self->wrapper(self, args, kwds);
    return result;
}

static PyObject *
lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type)
{
    if (obj == Py_None || obj == NULL) {
        return Py_NewRef(self);
    }
    return PyMethod_New(self, obj);
}

/*[clinic input]
@critical_section
_functools._lru_cache_wrapper.cache_info

Report cache statistics
[clinic start generated code]*/

static PyObject *
_functools__lru_cache_wrapper_cache_info_impl(PyObject *self)
/*[clinic end generated code: output=cc796a0b06dbd717 input=00e1acb31aa21ecc]*/
{
    lru_cache_object *_self = (lru_cache_object *) self;
    if (_self->maxsize == -1) {
        return PyObject_CallFunction(_self->cache_info_type, "nnOn",
                                     FT_ATOMIC_LOAD_SSIZE_RELAXED(_self->hits),
                                     FT_ATOMIC_LOAD_SSIZE_RELAXED(_self->misses),
                                     Py_None,
                                     PyDict_GET_SIZE(_self->cache));
    }
    return PyObject_CallFunction(_self->cache_info_type, "nnnn",
                                 FT_ATOMIC_LOAD_SSIZE_RELAXED(_self->hits),
                                 FT_ATOMIC_LOAD_SSIZE_RELAXED(_self->misses),
                                 _self->maxsize,
                                 PyDict_GET_SIZE(_self->cache));
}

/*[clinic input]
@critical_section
_functools._lru_cache_wrapper.cache_clear

Clear the cache and cache statistics
[clinic start generated code]*/

static PyObject *
_functools__lru_cache_wrapper_cache_clear_impl(PyObject *self)
/*[clinic end generated code: output=58423b35efc3e381 input=dfa33acbecf8b4b2]*/
{
    lru_cache_object *_self = (lru_cache_object *) self;
    lru_list_elem *list = lru_cache_unlink_list(_self);
    FT_ATOMIC_STORE_SSIZE_RELAXED(_self->hits, 0);
    FT_ATOMIC_STORE_SSIZE_RELAXED(_self->misses, 0);
    PyDict_Clear(_self->cache);
    lru_cache_clear_list(list);
    Py_RETURN_NONE;
}

static PyObject *
lru_cache_reduce(PyObject *self, PyObject *Py_UNUSED(dummy))
{
    return PyObject_GetAttrString(self, "__qualname__");
}

static PyObject *
lru_cache_copy(PyObject *self, PyObject *Py_UNUSED(args))
{
    return Py_NewRef(self);
}

static PyObject *
lru_cache_deepcopy(PyObject *self, PyObject *Py_UNUSED(args))
{
    return Py_NewRef(self);
}

static int
lru_cache_tp_traverse(PyObject *op, visitproc visit, void *arg)
{
    lru_cache_object *self = lru_cache_object_CAST(op);
    Py_VISIT(Py_TYPE(self));
    lru_list_elem *link = self->root.next;
    while (link != &self->root) {
        lru_list_elem *next = link->next;
        Py_VISIT(link->key);
        Py_VISIT(link->result);
        Py_VISIT(Py_TYPE(link));
        link = next;
    }
    Py_VISIT(self->cache);
    Py_VISIT(self->func);
    Py_VISIT(self->kwd_mark);
    Py_VISIT(self->lru_list_elem_type);
    Py_VISIT(self->cache_info_type);
    Py_VISIT(self->dict);
    return 0;
}


PyDoc_STRVAR(lru_cache_doc,
"Create a cached callable that wraps another function.\n\
\n\
user_function:      the function being cached\n\
\n\
maxsize:  0         for no caching\n\
          None      for unlimited cache size\n\
          n         for a bounded cache\n\
\n\
typed:    False     cache f(3) and f(3.0) as identical calls\n\
          True      cache f(3) and f(3.0) as distinct calls\n\
\n\
cache_info_type:    namedtuple class with the fields:\n\
                        hits misses currsize maxsize\n"
);

static PyMethodDef lru_cache_methods[] = {
    _FUNCTOOLS__LRU_CACHE_WRAPPER_CACHE_INFO_METHODDEF
    _FUNCTOOLS__LRU_CACHE_WRAPPER_CACHE_CLEAR_METHODDEF
    {"__reduce__", lru_cache_reduce, METH_NOARGS},
    {"__copy__", lru_cache_copy, METH_VARARGS},
    {"__deepcopy__", lru_cache_deepcopy, METH_VARARGS},
    {NULL}
};

static PyGetSetDef lru_cache_getsetlist[] = {
    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
    {NULL}
};

static PyMemberDef lru_cache_memberlist[] = {
    {"__dictoffset__", Py_T_PYSSIZET,
     offsetof(lru_cache_object, dict), Py_READONLY},
    {"__weaklistoffset__", Py_T_PYSSIZET,
     offsetof(lru_cache_object, weakreflist), Py_READONLY},
    {NULL}  /* Sentinel */
};

static PyType_Slot lru_cache_type_slots[] = {
    {Py_tp_dealloc, lru_cache_dealloc},
    {Py_tp_call, lru_cache_call},
    {Py_tp_doc, (void *)lru_cache_doc},
    {Py_tp_traverse, lru_cache_tp_traverse},
    {Py_tp_clear, lru_cache_tp_clear},
    {Py_tp_methods, lru_cache_methods},
    {Py_tp_members, lru_cache_memberlist},
    {Py_tp_getset, lru_cache_getsetlist},
    {Py_tp_descr_get, lru_cache_descr_get},
    {Py_tp_new, lru_cache_new},
    {0, 0}
};

static PyType_Spec lru_cache_type_spec = {
    .name = "functools._lru_cache_wrapper",
    .basicsize = sizeof(lru_cache_object),
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
             Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_IMMUTABLETYPE,
    .slots = lru_cache_type_slots
};


/* module level code ********************************************************/

PyDoc_STRVAR(_functools_doc,
"Tools that operate on functions.");

static PyMethodDef _functools_methods[] = {
    _FUNCTOOLS_REDUCE_METHODDEF
    _FUNCTOOLS_CMP_TO_KEY_METHODDEF
    {NULL,              NULL}           /* sentinel */
};

static int
_functools_exec(PyObject *module)
{
    _functools_state *state = get_functools_state(module);
    state->kwd_mark = _PyObject_CallNoArgs((PyObject *)&PyBaseObject_Type);
    if (state->kwd_mark == NULL) {
        return -1;
    }

    state->placeholder_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
        &placeholder_type_spec, NULL);
    if (state->placeholder_type == NULL) {
        return -1;
    }
    if (PyModule_AddType(module, state->placeholder_type) < 0) {
        return -1;
    }

    PyObject *placeholder = PyObject_CallNoArgs((PyObject *)state->placeholder_type);
    if (placeholder == NULL) {
        return -1;
    }
    if (PyModule_AddObjectRef(module, "Placeholder", placeholder) < 0) {
        Py_DECREF(placeholder);
        return -1;
    }
    Py_DECREF(placeholder);

    state->partial_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
        &partial_type_spec, NULL);
    if (state->partial_type == NULL) {
        return -1;
    }
    if (PyModule_AddType(module, state->partial_type) < 0) {
        return -1;
    }

    PyObject *lru_cache_type = PyType_FromModuleAndSpec(module,
        &lru_cache_type_spec, NULL);
    if (lru_cache_type == NULL) {
        return -1;
    }
    if (PyModule_AddType(module, (PyTypeObject *)lru_cache_type) < 0) {
        Py_DECREF(lru_cache_type);
        return -1;
    }
    Py_DECREF(lru_cache_type);

    state->keyobject_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
        &keyobject_type_spec, NULL);
    if (state->keyobject_type == NULL) {
        return -1;
    }
    // keyobject_type is used only internally.
    // So we don't expose it in module namespace.

    state->lru_list_elem_type = (PyTypeObject *)PyType_FromModuleAndSpec(
        module, &lru_list_elem_type_spec, NULL);
    if (state->lru_list_elem_type == NULL) {
        return -1;
    }
    // lru_list_elem is used only in _lru_cache_wrapper.
    // So we don't expose it in module namespace.

    return 0;
}

static int
_functools_traverse(PyObject *module, visitproc visit, void *arg)
{
    _functools_state *state = get_functools_state(module);
    Py_VISIT(state->kwd_mark);
    Py_VISIT(state->placeholder_type);
    Py_VISIT(state->placeholder);
    Py_VISIT(state->partial_type);
    Py_VISIT(state->keyobject_type);
    Py_VISIT(state->lru_list_elem_type);
    return 0;
}

static int
_functools_clear(PyObject *module)
{
    _functools_state *state = get_functools_state(module);
    Py_CLEAR(state->kwd_mark);
    Py_CLEAR(state->placeholder_type);
    Py_CLEAR(state->placeholder);
    Py_CLEAR(state->partial_type);
    Py_CLEAR(state->keyobject_type);
    Py_CLEAR(state->lru_list_elem_type);
    return 0;
}

static void
_functools_free(void *module)
{
    (void)_functools_clear((PyObject *)module);
}

static struct PyModuleDef_Slot _functools_slots[] = {
    {Py_mod_exec, _functools_exec},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL}
};

static struct PyModuleDef _functools_module = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_functools",
    .m_doc = _functools_doc,
    .m_size = sizeof(_functools_state),
    .m_methods = _functools_methods,
    .m_slots = _functools_slots,
    .m_traverse = _functools_traverse,
    .m_clear = _functools_clear,
    .m_free = _functools_free,
};

PyMODINIT_FUNC
PyInit__functools(void)
{
    return PyModuleDef_Init(&_functools_module);
}
