#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 "pycore_weakref.h"       // FT_CLEAR_WEAKREFS()


#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 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, _PyObject_VisitType},
    {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);
        if (tot_args == NULL) {
            Py_DECREF(new_args);
            Py_DECREF(pto);
            return NULL;
        }
        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 (_PyObject_IsUniquelyReferenced(kw)) {
            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);
    FT_CLEAR_WEAKREFS(self, partialobject_CAST(self)->weakreflist);
    (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);
}

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);

    /* Placeholder check */
    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;
    }

    PyObject *result = NULL;
    PyObject *partial_function = Py_NewRef(pto->fn);
    PyObject *partial_args = Py_NewRef(pto->args);
    PyObject *partial_keywords = Py_NewRef(pto->kw);

    PyObject **pto_args = _PyTuple_ITEMS(partial_args);
    Py_ssize_t pto_nargs = PyTuple_GET_SIZE(partial_args);
    Py_ssize_t pto_nkwds = PyDict_GET_SIZE(partial_keywords);
    Py_ssize_t nkwds = kwnames == NULL ? 0 : PyTuple_GET_SIZE(kwnames);
    Py_ssize_t nargskw = nargs + nkwds;

    /* Special cases */
    if (!pto_nkwds) {
        /* Fast path if we're called without arguments */
        if (nargskw == 0) {
            result = _PyObject_VectorcallTstate(tstate, partial_function, pto_args,
                                                pto_nargs, NULL);
            goto done;
        }

        /* Use 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];
            result = _PyObject_VectorcallTstate(tstate, partial_function, newargs,
                                                nargs + 1, kwnames);
            newargs[0] = tmp;
            goto done;
        }
    }

    /* Total sizes */
    Py_ssize_t tot_nargs = pto_nargs + nargs - pto_phcount;
    Py_ssize_t tot_nkwds = pto_nkwds + nkwds;
    Py_ssize_t tot_nargskw = tot_nargs + tot_nkwds;

    PyObject *pto_kw_merged = NULL;  // pto_kw with duplicates merged (if any)
    PyObject *tot_kwnames;

    /* Allocate Stack
     * Note, _PY_FASTCALL_SMALL_STACK is optimal for positional only
     * This case might have keyword arguments
     *  furthermore, it might use extra stack space for temporary key storage
     *  thus, double small_stack size is used, which is 10 * 8 = 80 bytes */
    PyObject *small_stack[_PY_FASTCALL_SMALL_STACK * 2];
    PyObject **tmp_stack, **stack;
    Py_ssize_t init_stack_size = tot_nargskw;
    if (pto_nkwds) {
        // If pto_nkwds, allocate additional space for temporary new keys
        init_stack_size += nkwds;
    }
    if (init_stack_size <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
        stack = small_stack;
    }
    else {
        stack = PyMem_Malloc(init_stack_size * sizeof(PyObject *));
        if (stack == NULL) {
            PyErr_NoMemory();
            goto done;
        }
    }

    /* Copy keywords to stack */
    if (!pto_nkwds) {
        tot_kwnames = kwnames;
        if (nkwds) {
            /* if !pto_nkwds & nkwds, then simply append kw */
            memcpy(stack + tot_nargs, args + nargs, nkwds * sizeof(PyObject*));
        }
    }
    else {
        /* stack is now         [<positionals>, <pto_kwds>, <kwds>, <kwds_keys>]
         * Will resize later to [<positionals>, <merged_kwds>] */
        PyObject *key, *val;

        /* Merge kw to pto_kw or add to tail (if not duplicate) */
        Py_ssize_t n_tail = 0;
        for (Py_ssize_t i = 0; i < nkwds; ++i) {
            key = PyTuple_GET_ITEM(kwnames, i);
            val = args[nargs + i];
            int contains = PyDict_Contains(partial_keywords, key);
            if (contains < 0) {
                goto clean_stack;
            }
            else if (contains == 1) {
                if (pto_kw_merged == NULL) {
                    pto_kw_merged = PyDict_Copy(partial_keywords);
                    if (pto_kw_merged == NULL) {
                        goto clean_stack;
                    }
                }
                if (PyDict_SetItem(pto_kw_merged, key, val) < 0) {
                    Py_DECREF(pto_kw_merged);
                    goto clean_stack;
                }
            }
            else {
                /* Copy keyword tail to stack */
                stack[tot_nargs + pto_nkwds + n_tail] = val;
                stack[tot_nargskw + n_tail] = key;
                n_tail++;
            }
        }
        Py_ssize_t n_merges = nkwds - n_tail;

        /* Create total kwnames */
        tot_kwnames = PyTuple_New(tot_nkwds - n_merges);
        if (tot_kwnames == NULL) {
            Py_XDECREF(pto_kw_merged);
            goto clean_stack;
        }
        for (Py_ssize_t i = 0; i < n_tail; ++i) {
            key = Py_NewRef(stack[tot_nargskw + i]);
            PyTuple_SET_ITEM(tot_kwnames, pto_nkwds + i, key);
        }

        /* Copy pto_keywords with overlapping call keywords merged
         * Note, tail is already coppied. */
        Py_ssize_t pos = 0, i = 0;
        PyObject *keyword_dict = n_merges ? pto_kw_merged : partial_keywords;
        Py_BEGIN_CRITICAL_SECTION(keyword_dict);
        while (PyDict_Next(keyword_dict, &pos, &key, &val)) {
            assert(i < pto_nkwds);
            PyTuple_SET_ITEM(tot_kwnames, i, Py_NewRef(key));
            stack[tot_nargs + i] = val;
            i++;
        }
        Py_END_CRITICAL_SECTION();
        assert(i == pto_nkwds);
        Py_XDECREF(pto_kw_merged);

        /* Resize Stack if the removing overallocation saves some noticable memory
         * NOTE: This whole block can be removed without breaking anything */
        Py_ssize_t noveralloc = n_merges + nkwds;
        if (stack != small_stack && noveralloc > 6 && noveralloc > init_stack_size / 10) {
            tmp_stack = PyMem_Realloc(stack, (tot_nargskw - n_merges) * sizeof(PyObject *));
            if (tmp_stack == NULL) {
                Py_DECREF(tot_kwnames);
                PyErr_NoMemory();
                goto clean_stack;
            }
            stack = tmp_stack;
        }
    }

    /* Copy Positionals to stack */
    if (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);
        /* Add remaining args from new_args */
        if (nargs > pto_phcount) {
            memcpy(stack + pto_nargs, args + j, (nargs - j) * sizeof(PyObject*));
        }
    }
    else {
        memcpy(stack, pto_args, pto_nargs * sizeof(PyObject*));
        memcpy(stack + pto_nargs, args, nargs * sizeof(PyObject*));
    }

    result = _PyObject_VectorcallTstate(tstate, partial_function, stack,
                                        tot_nargs, tot_kwnames);
    if (pto_nkwds) {
        Py_DECREF(tot_kwnames);
    }

 clean_stack:
    if (stack != small_stack) {
        PyMem_Free(stack);
    }

 done:
    Py_DECREF(partial_function);
    Py_DECREF(partial_args);
    Py_DECREF(partial_keywords);
    return result;
}

/* 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 = NULL;
    PyObject *mod = NULL;
    PyObject *name = NULL;
    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("...");
    }
    /* Reference arguments in case they change */
    PyObject *fn = Py_NewRef(pto->fn);
    PyObject *args = Py_NewRef(pto->args);
    PyObject *kw = Py_NewRef(pto->kw);
    assert(PyTuple_Check(args));
    assert(PyDict_Check(kw));

    arglist = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
    if (arglist == NULL) {
        goto done;
    }
    /* Pack positional arguments */
    n = PyTuple_GET_SIZE(args);
    for (i = 0; i < n; i++) {
        Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist,
                                        PyTuple_GET_ITEM(args, i)));
        if (arglist == NULL) {
            goto done;
        }
    }
    /* Pack keyword arguments */
    int error = 0;
    Py_BEGIN_CRITICAL_SECTION(kw);
    for (i = 0; PyDict_Next(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) {
            error = 1;
            break;
        }
    }
    Py_END_CRITICAL_SECTION();
    if (error) {
        goto done;
    }

    mod = PyType_GetModuleName(Py_TYPE(pto));
    if (mod == NULL) {
        goto done;
    }

    name = PyType_GetQualName(Py_TYPE(pto));
    if (name == NULL) {
        goto done;
    }

    result = PyUnicode_FromFormat("%S.%S(%R%U)", mod, name, fn, arglist);
done:
    Py_XDECREF(name);
    Py_XDECREF(mod);
    Py_XDECREF(arglist);
    Py_DECREF(fn);
    Py_DECREF(args);
    Py_DECREF(kw);
    Py_ReprLeave(self);
    return result;
}

/* 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)) ||
        (dict != Py_None && !PyDict_Check(dict)))
    {
        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("partial is generic over the wrapped function's return type")},
    {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]
@permit_long_summary
_functools.reduce

    function as func: object
    iterable as seq: object
    /
    initial as result: object(c_default="NULL") = functools._initial_missing

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=ff4d5c73100e72e8]*/
{
    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 (!_PyObject_IsUniquelyReferenced(args)) {
            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_LockHeld((PyDictObject *)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_LockHeld((PyDictObject *)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);
    FT_CLEAR_WEAKREFS(op, obj->weakreflist);

    (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);
    if (_self->wrapper == bounded_lru_cache_wrapper) {
        /* The critical section on the lru cache itself protects the dictionary
           for bounded_lru_cache instances. */
        _PyDict_Clear_LockHeld(_self->cache);
    } else {
        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_ABI_SLOT,
    {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);
}
