17db96d56Sopenharmony_ci
27db96d56Sopenharmony_ci/* Function object implementation */
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci#include "Python.h"
57db96d56Sopenharmony_ci#include "pycore_ceval.h"         // _PyEval_BuiltinsFromGlobals()
67db96d56Sopenharmony_ci#include "pycore_object.h"        // _PyObject_GC_UNTRACK()
77db96d56Sopenharmony_ci#include "pycore_pyerrors.h"      // _PyErr_Occurred()
87db96d56Sopenharmony_ci#include "structmember.h"         // PyMemberDef
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_cistatic uint32_t next_func_version = 1;
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_ciPyFunctionObject *
137db96d56Sopenharmony_ci_PyFunction_FromConstructor(PyFrameConstructor *constr)
147db96d56Sopenharmony_ci{
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci    PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type);
177db96d56Sopenharmony_ci    if (op == NULL) {
187db96d56Sopenharmony_ci        return NULL;
197db96d56Sopenharmony_ci    }
207db96d56Sopenharmony_ci    Py_INCREF(constr->fc_globals);
217db96d56Sopenharmony_ci    op->func_globals = constr->fc_globals;
227db96d56Sopenharmony_ci    Py_INCREF(constr->fc_builtins);
237db96d56Sopenharmony_ci    op->func_builtins = constr->fc_builtins;
247db96d56Sopenharmony_ci    Py_INCREF(constr->fc_name);
257db96d56Sopenharmony_ci    op->func_name = constr->fc_name;
267db96d56Sopenharmony_ci    Py_INCREF(constr->fc_qualname);
277db96d56Sopenharmony_ci    op->func_qualname = constr->fc_qualname;
287db96d56Sopenharmony_ci    Py_INCREF(constr->fc_code);
297db96d56Sopenharmony_ci    op->func_code = constr->fc_code;
307db96d56Sopenharmony_ci    Py_XINCREF(constr->fc_defaults);
317db96d56Sopenharmony_ci    op->func_defaults = constr->fc_defaults;
327db96d56Sopenharmony_ci    Py_XINCREF(constr->fc_kwdefaults);
337db96d56Sopenharmony_ci    op->func_kwdefaults = constr->fc_kwdefaults;
347db96d56Sopenharmony_ci    Py_XINCREF(constr->fc_closure);
357db96d56Sopenharmony_ci    op->func_closure = constr->fc_closure;
367db96d56Sopenharmony_ci    Py_INCREF(Py_None);
377db96d56Sopenharmony_ci    op->func_doc = Py_None;
387db96d56Sopenharmony_ci    op->func_dict = NULL;
397db96d56Sopenharmony_ci    op->func_weakreflist = NULL;
407db96d56Sopenharmony_ci    op->func_module = NULL;
417db96d56Sopenharmony_ci    op->func_annotations = NULL;
427db96d56Sopenharmony_ci    op->vectorcall = _PyFunction_Vectorcall;
437db96d56Sopenharmony_ci    op->func_version = 0;
447db96d56Sopenharmony_ci    _PyObject_GC_TRACK(op);
457db96d56Sopenharmony_ci    return op;
467db96d56Sopenharmony_ci}
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_ciPyObject *
497db96d56Sopenharmony_ciPyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname)
507db96d56Sopenharmony_ci{
517db96d56Sopenharmony_ci    assert(globals != NULL);
527db96d56Sopenharmony_ci    assert(PyDict_Check(globals));
537db96d56Sopenharmony_ci    Py_INCREF(globals);
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci    PyCodeObject *code_obj = (PyCodeObject *)code;
587db96d56Sopenharmony_ci    Py_INCREF(code_obj);
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci    PyObject *name = code_obj->co_name;
617db96d56Sopenharmony_ci    assert(name != NULL);
627db96d56Sopenharmony_ci    Py_INCREF(name);
637db96d56Sopenharmony_ci
647db96d56Sopenharmony_ci    if (!qualname) {
657db96d56Sopenharmony_ci        qualname = code_obj->co_qualname;
667db96d56Sopenharmony_ci    }
677db96d56Sopenharmony_ci    assert(qualname != NULL);
687db96d56Sopenharmony_ci    Py_INCREF(qualname);
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci    PyObject *consts = code_obj->co_consts;
717db96d56Sopenharmony_ci    assert(PyTuple_Check(consts));
727db96d56Sopenharmony_ci    PyObject *doc;
737db96d56Sopenharmony_ci    if (PyTuple_Size(consts) >= 1) {
747db96d56Sopenharmony_ci        doc = PyTuple_GetItem(consts, 0);
757db96d56Sopenharmony_ci        if (!PyUnicode_Check(doc)) {
767db96d56Sopenharmony_ci            doc = Py_None;
777db96d56Sopenharmony_ci        }
787db96d56Sopenharmony_ci    }
797db96d56Sopenharmony_ci    else {
807db96d56Sopenharmony_ci        doc = Py_None;
817db96d56Sopenharmony_ci    }
827db96d56Sopenharmony_ci    Py_INCREF(doc);
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci    // __module__: Use globals['__name__'] if it exists, or NULL.
857db96d56Sopenharmony_ci    PyObject *module = PyDict_GetItemWithError(globals, &_Py_ID(__name__));
867db96d56Sopenharmony_ci    PyObject *builtins = NULL;
877db96d56Sopenharmony_ci    if (module == NULL && _PyErr_Occurred(tstate)) {
887db96d56Sopenharmony_ci        goto error;
897db96d56Sopenharmony_ci    }
907db96d56Sopenharmony_ci    Py_XINCREF(module);
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ci    builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref
937db96d56Sopenharmony_ci    if (builtins == NULL) {
947db96d56Sopenharmony_ci        goto error;
957db96d56Sopenharmony_ci    }
967db96d56Sopenharmony_ci    Py_INCREF(builtins);
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_ci    PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type);
997db96d56Sopenharmony_ci    if (op == NULL) {
1007db96d56Sopenharmony_ci        goto error;
1017db96d56Sopenharmony_ci    }
1027db96d56Sopenharmony_ci    /* Note: No failures from this point on, since func_dealloc() does not
1037db96d56Sopenharmony_ci       expect a partially-created object. */
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_ci    op->func_globals = globals;
1067db96d56Sopenharmony_ci    op->func_builtins = builtins;
1077db96d56Sopenharmony_ci    op->func_name = name;
1087db96d56Sopenharmony_ci    op->func_qualname = qualname;
1097db96d56Sopenharmony_ci    op->func_code = (PyObject*)code_obj;
1107db96d56Sopenharmony_ci    op->func_defaults = NULL;    // No default positional arguments
1117db96d56Sopenharmony_ci    op->func_kwdefaults = NULL;  // No default keyword arguments
1127db96d56Sopenharmony_ci    op->func_closure = NULL;
1137db96d56Sopenharmony_ci    op->func_doc = doc;
1147db96d56Sopenharmony_ci    op->func_dict = NULL;
1157db96d56Sopenharmony_ci    op->func_weakreflist = NULL;
1167db96d56Sopenharmony_ci    op->func_module = module;
1177db96d56Sopenharmony_ci    op->func_annotations = NULL;
1187db96d56Sopenharmony_ci    op->vectorcall = _PyFunction_Vectorcall;
1197db96d56Sopenharmony_ci    op->func_version = 0;
1207db96d56Sopenharmony_ci    _PyObject_GC_TRACK(op);
1217db96d56Sopenharmony_ci    return (PyObject *)op;
1227db96d56Sopenharmony_ci
1237db96d56Sopenharmony_cierror:
1247db96d56Sopenharmony_ci    Py_DECREF(globals);
1257db96d56Sopenharmony_ci    Py_DECREF(code_obj);
1267db96d56Sopenharmony_ci    Py_DECREF(name);
1277db96d56Sopenharmony_ci    Py_DECREF(qualname);
1287db96d56Sopenharmony_ci    Py_DECREF(doc);
1297db96d56Sopenharmony_ci    Py_XDECREF(module);
1307db96d56Sopenharmony_ci    Py_XDECREF(builtins);
1317db96d56Sopenharmony_ci    return NULL;
1327db96d56Sopenharmony_ci}
1337db96d56Sopenharmony_ci
1347db96d56Sopenharmony_ciuint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func)
1357db96d56Sopenharmony_ci{
1367db96d56Sopenharmony_ci    if (func->func_version != 0) {
1377db96d56Sopenharmony_ci        return func->func_version;
1387db96d56Sopenharmony_ci    }
1397db96d56Sopenharmony_ci    if (next_func_version == 0) {
1407db96d56Sopenharmony_ci        return 0;
1417db96d56Sopenharmony_ci    }
1427db96d56Sopenharmony_ci    uint32_t v = next_func_version++;
1437db96d56Sopenharmony_ci    func->func_version = v;
1447db96d56Sopenharmony_ci    return v;
1457db96d56Sopenharmony_ci}
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ciPyObject *
1487db96d56Sopenharmony_ciPyFunction_New(PyObject *code, PyObject *globals)
1497db96d56Sopenharmony_ci{
1507db96d56Sopenharmony_ci    return PyFunction_NewWithQualName(code, globals, NULL);
1517db96d56Sopenharmony_ci}
1527db96d56Sopenharmony_ci
1537db96d56Sopenharmony_ciPyObject *
1547db96d56Sopenharmony_ciPyFunction_GetCode(PyObject *op)
1557db96d56Sopenharmony_ci{
1567db96d56Sopenharmony_ci    if (!PyFunction_Check(op)) {
1577db96d56Sopenharmony_ci        PyErr_BadInternalCall();
1587db96d56Sopenharmony_ci        return NULL;
1597db96d56Sopenharmony_ci    }
1607db96d56Sopenharmony_ci    return ((PyFunctionObject *) op) -> func_code;
1617db96d56Sopenharmony_ci}
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ciPyObject *
1647db96d56Sopenharmony_ciPyFunction_GetGlobals(PyObject *op)
1657db96d56Sopenharmony_ci{
1667db96d56Sopenharmony_ci    if (!PyFunction_Check(op)) {
1677db96d56Sopenharmony_ci        PyErr_BadInternalCall();
1687db96d56Sopenharmony_ci        return NULL;
1697db96d56Sopenharmony_ci    }
1707db96d56Sopenharmony_ci    return ((PyFunctionObject *) op) -> func_globals;
1717db96d56Sopenharmony_ci}
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ciPyObject *
1747db96d56Sopenharmony_ciPyFunction_GetModule(PyObject *op)
1757db96d56Sopenharmony_ci{
1767db96d56Sopenharmony_ci    if (!PyFunction_Check(op)) {
1777db96d56Sopenharmony_ci        PyErr_BadInternalCall();
1787db96d56Sopenharmony_ci        return NULL;
1797db96d56Sopenharmony_ci    }
1807db96d56Sopenharmony_ci    return ((PyFunctionObject *) op) -> func_module;
1817db96d56Sopenharmony_ci}
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_ciPyObject *
1847db96d56Sopenharmony_ciPyFunction_GetDefaults(PyObject *op)
1857db96d56Sopenharmony_ci{
1867db96d56Sopenharmony_ci    if (!PyFunction_Check(op)) {
1877db96d56Sopenharmony_ci        PyErr_BadInternalCall();
1887db96d56Sopenharmony_ci        return NULL;
1897db96d56Sopenharmony_ci    }
1907db96d56Sopenharmony_ci    return ((PyFunctionObject *) op) -> func_defaults;
1917db96d56Sopenharmony_ci}
1927db96d56Sopenharmony_ci
1937db96d56Sopenharmony_ciint
1947db96d56Sopenharmony_ciPyFunction_SetDefaults(PyObject *op, PyObject *defaults)
1957db96d56Sopenharmony_ci{
1967db96d56Sopenharmony_ci    if (!PyFunction_Check(op)) {
1977db96d56Sopenharmony_ci        PyErr_BadInternalCall();
1987db96d56Sopenharmony_ci        return -1;
1997db96d56Sopenharmony_ci    }
2007db96d56Sopenharmony_ci    if (defaults == Py_None)
2017db96d56Sopenharmony_ci        defaults = NULL;
2027db96d56Sopenharmony_ci    else if (defaults && PyTuple_Check(defaults)) {
2037db96d56Sopenharmony_ci        Py_INCREF(defaults);
2047db96d56Sopenharmony_ci    }
2057db96d56Sopenharmony_ci    else {
2067db96d56Sopenharmony_ci        PyErr_SetString(PyExc_SystemError, "non-tuple default args");
2077db96d56Sopenharmony_ci        return -1;
2087db96d56Sopenharmony_ci    }
2097db96d56Sopenharmony_ci    ((PyFunctionObject *)op)->func_version = 0;
2107db96d56Sopenharmony_ci    Py_XSETREF(((PyFunctionObject *)op)->func_defaults, defaults);
2117db96d56Sopenharmony_ci    return 0;
2127db96d56Sopenharmony_ci}
2137db96d56Sopenharmony_ci
2147db96d56Sopenharmony_ciPyObject *
2157db96d56Sopenharmony_ciPyFunction_GetKwDefaults(PyObject *op)
2167db96d56Sopenharmony_ci{
2177db96d56Sopenharmony_ci    if (!PyFunction_Check(op)) {
2187db96d56Sopenharmony_ci        PyErr_BadInternalCall();
2197db96d56Sopenharmony_ci        return NULL;
2207db96d56Sopenharmony_ci    }
2217db96d56Sopenharmony_ci    return ((PyFunctionObject *) op) -> func_kwdefaults;
2227db96d56Sopenharmony_ci}
2237db96d56Sopenharmony_ci
2247db96d56Sopenharmony_ciint
2257db96d56Sopenharmony_ciPyFunction_SetKwDefaults(PyObject *op, PyObject *defaults)
2267db96d56Sopenharmony_ci{
2277db96d56Sopenharmony_ci    if (!PyFunction_Check(op)) {
2287db96d56Sopenharmony_ci        PyErr_BadInternalCall();
2297db96d56Sopenharmony_ci        return -1;
2307db96d56Sopenharmony_ci    }
2317db96d56Sopenharmony_ci    if (defaults == Py_None)
2327db96d56Sopenharmony_ci        defaults = NULL;
2337db96d56Sopenharmony_ci    else if (defaults && PyDict_Check(defaults)) {
2347db96d56Sopenharmony_ci        Py_INCREF(defaults);
2357db96d56Sopenharmony_ci    }
2367db96d56Sopenharmony_ci    else {
2377db96d56Sopenharmony_ci        PyErr_SetString(PyExc_SystemError,
2387db96d56Sopenharmony_ci                        "non-dict keyword only default args");
2397db96d56Sopenharmony_ci        return -1;
2407db96d56Sopenharmony_ci    }
2417db96d56Sopenharmony_ci    ((PyFunctionObject *)op)->func_version = 0;
2427db96d56Sopenharmony_ci    Py_XSETREF(((PyFunctionObject *)op)->func_kwdefaults, defaults);
2437db96d56Sopenharmony_ci    return 0;
2447db96d56Sopenharmony_ci}
2457db96d56Sopenharmony_ci
2467db96d56Sopenharmony_ciPyObject *
2477db96d56Sopenharmony_ciPyFunction_GetClosure(PyObject *op)
2487db96d56Sopenharmony_ci{
2497db96d56Sopenharmony_ci    if (!PyFunction_Check(op)) {
2507db96d56Sopenharmony_ci        PyErr_BadInternalCall();
2517db96d56Sopenharmony_ci        return NULL;
2527db96d56Sopenharmony_ci    }
2537db96d56Sopenharmony_ci    return ((PyFunctionObject *) op) -> func_closure;
2547db96d56Sopenharmony_ci}
2557db96d56Sopenharmony_ci
2567db96d56Sopenharmony_ciint
2577db96d56Sopenharmony_ciPyFunction_SetClosure(PyObject *op, PyObject *closure)
2587db96d56Sopenharmony_ci{
2597db96d56Sopenharmony_ci    if (!PyFunction_Check(op)) {
2607db96d56Sopenharmony_ci        PyErr_BadInternalCall();
2617db96d56Sopenharmony_ci        return -1;
2627db96d56Sopenharmony_ci    }
2637db96d56Sopenharmony_ci    if (closure == Py_None)
2647db96d56Sopenharmony_ci        closure = NULL;
2657db96d56Sopenharmony_ci    else if (PyTuple_Check(closure)) {
2667db96d56Sopenharmony_ci        Py_INCREF(closure);
2677db96d56Sopenharmony_ci    }
2687db96d56Sopenharmony_ci    else {
2697db96d56Sopenharmony_ci        PyErr_Format(PyExc_SystemError,
2707db96d56Sopenharmony_ci                     "expected tuple for closure, got '%.100s'",
2717db96d56Sopenharmony_ci                     Py_TYPE(closure)->tp_name);
2727db96d56Sopenharmony_ci        return -1;
2737db96d56Sopenharmony_ci    }
2747db96d56Sopenharmony_ci    ((PyFunctionObject *)op)->func_version = 0;
2757db96d56Sopenharmony_ci    Py_XSETREF(((PyFunctionObject *)op)->func_closure, closure);
2767db96d56Sopenharmony_ci    return 0;
2777db96d56Sopenharmony_ci}
2787db96d56Sopenharmony_ci
2797db96d56Sopenharmony_cistatic PyObject *
2807db96d56Sopenharmony_cifunc_get_annotation_dict(PyFunctionObject *op)
2817db96d56Sopenharmony_ci{
2827db96d56Sopenharmony_ci    if (op->func_annotations == NULL) {
2837db96d56Sopenharmony_ci        return NULL;
2847db96d56Sopenharmony_ci    }
2857db96d56Sopenharmony_ci    if (PyTuple_CheckExact(op->func_annotations)) {
2867db96d56Sopenharmony_ci        PyObject *ann_tuple = op->func_annotations;
2877db96d56Sopenharmony_ci        PyObject *ann_dict = PyDict_New();
2887db96d56Sopenharmony_ci        if (ann_dict == NULL) {
2897db96d56Sopenharmony_ci            return NULL;
2907db96d56Sopenharmony_ci        }
2917db96d56Sopenharmony_ci
2927db96d56Sopenharmony_ci        assert(PyTuple_GET_SIZE(ann_tuple) % 2 == 0);
2937db96d56Sopenharmony_ci
2947db96d56Sopenharmony_ci        for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(ann_tuple); i += 2) {
2957db96d56Sopenharmony_ci            int err = PyDict_SetItem(ann_dict,
2967db96d56Sopenharmony_ci                                     PyTuple_GET_ITEM(ann_tuple, i),
2977db96d56Sopenharmony_ci                                     PyTuple_GET_ITEM(ann_tuple, i + 1));
2987db96d56Sopenharmony_ci
2997db96d56Sopenharmony_ci            if (err < 0) {
3007db96d56Sopenharmony_ci                return NULL;
3017db96d56Sopenharmony_ci            }
3027db96d56Sopenharmony_ci        }
3037db96d56Sopenharmony_ci        Py_SETREF(op->func_annotations, ann_dict);
3047db96d56Sopenharmony_ci    }
3057db96d56Sopenharmony_ci    assert(PyDict_Check(op->func_annotations));
3067db96d56Sopenharmony_ci    return op->func_annotations;
3077db96d56Sopenharmony_ci}
3087db96d56Sopenharmony_ci
3097db96d56Sopenharmony_ciPyObject *
3107db96d56Sopenharmony_ciPyFunction_GetAnnotations(PyObject *op)
3117db96d56Sopenharmony_ci{
3127db96d56Sopenharmony_ci    if (!PyFunction_Check(op)) {
3137db96d56Sopenharmony_ci        PyErr_BadInternalCall();
3147db96d56Sopenharmony_ci        return NULL;
3157db96d56Sopenharmony_ci    }
3167db96d56Sopenharmony_ci    return func_get_annotation_dict((PyFunctionObject *)op);
3177db96d56Sopenharmony_ci}
3187db96d56Sopenharmony_ci
3197db96d56Sopenharmony_ciint
3207db96d56Sopenharmony_ciPyFunction_SetAnnotations(PyObject *op, PyObject *annotations)
3217db96d56Sopenharmony_ci{
3227db96d56Sopenharmony_ci    if (!PyFunction_Check(op)) {
3237db96d56Sopenharmony_ci        PyErr_BadInternalCall();
3247db96d56Sopenharmony_ci        return -1;
3257db96d56Sopenharmony_ci    }
3267db96d56Sopenharmony_ci    if (annotations == Py_None)
3277db96d56Sopenharmony_ci        annotations = NULL;
3287db96d56Sopenharmony_ci    else if (annotations && PyDict_Check(annotations)) {
3297db96d56Sopenharmony_ci        Py_INCREF(annotations);
3307db96d56Sopenharmony_ci    }
3317db96d56Sopenharmony_ci    else {
3327db96d56Sopenharmony_ci        PyErr_SetString(PyExc_SystemError,
3337db96d56Sopenharmony_ci                        "non-dict annotations");
3347db96d56Sopenharmony_ci        return -1;
3357db96d56Sopenharmony_ci    }
3367db96d56Sopenharmony_ci    ((PyFunctionObject *)op)->func_version = 0;
3377db96d56Sopenharmony_ci    Py_XSETREF(((PyFunctionObject *)op)->func_annotations, annotations);
3387db96d56Sopenharmony_ci    return 0;
3397db96d56Sopenharmony_ci}
3407db96d56Sopenharmony_ci
3417db96d56Sopenharmony_ci/* Methods */
3427db96d56Sopenharmony_ci
3437db96d56Sopenharmony_ci#define OFF(x) offsetof(PyFunctionObject, x)
3447db96d56Sopenharmony_ci
3457db96d56Sopenharmony_cistatic PyMemberDef func_memberlist[] = {
3467db96d56Sopenharmony_ci    {"__closure__",   T_OBJECT,     OFF(func_closure), READONLY},
3477db96d56Sopenharmony_ci    {"__doc__",       T_OBJECT,     OFF(func_doc), 0},
3487db96d56Sopenharmony_ci    {"__globals__",   T_OBJECT,     OFF(func_globals), READONLY},
3497db96d56Sopenharmony_ci    {"__module__",    T_OBJECT,     OFF(func_module), 0},
3507db96d56Sopenharmony_ci    {"__builtins__",  T_OBJECT,     OFF(func_builtins), READONLY},
3517db96d56Sopenharmony_ci    {NULL}  /* Sentinel */
3527db96d56Sopenharmony_ci};
3537db96d56Sopenharmony_ci
3547db96d56Sopenharmony_cistatic PyObject *
3557db96d56Sopenharmony_cifunc_get_code(PyFunctionObject *op, void *Py_UNUSED(ignored))
3567db96d56Sopenharmony_ci{
3577db96d56Sopenharmony_ci    if (PySys_Audit("object.__getattr__", "Os", op, "__code__") < 0) {
3587db96d56Sopenharmony_ci        return NULL;
3597db96d56Sopenharmony_ci    }
3607db96d56Sopenharmony_ci
3617db96d56Sopenharmony_ci    Py_INCREF(op->func_code);
3627db96d56Sopenharmony_ci    return op->func_code;
3637db96d56Sopenharmony_ci}
3647db96d56Sopenharmony_ci
3657db96d56Sopenharmony_cistatic int
3667db96d56Sopenharmony_cifunc_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
3677db96d56Sopenharmony_ci{
3687db96d56Sopenharmony_ci    Py_ssize_t nclosure;
3697db96d56Sopenharmony_ci    int nfree;
3707db96d56Sopenharmony_ci
3717db96d56Sopenharmony_ci    /* Not legal to del f.func_code or to set it to anything
3727db96d56Sopenharmony_ci     * other than a code object. */
3737db96d56Sopenharmony_ci    if (value == NULL || !PyCode_Check(value)) {
3747db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
3757db96d56Sopenharmony_ci                        "__code__ must be set to a code object");
3767db96d56Sopenharmony_ci        return -1;
3777db96d56Sopenharmony_ci    }
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_ci    if (PySys_Audit("object.__setattr__", "OsO",
3807db96d56Sopenharmony_ci                    op, "__code__", value) < 0) {
3817db96d56Sopenharmony_ci        return -1;
3827db96d56Sopenharmony_ci    }
3837db96d56Sopenharmony_ci
3847db96d56Sopenharmony_ci    nfree = ((PyCodeObject *)value)->co_nfreevars;
3857db96d56Sopenharmony_ci    nclosure = (op->func_closure == NULL ? 0 :
3867db96d56Sopenharmony_ci            PyTuple_GET_SIZE(op->func_closure));
3877db96d56Sopenharmony_ci    if (nclosure != nfree) {
3887db96d56Sopenharmony_ci        PyErr_Format(PyExc_ValueError,
3897db96d56Sopenharmony_ci                     "%U() requires a code object with %zd free vars,"
3907db96d56Sopenharmony_ci                     " not %zd",
3917db96d56Sopenharmony_ci                     op->func_name,
3927db96d56Sopenharmony_ci                     nclosure, nfree);
3937db96d56Sopenharmony_ci        return -1;
3947db96d56Sopenharmony_ci    }
3957db96d56Sopenharmony_ci    op->func_version = 0;
3967db96d56Sopenharmony_ci    Py_INCREF(value);
3977db96d56Sopenharmony_ci    Py_XSETREF(op->func_code, value);
3987db96d56Sopenharmony_ci    return 0;
3997db96d56Sopenharmony_ci}
4007db96d56Sopenharmony_ci
4017db96d56Sopenharmony_cistatic PyObject *
4027db96d56Sopenharmony_cifunc_get_name(PyFunctionObject *op, void *Py_UNUSED(ignored))
4037db96d56Sopenharmony_ci{
4047db96d56Sopenharmony_ci    Py_INCREF(op->func_name);
4057db96d56Sopenharmony_ci    return op->func_name;
4067db96d56Sopenharmony_ci}
4077db96d56Sopenharmony_ci
4087db96d56Sopenharmony_cistatic int
4097db96d56Sopenharmony_cifunc_set_name(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
4107db96d56Sopenharmony_ci{
4117db96d56Sopenharmony_ci    /* Not legal to del f.func_name or to set it to anything
4127db96d56Sopenharmony_ci     * other than a string object. */
4137db96d56Sopenharmony_ci    if (value == NULL || !PyUnicode_Check(value)) {
4147db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
4157db96d56Sopenharmony_ci                        "__name__ must be set to a string object");
4167db96d56Sopenharmony_ci        return -1;
4177db96d56Sopenharmony_ci    }
4187db96d56Sopenharmony_ci    Py_INCREF(value);
4197db96d56Sopenharmony_ci    Py_XSETREF(op->func_name, value);
4207db96d56Sopenharmony_ci    return 0;
4217db96d56Sopenharmony_ci}
4227db96d56Sopenharmony_ci
4237db96d56Sopenharmony_cistatic PyObject *
4247db96d56Sopenharmony_cifunc_get_qualname(PyFunctionObject *op, void *Py_UNUSED(ignored))
4257db96d56Sopenharmony_ci{
4267db96d56Sopenharmony_ci    Py_INCREF(op->func_qualname);
4277db96d56Sopenharmony_ci    return op->func_qualname;
4287db96d56Sopenharmony_ci}
4297db96d56Sopenharmony_ci
4307db96d56Sopenharmony_cistatic int
4317db96d56Sopenharmony_cifunc_set_qualname(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
4327db96d56Sopenharmony_ci{
4337db96d56Sopenharmony_ci    /* Not legal to del f.__qualname__ or to set it to anything
4347db96d56Sopenharmony_ci     * other than a string object. */
4357db96d56Sopenharmony_ci    if (value == NULL || !PyUnicode_Check(value)) {
4367db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
4377db96d56Sopenharmony_ci                        "__qualname__ must be set to a string object");
4387db96d56Sopenharmony_ci        return -1;
4397db96d56Sopenharmony_ci    }
4407db96d56Sopenharmony_ci    Py_INCREF(value);
4417db96d56Sopenharmony_ci    Py_XSETREF(op->func_qualname, value);
4427db96d56Sopenharmony_ci    return 0;
4437db96d56Sopenharmony_ci}
4447db96d56Sopenharmony_ci
4457db96d56Sopenharmony_cistatic PyObject *
4467db96d56Sopenharmony_cifunc_get_defaults(PyFunctionObject *op, void *Py_UNUSED(ignored))
4477db96d56Sopenharmony_ci{
4487db96d56Sopenharmony_ci    if (PySys_Audit("object.__getattr__", "Os", op, "__defaults__") < 0) {
4497db96d56Sopenharmony_ci        return NULL;
4507db96d56Sopenharmony_ci    }
4517db96d56Sopenharmony_ci    if (op->func_defaults == NULL) {
4527db96d56Sopenharmony_ci        Py_RETURN_NONE;
4537db96d56Sopenharmony_ci    }
4547db96d56Sopenharmony_ci    Py_INCREF(op->func_defaults);
4557db96d56Sopenharmony_ci    return op->func_defaults;
4567db96d56Sopenharmony_ci}
4577db96d56Sopenharmony_ci
4587db96d56Sopenharmony_cistatic int
4597db96d56Sopenharmony_cifunc_set_defaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
4607db96d56Sopenharmony_ci{
4617db96d56Sopenharmony_ci    /* Legal to del f.func_defaults.
4627db96d56Sopenharmony_ci     * Can only set func_defaults to NULL or a tuple. */
4637db96d56Sopenharmony_ci    if (value == Py_None)
4647db96d56Sopenharmony_ci        value = NULL;
4657db96d56Sopenharmony_ci    if (value != NULL && !PyTuple_Check(value)) {
4667db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
4677db96d56Sopenharmony_ci                        "__defaults__ must be set to a tuple object");
4687db96d56Sopenharmony_ci        return -1;
4697db96d56Sopenharmony_ci    }
4707db96d56Sopenharmony_ci    if (value) {
4717db96d56Sopenharmony_ci        if (PySys_Audit("object.__setattr__", "OsO",
4727db96d56Sopenharmony_ci                        op, "__defaults__", value) < 0) {
4737db96d56Sopenharmony_ci            return -1;
4747db96d56Sopenharmony_ci        }
4757db96d56Sopenharmony_ci    } else if (PySys_Audit("object.__delattr__", "Os",
4767db96d56Sopenharmony_ci                           op, "__defaults__") < 0) {
4777db96d56Sopenharmony_ci        return -1;
4787db96d56Sopenharmony_ci    }
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_ci    op->func_version = 0;
4817db96d56Sopenharmony_ci    Py_XINCREF(value);
4827db96d56Sopenharmony_ci    Py_XSETREF(op->func_defaults, value);
4837db96d56Sopenharmony_ci    return 0;
4847db96d56Sopenharmony_ci}
4857db96d56Sopenharmony_ci
4867db96d56Sopenharmony_cistatic PyObject *
4877db96d56Sopenharmony_cifunc_get_kwdefaults(PyFunctionObject *op, void *Py_UNUSED(ignored))
4887db96d56Sopenharmony_ci{
4897db96d56Sopenharmony_ci    if (PySys_Audit("object.__getattr__", "Os",
4907db96d56Sopenharmony_ci                    op, "__kwdefaults__") < 0) {
4917db96d56Sopenharmony_ci        return NULL;
4927db96d56Sopenharmony_ci    }
4937db96d56Sopenharmony_ci    if (op->func_kwdefaults == NULL) {
4947db96d56Sopenharmony_ci        Py_RETURN_NONE;
4957db96d56Sopenharmony_ci    }
4967db96d56Sopenharmony_ci    Py_INCREF(op->func_kwdefaults);
4977db96d56Sopenharmony_ci    return op->func_kwdefaults;
4987db96d56Sopenharmony_ci}
4997db96d56Sopenharmony_ci
5007db96d56Sopenharmony_cistatic int
5017db96d56Sopenharmony_cifunc_set_kwdefaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
5027db96d56Sopenharmony_ci{
5037db96d56Sopenharmony_ci    if (value == Py_None)
5047db96d56Sopenharmony_ci        value = NULL;
5057db96d56Sopenharmony_ci    /* Legal to del f.func_kwdefaults.
5067db96d56Sopenharmony_ci     * Can only set func_kwdefaults to NULL or a dict. */
5077db96d56Sopenharmony_ci    if (value != NULL && !PyDict_Check(value)) {
5087db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
5097db96d56Sopenharmony_ci            "__kwdefaults__ must be set to a dict object");
5107db96d56Sopenharmony_ci        return -1;
5117db96d56Sopenharmony_ci    }
5127db96d56Sopenharmony_ci    if (value) {
5137db96d56Sopenharmony_ci        if (PySys_Audit("object.__setattr__", "OsO",
5147db96d56Sopenharmony_ci                        op, "__kwdefaults__", value) < 0) {
5157db96d56Sopenharmony_ci            return -1;
5167db96d56Sopenharmony_ci        }
5177db96d56Sopenharmony_ci    } else if (PySys_Audit("object.__delattr__", "Os",
5187db96d56Sopenharmony_ci                           op, "__kwdefaults__") < 0) {
5197db96d56Sopenharmony_ci        return -1;
5207db96d56Sopenharmony_ci    }
5217db96d56Sopenharmony_ci
5227db96d56Sopenharmony_ci    op->func_version = 0;
5237db96d56Sopenharmony_ci    Py_XINCREF(value);
5247db96d56Sopenharmony_ci    Py_XSETREF(op->func_kwdefaults, value);
5257db96d56Sopenharmony_ci    return 0;
5267db96d56Sopenharmony_ci}
5277db96d56Sopenharmony_ci
5287db96d56Sopenharmony_cistatic PyObject *
5297db96d56Sopenharmony_cifunc_get_annotations(PyFunctionObject *op, void *Py_UNUSED(ignored))
5307db96d56Sopenharmony_ci{
5317db96d56Sopenharmony_ci    if (op->func_annotations == NULL) {
5327db96d56Sopenharmony_ci        op->func_annotations = PyDict_New();
5337db96d56Sopenharmony_ci        if (op->func_annotations == NULL)
5347db96d56Sopenharmony_ci            return NULL;
5357db96d56Sopenharmony_ci    }
5367db96d56Sopenharmony_ci    PyObject *d = func_get_annotation_dict(op);
5377db96d56Sopenharmony_ci    if (d) {
5387db96d56Sopenharmony_ci        Py_INCREF(d);
5397db96d56Sopenharmony_ci    }
5407db96d56Sopenharmony_ci    return d;
5417db96d56Sopenharmony_ci}
5427db96d56Sopenharmony_ci
5437db96d56Sopenharmony_cistatic int
5447db96d56Sopenharmony_cifunc_set_annotations(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
5457db96d56Sopenharmony_ci{
5467db96d56Sopenharmony_ci    if (value == Py_None)
5477db96d56Sopenharmony_ci        value = NULL;
5487db96d56Sopenharmony_ci    /* Legal to del f.func_annotations.
5497db96d56Sopenharmony_ci     * Can only set func_annotations to NULL (through C api)
5507db96d56Sopenharmony_ci     * or a dict. */
5517db96d56Sopenharmony_ci    if (value != NULL && !PyDict_Check(value)) {
5527db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
5537db96d56Sopenharmony_ci            "__annotations__ must be set to a dict object");
5547db96d56Sopenharmony_ci        return -1;
5557db96d56Sopenharmony_ci    }
5567db96d56Sopenharmony_ci    op->func_version = 0;
5577db96d56Sopenharmony_ci    Py_XINCREF(value);
5587db96d56Sopenharmony_ci    Py_XSETREF(op->func_annotations, value);
5597db96d56Sopenharmony_ci    return 0;
5607db96d56Sopenharmony_ci}
5617db96d56Sopenharmony_ci
5627db96d56Sopenharmony_cistatic PyGetSetDef func_getsetlist[] = {
5637db96d56Sopenharmony_ci    {"__code__", (getter)func_get_code, (setter)func_set_code},
5647db96d56Sopenharmony_ci    {"__defaults__", (getter)func_get_defaults,
5657db96d56Sopenharmony_ci     (setter)func_set_defaults},
5667db96d56Sopenharmony_ci    {"__kwdefaults__", (getter)func_get_kwdefaults,
5677db96d56Sopenharmony_ci     (setter)func_set_kwdefaults},
5687db96d56Sopenharmony_ci    {"__annotations__", (getter)func_get_annotations,
5697db96d56Sopenharmony_ci     (setter)func_set_annotations},
5707db96d56Sopenharmony_ci    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
5717db96d56Sopenharmony_ci    {"__name__", (getter)func_get_name, (setter)func_set_name},
5727db96d56Sopenharmony_ci    {"__qualname__", (getter)func_get_qualname, (setter)func_set_qualname},
5737db96d56Sopenharmony_ci    {NULL} /* Sentinel */
5747db96d56Sopenharmony_ci};
5757db96d56Sopenharmony_ci
5767db96d56Sopenharmony_ci/*[clinic input]
5777db96d56Sopenharmony_ciclass function "PyFunctionObject *" "&PyFunction_Type"
5787db96d56Sopenharmony_ci[clinic start generated code]*/
5797db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=70af9c90aa2e71b0]*/
5807db96d56Sopenharmony_ci
5817db96d56Sopenharmony_ci#include "clinic/funcobject.c.h"
5827db96d56Sopenharmony_ci
5837db96d56Sopenharmony_ci/* function.__new__() maintains the following invariants for closures.
5847db96d56Sopenharmony_ci   The closure must correspond to the free variables of the code object.
5857db96d56Sopenharmony_ci
5867db96d56Sopenharmony_ci   if len(code.co_freevars) == 0:
5877db96d56Sopenharmony_ci       closure = NULL
5887db96d56Sopenharmony_ci   else:
5897db96d56Sopenharmony_ci       len(closure) == len(code.co_freevars)
5907db96d56Sopenharmony_ci   for every elt in closure, type(elt) == cell
5917db96d56Sopenharmony_ci*/
5927db96d56Sopenharmony_ci
5937db96d56Sopenharmony_ci/*[clinic input]
5947db96d56Sopenharmony_ci@classmethod
5957db96d56Sopenharmony_cifunction.__new__ as func_new
5967db96d56Sopenharmony_ci    code: object(type="PyCodeObject *", subclass_of="&PyCode_Type")
5977db96d56Sopenharmony_ci        a code object
5987db96d56Sopenharmony_ci    globals: object(subclass_of="&PyDict_Type")
5997db96d56Sopenharmony_ci        the globals dictionary
6007db96d56Sopenharmony_ci    name: object = None
6017db96d56Sopenharmony_ci        a string that overrides the name from the code object
6027db96d56Sopenharmony_ci    argdefs as defaults: object = None
6037db96d56Sopenharmony_ci        a tuple that specifies the default argument values
6047db96d56Sopenharmony_ci    closure: object = None
6057db96d56Sopenharmony_ci        a tuple that supplies the bindings for free variables
6067db96d56Sopenharmony_ci
6077db96d56Sopenharmony_ciCreate a function object.
6087db96d56Sopenharmony_ci[clinic start generated code]*/
6097db96d56Sopenharmony_ci
6107db96d56Sopenharmony_cistatic PyObject *
6117db96d56Sopenharmony_cifunc_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals,
6127db96d56Sopenharmony_ci              PyObject *name, PyObject *defaults, PyObject *closure)
6137db96d56Sopenharmony_ci/*[clinic end generated code: output=99c6d9da3a24e3be input=93611752fc2daf11]*/
6147db96d56Sopenharmony_ci{
6157db96d56Sopenharmony_ci    PyFunctionObject *newfunc;
6167db96d56Sopenharmony_ci    Py_ssize_t nclosure;
6177db96d56Sopenharmony_ci
6187db96d56Sopenharmony_ci    if (name != Py_None && !PyUnicode_Check(name)) {
6197db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
6207db96d56Sopenharmony_ci                        "arg 3 (name) must be None or string");
6217db96d56Sopenharmony_ci        return NULL;
6227db96d56Sopenharmony_ci    }
6237db96d56Sopenharmony_ci    if (defaults != Py_None && !PyTuple_Check(defaults)) {
6247db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
6257db96d56Sopenharmony_ci                        "arg 4 (defaults) must be None or tuple");
6267db96d56Sopenharmony_ci        return NULL;
6277db96d56Sopenharmony_ci    }
6287db96d56Sopenharmony_ci    if (!PyTuple_Check(closure)) {
6297db96d56Sopenharmony_ci        if (code->co_nfreevars && closure == Py_None) {
6307db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError,
6317db96d56Sopenharmony_ci                            "arg 5 (closure) must be tuple");
6327db96d56Sopenharmony_ci            return NULL;
6337db96d56Sopenharmony_ci        }
6347db96d56Sopenharmony_ci        else if (closure != Py_None) {
6357db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError,
6367db96d56Sopenharmony_ci                "arg 5 (closure) must be None or tuple");
6377db96d56Sopenharmony_ci            return NULL;
6387db96d56Sopenharmony_ci        }
6397db96d56Sopenharmony_ci    }
6407db96d56Sopenharmony_ci
6417db96d56Sopenharmony_ci    /* check that the closure is well-formed */
6427db96d56Sopenharmony_ci    nclosure = closure == Py_None ? 0 : PyTuple_GET_SIZE(closure);
6437db96d56Sopenharmony_ci    if (code->co_nfreevars != nclosure)
6447db96d56Sopenharmony_ci        return PyErr_Format(PyExc_ValueError,
6457db96d56Sopenharmony_ci                            "%U requires closure of length %zd, not %zd",
6467db96d56Sopenharmony_ci                            code->co_name, code->co_nfreevars, nclosure);
6477db96d56Sopenharmony_ci    if (nclosure) {
6487db96d56Sopenharmony_ci        Py_ssize_t i;
6497db96d56Sopenharmony_ci        for (i = 0; i < nclosure; i++) {
6507db96d56Sopenharmony_ci            PyObject *o = PyTuple_GET_ITEM(closure, i);
6517db96d56Sopenharmony_ci            if (!PyCell_Check(o)) {
6527db96d56Sopenharmony_ci                return PyErr_Format(PyExc_TypeError,
6537db96d56Sopenharmony_ci                    "arg 5 (closure) expected cell, found %s",
6547db96d56Sopenharmony_ci                                    Py_TYPE(o)->tp_name);
6557db96d56Sopenharmony_ci            }
6567db96d56Sopenharmony_ci        }
6577db96d56Sopenharmony_ci    }
6587db96d56Sopenharmony_ci    if (PySys_Audit("function.__new__", "O", code) < 0) {
6597db96d56Sopenharmony_ci        return NULL;
6607db96d56Sopenharmony_ci    }
6617db96d56Sopenharmony_ci
6627db96d56Sopenharmony_ci    newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code,
6637db96d56Sopenharmony_ci                                                 globals);
6647db96d56Sopenharmony_ci    if (newfunc == NULL) {
6657db96d56Sopenharmony_ci        return NULL;
6667db96d56Sopenharmony_ci    }
6677db96d56Sopenharmony_ci    if (name != Py_None) {
6687db96d56Sopenharmony_ci        Py_INCREF(name);
6697db96d56Sopenharmony_ci        Py_SETREF(newfunc->func_name, name);
6707db96d56Sopenharmony_ci    }
6717db96d56Sopenharmony_ci    if (defaults != Py_None) {
6727db96d56Sopenharmony_ci        Py_INCREF(defaults);
6737db96d56Sopenharmony_ci        newfunc->func_defaults  = defaults;
6747db96d56Sopenharmony_ci    }
6757db96d56Sopenharmony_ci    if (closure != Py_None) {
6767db96d56Sopenharmony_ci        Py_INCREF(closure);
6777db96d56Sopenharmony_ci        newfunc->func_closure = closure;
6787db96d56Sopenharmony_ci    }
6797db96d56Sopenharmony_ci
6807db96d56Sopenharmony_ci    return (PyObject *)newfunc;
6817db96d56Sopenharmony_ci}
6827db96d56Sopenharmony_ci
6837db96d56Sopenharmony_cistatic int
6847db96d56Sopenharmony_cifunc_clear(PyFunctionObject *op)
6857db96d56Sopenharmony_ci{
6867db96d56Sopenharmony_ci    op->func_version = 0;
6877db96d56Sopenharmony_ci    Py_CLEAR(op->func_globals);
6887db96d56Sopenharmony_ci    Py_CLEAR(op->func_builtins);
6897db96d56Sopenharmony_ci    Py_CLEAR(op->func_module);
6907db96d56Sopenharmony_ci    Py_CLEAR(op->func_defaults);
6917db96d56Sopenharmony_ci    Py_CLEAR(op->func_kwdefaults);
6927db96d56Sopenharmony_ci    Py_CLEAR(op->func_doc);
6937db96d56Sopenharmony_ci    Py_CLEAR(op->func_dict);
6947db96d56Sopenharmony_ci    Py_CLEAR(op->func_closure);
6957db96d56Sopenharmony_ci    Py_CLEAR(op->func_annotations);
6967db96d56Sopenharmony_ci    // Don't Py_CLEAR(op->func_code), since code is always required
6977db96d56Sopenharmony_ci    // to be non-NULL. Similarly, name and qualname shouldn't be NULL.
6987db96d56Sopenharmony_ci    // However, name and qualname could be str subclasses, so they
6997db96d56Sopenharmony_ci    // could have reference cycles. The solution is to replace them
7007db96d56Sopenharmony_ci    // with a genuinely immutable string.
7017db96d56Sopenharmony_ci    Py_SETREF(op->func_name, Py_NewRef(&_Py_STR(empty)));
7027db96d56Sopenharmony_ci    Py_SETREF(op->func_qualname, Py_NewRef(&_Py_STR(empty)));
7037db96d56Sopenharmony_ci    return 0;
7047db96d56Sopenharmony_ci}
7057db96d56Sopenharmony_ci
7067db96d56Sopenharmony_cistatic void
7077db96d56Sopenharmony_cifunc_dealloc(PyFunctionObject *op)
7087db96d56Sopenharmony_ci{
7097db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK(op);
7107db96d56Sopenharmony_ci    if (op->func_weakreflist != NULL) {
7117db96d56Sopenharmony_ci        PyObject_ClearWeakRefs((PyObject *) op);
7127db96d56Sopenharmony_ci    }
7137db96d56Sopenharmony_ci    (void)func_clear(op);
7147db96d56Sopenharmony_ci    // These aren't cleared by func_clear().
7157db96d56Sopenharmony_ci    Py_DECREF(op->func_code);
7167db96d56Sopenharmony_ci    Py_DECREF(op->func_name);
7177db96d56Sopenharmony_ci    Py_DECREF(op->func_qualname);
7187db96d56Sopenharmony_ci    PyObject_GC_Del(op);
7197db96d56Sopenharmony_ci}
7207db96d56Sopenharmony_ci
7217db96d56Sopenharmony_cistatic PyObject*
7227db96d56Sopenharmony_cifunc_repr(PyFunctionObject *op)
7237db96d56Sopenharmony_ci{
7247db96d56Sopenharmony_ci    return PyUnicode_FromFormat("<function %U at %p>",
7257db96d56Sopenharmony_ci                                op->func_qualname, op);
7267db96d56Sopenharmony_ci}
7277db96d56Sopenharmony_ci
7287db96d56Sopenharmony_cistatic int
7297db96d56Sopenharmony_cifunc_traverse(PyFunctionObject *f, visitproc visit, void *arg)
7307db96d56Sopenharmony_ci{
7317db96d56Sopenharmony_ci    Py_VISIT(f->func_code);
7327db96d56Sopenharmony_ci    Py_VISIT(f->func_globals);
7337db96d56Sopenharmony_ci    Py_VISIT(f->func_builtins);
7347db96d56Sopenharmony_ci    Py_VISIT(f->func_module);
7357db96d56Sopenharmony_ci    Py_VISIT(f->func_defaults);
7367db96d56Sopenharmony_ci    Py_VISIT(f->func_kwdefaults);
7377db96d56Sopenharmony_ci    Py_VISIT(f->func_doc);
7387db96d56Sopenharmony_ci    Py_VISIT(f->func_name);
7397db96d56Sopenharmony_ci    Py_VISIT(f->func_dict);
7407db96d56Sopenharmony_ci    Py_VISIT(f->func_closure);
7417db96d56Sopenharmony_ci    Py_VISIT(f->func_annotations);
7427db96d56Sopenharmony_ci    Py_VISIT(f->func_qualname);
7437db96d56Sopenharmony_ci    return 0;
7447db96d56Sopenharmony_ci}
7457db96d56Sopenharmony_ci
7467db96d56Sopenharmony_ci/* Bind a function to an object */
7477db96d56Sopenharmony_cistatic PyObject *
7487db96d56Sopenharmony_cifunc_descr_get(PyObject *func, PyObject *obj, PyObject *type)
7497db96d56Sopenharmony_ci{
7507db96d56Sopenharmony_ci    if (obj == Py_None || obj == NULL) {
7517db96d56Sopenharmony_ci        Py_INCREF(func);
7527db96d56Sopenharmony_ci        return func;
7537db96d56Sopenharmony_ci    }
7547db96d56Sopenharmony_ci    return PyMethod_New(func, obj);
7557db96d56Sopenharmony_ci}
7567db96d56Sopenharmony_ci
7577db96d56Sopenharmony_ciPyTypeObject PyFunction_Type = {
7587db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
7597db96d56Sopenharmony_ci    "function",
7607db96d56Sopenharmony_ci    sizeof(PyFunctionObject),
7617db96d56Sopenharmony_ci    0,
7627db96d56Sopenharmony_ci    (destructor)func_dealloc,                   /* tp_dealloc */
7637db96d56Sopenharmony_ci    offsetof(PyFunctionObject, vectorcall),     /* tp_vectorcall_offset */
7647db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
7657db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
7667db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
7677db96d56Sopenharmony_ci    (reprfunc)func_repr,                        /* tp_repr */
7687db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
7697db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
7707db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
7717db96d56Sopenharmony_ci    0,                                          /* tp_hash */
7727db96d56Sopenharmony_ci    PyVectorcall_Call,                          /* tp_call */
7737db96d56Sopenharmony_ci    0,                                          /* tp_str */
7747db96d56Sopenharmony_ci    0,                                          /* tp_getattro */
7757db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
7767db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
7777db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
7787db96d56Sopenharmony_ci    Py_TPFLAGS_HAVE_VECTORCALL |
7797db96d56Sopenharmony_ci    Py_TPFLAGS_METHOD_DESCRIPTOR,               /* tp_flags */
7807db96d56Sopenharmony_ci    func_new__doc__,                            /* tp_doc */
7817db96d56Sopenharmony_ci    (traverseproc)func_traverse,                /* tp_traverse */
7827db96d56Sopenharmony_ci    (inquiry)func_clear,                        /* tp_clear */
7837db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
7847db96d56Sopenharmony_ci    offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
7857db96d56Sopenharmony_ci    0,                                          /* tp_iter */
7867db96d56Sopenharmony_ci    0,                                          /* tp_iternext */
7877db96d56Sopenharmony_ci    0,                                          /* tp_methods */
7887db96d56Sopenharmony_ci    func_memberlist,                            /* tp_members */
7897db96d56Sopenharmony_ci    func_getsetlist,                            /* tp_getset */
7907db96d56Sopenharmony_ci    0,                                          /* tp_base */
7917db96d56Sopenharmony_ci    0,                                          /* tp_dict */
7927db96d56Sopenharmony_ci    func_descr_get,                             /* tp_descr_get */
7937db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
7947db96d56Sopenharmony_ci    offsetof(PyFunctionObject, func_dict),      /* tp_dictoffset */
7957db96d56Sopenharmony_ci    0,                                          /* tp_init */
7967db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
7977db96d56Sopenharmony_ci    func_new,                                   /* tp_new */
7987db96d56Sopenharmony_ci};
7997db96d56Sopenharmony_ci
8007db96d56Sopenharmony_ci
8017db96d56Sopenharmony_cistatic int
8027db96d56Sopenharmony_cifunctools_copy_attr(PyObject *wrapper, PyObject *wrapped, PyObject *name)
8037db96d56Sopenharmony_ci{
8047db96d56Sopenharmony_ci    PyObject *value = PyObject_GetAttr(wrapped, name);
8057db96d56Sopenharmony_ci    if (value == NULL) {
8067db96d56Sopenharmony_ci        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
8077db96d56Sopenharmony_ci            PyErr_Clear();
8087db96d56Sopenharmony_ci            return 0;
8097db96d56Sopenharmony_ci        }
8107db96d56Sopenharmony_ci        return -1;
8117db96d56Sopenharmony_ci    }
8127db96d56Sopenharmony_ci
8137db96d56Sopenharmony_ci    int res = PyObject_SetAttr(wrapper, name, value);
8147db96d56Sopenharmony_ci    Py_DECREF(value);
8157db96d56Sopenharmony_ci    return res;
8167db96d56Sopenharmony_ci}
8177db96d56Sopenharmony_ci
8187db96d56Sopenharmony_ci// Similar to functools.wraps(wrapper, wrapped)
8197db96d56Sopenharmony_cistatic int
8207db96d56Sopenharmony_cifunctools_wraps(PyObject *wrapper, PyObject *wrapped)
8217db96d56Sopenharmony_ci{
8227db96d56Sopenharmony_ci#define COPY_ATTR(ATTR) \
8237db96d56Sopenharmony_ci    do { \
8247db96d56Sopenharmony_ci        if (functools_copy_attr(wrapper, wrapped, &_Py_ID(ATTR)) < 0) { \
8257db96d56Sopenharmony_ci            return -1; \
8267db96d56Sopenharmony_ci        } \
8277db96d56Sopenharmony_ci    } while (0) \
8287db96d56Sopenharmony_ci
8297db96d56Sopenharmony_ci    COPY_ATTR(__module__);
8307db96d56Sopenharmony_ci    COPY_ATTR(__name__);
8317db96d56Sopenharmony_ci    COPY_ATTR(__qualname__);
8327db96d56Sopenharmony_ci    COPY_ATTR(__doc__);
8337db96d56Sopenharmony_ci    COPY_ATTR(__annotations__);
8347db96d56Sopenharmony_ci    return 0;
8357db96d56Sopenharmony_ci
8367db96d56Sopenharmony_ci#undef COPY_ATTR
8377db96d56Sopenharmony_ci}
8387db96d56Sopenharmony_ci
8397db96d56Sopenharmony_ci
8407db96d56Sopenharmony_ci/* Class method object */
8417db96d56Sopenharmony_ci
8427db96d56Sopenharmony_ci/* A class method receives the class as implicit first argument,
8437db96d56Sopenharmony_ci   just like an instance method receives the instance.
8447db96d56Sopenharmony_ci   To declare a class method, use this idiom:
8457db96d56Sopenharmony_ci
8467db96d56Sopenharmony_ci     class C:
8477db96d56Sopenharmony_ci         @classmethod
8487db96d56Sopenharmony_ci         def f(cls, arg1, arg2, argN):
8497db96d56Sopenharmony_ci             ...
8507db96d56Sopenharmony_ci
8517db96d56Sopenharmony_ci   It can be called either on the class (e.g. C.f()) or on an instance
8527db96d56Sopenharmony_ci   (e.g. C().f()); the instance is ignored except for its class.
8537db96d56Sopenharmony_ci   If a class method is called for a derived class, the derived class
8547db96d56Sopenharmony_ci   object is passed as the implied first argument.
8557db96d56Sopenharmony_ci
8567db96d56Sopenharmony_ci   Class methods are different than C++ or Java static methods.
8577db96d56Sopenharmony_ci   If you want those, see static methods below.
8587db96d56Sopenharmony_ci*/
8597db96d56Sopenharmony_ci
8607db96d56Sopenharmony_citypedef struct {
8617db96d56Sopenharmony_ci    PyObject_HEAD
8627db96d56Sopenharmony_ci    PyObject *cm_callable;
8637db96d56Sopenharmony_ci    PyObject *cm_dict;
8647db96d56Sopenharmony_ci} classmethod;
8657db96d56Sopenharmony_ci
8667db96d56Sopenharmony_cistatic void
8677db96d56Sopenharmony_cicm_dealloc(classmethod *cm)
8687db96d56Sopenharmony_ci{
8697db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK((PyObject *)cm);
8707db96d56Sopenharmony_ci    Py_XDECREF(cm->cm_callable);
8717db96d56Sopenharmony_ci    Py_XDECREF(cm->cm_dict);
8727db96d56Sopenharmony_ci    Py_TYPE(cm)->tp_free((PyObject *)cm);
8737db96d56Sopenharmony_ci}
8747db96d56Sopenharmony_ci
8757db96d56Sopenharmony_cistatic int
8767db96d56Sopenharmony_cicm_traverse(classmethod *cm, visitproc visit, void *arg)
8777db96d56Sopenharmony_ci{
8787db96d56Sopenharmony_ci    Py_VISIT(cm->cm_callable);
8797db96d56Sopenharmony_ci    Py_VISIT(cm->cm_dict);
8807db96d56Sopenharmony_ci    return 0;
8817db96d56Sopenharmony_ci}
8827db96d56Sopenharmony_ci
8837db96d56Sopenharmony_cistatic int
8847db96d56Sopenharmony_cicm_clear(classmethod *cm)
8857db96d56Sopenharmony_ci{
8867db96d56Sopenharmony_ci    Py_CLEAR(cm->cm_callable);
8877db96d56Sopenharmony_ci    Py_CLEAR(cm->cm_dict);
8887db96d56Sopenharmony_ci    return 0;
8897db96d56Sopenharmony_ci}
8907db96d56Sopenharmony_ci
8917db96d56Sopenharmony_ci
8927db96d56Sopenharmony_cistatic PyObject *
8937db96d56Sopenharmony_cicm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
8947db96d56Sopenharmony_ci{
8957db96d56Sopenharmony_ci    classmethod *cm = (classmethod *)self;
8967db96d56Sopenharmony_ci
8977db96d56Sopenharmony_ci    if (cm->cm_callable == NULL) {
8987db96d56Sopenharmony_ci        PyErr_SetString(PyExc_RuntimeError,
8997db96d56Sopenharmony_ci                        "uninitialized classmethod object");
9007db96d56Sopenharmony_ci        return NULL;
9017db96d56Sopenharmony_ci    }
9027db96d56Sopenharmony_ci    if (type == NULL)
9037db96d56Sopenharmony_ci        type = (PyObject *)(Py_TYPE(obj));
9047db96d56Sopenharmony_ci    if (Py_TYPE(cm->cm_callable)->tp_descr_get != NULL) {
9057db96d56Sopenharmony_ci        return Py_TYPE(cm->cm_callable)->tp_descr_get(cm->cm_callable, type,
9067db96d56Sopenharmony_ci                                                      type);
9077db96d56Sopenharmony_ci    }
9087db96d56Sopenharmony_ci    return PyMethod_New(cm->cm_callable, type);
9097db96d56Sopenharmony_ci}
9107db96d56Sopenharmony_ci
9117db96d56Sopenharmony_cistatic int
9127db96d56Sopenharmony_cicm_init(PyObject *self, PyObject *args, PyObject *kwds)
9137db96d56Sopenharmony_ci{
9147db96d56Sopenharmony_ci    classmethod *cm = (classmethod *)self;
9157db96d56Sopenharmony_ci    PyObject *callable;
9167db96d56Sopenharmony_ci
9177db96d56Sopenharmony_ci    if (!_PyArg_NoKeywords("classmethod", kwds))
9187db96d56Sopenharmony_ci        return -1;
9197db96d56Sopenharmony_ci    if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable))
9207db96d56Sopenharmony_ci        return -1;
9217db96d56Sopenharmony_ci    Py_INCREF(callable);
9227db96d56Sopenharmony_ci    Py_XSETREF(cm->cm_callable, callable);
9237db96d56Sopenharmony_ci
9247db96d56Sopenharmony_ci    if (functools_wraps((PyObject *)cm, cm->cm_callable) < 0) {
9257db96d56Sopenharmony_ci        return -1;
9267db96d56Sopenharmony_ci    }
9277db96d56Sopenharmony_ci    return 0;
9287db96d56Sopenharmony_ci}
9297db96d56Sopenharmony_ci
9307db96d56Sopenharmony_cistatic PyMemberDef cm_memberlist[] = {
9317db96d56Sopenharmony_ci    {"__func__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY},
9327db96d56Sopenharmony_ci    {"__wrapped__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY},
9337db96d56Sopenharmony_ci    {NULL}  /* Sentinel */
9347db96d56Sopenharmony_ci};
9357db96d56Sopenharmony_ci
9367db96d56Sopenharmony_cistatic PyObject *
9377db96d56Sopenharmony_cicm_get___isabstractmethod__(classmethod *cm, void *closure)
9387db96d56Sopenharmony_ci{
9397db96d56Sopenharmony_ci    int res = _PyObject_IsAbstract(cm->cm_callable);
9407db96d56Sopenharmony_ci    if (res == -1) {
9417db96d56Sopenharmony_ci        return NULL;
9427db96d56Sopenharmony_ci    }
9437db96d56Sopenharmony_ci    else if (res) {
9447db96d56Sopenharmony_ci        Py_RETURN_TRUE;
9457db96d56Sopenharmony_ci    }
9467db96d56Sopenharmony_ci    Py_RETURN_FALSE;
9477db96d56Sopenharmony_ci}
9487db96d56Sopenharmony_ci
9497db96d56Sopenharmony_cistatic PyGetSetDef cm_getsetlist[] = {
9507db96d56Sopenharmony_ci    {"__isabstractmethod__",
9517db96d56Sopenharmony_ci     (getter)cm_get___isabstractmethod__, NULL, NULL, NULL},
9527db96d56Sopenharmony_ci    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, NULL, NULL},
9537db96d56Sopenharmony_ci    {NULL} /* Sentinel */
9547db96d56Sopenharmony_ci};
9557db96d56Sopenharmony_ci
9567db96d56Sopenharmony_cistatic PyObject*
9577db96d56Sopenharmony_cicm_repr(classmethod *cm)
9587db96d56Sopenharmony_ci{
9597db96d56Sopenharmony_ci    return PyUnicode_FromFormat("<classmethod(%R)>", cm->cm_callable);
9607db96d56Sopenharmony_ci}
9617db96d56Sopenharmony_ci
9627db96d56Sopenharmony_ciPyDoc_STRVAR(classmethod_doc,
9637db96d56Sopenharmony_ci"classmethod(function) -> method\n\
9647db96d56Sopenharmony_ci\n\
9657db96d56Sopenharmony_ciConvert a function to be a class method.\n\
9667db96d56Sopenharmony_ci\n\
9677db96d56Sopenharmony_ciA class method receives the class as implicit first argument,\n\
9687db96d56Sopenharmony_cijust like an instance method receives the instance.\n\
9697db96d56Sopenharmony_ciTo declare a class method, use this idiom:\n\
9707db96d56Sopenharmony_ci\n\
9717db96d56Sopenharmony_ci  class C:\n\
9727db96d56Sopenharmony_ci      @classmethod\n\
9737db96d56Sopenharmony_ci      def f(cls, arg1, arg2, argN):\n\
9747db96d56Sopenharmony_ci          ...\n\
9757db96d56Sopenharmony_ci\n\
9767db96d56Sopenharmony_ciIt can be called either on the class (e.g. C.f()) or on an instance\n\
9777db96d56Sopenharmony_ci(e.g. C().f()).  The instance is ignored except for its class.\n\
9787db96d56Sopenharmony_ciIf a class method is called for a derived class, the derived class\n\
9797db96d56Sopenharmony_ciobject is passed as the implied first argument.\n\
9807db96d56Sopenharmony_ci\n\
9817db96d56Sopenharmony_ciClass methods are different than C++ or Java static methods.\n\
9827db96d56Sopenharmony_ciIf you want those, see the staticmethod builtin.");
9837db96d56Sopenharmony_ci
9847db96d56Sopenharmony_ciPyTypeObject PyClassMethod_Type = {
9857db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
9867db96d56Sopenharmony_ci    "classmethod",
9877db96d56Sopenharmony_ci    sizeof(classmethod),
9887db96d56Sopenharmony_ci    0,
9897db96d56Sopenharmony_ci    (destructor)cm_dealloc,                     /* tp_dealloc */
9907db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
9917db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
9927db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
9937db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
9947db96d56Sopenharmony_ci    (reprfunc)cm_repr,                          /* tp_repr */
9957db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
9967db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
9977db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
9987db96d56Sopenharmony_ci    0,                                          /* tp_hash */
9997db96d56Sopenharmony_ci    0,                                          /* tp_call */
10007db96d56Sopenharmony_ci    0,                                          /* tp_str */
10017db96d56Sopenharmony_ci    0,                                          /* tp_getattro */
10027db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
10037db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
10047db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
10057db96d56Sopenharmony_ci    classmethod_doc,                            /* tp_doc */
10067db96d56Sopenharmony_ci    (traverseproc)cm_traverse,                  /* tp_traverse */
10077db96d56Sopenharmony_ci    (inquiry)cm_clear,                          /* tp_clear */
10087db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
10097db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
10107db96d56Sopenharmony_ci    0,                                          /* tp_iter */
10117db96d56Sopenharmony_ci    0,                                          /* tp_iternext */
10127db96d56Sopenharmony_ci    0,                                          /* tp_methods */
10137db96d56Sopenharmony_ci    cm_memberlist,              /* tp_members */
10147db96d56Sopenharmony_ci    cm_getsetlist,                              /* tp_getset */
10157db96d56Sopenharmony_ci    0,                                          /* tp_base */
10167db96d56Sopenharmony_ci    0,                                          /* tp_dict */
10177db96d56Sopenharmony_ci    cm_descr_get,                               /* tp_descr_get */
10187db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
10197db96d56Sopenharmony_ci    offsetof(classmethod, cm_dict),             /* tp_dictoffset */
10207db96d56Sopenharmony_ci    cm_init,                                    /* tp_init */
10217db96d56Sopenharmony_ci    PyType_GenericAlloc,                        /* tp_alloc */
10227db96d56Sopenharmony_ci    PyType_GenericNew,                          /* tp_new */
10237db96d56Sopenharmony_ci    PyObject_GC_Del,                            /* tp_free */
10247db96d56Sopenharmony_ci};
10257db96d56Sopenharmony_ci
10267db96d56Sopenharmony_ciPyObject *
10277db96d56Sopenharmony_ciPyClassMethod_New(PyObject *callable)
10287db96d56Sopenharmony_ci{
10297db96d56Sopenharmony_ci    classmethod *cm = (classmethod *)
10307db96d56Sopenharmony_ci        PyType_GenericAlloc(&PyClassMethod_Type, 0);
10317db96d56Sopenharmony_ci    if (cm != NULL) {
10327db96d56Sopenharmony_ci        Py_INCREF(callable);
10337db96d56Sopenharmony_ci        cm->cm_callable = callable;
10347db96d56Sopenharmony_ci    }
10357db96d56Sopenharmony_ci    return (PyObject *)cm;
10367db96d56Sopenharmony_ci}
10377db96d56Sopenharmony_ci
10387db96d56Sopenharmony_ci
10397db96d56Sopenharmony_ci/* Static method object */
10407db96d56Sopenharmony_ci
10417db96d56Sopenharmony_ci/* A static method does not receive an implicit first argument.
10427db96d56Sopenharmony_ci   To declare a static method, use this idiom:
10437db96d56Sopenharmony_ci
10447db96d56Sopenharmony_ci     class C:
10457db96d56Sopenharmony_ci         @staticmethod
10467db96d56Sopenharmony_ci         def f(arg1, arg2, argN):
10477db96d56Sopenharmony_ci             ...
10487db96d56Sopenharmony_ci
10497db96d56Sopenharmony_ci   It can be called either on the class (e.g. C.f()) or on an instance
10507db96d56Sopenharmony_ci   (e.g. C().f()). Both the class and the instance are ignored, and
10517db96d56Sopenharmony_ci   neither is passed implicitly as the first argument to the method.
10527db96d56Sopenharmony_ci
10537db96d56Sopenharmony_ci   Static methods in Python are similar to those found in Java or C++.
10547db96d56Sopenharmony_ci   For a more advanced concept, see class methods above.
10557db96d56Sopenharmony_ci*/
10567db96d56Sopenharmony_ci
10577db96d56Sopenharmony_citypedef struct {
10587db96d56Sopenharmony_ci    PyObject_HEAD
10597db96d56Sopenharmony_ci    PyObject *sm_callable;
10607db96d56Sopenharmony_ci    PyObject *sm_dict;
10617db96d56Sopenharmony_ci} staticmethod;
10627db96d56Sopenharmony_ci
10637db96d56Sopenharmony_cistatic void
10647db96d56Sopenharmony_cism_dealloc(staticmethod *sm)
10657db96d56Sopenharmony_ci{
10667db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK((PyObject *)sm);
10677db96d56Sopenharmony_ci    Py_XDECREF(sm->sm_callable);
10687db96d56Sopenharmony_ci    Py_XDECREF(sm->sm_dict);
10697db96d56Sopenharmony_ci    Py_TYPE(sm)->tp_free((PyObject *)sm);
10707db96d56Sopenharmony_ci}
10717db96d56Sopenharmony_ci
10727db96d56Sopenharmony_cistatic int
10737db96d56Sopenharmony_cism_traverse(staticmethod *sm, visitproc visit, void *arg)
10747db96d56Sopenharmony_ci{
10757db96d56Sopenharmony_ci    Py_VISIT(sm->sm_callable);
10767db96d56Sopenharmony_ci    Py_VISIT(sm->sm_dict);
10777db96d56Sopenharmony_ci    return 0;
10787db96d56Sopenharmony_ci}
10797db96d56Sopenharmony_ci
10807db96d56Sopenharmony_cistatic int
10817db96d56Sopenharmony_cism_clear(staticmethod *sm)
10827db96d56Sopenharmony_ci{
10837db96d56Sopenharmony_ci    Py_CLEAR(sm->sm_callable);
10847db96d56Sopenharmony_ci    Py_CLEAR(sm->sm_dict);
10857db96d56Sopenharmony_ci    return 0;
10867db96d56Sopenharmony_ci}
10877db96d56Sopenharmony_ci
10887db96d56Sopenharmony_cistatic PyObject *
10897db96d56Sopenharmony_cism_descr_get(PyObject *self, PyObject *obj, PyObject *type)
10907db96d56Sopenharmony_ci{
10917db96d56Sopenharmony_ci    staticmethod *sm = (staticmethod *)self;
10927db96d56Sopenharmony_ci
10937db96d56Sopenharmony_ci    if (sm->sm_callable == NULL) {
10947db96d56Sopenharmony_ci        PyErr_SetString(PyExc_RuntimeError,
10957db96d56Sopenharmony_ci                        "uninitialized staticmethod object");
10967db96d56Sopenharmony_ci        return NULL;
10977db96d56Sopenharmony_ci    }
10987db96d56Sopenharmony_ci    Py_INCREF(sm->sm_callable);
10997db96d56Sopenharmony_ci    return sm->sm_callable;
11007db96d56Sopenharmony_ci}
11017db96d56Sopenharmony_ci
11027db96d56Sopenharmony_cistatic int
11037db96d56Sopenharmony_cism_init(PyObject *self, PyObject *args, PyObject *kwds)
11047db96d56Sopenharmony_ci{
11057db96d56Sopenharmony_ci    staticmethod *sm = (staticmethod *)self;
11067db96d56Sopenharmony_ci    PyObject *callable;
11077db96d56Sopenharmony_ci
11087db96d56Sopenharmony_ci    if (!_PyArg_NoKeywords("staticmethod", kwds))
11097db96d56Sopenharmony_ci        return -1;
11107db96d56Sopenharmony_ci    if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable))
11117db96d56Sopenharmony_ci        return -1;
11127db96d56Sopenharmony_ci    Py_INCREF(callable);
11137db96d56Sopenharmony_ci    Py_XSETREF(sm->sm_callable, callable);
11147db96d56Sopenharmony_ci
11157db96d56Sopenharmony_ci    if (functools_wraps((PyObject *)sm, sm->sm_callable) < 0) {
11167db96d56Sopenharmony_ci        return -1;
11177db96d56Sopenharmony_ci    }
11187db96d56Sopenharmony_ci    return 0;
11197db96d56Sopenharmony_ci}
11207db96d56Sopenharmony_ci
11217db96d56Sopenharmony_cistatic PyObject*
11227db96d56Sopenharmony_cism_call(PyObject *callable, PyObject *args, PyObject *kwargs)
11237db96d56Sopenharmony_ci{
11247db96d56Sopenharmony_ci    staticmethod *sm = (staticmethod *)callable;
11257db96d56Sopenharmony_ci    return PyObject_Call(sm->sm_callable, args, kwargs);
11267db96d56Sopenharmony_ci}
11277db96d56Sopenharmony_ci
11287db96d56Sopenharmony_cistatic PyMemberDef sm_memberlist[] = {
11297db96d56Sopenharmony_ci    {"__func__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY},
11307db96d56Sopenharmony_ci    {"__wrapped__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY},
11317db96d56Sopenharmony_ci    {NULL}  /* Sentinel */
11327db96d56Sopenharmony_ci};
11337db96d56Sopenharmony_ci
11347db96d56Sopenharmony_cistatic PyObject *
11357db96d56Sopenharmony_cism_get___isabstractmethod__(staticmethod *sm, void *closure)
11367db96d56Sopenharmony_ci{
11377db96d56Sopenharmony_ci    int res = _PyObject_IsAbstract(sm->sm_callable);
11387db96d56Sopenharmony_ci    if (res == -1) {
11397db96d56Sopenharmony_ci        return NULL;
11407db96d56Sopenharmony_ci    }
11417db96d56Sopenharmony_ci    else if (res) {
11427db96d56Sopenharmony_ci        Py_RETURN_TRUE;
11437db96d56Sopenharmony_ci    }
11447db96d56Sopenharmony_ci    Py_RETURN_FALSE;
11457db96d56Sopenharmony_ci}
11467db96d56Sopenharmony_ci
11477db96d56Sopenharmony_cistatic PyGetSetDef sm_getsetlist[] = {
11487db96d56Sopenharmony_ci    {"__isabstractmethod__",
11497db96d56Sopenharmony_ci     (getter)sm_get___isabstractmethod__, NULL, NULL, NULL},
11507db96d56Sopenharmony_ci    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, NULL, NULL},
11517db96d56Sopenharmony_ci    {NULL} /* Sentinel */
11527db96d56Sopenharmony_ci};
11537db96d56Sopenharmony_ci
11547db96d56Sopenharmony_cistatic PyObject*
11557db96d56Sopenharmony_cism_repr(staticmethod *sm)
11567db96d56Sopenharmony_ci{
11577db96d56Sopenharmony_ci    return PyUnicode_FromFormat("<staticmethod(%R)>", sm->sm_callable);
11587db96d56Sopenharmony_ci}
11597db96d56Sopenharmony_ci
11607db96d56Sopenharmony_ciPyDoc_STRVAR(staticmethod_doc,
11617db96d56Sopenharmony_ci"staticmethod(function) -> method\n\
11627db96d56Sopenharmony_ci\n\
11637db96d56Sopenharmony_ciConvert a function to be a static method.\n\
11647db96d56Sopenharmony_ci\n\
11657db96d56Sopenharmony_ciA static method does not receive an implicit first argument.\n\
11667db96d56Sopenharmony_ciTo declare a static method, use this idiom:\n\
11677db96d56Sopenharmony_ci\n\
11687db96d56Sopenharmony_ci     class C:\n\
11697db96d56Sopenharmony_ci         @staticmethod\n\
11707db96d56Sopenharmony_ci         def f(arg1, arg2, argN):\n\
11717db96d56Sopenharmony_ci             ...\n\
11727db96d56Sopenharmony_ci\n\
11737db96d56Sopenharmony_ciIt can be called either on the class (e.g. C.f()) or on an instance\n\
11747db96d56Sopenharmony_ci(e.g. C().f()). Both the class and the instance are ignored, and\n\
11757db96d56Sopenharmony_cineither is passed implicitly as the first argument to the method.\n\
11767db96d56Sopenharmony_ci\n\
11777db96d56Sopenharmony_ciStatic methods in Python are similar to those found in Java or C++.\n\
11787db96d56Sopenharmony_ciFor a more advanced concept, see the classmethod builtin.");
11797db96d56Sopenharmony_ci
11807db96d56Sopenharmony_ciPyTypeObject PyStaticMethod_Type = {
11817db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
11827db96d56Sopenharmony_ci    "staticmethod",
11837db96d56Sopenharmony_ci    sizeof(staticmethod),
11847db96d56Sopenharmony_ci    0,
11857db96d56Sopenharmony_ci    (destructor)sm_dealloc,                     /* tp_dealloc */
11867db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
11877db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
11887db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
11897db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
11907db96d56Sopenharmony_ci    (reprfunc)sm_repr,                          /* tp_repr */
11917db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
11927db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
11937db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
11947db96d56Sopenharmony_ci    0,                                          /* tp_hash */
11957db96d56Sopenharmony_ci    sm_call,                                    /* tp_call */
11967db96d56Sopenharmony_ci    0,                                          /* tp_str */
11977db96d56Sopenharmony_ci    0,                                          /* tp_getattro */
11987db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
11997db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
12007db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
12017db96d56Sopenharmony_ci    staticmethod_doc,                           /* tp_doc */
12027db96d56Sopenharmony_ci    (traverseproc)sm_traverse,                  /* tp_traverse */
12037db96d56Sopenharmony_ci    (inquiry)sm_clear,                          /* tp_clear */
12047db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
12057db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
12067db96d56Sopenharmony_ci    0,                                          /* tp_iter */
12077db96d56Sopenharmony_ci    0,                                          /* tp_iternext */
12087db96d56Sopenharmony_ci    0,                                          /* tp_methods */
12097db96d56Sopenharmony_ci    sm_memberlist,              /* tp_members */
12107db96d56Sopenharmony_ci    sm_getsetlist,                              /* tp_getset */
12117db96d56Sopenharmony_ci    0,                                          /* tp_base */
12127db96d56Sopenharmony_ci    0,                                          /* tp_dict */
12137db96d56Sopenharmony_ci    sm_descr_get,                               /* tp_descr_get */
12147db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
12157db96d56Sopenharmony_ci    offsetof(staticmethod, sm_dict),            /* tp_dictoffset */
12167db96d56Sopenharmony_ci    sm_init,                                    /* tp_init */
12177db96d56Sopenharmony_ci    PyType_GenericAlloc,                        /* tp_alloc */
12187db96d56Sopenharmony_ci    PyType_GenericNew,                          /* tp_new */
12197db96d56Sopenharmony_ci    PyObject_GC_Del,                            /* tp_free */
12207db96d56Sopenharmony_ci};
12217db96d56Sopenharmony_ci
12227db96d56Sopenharmony_ciPyObject *
12237db96d56Sopenharmony_ciPyStaticMethod_New(PyObject *callable)
12247db96d56Sopenharmony_ci{
12257db96d56Sopenharmony_ci    staticmethod *sm = (staticmethod *)
12267db96d56Sopenharmony_ci        PyType_GenericAlloc(&PyStaticMethod_Type, 0);
12277db96d56Sopenharmony_ci    if (sm != NULL) {
12287db96d56Sopenharmony_ci        Py_INCREF(callable);
12297db96d56Sopenharmony_ci        sm->sm_callable = callable;
12307db96d56Sopenharmony_ci    }
12317db96d56Sopenharmony_ci    return (PyObject *)sm;
12327db96d56Sopenharmony_ci}
1233