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