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