LCOV - code coverage report
Current view: | top level - Objects - funcobject.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 266 | 538 | 49.4 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 36 | 59 | 61.0 %
|  |  | Branches: | 134 | 352 | 38.1 %

               Branch data     Line data    Source code
           1                 :            :
           2                 :            : /* Function object implementation */
           3                 :            :
           4                 :            : #include "Python.h"
           5                 :            : #include "pycore_ceval.h"         // _PyEval_BuiltinsFromGlobals()
           6                 :            : #include "pycore_code.h"          // _Py_next_func_version
           7                 :            : #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
           8                 :            : #include "pycore_pyerrors.h"      // _PyErr_Occurred()
           9                 :            : #include "structmember.h"         // PyMemberDef
          10                 :            :
          11                 :            : static PyObject* func_repr(PyFunctionObject *op);
          12                 :            :
          13                 :            : static const char *
          14                 :          0 : func_event_name(PyFunction_WatchEvent event) {
          15   [ #  #  #  #  :          0 :     switch (event) {
                       #  # ]
          16                 :            :         #define CASE(op)                \
          17                 :            :         case PyFunction_EVENT_##op:         \
          18                 :            :             return "PyFunction_EVENT_" #op;
          19                 :          0 :         PY_FOREACH_FUNC_EVENT(CASE)
          20                 :            :         #undef CASE
          21                 :            :     }
          22                 :          0 :     Py_UNREACHABLE();
          23                 :            : }
          24                 :            :
          25                 :            : static void
          26                 :          0 : notify_func_watchers(PyInterpreterState *interp, PyFunction_WatchEvent event,
          27                 :            :                      PyFunctionObject *func, PyObject *new_value)
          28                 :            : {
          29                 :          0 :     uint8_t bits = interp->active_func_watchers;
          30                 :          0 :     int i = 0;
          31         [ #  # ]:          0 :     while (bits) {
          32                 :            :         assert(i < FUNC_MAX_WATCHERS);
          33         [ #  # ]:          0 :         if (bits & 1) {
          34                 :          0 :             PyFunction_WatchCallback cb = interp->func_watchers[i];
          35                 :            :             // callback must be non-null if the watcher bit is set
          36                 :            :             assert(cb != NULL);
          37         [ #  # ]:          0 :             if (cb(event, func, new_value) < 0) {
          38                 :            :                 // Don't risk resurrecting the func if an unraisablehook keeps a
          39                 :            :                 // reference; pass a string as context.
          40                 :          0 :                 PyObject *context = NULL;
          41                 :          0 :                 PyObject *repr = func_repr(func);
          42         [ #  # ]:          0 :                 if (repr != NULL) {
          43                 :          0 :                     context = PyUnicode_FromFormat(
          44                 :            :                         "%s watcher callback for %U",
          45                 :            :                         func_event_name(event), repr);
          46                 :          0 :                     Py_DECREF(repr);
          47                 :            :                 }
          48         [ #  # ]:          0 :                 if (context == NULL) {
          49                 :          0 :                     context = Py_NewRef(Py_None);
          50                 :            :                 }
          51                 :          0 :                 PyErr_WriteUnraisable(context);
          52                 :          0 :                 Py_DECREF(context);
          53                 :            :             }
          54                 :            :         }
          55                 :          0 :         i++;
          56                 :          0 :         bits >>= 1;
          57                 :            :     }
          58                 :          0 : }
          59                 :            :
          60                 :            : static inline void
          61                 :     395820 : handle_func_event(PyFunction_WatchEvent event, PyFunctionObject *func,
          62                 :            :                   PyObject *new_value)
          63                 :            : {
          64                 :            :     assert(Py_REFCNT(func) > 0);
          65                 :     395820 :     PyInterpreterState *interp = _PyInterpreterState_GET();
          66                 :            :     assert(interp->_initialized);
          67         [ -  + ]:     395820 :     if (interp->active_func_watchers) {
          68                 :          0 :         notify_func_watchers(interp, event, func, new_value);
          69                 :            :     }
          70                 :     395820 : }
          71                 :            :
          72                 :            : int
          73                 :          0 : PyFunction_AddWatcher(PyFunction_WatchCallback callback)
          74                 :            : {
          75                 :          0 :     PyInterpreterState *interp = _PyInterpreterState_GET();
          76                 :            :     assert(interp->_initialized);
          77         [ #  # ]:          0 :     for (int i = 0; i < FUNC_MAX_WATCHERS; i++) {
          78         [ #  # ]:          0 :         if (interp->func_watchers[i] == NULL) {
          79                 :          0 :             interp->func_watchers[i] = callback;
          80                 :          0 :             interp->active_func_watchers |= (1 << i);
          81                 :          0 :             return i;
          82                 :            :         }
          83                 :            :     }
          84                 :          0 :     PyErr_SetString(PyExc_RuntimeError, "no more func watcher IDs available");
          85                 :          0 :     return -1;
          86                 :            : }
          87                 :            :
          88                 :            : int
          89                 :          0 : PyFunction_ClearWatcher(int watcher_id)
          90                 :            : {
          91                 :          0 :     PyInterpreterState *interp = _PyInterpreterState_GET();
          92   [ #  #  #  # ]:          0 :     if (watcher_id < 0 || watcher_id >= FUNC_MAX_WATCHERS) {
          93                 :          0 :         PyErr_Format(PyExc_ValueError, "invalid func watcher ID %d",
          94                 :            :                      watcher_id);
          95                 :          0 :         return -1;
          96                 :            :     }
          97         [ #  # ]:          0 :     if (!interp->func_watchers[watcher_id]) {
          98                 :          0 :         PyErr_Format(PyExc_ValueError, "no func watcher set for ID %d",
          99                 :            :                      watcher_id);
         100                 :          0 :         return -1;
         101                 :            :     }
         102                 :          0 :     interp->func_watchers[watcher_id] = NULL;
         103                 :          0 :     interp->active_func_watchers &= ~(1 << watcher_id);
         104                 :          0 :     return 0;
         105                 :            : }
         106                 :            : PyFunctionObject *
         107                 :        828 : _PyFunction_FromConstructor(PyFrameConstructor *constr)
         108                 :            : {
         109                 :            :
         110                 :        828 :     PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type);
         111         [ -  + ]:        828 :     if (op == NULL) {
         112                 :          0 :         return NULL;
         113                 :            :     }
         114                 :        828 :     op->func_globals = Py_NewRef(constr->fc_globals);
         115                 :        828 :     op->func_builtins = Py_NewRef(constr->fc_builtins);
         116                 :        828 :     op->func_name = Py_NewRef(constr->fc_name);
         117                 :        828 :     op->func_qualname = Py_NewRef(constr->fc_qualname);
         118                 :        828 :     op->func_code = Py_NewRef(constr->fc_code);
         119                 :        828 :     op->func_defaults = Py_XNewRef(constr->fc_defaults);
         120                 :        828 :     op->func_kwdefaults = Py_XNewRef(constr->fc_kwdefaults);
         121                 :        828 :     op->func_closure = Py_XNewRef(constr->fc_closure);
         122                 :        828 :     op->func_doc = Py_NewRef(Py_None);
         123                 :        828 :     op->func_dict = NULL;
         124                 :        828 :     op->func_weakreflist = NULL;
         125                 :        828 :     op->func_module = Py_XNewRef(PyDict_GetItem(op->func_globals, &_Py_ID(__name__)));
         126         [ +  + ]:        828 :     if (!op->func_module) {
         127                 :         81 :         PyErr_Clear();
         128                 :            :     }
         129                 :        828 :     op->func_annotations = NULL;
         130                 :        828 :     op->vectorcall = _PyFunction_Vectorcall;
         131                 :        828 :     op->func_version = 0;
         132                 :        828 :     _PyObject_GC_TRACK(op);
         133                 :        828 :     handle_func_event(PyFunction_EVENT_CREATE, op, NULL);
         134                 :        828 :     return op;
         135                 :            : }
         136                 :            :
         137                 :            : PyObject *
         138                 :     197280 : PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname)
         139                 :            : {
         140                 :            :     assert(globals != NULL);
         141                 :            :     assert(PyDict_Check(globals));
         142                 :     197280 :     Py_INCREF(globals);
         143                 :            :
         144                 :     197280 :     PyThreadState *tstate = _PyThreadState_GET();
         145                 :            :
         146                 :     197280 :     PyCodeObject *code_obj = (PyCodeObject *)Py_NewRef(code);
         147                 :            :
         148                 :            :     assert(code_obj->co_name != NULL);
         149                 :     197280 :     PyObject *name = Py_NewRef(code_obj->co_name);
         150                 :            :
         151         [ +  - ]:     197280 :     if (!qualname) {
         152                 :     197280 :         qualname = code_obj->co_qualname;
         153                 :            :     }
         154                 :            :     assert(qualname != NULL);
         155                 :     197280 :     Py_INCREF(qualname);
         156                 :            :
         157                 :     197280 :     PyObject *consts = code_obj->co_consts;
         158                 :            :     assert(PyTuple_Check(consts));
         159                 :            :     PyObject *doc;
         160         [ +  - ]:     197280 :     if (PyTuple_Size(consts) >= 1) {
         161                 :     197280 :         doc = PyTuple_GetItem(consts, 0);
         162         [ +  + ]:     197280 :         if (!PyUnicode_Check(doc)) {
         163                 :     180435 :             doc = Py_None;
         164                 :            :         }
         165                 :            :     }
         166                 :            :     else {
         167                 :          0 :         doc = Py_None;
         168                 :            :     }
         169                 :     197280 :     Py_INCREF(doc);
         170                 :            :
         171                 :            :     // __module__: Use globals['__name__'] if it exists, or NULL.
         172                 :     197280 :     PyObject *module = PyDict_GetItemWithError(globals, &_Py_ID(__name__));
         173                 :     197280 :     PyObject *builtins = NULL;
         174   [ +  +  -  + ]:     197280 :     if (module == NULL && _PyErr_Occurred(tstate)) {
         175                 :          0 :         goto error;
         176                 :            :     }
         177                 :     197280 :     Py_XINCREF(module);
         178                 :            :
         179                 :     197280 :     builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref
         180         [ -  + ]:     197280 :     if (builtins == NULL) {
         181                 :          0 :         goto error;
         182                 :            :     }
         183                 :     197280 :     Py_INCREF(builtins);
         184                 :            :
         185                 :     197280 :     PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type);
         186         [ -  + ]:     197280 :     if (op == NULL) {
         187                 :          0 :         goto error;
         188                 :            :     }
         189                 :            :     /* Note: No failures from this point on, since func_dealloc() does not
         190                 :            :        expect a partially-created object. */
         191                 :            :
         192                 :     197280 :     op->func_globals = globals;
         193                 :     197280 :     op->func_builtins = builtins;
         194                 :     197280 :     op->func_name = name;
         195                 :     197280 :     op->func_qualname = qualname;
         196                 :     197280 :     op->func_code = (PyObject*)code_obj;
         197                 :     197280 :     op->func_defaults = NULL;    // No default positional arguments
         198                 :     197280 :     op->func_kwdefaults = NULL;  // No default keyword arguments
         199                 :     197280 :     op->func_closure = NULL;
         200                 :     197280 :     op->func_doc = doc;
         201                 :     197280 :     op->func_dict = NULL;
         202                 :     197280 :     op->func_weakreflist = NULL;
         203                 :     197280 :     op->func_module = module;
         204                 :     197280 :     op->func_annotations = NULL;
         205                 :     197280 :     op->vectorcall = _PyFunction_Vectorcall;
         206                 :     197280 :     op->func_version = 0;
         207                 :     197280 :     _PyObject_GC_TRACK(op);
         208                 :     197280 :     handle_func_event(PyFunction_EVENT_CREATE, op, NULL);
         209                 :     197280 :     return (PyObject *)op;
         210                 :            :
         211                 :          0 : error:
         212                 :          0 :     Py_DECREF(globals);
         213                 :          0 :     Py_DECREF(code_obj);
         214                 :          0 :     Py_DECREF(name);
         215                 :          0 :     Py_DECREF(qualname);
         216                 :          0 :     Py_DECREF(doc);
         217                 :          0 :     Py_XDECREF(module);
         218                 :          0 :     Py_XDECREF(builtins);
         219                 :          0 :     return NULL;
         220                 :            : }
         221                 :            :
         222                 :       5496 : uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func)
         223                 :            : {
         224         [ +  - ]:       5496 :     if (func->func_version != 0) {
         225                 :       5496 :         return func->func_version;
         226                 :            :     }
         227         [ #  # ]:          0 :     if (func->vectorcall != _PyFunction_Vectorcall) {
         228                 :          0 :         return 0;
         229                 :            :     }
         230                 :          0 :     PyInterpreterState *interp = _PyInterpreterState_GET();
         231         [ #  # ]:          0 :     if (interp->func_state.next_version == 0) {
         232                 :          0 :         return 0;
         233                 :            :     }
         234                 :          0 :     uint32_t v = interp->func_state.next_version++;
         235                 :          0 :     func->func_version = v;
         236                 :          0 :     return v;
         237                 :            : }
         238                 :            :
         239                 :            : PyObject *
         240                 :     197280 : PyFunction_New(PyObject *code, PyObject *globals)
         241                 :            : {
         242                 :     197280 :     return PyFunction_NewWithQualName(code, globals, NULL);
         243                 :            : }
         244                 :            :
         245                 :            : PyObject *
         246                 :          0 : PyFunction_GetCode(PyObject *op)
         247                 :            : {
         248         [ #  # ]:          0 :     if (!PyFunction_Check(op)) {
         249                 :          0 :         PyErr_BadInternalCall();
         250                 :          0 :         return NULL;
         251                 :            :     }
         252                 :          0 :     return ((PyFunctionObject *) op) -> func_code;
         253                 :            : }
         254                 :            :
         255                 :            : PyObject *
         256                 :          0 : PyFunction_GetGlobals(PyObject *op)
         257                 :            : {
         258         [ #  # ]:          0 :     if (!PyFunction_Check(op)) {
         259                 :          0 :         PyErr_BadInternalCall();
         260                 :          0 :         return NULL;
         261                 :            :     }
         262                 :          0 :     return ((PyFunctionObject *) op) -> func_globals;
         263                 :            : }
         264                 :            :
         265                 :            : PyObject *
         266                 :         88 : PyFunction_GetModule(PyObject *op)
         267                 :            : {
         268         [ -  + ]:         88 :     if (!PyFunction_Check(op)) {
         269                 :          0 :         PyErr_BadInternalCall();
         270                 :          0 :         return NULL;
         271                 :            :     }
         272                 :         88 :     return ((PyFunctionObject *) op) -> func_module;
         273                 :            : }
         274                 :            :
         275                 :            : PyObject *
         276                 :          0 : PyFunction_GetDefaults(PyObject *op)
         277                 :            : {
         278         [ #  # ]:          0 :     if (!PyFunction_Check(op)) {
         279                 :          0 :         PyErr_BadInternalCall();
         280                 :          0 :         return NULL;
         281                 :            :     }
         282                 :          0 :     return ((PyFunctionObject *) op) -> func_defaults;
         283                 :            : }
         284                 :            :
         285                 :            : int
         286                 :          0 : PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
         287                 :            : {
         288         [ #  # ]:          0 :     if (!PyFunction_Check(op)) {
         289                 :          0 :         PyErr_BadInternalCall();
         290                 :          0 :         return -1;
         291                 :            :     }
         292         [ #  # ]:          0 :     if (defaults == Py_None)
         293                 :          0 :         defaults = NULL;
         294   [ #  #  #  # ]:          0 :     else if (defaults && PyTuple_Check(defaults)) {
         295                 :          0 :         Py_INCREF(defaults);
         296                 :            :     }
         297                 :            :     else {
         298                 :          0 :         PyErr_SetString(PyExc_SystemError, "non-tuple default args");
         299                 :          0 :         return -1;
         300                 :            :     }
         301                 :          0 :     handle_func_event(PyFunction_EVENT_MODIFY_DEFAULTS,
         302                 :            :                       (PyFunctionObject *) op, defaults);
         303                 :          0 :     ((PyFunctionObject *)op)->func_version = 0;
         304                 :          0 :     Py_XSETREF(((PyFunctionObject *)op)->func_defaults, defaults);
         305                 :          0 :     return 0;
         306                 :            : }
         307                 :            :
         308                 :            : void
         309                 :          0 : PyFunction_SetVectorcall(PyFunctionObject *func, vectorcallfunc vectorcall)
         310                 :            : {
         311                 :            :     assert(func != NULL);
         312                 :          0 :     func->func_version = 0;
         313                 :          0 :     func->vectorcall = vectorcall;
         314                 :          0 : }
         315                 :            :
         316                 :            : PyObject *
         317                 :          0 : PyFunction_GetKwDefaults(PyObject *op)
         318                 :            : {
         319         [ #  # ]:          0 :     if (!PyFunction_Check(op)) {
         320                 :          0 :         PyErr_BadInternalCall();
         321                 :          0 :         return NULL;
         322                 :            :     }
         323                 :          0 :     return ((PyFunctionObject *) op) -> func_kwdefaults;
         324                 :            : }
         325                 :            :
         326                 :            : int
         327                 :          0 : PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults)
         328                 :            : {
         329         [ #  # ]:          0 :     if (!PyFunction_Check(op)) {
         330                 :          0 :         PyErr_BadInternalCall();
         331                 :          0 :         return -1;
         332                 :            :     }
         333         [ #  # ]:          0 :     if (defaults == Py_None)
         334                 :          0 :         defaults = NULL;
         335   [ #  #  #  # ]:          0 :     else if (defaults && PyDict_Check(defaults)) {
         336                 :          0 :         Py_INCREF(defaults);
         337                 :            :     }
         338                 :            :     else {
         339                 :          0 :         PyErr_SetString(PyExc_SystemError,
         340                 :            :                         "non-dict keyword only default args");
         341                 :          0 :         return -1;
         342                 :            :     }
         343                 :          0 :     handle_func_event(PyFunction_EVENT_MODIFY_KWDEFAULTS,
         344                 :            :                       (PyFunctionObject *) op, defaults);
         345                 :          0 :     ((PyFunctionObject *)op)->func_version = 0;
         346                 :          0 :     Py_XSETREF(((PyFunctionObject *)op)->func_kwdefaults, defaults);
         347                 :          0 :     return 0;
         348                 :            : }
         349                 :            :
         350                 :            : PyObject *
         351                 :          0 : PyFunction_GetClosure(PyObject *op)
         352                 :            : {
         353         [ #  # ]:          0 :     if (!PyFunction_Check(op)) {
         354                 :          0 :         PyErr_BadInternalCall();
         355                 :          0 :         return NULL;
         356                 :            :     }
         357                 :          0 :     return ((PyFunctionObject *) op) -> func_closure;
         358                 :            : }
         359                 :            :
         360                 :            : int
         361                 :          0 : PyFunction_SetClosure(PyObject *op, PyObject *closure)
         362                 :            : {
         363         [ #  # ]:          0 :     if (!PyFunction_Check(op)) {
         364                 :          0 :         PyErr_BadInternalCall();
         365                 :          0 :         return -1;
         366                 :            :     }
         367         [ #  # ]:          0 :     if (closure == Py_None)
         368                 :          0 :         closure = NULL;
         369         [ #  # ]:          0 :     else if (PyTuple_Check(closure)) {
         370                 :          0 :         Py_INCREF(closure);
         371                 :            :     }
         372                 :            :     else {
         373                 :          0 :         PyErr_Format(PyExc_SystemError,
         374                 :            :                      "expected tuple for closure, got '%.100s'",
         375                 :          0 :                      Py_TYPE(closure)->tp_name);
         376                 :          0 :         return -1;
         377                 :            :     }
         378                 :          0 :     ((PyFunctionObject *)op)->func_version = 0;
         379                 :          0 :     Py_XSETREF(((PyFunctionObject *)op)->func_closure, closure);
         380                 :          0 :     return 0;
         381                 :            : }
         382                 :            :
         383                 :            : static PyObject *
         384                 :       1564 : func_get_annotation_dict(PyFunctionObject *op)
         385                 :            : {
         386         [ -  + ]:       1564 :     if (op->func_annotations == NULL) {
         387                 :          0 :         return NULL;
         388                 :            :     }
         389         [ +  + ]:       1564 :     if (PyTuple_CheckExact(op->func_annotations)) {
         390                 :          3 :         PyObject *ann_tuple = op->func_annotations;
         391                 :          3 :         PyObject *ann_dict = PyDict_New();
         392         [ -  + ]:          3 :         if (ann_dict == NULL) {
         393                 :          0 :             return NULL;
         394                 :            :         }
         395                 :            :
         396                 :            :         assert(PyTuple_GET_SIZE(ann_tuple) % 2 == 0);
         397                 :            :
         398         [ +  + ]:          8 :         for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(ann_tuple); i += 2) {
         399                 :          5 :             int err = PyDict_SetItem(ann_dict,
         400                 :            :                                      PyTuple_GET_ITEM(ann_tuple, i),
         401                 :          5 :                                      PyTuple_GET_ITEM(ann_tuple, i + 1));
         402                 :            :
         403         [ -  + ]:          5 :             if (err < 0) {
         404                 :          0 :                 return NULL;
         405                 :            :             }
         406                 :            :         }
         407                 :          3 :         Py_SETREF(op->func_annotations, ann_dict);
         408                 :            :     }
         409                 :            :     assert(PyDict_Check(op->func_annotations));
         410                 :       1564 :     return op->func_annotations;
         411                 :            : }
         412                 :            :
         413                 :            : PyObject *
         414                 :          0 : PyFunction_GetAnnotations(PyObject *op)
         415                 :            : {
         416         [ #  # ]:          0 :     if (!PyFunction_Check(op)) {
         417                 :          0 :         PyErr_BadInternalCall();
         418                 :          0 :         return NULL;
         419                 :            :     }
         420                 :          0 :     return func_get_annotation_dict((PyFunctionObject *)op);
         421                 :            : }
         422                 :            :
         423                 :            : int
         424                 :          0 : PyFunction_SetAnnotations(PyObject *op, PyObject *annotations)
         425                 :            : {
         426         [ #  # ]:          0 :     if (!PyFunction_Check(op)) {
         427                 :          0 :         PyErr_BadInternalCall();
         428                 :          0 :         return -1;
         429                 :            :     }
         430         [ #  # ]:          0 :     if (annotations == Py_None)
         431                 :          0 :         annotations = NULL;
         432   [ #  #  #  # ]:          0 :     else if (annotations && PyDict_Check(annotations)) {
         433                 :          0 :         Py_INCREF(annotations);
         434                 :            :     }
         435                 :            :     else {
         436                 :          0 :         PyErr_SetString(PyExc_SystemError,
         437                 :            :                         "non-dict annotations");
         438                 :          0 :         return -1;
         439                 :            :     }
         440                 :          0 :     ((PyFunctionObject *)op)->func_version = 0;
         441                 :          0 :     Py_XSETREF(((PyFunctionObject *)op)->func_annotations, annotations);
         442                 :          0 :     return 0;
         443                 :            : }
         444                 :            :
         445                 :            : /* Methods */
         446                 :            :
         447                 :            : #define OFF(x) offsetof(PyFunctionObject, x)
         448                 :            :
         449                 :            : static PyMemberDef func_memberlist[] = {
         450                 :            :     {"__closure__",   T_OBJECT,     OFF(func_closure), READONLY},
         451                 :            :     {"__doc__",       T_OBJECT,     OFF(func_doc), 0},
         452                 :            :     {"__globals__",   T_OBJECT,     OFF(func_globals), READONLY},
         453                 :            :     {"__module__",    T_OBJECT,     OFF(func_module), 0},
         454                 :            :     {"__builtins__",  T_OBJECT,     OFF(func_builtins), READONLY},
         455                 :            :     {NULL}  /* Sentinel */
         456                 :            : };
         457                 :            :
         458                 :            : static PyObject *
         459                 :         59 : func_get_code(PyFunctionObject *op, void *Py_UNUSED(ignored))
         460                 :            : {
         461         [ -  + ]:         59 :     if (PySys_Audit("object.__getattr__", "Os", op, "__code__") < 0) {
         462                 :          0 :         return NULL;
         463                 :            :     }
         464                 :            :
         465                 :         59 :     return Py_NewRef(op->func_code);
         466                 :            : }
         467                 :            :
         468                 :            : static int
         469                 :          1 : func_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
         470                 :            : {
         471                 :            :     Py_ssize_t nclosure;
         472                 :            :     int nfree;
         473                 :            :
         474                 :            :     /* Not legal to del f.func_code or to set it to anything
         475                 :            :      * other than a code object. */
         476   [ +  -  -  + ]:          1 :     if (value == NULL || !PyCode_Check(value)) {
         477                 :          0 :         PyErr_SetString(PyExc_TypeError,
         478                 :            :                         "__code__ must be set to a code object");
         479                 :          0 :         return -1;
         480                 :            :     }
         481                 :            :
         482         [ -  + ]:          1 :     if (PySys_Audit("object.__setattr__", "OsO",
         483                 :            :                     op, "__code__", value) < 0) {
         484                 :          0 :         return -1;
         485                 :            :     }
         486                 :            :
         487                 :          1 :     nfree = ((PyCodeObject *)value)->co_nfreevars;
         488         [ -  + ]:          1 :     nclosure = (op->func_closure == NULL ? 0 :
         489                 :          0 :             PyTuple_GET_SIZE(op->func_closure));
         490         [ -  + ]:          1 :     if (nclosure != nfree) {
         491                 :          0 :         PyErr_Format(PyExc_ValueError,
         492                 :            :                      "%U() requires a code object with %zd free vars,"
         493                 :            :                      " not %zd",
         494                 :            :                      op->func_name,
         495                 :            :                      nclosure, nfree);
         496                 :          0 :         return -1;
         497                 :            :     }
         498                 :          1 :     handle_func_event(PyFunction_EVENT_MODIFY_CODE, op, value);
         499                 :          1 :     op->func_version = 0;
         500                 :          1 :     Py_XSETREF(op->func_code, Py_NewRef(value));
         501                 :          1 :     return 0;
         502                 :            : }
         503                 :            :
         504                 :            : static PyObject *
         505                 :       2466 : func_get_name(PyFunctionObject *op, void *Py_UNUSED(ignored))
         506                 :            : {
         507                 :       2466 :     return Py_NewRef(op->func_name);
         508                 :            : }
         509                 :            :
         510                 :            : static int
         511                 :        416 : func_set_name(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
         512                 :            : {
         513                 :            :     /* Not legal to del f.func_name or to set it to anything
         514                 :            :      * other than a string object. */
         515   [ +  -  -  + ]:        416 :     if (value == NULL || !PyUnicode_Check(value)) {
         516                 :          0 :         PyErr_SetString(PyExc_TypeError,
         517                 :            :                         "__name__ must be set to a string object");
         518                 :          0 :         return -1;
         519                 :            :     }
         520                 :        416 :     Py_XSETREF(op->func_name, Py_NewRef(value));
         521                 :        416 :     return 0;
         522                 :            : }
         523                 :            :
         524                 :            : static PyObject *
         525                 :       2064 : func_get_qualname(PyFunctionObject *op, void *Py_UNUSED(ignored))
         526                 :            : {
         527                 :       2064 :     return Py_NewRef(op->func_qualname);
         528                 :            : }
         529                 :            :
         530                 :            : static int
         531                 :        681 : func_set_qualname(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
         532                 :            : {
         533                 :            :     /* Not legal to del f.__qualname__ or to set it to anything
         534                 :            :      * other than a string object. */
         535   [ +  -  -  + ]:        681 :     if (value == NULL || !PyUnicode_Check(value)) {
         536                 :          0 :         PyErr_SetString(PyExc_TypeError,
         537                 :            :                         "__qualname__ must be set to a string object");
         538                 :          0 :         return -1;
         539                 :            :     }
         540                 :        681 :     Py_XSETREF(op->func_qualname, Py_NewRef(value));
         541                 :        681 :     return 0;
         542                 :            : }
         543                 :            :
         544                 :            : static PyObject *
         545                 :          0 : func_get_defaults(PyFunctionObject *op, void *Py_UNUSED(ignored))
         546                 :            : {
         547         [ #  # ]:          0 :     if (PySys_Audit("object.__getattr__", "Os", op, "__defaults__") < 0) {
         548                 :          0 :         return NULL;
         549                 :            :     }
         550         [ #  # ]:          0 :     if (op->func_defaults == NULL) {
         551                 :          0 :         Py_RETURN_NONE;
         552                 :            :     }
         553                 :          0 :     return Py_NewRef(op->func_defaults);
         554                 :            : }
         555                 :            :
         556                 :            : static int
         557                 :          8 : func_set_defaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
         558                 :            : {
         559                 :            :     /* Legal to del f.func_defaults.
         560                 :            :      * Can only set func_defaults to NULL or a tuple. */
         561         [ -  + ]:          8 :     if (value == Py_None)
         562                 :          0 :         value = NULL;
         563   [ +  -  -  + ]:          8 :     if (value != NULL && !PyTuple_Check(value)) {
         564                 :          0 :         PyErr_SetString(PyExc_TypeError,
         565                 :            :                         "__defaults__ must be set to a tuple object");
         566                 :          0 :         return -1;
         567                 :            :     }
         568         [ +  - ]:          8 :     if (value) {
         569         [ -  + ]:          8 :         if (PySys_Audit("object.__setattr__", "OsO",
         570                 :            :                         op, "__defaults__", value) < 0) {
         571                 :          0 :             return -1;
         572                 :            :         }
         573         [ #  # ]:          0 :     } else if (PySys_Audit("object.__delattr__", "Os",
         574                 :            :                            op, "__defaults__") < 0) {
         575                 :          0 :         return -1;
         576                 :            :     }
         577                 :            :
         578                 :          8 :     handle_func_event(PyFunction_EVENT_MODIFY_DEFAULTS, op, value);
         579                 :          8 :     op->func_version = 0;
         580                 :          8 :     Py_XSETREF(op->func_defaults, Py_XNewRef(value));
         581                 :          8 :     return 0;
         582                 :            : }
         583                 :            :
         584                 :            : static PyObject *
         585                 :          0 : func_get_kwdefaults(PyFunctionObject *op, void *Py_UNUSED(ignored))
         586                 :            : {
         587         [ #  # ]:          0 :     if (PySys_Audit("object.__getattr__", "Os",
         588                 :            :                     op, "__kwdefaults__") < 0) {
         589                 :          0 :         return NULL;
         590                 :            :     }
         591         [ #  # ]:          0 :     if (op->func_kwdefaults == NULL) {
         592                 :          0 :         Py_RETURN_NONE;
         593                 :            :     }
         594                 :          0 :     return Py_NewRef(op->func_kwdefaults);
         595                 :            : }
         596                 :            :
         597                 :            : static int
         598                 :          0 : func_set_kwdefaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
         599                 :            : {
         600         [ #  # ]:          0 :     if (value == Py_None)
         601                 :          0 :         value = NULL;
         602                 :            :     /* Legal to del f.func_kwdefaults.
         603                 :            :      * Can only set func_kwdefaults to NULL or a dict. */
         604   [ #  #  #  # ]:          0 :     if (value != NULL && !PyDict_Check(value)) {
         605                 :          0 :         PyErr_SetString(PyExc_TypeError,
         606                 :            :             "__kwdefaults__ must be set to a dict object");
         607                 :          0 :         return -1;
         608                 :            :     }
         609         [ #  # ]:          0 :     if (value) {
         610         [ #  # ]:          0 :         if (PySys_Audit("object.__setattr__", "OsO",
         611                 :            :                         op, "__kwdefaults__", value) < 0) {
         612                 :          0 :             return -1;
         613                 :            :         }
         614         [ #  # ]:          0 :     } else if (PySys_Audit("object.__delattr__", "Os",
         615                 :            :                            op, "__kwdefaults__") < 0) {
         616                 :          0 :         return -1;
         617                 :            :     }
         618                 :            :
         619                 :          0 :     handle_func_event(PyFunction_EVENT_MODIFY_KWDEFAULTS, op, value);
         620                 :          0 :     op->func_version = 0;
         621                 :          0 :     Py_XSETREF(op->func_kwdefaults, Py_XNewRef(value));
         622                 :          0 :     return 0;
         623                 :            : }
         624                 :            :
         625                 :            : static PyObject *
         626                 :       1564 : func_get_annotations(PyFunctionObject *op, void *Py_UNUSED(ignored))
         627                 :            : {
         628         [ +  + ]:       1564 :     if (op->func_annotations == NULL) {
         629                 :       1537 :         op->func_annotations = PyDict_New();
         630         [ -  + ]:       1537 :         if (op->func_annotations == NULL)
         631                 :          0 :             return NULL;
         632                 :            :     }
         633                 :       1564 :     PyObject *d = func_get_annotation_dict(op);
         634                 :       1564 :     return Py_XNewRef(d);
         635                 :            : }
         636                 :            :
         637                 :            : static int
         638                 :         86 : func_set_annotations(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
         639                 :            : {
         640         [ -  + ]:         86 :     if (value == Py_None)
         641                 :          0 :         value = NULL;
         642                 :            :     /* Legal to del f.func_annotations.
         643                 :            :      * Can only set func_annotations to NULL (through C api)
         644                 :            :      * or a dict. */
         645   [ +  -  -  + ]:         86 :     if (value != NULL && !PyDict_Check(value)) {
         646                 :          0 :         PyErr_SetString(PyExc_TypeError,
         647                 :            :             "__annotations__ must be set to a dict object");
         648                 :          0 :         return -1;
         649                 :            :     }
         650                 :         86 :     op->func_version = 0;
         651                 :         86 :     Py_XSETREF(op->func_annotations, Py_XNewRef(value));
         652                 :         86 :     return 0;
         653                 :            : }
         654                 :            :
         655                 :            : static PyGetSetDef func_getsetlist[] = {
         656                 :            :     {"__code__", (getter)func_get_code, (setter)func_set_code},
         657                 :            :     {"__defaults__", (getter)func_get_defaults,
         658                 :            :      (setter)func_set_defaults},
         659                 :            :     {"__kwdefaults__", (getter)func_get_kwdefaults,
         660                 :            :      (setter)func_set_kwdefaults},
         661                 :            :     {"__annotations__", (getter)func_get_annotations,
         662                 :            :      (setter)func_set_annotations},
         663                 :            :     {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
         664                 :            :     {"__name__", (getter)func_get_name, (setter)func_set_name},
         665                 :            :     {"__qualname__", (getter)func_get_qualname, (setter)func_set_qualname},
         666                 :            :     {NULL} /* Sentinel */
         667                 :            : };
         668                 :            :
         669                 :            : /*[clinic input]
         670                 :            : class function "PyFunctionObject *" "&PyFunction_Type"
         671                 :            : [clinic start generated code]*/
         672                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=70af9c90aa2e71b0]*/
         673                 :            :
         674                 :            : #include "clinic/funcobject.c.h"
         675                 :            :
         676                 :            : /* function.__new__() maintains the following invariants for closures.
         677                 :            :    The closure must correspond to the free variables of the code object.
         678                 :            :
         679                 :            :    if len(code.co_freevars) == 0:
         680                 :            :        closure = NULL
         681                 :            :    else:
         682                 :            :        len(closure) == len(code.co_freevars)
         683                 :            :    for every elt in closure, type(elt) == cell
         684                 :            : */
         685                 :            :
         686                 :            : /*[clinic input]
         687                 :            : @classmethod
         688                 :            : function.__new__ as func_new
         689                 :            :     code: object(type="PyCodeObject *", subclass_of="&PyCode_Type")
         690                 :            :         a code object
         691                 :            :     globals: object(subclass_of="&PyDict_Type")
         692                 :            :         the globals dictionary
         693                 :            :     name: object = None
         694                 :            :         a string that overrides the name from the code object
         695                 :            :     argdefs as defaults: object = None
         696                 :            :         a tuple that specifies the default argument values
         697                 :            :     closure: object = None
         698                 :            :         a tuple that supplies the bindings for free variables
         699                 :            :
         700                 :            : Create a function object.
         701                 :            : [clinic start generated code]*/
         702                 :            :
         703                 :            : static PyObject *
         704                 :          0 : func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals,
         705                 :            :               PyObject *name, PyObject *defaults, PyObject *closure)
         706                 :            : /*[clinic end generated code: output=99c6d9da3a24e3be input=93611752fc2daf11]*/
         707                 :            : {
         708                 :            :     PyFunctionObject *newfunc;
         709                 :            :     Py_ssize_t nclosure;
         710                 :            :
         711   [ #  #  #  # ]:          0 :     if (name != Py_None && !PyUnicode_Check(name)) {
         712                 :          0 :         PyErr_SetString(PyExc_TypeError,
         713                 :            :                         "arg 3 (name) must be None or string");
         714                 :          0 :         return NULL;
         715                 :            :     }
         716   [ #  #  #  # ]:          0 :     if (defaults != Py_None && !PyTuple_Check(defaults)) {
         717                 :          0 :         PyErr_SetString(PyExc_TypeError,
         718                 :            :                         "arg 4 (defaults) must be None or tuple");
         719                 :          0 :         return NULL;
         720                 :            :     }
         721         [ #  # ]:          0 :     if (!PyTuple_Check(closure)) {
         722   [ #  #  #  # ]:          0 :         if (code->co_nfreevars && closure == Py_None) {
         723                 :          0 :             PyErr_SetString(PyExc_TypeError,
         724                 :            :                             "arg 5 (closure) must be tuple");
         725                 :          0 :             return NULL;
         726                 :            :         }
         727         [ #  # ]:          0 :         else if (closure != Py_None) {
         728                 :          0 :             PyErr_SetString(PyExc_TypeError,
         729                 :            :                 "arg 5 (closure) must be None or tuple");
         730                 :          0 :             return NULL;
         731                 :            :         }
         732                 :            :     }
         733                 :            :
         734                 :            :     /* check that the closure is well-formed */
         735         [ #  # ]:          0 :     nclosure = closure == Py_None ? 0 : PyTuple_GET_SIZE(closure);
         736         [ #  # ]:          0 :     if (code->co_nfreevars != nclosure)
         737                 :          0 :         return PyErr_Format(PyExc_ValueError,
         738                 :            :                             "%U requires closure of length %zd, not %zd",
         739                 :            :                             code->co_name, code->co_nfreevars, nclosure);
         740         [ #  # ]:          0 :     if (nclosure) {
         741                 :            :         Py_ssize_t i;
         742         [ #  # ]:          0 :         for (i = 0; i < nclosure; i++) {
         743                 :          0 :             PyObject *o = PyTuple_GET_ITEM(closure, i);
         744         [ #  # ]:          0 :             if (!PyCell_Check(o)) {
         745                 :          0 :                 return PyErr_Format(PyExc_TypeError,
         746                 :            :                     "arg 5 (closure) expected cell, found %s",
         747                 :          0 :                                     Py_TYPE(o)->tp_name);
         748                 :            :             }
         749                 :            :         }
         750                 :            :     }
         751         [ #  # ]:          0 :     if (PySys_Audit("function.__new__", "O", code) < 0) {
         752                 :          0 :         return NULL;
         753                 :            :     }
         754                 :            :
         755                 :          0 :     newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code,
         756                 :            :                                                  globals);
         757         [ #  # ]:          0 :     if (newfunc == NULL) {
         758                 :          0 :         return NULL;
         759                 :            :     }
         760         [ #  # ]:          0 :     if (name != Py_None) {
         761                 :          0 :         Py_SETREF(newfunc->func_name, Py_NewRef(name));
         762                 :            :     }
         763         [ #  # ]:          0 :     if (defaults != Py_None) {
         764                 :          0 :         newfunc->func_defaults = Py_NewRef(defaults);
         765                 :            :     }
         766         [ #  # ]:          0 :     if (closure != Py_None) {
         767                 :          0 :         newfunc->func_closure = Py_NewRef(closure);
         768                 :            :     }
         769                 :            :
         770                 :          0 :     return (PyObject *)newfunc;
         771                 :            : }
         772                 :            :
         773                 :            : static int
         774                 :     198288 : func_clear(PyFunctionObject *op)
         775                 :            : {
         776                 :     198288 :     op->func_version = 0;
         777         [ +  + ]:     198288 :     Py_CLEAR(op->func_globals);
         778         [ +  + ]:     198288 :     Py_CLEAR(op->func_builtins);
         779         [ +  + ]:     198288 :     Py_CLEAR(op->func_module);
         780         [ +  + ]:     198288 :     Py_CLEAR(op->func_defaults);
         781         [ +  + ]:     198288 :     Py_CLEAR(op->func_kwdefaults);
         782         [ +  + ]:     198288 :     Py_CLEAR(op->func_doc);
         783         [ +  + ]:     198288 :     Py_CLEAR(op->func_dict);
         784         [ +  + ]:     198288 :     Py_CLEAR(op->func_closure);
         785         [ +  + ]:     198288 :     Py_CLEAR(op->func_annotations);
         786                 :            :     // Don't Py_CLEAR(op->func_code), since code is always required
         787                 :            :     // to be non-NULL. Similarly, name and qualname shouldn't be NULL.
         788                 :            :     // However, name and qualname could be str subclasses, so they
         789                 :            :     // could have reference cycles. The solution is to replace them
         790                 :            :     // with a genuinely immutable string.
         791                 :     198288 :     Py_SETREF(op->func_name, Py_NewRef(&_Py_STR(empty)));
         792                 :     198288 :     Py_SETREF(op->func_qualname, Py_NewRef(&_Py_STR(empty)));
         793                 :     198288 :     return 0;
         794                 :            : }
         795                 :            :
         796                 :            : static void
         797                 :     197703 : func_dealloc(PyFunctionObject *op)
         798                 :            : {
         799                 :            :     assert(Py_REFCNT(op) == 0);
         800                 :     197703 :     Py_SET_REFCNT(op, 1);
         801                 :     197703 :     handle_func_event(PyFunction_EVENT_DESTROY, op, NULL);
         802         [ -  + ]:     197703 :     if (Py_REFCNT(op) > 1) {
         803                 :          0 :         Py_SET_REFCNT(op, Py_REFCNT(op) - 1);
         804                 :          0 :         return;
         805                 :            :     }
         806                 :     197703 :     Py_SET_REFCNT(op, 0);
         807                 :     197703 :     _PyObject_GC_UNTRACK(op);
         808         [ -  + ]:     197703 :     if (op->func_weakreflist != NULL) {
         809                 :          0 :         PyObject_ClearWeakRefs((PyObject *) op);
         810                 :            :     }
         811                 :     197703 :     (void)func_clear(op);
         812                 :            :     // These aren't cleared by func_clear().
         813                 :     197703 :     Py_DECREF(op->func_code);
         814                 :     197703 :     Py_DECREF(op->func_name);
         815                 :     197703 :     Py_DECREF(op->func_qualname);
         816                 :     197703 :     PyObject_GC_Del(op);
         817                 :            : }
         818                 :            :
         819                 :            : static PyObject*
         820                 :          0 : func_repr(PyFunctionObject *op)
         821                 :            : {
         822                 :          0 :     return PyUnicode_FromFormat("<function %U at %p>",
         823                 :            :                                 op->func_qualname, op);
         824                 :            : }
         825                 :            :
         826                 :            : static int
         827                 :     280598 : func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
         828                 :            : {
         829   [ +  -  -  + ]:     280598 :     Py_VISIT(f->func_code);
         830   [ +  -  -  + ]:     280598 :     Py_VISIT(f->func_globals);
         831   [ +  -  -  + ]:     280598 :     Py_VISIT(f->func_builtins);
         832   [ +  +  -  + ]:     280598 :     Py_VISIT(f->func_module);
         833   [ +  +  -  + ]:     280598 :     Py_VISIT(f->func_defaults);
         834   [ +  +  -  + ]:     280598 :     Py_VISIT(f->func_kwdefaults);
         835   [ +  -  -  + ]:     280598 :     Py_VISIT(f->func_doc);
         836   [ +  -  -  + ]:     280598 :     Py_VISIT(f->func_name);
         837   [ +  +  -  + ]:     280598 :     Py_VISIT(f->func_dict);
         838   [ +  +  -  + ]:     280598 :     Py_VISIT(f->func_closure);
         839   [ +  +  -  + ]:     280598 :     Py_VISIT(f->func_annotations);
         840   [ +  -  -  + ]:     280598 :     Py_VISIT(f->func_qualname);
         841                 :     280598 :     return 0;
         842                 :            : }
         843                 :            :
         844                 :            : /* Bind a function to an object */
         845                 :            : static PyObject *
         846                 :     553940 : func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
         847                 :            : {
         848   [ +  -  +  + ]:     553940 :     if (obj == Py_None || obj == NULL) {
         849                 :       3122 :         return Py_NewRef(func);
         850                 :            :     }
         851                 :     550818 :     return PyMethod_New(func, obj);
         852                 :            : }
         853                 :            :
         854                 :            : PyTypeObject PyFunction_Type = {
         855                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
         856                 :            :     "function",
         857                 :            :     sizeof(PyFunctionObject),
         858                 :            :     0,
         859                 :            :     (destructor)func_dealloc,                   /* tp_dealloc */
         860                 :            :     offsetof(PyFunctionObject, vectorcall),     /* tp_vectorcall_offset */
         861                 :            :     0,                                          /* tp_getattr */
         862                 :            :     0,                                          /* tp_setattr */
         863                 :            :     0,                                          /* tp_as_async */
         864                 :            :     (reprfunc)func_repr,                        /* tp_repr */
         865                 :            :     0,                                          /* tp_as_number */
         866                 :            :     0,                                          /* tp_as_sequence */
         867                 :            :     0,                                          /* tp_as_mapping */
         868                 :            :     0,                                          /* tp_hash */
         869                 :            :     PyVectorcall_Call,                          /* tp_call */
         870                 :            :     0,                                          /* tp_str */
         871                 :            :     0,                                          /* tp_getattro */
         872                 :            :     0,                                          /* tp_setattro */
         873                 :            :     0,                                          /* tp_as_buffer */
         874                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
         875                 :            :     Py_TPFLAGS_HAVE_VECTORCALL |
         876                 :            :     Py_TPFLAGS_METHOD_DESCRIPTOR,               /* tp_flags */
         877                 :            :     func_new__doc__,                            /* tp_doc */
         878                 :            :     (traverseproc)func_traverse,                /* tp_traverse */
         879                 :            :     (inquiry)func_clear,                        /* tp_clear */
         880                 :            :     0,                                          /* tp_richcompare */
         881                 :            :     offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
         882                 :            :     0,                                          /* tp_iter */
         883                 :            :     0,                                          /* tp_iternext */
         884                 :            :     0,                                          /* tp_methods */
         885                 :            :     func_memberlist,                            /* tp_members */
         886                 :            :     func_getsetlist,                            /* tp_getset */
         887                 :            :     0,                                          /* tp_base */
         888                 :            :     0,                                          /* tp_dict */
         889                 :            :     func_descr_get,                             /* tp_descr_get */
         890                 :            :     0,                                          /* tp_descr_set */
         891                 :            :     offsetof(PyFunctionObject, func_dict),      /* tp_dictoffset */
         892                 :            :     0,                                          /* tp_init */
         893                 :            :     0,                                          /* tp_alloc */
         894                 :            :     func_new,                                   /* tp_new */
         895                 :            : };
         896                 :            :
         897                 :            :
         898                 :            : static int
         899                 :       8265 : functools_copy_attr(PyObject *wrapper, PyObject *wrapped, PyObject *name)
         900                 :            : {
         901                 :       8265 :     PyObject *value = PyObject_GetAttr(wrapped, name);
         902         [ +  + ]:       8265 :     if (value == NULL) {
         903         [ +  - ]:        188 :         if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
         904                 :        188 :             PyErr_Clear();
         905                 :        188 :             return 0;
         906                 :            :         }
         907                 :          0 :         return -1;
         908                 :            :     }
         909                 :            :
         910                 :       8077 :     int res = PyObject_SetAttr(wrapper, name, value);
         911                 :       8077 :     Py_DECREF(value);
         912                 :       8077 :     return res;
         913                 :            : }
         914                 :            :
         915                 :            : // Similar to functools.wraps(wrapper, wrapped)
         916                 :            : static int
         917                 :       1653 : functools_wraps(PyObject *wrapper, PyObject *wrapped)
         918                 :            : {
         919                 :            : #define COPY_ATTR(ATTR) \
         920                 :            :     do { \
         921                 :            :         if (functools_copy_attr(wrapper, wrapped, &_Py_ID(ATTR)) < 0) { \
         922                 :            :             return -1; \
         923                 :            :         } \
         924                 :            :     } while (0) \
         925                 :            :
         926         [ -  + ]:       1653 :     COPY_ATTR(__module__);
         927         [ -  + ]:       1653 :     COPY_ATTR(__name__);
         928         [ -  + ]:       1653 :     COPY_ATTR(__qualname__);
         929         [ -  + ]:       1653 :     COPY_ATTR(__doc__);
         930         [ -  + ]:       1653 :     COPY_ATTR(__annotations__);
         931                 :       1653 :     return 0;
         932                 :            :
         933                 :            : #undef COPY_ATTR
         934                 :            : }
         935                 :            :
         936                 :            :
         937                 :            : /* Class method object */
         938                 :            :
         939                 :            : /* A class method receives the class as implicit first argument,
         940                 :            :    just like an instance method receives the instance.
         941                 :            :    To declare a class method, use this idiom:
         942                 :            :
         943                 :            :      class C:
         944                 :            :          @classmethod
         945                 :            :          def f(cls, arg1, arg2, ...):
         946                 :            :              ...
         947                 :            :
         948                 :            :    It can be called either on the class (e.g. C.f()) or on an instance
         949                 :            :    (e.g. C().f()); the instance is ignored except for its class.
         950                 :            :    If a class method is called for a derived class, the derived class
         951                 :            :    object is passed as the implied first argument.
         952                 :            :
         953                 :            :    Class methods are different than C++ or Java static methods.
         954                 :            :    If you want those, see static methods below.
         955                 :            : */
         956                 :            :
         957                 :            : typedef struct {
         958                 :            :     PyObject_HEAD
         959                 :            :     PyObject *cm_callable;
         960                 :            :     PyObject *cm_dict;
         961                 :            : } classmethod;
         962                 :            :
         963                 :            : static void
         964                 :       1401 : cm_dealloc(classmethod *cm)
         965                 :            : {
         966                 :       1401 :     _PyObject_GC_UNTRACK((PyObject *)cm);
         967                 :       1401 :     Py_XDECREF(cm->cm_callable);
         968                 :       1401 :     Py_XDECREF(cm->cm_dict);
         969                 :       1401 :     Py_TYPE(cm)->tp_free((PyObject *)cm);
         970                 :       1401 : }
         971                 :            :
         972                 :            : static int
         973                 :      14354 : cm_traverse(classmethod *cm, visitproc visit, void *arg)
         974                 :            : {
         975   [ +  -  -  + ]:      14354 :     Py_VISIT(cm->cm_callable);
         976   [ +  +  -  + ]:      14354 :     Py_VISIT(cm->cm_dict);
         977                 :      14354 :     return 0;
         978                 :            : }
         979                 :            :
         980                 :            : static int
         981                 :         20 : cm_clear(classmethod *cm)
         982                 :            : {
         983         [ +  - ]:         20 :     Py_CLEAR(cm->cm_callable);
         984         [ +  - ]:         20 :     Py_CLEAR(cm->cm_dict);
         985                 :         20 :     return 0;
         986                 :            : }
         987                 :            :
         988                 :            :
         989                 :            : static PyObject *
         990                 :      86999 : cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
         991                 :            : {
         992                 :      86999 :     classmethod *cm = (classmethod *)self;
         993                 :            :
         994         [ -  + ]:      86999 :     if (cm->cm_callable == NULL) {
         995                 :          0 :         PyErr_SetString(PyExc_RuntimeError,
         996                 :            :                         "uninitialized classmethod object");
         997                 :          0 :         return NULL;
         998                 :            :     }
         999         [ -  + ]:      86999 :     if (type == NULL)
        1000                 :          0 :         type = (PyObject *)(Py_TYPE(obj));
        1001         [ +  - ]:      86999 :     if (Py_TYPE(cm->cm_callable)->tp_descr_get != NULL) {
        1002                 :      86999 :         return Py_TYPE(cm->cm_callable)->tp_descr_get(cm->cm_callable, type,
        1003                 :            :                                                       type);
        1004                 :            :     }
        1005                 :          0 :     return PyMethod_New(cm->cm_callable, type);
        1006                 :            : }
        1007                 :            :
        1008                 :            : static int
        1009                 :       1430 : cm_init(PyObject *self, PyObject *args, PyObject *kwds)
        1010                 :            : {
        1011                 :       1430 :     classmethod *cm = (classmethod *)self;
        1012                 :            :     PyObject *callable;
        1013                 :            :
        1014   [ -  +  -  - ]:       1430 :     if (!_PyArg_NoKeywords("classmethod", kwds))
        1015                 :          0 :         return -1;
        1016         [ -  + ]:       1430 :     if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable))
        1017                 :          0 :         return -1;
        1018                 :       1430 :     Py_XSETREF(cm->cm_callable, Py_NewRef(callable));
        1019                 :            :
        1020         [ -  + ]:       1430 :     if (functools_wraps((PyObject *)cm, cm->cm_callable) < 0) {
        1021                 :          0 :         return -1;
        1022                 :            :     }
        1023                 :       1430 :     return 0;
        1024                 :            : }
        1025                 :            :
        1026                 :            : static PyMemberDef cm_memberlist[] = {
        1027                 :            :     {"__func__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY},
        1028                 :            :     {"__wrapped__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY},
        1029                 :            :     {NULL}  /* Sentinel */
        1030                 :            : };
        1031                 :            :
        1032                 :            : static PyObject *
        1033                 :        661 : cm_get___isabstractmethod__(classmethod *cm, void *closure)
        1034                 :            : {
        1035                 :        661 :     int res = _PyObject_IsAbstract(cm->cm_callable);
        1036         [ -  + ]:        661 :     if (res == -1) {
        1037                 :          0 :         return NULL;
        1038                 :            :     }
        1039         [ -  + ]:        661 :     else if (res) {
        1040                 :          0 :         Py_RETURN_TRUE;
        1041                 :            :     }
        1042                 :        661 :     Py_RETURN_FALSE;
        1043                 :            : }
        1044                 :            :
        1045                 :            : static PyGetSetDef cm_getsetlist[] = {
        1046                 :            :     {"__isabstractmethod__",
        1047                 :            :      (getter)cm_get___isabstractmethod__, NULL, NULL, NULL},
        1048                 :            :     {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, NULL, NULL},
        1049                 :            :     {NULL} /* Sentinel */
        1050                 :            : };
        1051                 :            :
        1052                 :            : static PyObject*
        1053                 :          0 : cm_repr(classmethod *cm)
        1054                 :            : {
        1055                 :          0 :     return PyUnicode_FromFormat("<classmethod(%R)>", cm->cm_callable);
        1056                 :            : }
        1057                 :            :
        1058                 :            : PyDoc_STRVAR(classmethod_doc,
        1059                 :            : "classmethod(function) -> method\n\
        1060                 :            : \n\
        1061                 :            : Convert a function to be a class method.\n\
        1062                 :            : \n\
        1063                 :            : A class method receives the class as implicit first argument,\n\
        1064                 :            : just like an instance method receives the instance.\n\
        1065                 :            : To declare a class method, use this idiom:\n\
        1066                 :            : \n\
        1067                 :            :   class C:\n\
        1068                 :            :       @classmethod\n\
        1069                 :            :       def f(cls, arg1, arg2, ...):\n\
        1070                 :            :           ...\n\
        1071                 :            : \n\
        1072                 :            : It can be called either on the class (e.g. C.f()) or on an instance\n\
        1073                 :            : (e.g. C().f()).  The instance is ignored except for its class.\n\
        1074                 :            : If a class method is called for a derived class, the derived class\n\
        1075                 :            : object is passed as the implied first argument.\n\
        1076                 :            : \n\
        1077                 :            : Class methods are different than C++ or Java static methods.\n\
        1078                 :            : If you want those, see the staticmethod builtin.");
        1079                 :            :
        1080                 :            : PyTypeObject PyClassMethod_Type = {
        1081                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
        1082                 :            :     "classmethod",
        1083                 :            :     sizeof(classmethod),
        1084                 :            :     0,
        1085                 :            :     (destructor)cm_dealloc,                     /* tp_dealloc */
        1086                 :            :     0,                                          /* tp_vectorcall_offset */
        1087                 :            :     0,                                          /* tp_getattr */
        1088                 :            :     0,                                          /* tp_setattr */
        1089                 :            :     0,                                          /* tp_as_async */
        1090                 :            :     (reprfunc)cm_repr,                          /* tp_repr */
        1091                 :            :     0,                                          /* tp_as_number */
        1092                 :            :     0,                                          /* tp_as_sequence */
        1093                 :            :     0,                                          /* tp_as_mapping */
        1094                 :            :     0,                                          /* tp_hash */
        1095                 :            :     0,                                          /* tp_call */
        1096                 :            :     0,                                          /* tp_str */
        1097                 :            :     0,                                          /* tp_getattro */
        1098                 :            :     0,                                          /* tp_setattro */
        1099                 :            :     0,                                          /* tp_as_buffer */
        1100                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
        1101                 :            :     classmethod_doc,                            /* tp_doc */
        1102                 :            :     (traverseproc)cm_traverse,                  /* tp_traverse */
        1103                 :            :     (inquiry)cm_clear,                          /* tp_clear */
        1104                 :            :     0,                                          /* tp_richcompare */
        1105                 :            :     0,                                          /* tp_weaklistoffset */
        1106                 :            :     0,                                          /* tp_iter */
        1107                 :            :     0,                                          /* tp_iternext */
        1108                 :            :     0,                                          /* tp_methods */
        1109                 :            :     cm_memberlist,              /* tp_members */
        1110                 :            :     cm_getsetlist,                              /* tp_getset */
        1111                 :            :     0,                                          /* tp_base */
        1112                 :            :     0,                                          /* tp_dict */
        1113                 :            :     cm_descr_get,                               /* tp_descr_get */
        1114                 :            :     0,                                          /* tp_descr_set */
        1115                 :            :     offsetof(classmethod, cm_dict),             /* tp_dictoffset */
        1116                 :            :     cm_init,                                    /* tp_init */
        1117                 :            :     PyType_GenericAlloc,                        /* tp_alloc */
        1118                 :            :     PyType_GenericNew,                          /* tp_new */
        1119                 :            :     PyObject_GC_Del,                            /* tp_free */
        1120                 :            : };
        1121                 :            :
        1122                 :            : PyObject *
        1123                 :         25 : PyClassMethod_New(PyObject *callable)
        1124                 :            : {
        1125                 :            :     classmethod *cm = (classmethod *)
        1126                 :         25 :         PyType_GenericAlloc(&PyClassMethod_Type, 0);
        1127         [ +  - ]:         25 :     if (cm != NULL) {
        1128                 :         25 :         cm->cm_callable = Py_NewRef(callable);
        1129                 :            :     }
        1130                 :         25 :     return (PyObject *)cm;
        1131                 :            : }
        1132                 :            :
        1133                 :            :
        1134                 :            : /* Static method object */
        1135                 :            :
        1136                 :            : /* A static method does not receive an implicit first argument.
        1137                 :            :    To declare a static method, use this idiom:
        1138                 :            :
        1139                 :            :      class C:
        1140                 :            :          @staticmethod
        1141                 :            :          def f(arg1, arg2, ...):
        1142                 :            :              ...
        1143                 :            :
        1144                 :            :    It can be called either on the class (e.g. C.f()) or on an instance
        1145                 :            :    (e.g. C().f()). Both the class and the instance are ignored, and
        1146                 :            :    neither is passed implicitly as the first argument to the method.
        1147                 :            :
        1148                 :            :    Static methods in Python are similar to those found in Java or C++.
        1149                 :            :    For a more advanced concept, see class methods above.
        1150                 :            : */
        1151                 :            :
        1152                 :            : typedef struct {
        1153                 :            :     PyObject_HEAD
        1154                 :            :     PyObject *sm_callable;
        1155                 :            :     PyObject *sm_dict;
        1156                 :            : } staticmethod;
        1157                 :            :
        1158                 :            : static void
        1159                 :        508 : sm_dealloc(staticmethod *sm)
        1160                 :            : {
        1161                 :        508 :     _PyObject_GC_UNTRACK((PyObject *)sm);
        1162                 :        508 :     Py_XDECREF(sm->sm_callable);
        1163                 :        508 :     Py_XDECREF(sm->sm_dict);
        1164                 :        508 :     Py_TYPE(sm)->tp_free((PyObject *)sm);
        1165                 :        508 : }
        1166                 :            :
        1167                 :            : static int
        1168                 :       6158 : sm_traverse(staticmethod *sm, visitproc visit, void *arg)
        1169                 :            : {
        1170   [ +  -  -  + ]:       6158 :     Py_VISIT(sm->sm_callable);
        1171   [ +  +  -  + ]:       6158 :     Py_VISIT(sm->sm_dict);
        1172                 :       6158 :     return 0;
        1173                 :            : }
        1174                 :            :
        1175                 :            : static int
        1176                 :          1 : sm_clear(staticmethod *sm)
        1177                 :            : {
        1178         [ +  - ]:          1 :     Py_CLEAR(sm->sm_callable);
        1179         [ +  - ]:          1 :     Py_CLEAR(sm->sm_dict);
        1180                 :          1 :     return 0;
        1181                 :            : }
        1182                 :            :
        1183                 :            : static PyObject *
        1184                 :      54175 : sm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
        1185                 :            : {
        1186                 :      54175 :     staticmethod *sm = (staticmethod *)self;
        1187                 :            :
        1188         [ -  + ]:      54175 :     if (sm->sm_callable == NULL) {
        1189                 :          0 :         PyErr_SetString(PyExc_RuntimeError,
        1190                 :            :                         "uninitialized staticmethod object");
        1191                 :          0 :         return NULL;
        1192                 :            :     }
        1193                 :      54175 :     return Py_NewRef(sm->sm_callable);
        1194                 :            : }
        1195                 :            :
        1196                 :            : static int
        1197                 :        223 : sm_init(PyObject *self, PyObject *args, PyObject *kwds)
        1198                 :            : {
        1199                 :        223 :     staticmethod *sm = (staticmethod *)self;
        1200                 :            :     PyObject *callable;
        1201                 :            :
        1202   [ -  +  -  - ]:        223 :     if (!_PyArg_NoKeywords("staticmethod", kwds))
        1203                 :          0 :         return -1;
        1204         [ -  + ]:        223 :     if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable))
        1205                 :          0 :         return -1;
        1206                 :        223 :     Py_XSETREF(sm->sm_callable, Py_NewRef(callable));
        1207                 :            :
        1208         [ -  + ]:        223 :     if (functools_wraps((PyObject *)sm, sm->sm_callable) < 0) {
        1209                 :          0 :         return -1;
        1210                 :            :     }
        1211                 :        223 :     return 0;
        1212                 :            : }
        1213                 :            :
        1214                 :            : static PyObject*
        1215                 :          0 : sm_call(PyObject *callable, PyObject *args, PyObject *kwargs)
        1216                 :            : {
        1217                 :          0 :     staticmethod *sm = (staticmethod *)callable;
        1218                 :          0 :     return PyObject_Call(sm->sm_callable, args, kwargs);
        1219                 :            : }
        1220                 :            :
        1221                 :            : static PyMemberDef sm_memberlist[] = {
        1222                 :            :     {"__func__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY},
        1223                 :            :     {"__wrapped__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY},
        1224                 :            :     {NULL}  /* Sentinel */
        1225                 :            : };
        1226                 :            :
        1227                 :            : static PyObject *
        1228                 :         12 : sm_get___isabstractmethod__(staticmethod *sm, void *closure)
        1229                 :            : {
        1230                 :         12 :     int res = _PyObject_IsAbstract(sm->sm_callable);
        1231         [ -  + ]:         12 :     if (res == -1) {
        1232                 :          0 :         return NULL;
        1233                 :            :     }
        1234         [ -  + ]:         12 :     else if (res) {
        1235                 :          0 :         Py_RETURN_TRUE;
        1236                 :            :     }
        1237                 :         12 :     Py_RETURN_FALSE;
        1238                 :            : }
        1239                 :            :
        1240                 :            : static PyGetSetDef sm_getsetlist[] = {
        1241                 :            :     {"__isabstractmethod__",
        1242                 :            :      (getter)sm_get___isabstractmethod__, NULL, NULL, NULL},
        1243                 :            :     {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, NULL, NULL},
        1244                 :            :     {NULL} /* Sentinel */
        1245                 :            : };
        1246                 :            :
        1247                 :            : static PyObject*
        1248                 :          0 : sm_repr(staticmethod *sm)
        1249                 :            : {
        1250                 :          0 :     return PyUnicode_FromFormat("<staticmethod(%R)>", sm->sm_callable);
        1251                 :            : }
        1252                 :            :
        1253                 :            : PyDoc_STRVAR(staticmethod_doc,
        1254                 :            : "staticmethod(function) -> method\n\
        1255                 :            : \n\
        1256                 :            : Convert a function to be a static method.\n\
        1257                 :            : \n\
        1258                 :            : A static method does not receive an implicit first argument.\n\
        1259                 :            : To declare a static method, use this idiom:\n\
        1260                 :            : \n\
        1261                 :            :      class C:\n\
        1262                 :            :          @staticmethod\n\
        1263                 :            :          def f(arg1, arg2, ...):\n\
        1264                 :            :              ...\n\
        1265                 :            : \n\
        1266                 :            : It can be called either on the class (e.g. C.f()) or on an instance\n\
        1267                 :            : (e.g. C().f()). Both the class and the instance are ignored, and\n\
        1268                 :            : neither is passed implicitly as the first argument to the method.\n\
        1269                 :            : \n\
        1270                 :            : Static methods in Python are similar to those found in Java or C++.\n\
        1271                 :            : For a more advanced concept, see the classmethod builtin.");
        1272                 :            :
        1273                 :            : PyTypeObject PyStaticMethod_Type = {
        1274                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
        1275                 :            :     "staticmethod",
        1276                 :            :     sizeof(staticmethod),
        1277                 :            :     0,
        1278                 :            :     (destructor)sm_dealloc,                     /* tp_dealloc */
        1279                 :            :     0,                                          /* tp_vectorcall_offset */
        1280                 :            :     0,                                          /* tp_getattr */
        1281                 :            :     0,                                          /* tp_setattr */
        1282                 :            :     0,                                          /* tp_as_async */
        1283                 :            :     (reprfunc)sm_repr,                          /* tp_repr */
        1284                 :            :     0,                                          /* tp_as_number */
        1285                 :            :     0,                                          /* tp_as_sequence */
        1286                 :            :     0,                                          /* tp_as_mapping */
        1287                 :            :     0,                                          /* tp_hash */
        1288                 :            :     sm_call,                                    /* tp_call */
        1289                 :            :     0,                                          /* tp_str */
        1290                 :            :     0,                                          /* tp_getattro */
        1291                 :            :     0,                                          /* tp_setattro */
        1292                 :            :     0,                                          /* tp_as_buffer */
        1293                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
        1294                 :            :     staticmethod_doc,                           /* tp_doc */
        1295                 :            :     (traverseproc)sm_traverse,                  /* tp_traverse */
        1296                 :            :     (inquiry)sm_clear,                          /* tp_clear */
        1297                 :            :     0,                                          /* tp_richcompare */
        1298                 :            :     0,                                          /* tp_weaklistoffset */
        1299                 :            :     0,                                          /* tp_iter */
        1300                 :            :     0,                                          /* tp_iternext */
        1301                 :            :     0,                                          /* tp_methods */
        1302                 :            :     sm_memberlist,              /* tp_members */
        1303                 :            :     sm_getsetlist,                              /* tp_getset */
        1304                 :            :     0,                                          /* tp_base */
        1305                 :            :     0,                                          /* tp_dict */
        1306                 :            :     sm_descr_get,                               /* tp_descr_get */
        1307                 :            :     0,                                          /* tp_descr_set */
        1308                 :            :     offsetof(staticmethod, sm_dict),            /* tp_dictoffset */
        1309                 :            :     sm_init,                                    /* tp_init */
        1310                 :            :     PyType_GenericAlloc,                        /* tp_alloc */
        1311                 :            :     PyType_GenericNew,                          /* tp_new */
        1312                 :            :     PyObject_GC_Del,                            /* tp_free */
        1313                 :            : };
        1314                 :            :
        1315                 :            : PyObject *
        1316                 :        321 : PyStaticMethod_New(PyObject *callable)
        1317                 :            : {
        1318                 :            :     staticmethod *sm = (staticmethod *)
        1319                 :        321 :         PyType_GenericAlloc(&PyStaticMethod_Type, 0);
        1320         [ +  - ]:        321 :     if (sm != NULL) {
        1321                 :        321 :         sm->sm_callable = Py_NewRef(callable);
        1322                 :            :     }
        1323                 :        321 :     return (PyObject *)sm;
        1324                 :            : }

Generated by: LCOV version 1.14