LCOV - code coverage report
Current view: | top level - Objects - descrobject.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 394 | 668 | 59.0 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 54 | 91 | 59.3 %
|  |  | Branches: | 154 | 356 | 43.3 %

               Branch data     Line data    Source code
           1                 :            : /* Descriptors -- a new, flexible way to describe attributes */
           2                 :            :
           3                 :            : #include "Python.h"
           4                 :            : #include "pycore_ceval.h"         // _Py_EnterRecursiveCallTstate()
           5                 :            : #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
           6                 :            : #include "pycore_pystate.h"       // _PyThreadState_GET()
           7                 :            : #include "pycore_tuple.h"         // _PyTuple_ITEMS()
           8                 :            : #include "structmember.h"         // PyMemberDef
           9                 :            : #include "pycore_descrobject.h"
          10                 :            :
          11                 :            : /*[clinic input]
          12                 :            : class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type"
          13                 :            : class property "propertyobject *" "&PyProperty_Type"
          14                 :            : [clinic start generated code]*/
          15                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=556352653fd4c02e]*/
          16                 :            :
          17                 :            : // see pycore_object.h
          18                 :            : #if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
          19                 :            : #include <emscripten.h>
          20                 :            : EM_JS(int, descr_set_trampoline_call, (setter set, PyObject *obj, PyObject *value, void *closure), {
          21                 :            :     return wasmTable.get(set)(obj, value, closure);
          22                 :            : });
          23                 :            :
          24                 :            : EM_JS(PyObject*, descr_get_trampoline_call, (getter get, PyObject *obj, void *closure), {
          25                 :            :     return wasmTable.get(get)(obj, closure);
          26                 :            : });
          27                 :            : #else
          28                 :            : #define descr_set_trampoline_call(set, obj, value, closure) \
          29                 :            :     (set)((obj), (value), (closure))
          30                 :            :
          31                 :            : #define descr_get_trampoline_call(get, obj, closure) \
          32                 :            :     (get)((obj), (closure))
          33                 :            :
          34                 :            : #endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE
          35                 :            :
          36                 :            : static void
          37                 :      58398 : descr_dealloc(PyDescrObject *descr)
          38                 :            : {
          39                 :      58398 :     _PyObject_GC_UNTRACK(descr);
          40                 :      58398 :     Py_XDECREF(descr->d_type);
          41                 :      58398 :     Py_XDECREF(descr->d_name);
          42                 :      58398 :     Py_XDECREF(descr->d_qualname);
          43                 :      58398 :     PyObject_GC_Del(descr);
          44                 :      58398 : }
          45                 :            :
          46                 :            : static PyObject *
          47                 :          0 : descr_name(PyDescrObject *descr)
          48                 :            : {
          49   [ #  #  #  # ]:          0 :     if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
          50                 :          0 :         return descr->d_name;
          51                 :          0 :     return NULL;
          52                 :            : }
          53                 :            :
          54                 :            : static PyObject *
          55                 :          0 : descr_repr(PyDescrObject *descr, const char *format)
          56                 :            : {
          57                 :          0 :     PyObject *name = NULL;
          58   [ #  #  #  # ]:          0 :     if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
          59                 :          0 :         name = descr->d_name;
          60                 :            :
          61                 :          0 :     return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name);
          62                 :            : }
          63                 :            :
          64                 :            : static PyObject *
          65                 :          0 : method_repr(PyMethodDescrObject *descr)
          66                 :            : {
          67                 :          0 :     return descr_repr((PyDescrObject *)descr,
          68                 :            :                       "<method '%V' of '%s' objects>");
          69                 :            : }
          70                 :            :
          71                 :            : static PyObject *
          72                 :          0 : member_repr(PyMemberDescrObject *descr)
          73                 :            : {
          74                 :          0 :     return descr_repr((PyDescrObject *)descr,
          75                 :            :                       "<member '%V' of '%s' objects>");
          76                 :            : }
          77                 :            :
          78                 :            : static PyObject *
          79                 :          0 : getset_repr(PyGetSetDescrObject *descr)
          80                 :            : {
          81                 :          0 :     return descr_repr((PyDescrObject *)descr,
          82                 :            :                       "<attribute '%V' of '%s' objects>");
          83                 :            : }
          84                 :            :
          85                 :            : static PyObject *
          86                 :          0 : wrapperdescr_repr(PyWrapperDescrObject *descr)
          87                 :            : {
          88                 :          0 :     return descr_repr((PyDescrObject *)descr,
          89                 :            :                       "<slot wrapper '%V' of '%s' objects>");
          90                 :            : }
          91                 :            :
          92                 :            : static int
          93                 :    5039297 : descr_check(PyDescrObject *descr, PyObject *obj)
          94                 :            : {
          95         [ -  + ]:    5039297 :     if (!PyObject_TypeCheck(obj, descr->d_type)) {
          96                 :          0 :         PyErr_Format(PyExc_TypeError,
          97                 :            :                      "descriptor '%V' for '%.100s' objects "
          98                 :            :                      "doesn't apply to a '%.100s' object",
          99                 :            :                      descr_name((PyDescrObject *)descr), "?",
         100                 :          0 :                      descr->d_type->tp_name,
         101                 :          0 :                      Py_TYPE(obj)->tp_name);
         102                 :          0 :         return -1;
         103                 :            :     }
         104                 :    5039297 :     return 0;
         105                 :            : }
         106                 :            :
         107                 :            : static PyObject *
         108                 :      11152 : classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
         109                 :            : {
         110                 :            :     /* Ensure a valid type.  Class methods ignore obj. */
         111         [ -  + ]:      11152 :     if (type == NULL) {
         112         [ #  # ]:          0 :         if (obj != NULL)
         113                 :          0 :             type = (PyObject *)Py_TYPE(obj);
         114                 :            :         else {
         115                 :            :             /* Wot - no type?! */
         116                 :          0 :             PyErr_Format(PyExc_TypeError,
         117                 :            :                          "descriptor '%V' for type '%.100s' "
         118                 :            :                          "needs either an object or a type",
         119                 :            :                          descr_name((PyDescrObject *)descr), "?",
         120                 :          0 :                          PyDescr_TYPE(descr)->tp_name);
         121                 :          0 :             return NULL;
         122                 :            :         }
         123                 :            :     }
         124         [ -  + ]:      11152 :     if (!PyType_Check(type)) {
         125                 :          0 :         PyErr_Format(PyExc_TypeError,
         126                 :            :                      "descriptor '%V' for type '%.100s' "
         127                 :            :                      "needs a type, not a '%.100s' as arg 2",
         128                 :            :                      descr_name((PyDescrObject *)descr), "?",
         129                 :          0 :                      PyDescr_TYPE(descr)->tp_name,
         130                 :          0 :                      Py_TYPE(type)->tp_name);
         131                 :          0 :         return NULL;
         132                 :            :     }
         133         [ -  + ]:      11152 :     if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) {
         134                 :          0 :         PyErr_Format(PyExc_TypeError,
         135                 :            :                      "descriptor '%V' requires a subtype of '%.100s' "
         136                 :            :                      "but received '%.100s'",
         137                 :            :                      descr_name((PyDescrObject *)descr), "?",
         138                 :          0 :                      PyDescr_TYPE(descr)->tp_name,
         139                 :            :                      ((PyTypeObject *)type)->tp_name);
         140                 :          0 :         return NULL;
         141                 :            :     }
         142                 :      11152 :     PyTypeObject *cls = NULL;
         143         [ -  + ]:      11152 :     if (descr->d_method->ml_flags & METH_METHOD) {
         144                 :          0 :         cls = descr->d_common.d_type;
         145                 :            :     }
         146                 :      11152 :     return PyCMethod_New(descr->d_method, type, NULL, cls);
         147                 :            : }
         148                 :            :
         149                 :            : static PyObject *
         150                 :    2203082 : method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
         151                 :            : {
         152         [ +  + ]:    2203082 :     if (obj == NULL) {
         153                 :       1860 :         return Py_NewRef(descr);
         154                 :            :     }
         155         [ -  + ]:    2201222 :     if (descr_check((PyDescrObject *)descr, obj) < 0) {
         156                 :          0 :         return NULL;
         157                 :            :     }
         158         [ +  + ]:    2201222 :     if (descr->d_method->ml_flags & METH_METHOD) {
         159         [ +  - ]:    1443753 :         if (PyType_Check(type)) {
         160                 :    1443753 :             return PyCMethod_New(descr->d_method, obj, NULL, descr->d_common.d_type);
         161                 :            :         } else {
         162                 :          0 :             PyErr_Format(PyExc_TypeError,
         163                 :            :                         "descriptor '%V' needs a type, not '%s', as arg 2",
         164                 :            :                         descr_name((PyDescrObject *)descr),
         165                 :          0 :                         Py_TYPE(type)->tp_name);
         166                 :          0 :             return NULL;
         167                 :            :         }
         168                 :            :     } else {
         169                 :     757469 :         return PyCFunction_NewEx(descr->d_method, obj, NULL);
         170                 :            :     }
         171                 :            : }
         172                 :            :
         173                 :            : static PyObject *
         174                 :     131740 : member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
         175                 :            : {
         176         [ +  + ]:     131740 :     if (obj == NULL) {
         177                 :          5 :         return Py_NewRef(descr);
         178                 :            :     }
         179         [ -  + ]:     131735 :     if (descr_check((PyDescrObject *)descr, obj) < 0) {
         180                 :          0 :         return NULL;
         181                 :            :     }
         182                 :            :
         183         [ +  + ]:     131735 :     if (descr->d_member->flags & PY_AUDIT_READ) {
         184         [ -  + ]:        271 :         if (PySys_Audit("object.__getattr__", "Os",
         185         [ +  - ]:        271 :             obj ? obj : Py_None, descr->d_member->name) < 0) {
         186                 :          0 :             return NULL;
         187                 :            :         }
         188                 :            :     }
         189                 :            :
         190                 :     131735 :     return PyMember_GetOne((char *)obj, descr->d_member);
         191                 :            : }
         192                 :            :
         193                 :            : static PyObject *
         194                 :     596539 : getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
         195                 :            : {
         196         [ +  + ]:     596539 :     if (obj == NULL) {
         197                 :          6 :         return Py_NewRef(descr);
         198                 :            :     }
         199         [ -  + ]:     596533 :     if (descr_check((PyDescrObject *)descr, obj) < 0) {
         200                 :          0 :         return NULL;
         201                 :            :     }
         202         [ +  - ]:     596533 :     if (descr->d_getset->get != NULL)
         203                 :     596533 :         return descr_get_trampoline_call(
         204                 :            :             descr->d_getset->get, obj, descr->d_getset->closure);
         205                 :          0 :     PyErr_Format(PyExc_AttributeError,
         206                 :            :                  "attribute '%V' of '%.100s' objects is not readable",
         207                 :            :                  descr_name((PyDescrObject *)descr), "?",
         208                 :          0 :                  PyDescr_TYPE(descr)->tp_name);
         209                 :          0 :     return NULL;
         210                 :            : }
         211                 :            :
         212                 :            : static PyObject *
         213                 :       5266 : wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
         214                 :            : {
         215         [ +  + ]:       5266 :     if (obj == NULL) {
         216                 :       2809 :         return Py_NewRef(descr);
         217                 :            :     }
         218         [ -  + ]:       2457 :     if (descr_check((PyDescrObject *)descr, obj) < 0) {
         219                 :          0 :         return NULL;
         220                 :            :     }
         221                 :       2457 :     return PyWrapper_New((PyObject *)descr, obj);
         222                 :            : }
         223                 :            :
         224                 :            : static int
         225                 :      22137 : descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value)
         226                 :            : {
         227                 :            :     assert(obj != NULL);
         228         [ -  + ]:      22137 :     if (!PyObject_TypeCheck(obj, descr->d_type)) {
         229                 :          0 :         PyErr_Format(PyExc_TypeError,
         230                 :            :                      "descriptor '%V' for '%.100s' objects "
         231                 :            :                      "doesn't apply to a '%.100s' object",
         232                 :            :                      descr_name(descr), "?",
         233                 :          0 :                      descr->d_type->tp_name,
         234                 :          0 :                      Py_TYPE(obj)->tp_name);
         235                 :          0 :         return -1;
         236                 :            :     }
         237                 :      22137 :     return 0;
         238                 :            : }
         239                 :            :
         240                 :            : static int
         241                 :      19888 : member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
         242                 :            : {
         243         [ -  + ]:      19888 :     if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) {
         244                 :          0 :         return -1;
         245                 :            :     }
         246                 :      19888 :     return PyMember_SetOne((char *)obj, descr->d_member, value);
         247                 :            : }
         248                 :            :
         249                 :            : static int
         250                 :       2249 : getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
         251                 :            : {
         252         [ -  + ]:       2249 :     if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) {
         253                 :          0 :         return -1;
         254                 :            :     }
         255         [ +  - ]:       2249 :     if (descr->d_getset->set != NULL) {
         256                 :       2249 :         return descr_set_trampoline_call(
         257                 :            :             descr->d_getset->set, obj, value,
         258                 :            :             descr->d_getset->closure);
         259                 :            :     }
         260                 :          0 :     PyErr_Format(PyExc_AttributeError,
         261                 :            :                  "attribute '%V' of '%.100s' objects is not writable",
         262                 :            :                  descr_name((PyDescrObject *)descr), "?",
         263                 :          0 :                  PyDescr_TYPE(descr)->tp_name);
         264                 :          0 :     return -1;
         265                 :            : }
         266                 :            :
         267                 :            :
         268                 :            : /* Vectorcall functions for each of the PyMethodDescr calling conventions.
         269                 :            :  *
         270                 :            :  * First, common helpers
         271                 :            :  */
         272                 :            : static inline int
         273                 :    2107350 : method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
         274                 :            : {
         275                 :            :     assert(!PyErr_Occurred());
         276         [ -  + ]:    2107350 :     if (nargs < 1) {
         277                 :          0 :         PyObject *funcstr = _PyObject_FunctionStr(func);
         278         [ #  # ]:          0 :         if (funcstr != NULL) {
         279                 :          0 :             PyErr_Format(PyExc_TypeError,
         280                 :            :                          "unbound method %U needs an argument", funcstr);
         281                 :          0 :             Py_DECREF(funcstr);
         282                 :            :         }
         283                 :          0 :         return -1;
         284                 :            :     }
         285                 :    2107350 :     PyObject *self = args[0];
         286         [ -  + ]:    2107350 :     if (descr_check((PyDescrObject *)func, self) < 0) {
         287                 :          0 :         return -1;
         288                 :            :     }
         289   [ -  +  -  - ]:    2107350 :     if (kwnames && PyTuple_GET_SIZE(kwnames)) {
         290                 :          0 :         PyObject *funcstr = _PyObject_FunctionStr(func);
         291         [ #  # ]:          0 :         if (funcstr != NULL) {
         292                 :          0 :             PyErr_Format(PyExc_TypeError,
         293                 :            :                          "%U takes no keyword arguments", funcstr);
         294                 :          0 :             Py_DECREF(funcstr);
         295                 :            :         }
         296                 :          0 :         return -1;
         297                 :            :     }
         298                 :    2107350 :     return 0;
         299                 :            : }
         300                 :            :
         301                 :            : typedef void (*funcptr)(void);
         302                 :            :
         303                 :            : static inline funcptr
         304                 :    2107350 : method_enter_call(PyThreadState *tstate, PyObject *func)
         305                 :            : {
         306         [ -  + ]:    2107350 :     if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
         307                 :          0 :         return NULL;
         308                 :            :     }
         309                 :    2107350 :     return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth;
         310                 :            : }
         311                 :            :
         312                 :            : /* Now the actual vectorcall functions */
         313                 :            : static PyObject *
         314                 :      25127 : method_vectorcall_VARARGS(
         315                 :            :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
         316                 :            : {
         317                 :      25127 :     PyThreadState *tstate = _PyThreadState_GET();
         318                 :      25127 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
         319         [ -  + ]:      25127 :     if (method_check_args(func, args, nargs, kwnames)) {
         320                 :          0 :         return NULL;
         321                 :            :     }
         322                 :      25127 :     PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
         323         [ -  + ]:      25127 :     if (argstuple == NULL) {
         324                 :          0 :         return NULL;
         325                 :            :     }
         326                 :      25127 :     PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
         327         [ -  + ]:      25127 :     if (meth == NULL) {
         328                 :          0 :         Py_DECREF(argstuple);
         329                 :          0 :         return NULL;
         330                 :            :     }
         331                 :      25127 :     PyObject *result = _PyCFunction_TrampolineCall(
         332                 :            :         meth, args[0], argstuple);
         333                 :      25127 :     Py_DECREF(argstuple);
         334                 :      25127 :     _Py_LeaveRecursiveCallTstate(tstate);
         335                 :      25127 :     return result;
         336                 :            : }
         337                 :            :
         338                 :            : static PyObject *
         339                 :       1340 : method_vectorcall_VARARGS_KEYWORDS(
         340                 :            :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
         341                 :            : {
         342                 :       1340 :     PyThreadState *tstate = _PyThreadState_GET();
         343                 :       1340 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
         344         [ -  + ]:       1340 :     if (method_check_args(func, args, nargs, NULL)) {
         345                 :          0 :         return NULL;
         346                 :            :     }
         347                 :       1340 :     PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
         348         [ -  + ]:       1340 :     if (argstuple == NULL) {
         349                 :          0 :         return NULL;
         350                 :            :     }
         351                 :       1340 :     PyObject *result = NULL;
         352                 :            :     /* Create a temporary dict for keyword arguments */
         353                 :       1340 :     PyObject *kwdict = NULL;
         354   [ +  +  +  - ]:       1340 :     if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) > 0) {
         355                 :         29 :         kwdict = _PyStack_AsDict(args + nargs, kwnames);
         356         [ -  + ]:         29 :         if (kwdict == NULL) {
         357                 :          0 :             goto exit;
         358                 :            :         }
         359                 :            :     }
         360                 :            :     PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords)
         361                 :       1340 :                                    method_enter_call(tstate, func);
         362         [ -  + ]:       1340 :     if (meth == NULL) {
         363                 :          0 :         goto exit;
         364                 :            :     }
         365                 :       1340 :     result = _PyCFunctionWithKeywords_TrampolineCall(
         366                 :            :         meth, args[0], argstuple, kwdict);
         367                 :       1340 :     _Py_LeaveRecursiveCallTstate(tstate);
         368                 :       1340 : exit:
         369                 :       1340 :     Py_DECREF(argstuple);
         370                 :       1340 :     Py_XDECREF(kwdict);
         371                 :       1340 :     return result;
         372                 :            : }
         373                 :            :
         374                 :            : static PyObject *
         375                 :    1454773 : method_vectorcall_FASTCALL_KEYWORDS_METHOD(
         376                 :            :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
         377                 :            : {
         378                 :    1454773 :     PyThreadState *tstate = _PyThreadState_GET();
         379                 :    1454773 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
         380         [ -  + ]:    1454773 :     if (method_check_args(func, args, nargs, NULL)) {
         381                 :          0 :         return NULL;
         382                 :            :     }
         383                 :    1454773 :     PyCMethod meth = (PyCMethod) method_enter_call(tstate, func);
         384         [ -  + ]:    1454773 :     if (meth == NULL) {
         385                 :          0 :         return NULL;
         386                 :            :     }
         387                 :    1454773 :     PyObject *result = meth(args[0],
         388                 :            :                             ((PyMethodDescrObject *)func)->d_common.d_type,
         389                 :    1454773 :                             args+1, nargs-1, kwnames);
         390                 :    1454773 :     _Py_LeaveRecursiveCall();
         391                 :    1454773 :     return result;
         392                 :            : }
         393                 :            :
         394                 :            : static PyObject *
         395                 :       6642 : method_vectorcall_FASTCALL(
         396                 :            :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
         397                 :            : {
         398                 :       6642 :     PyThreadState *tstate = _PyThreadState_GET();
         399                 :       6642 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
         400         [ -  + ]:       6642 :     if (method_check_args(func, args, nargs, kwnames)) {
         401                 :          0 :         return NULL;
         402                 :            :     }
         403                 :            :     _PyCFunctionFast meth = (_PyCFunctionFast)
         404                 :       6642 :                             method_enter_call(tstate, func);
         405         [ -  + ]:       6642 :     if (meth == NULL) {
         406                 :          0 :         return NULL;
         407                 :            :     }
         408                 :       6642 :     PyObject *result = meth(args[0], args+1, nargs-1);
         409                 :       6642 :     _Py_LeaveRecursiveCallTstate(tstate);
         410                 :       6642 :     return result;
         411                 :            : }
         412                 :            :
         413                 :            : static PyObject *
         414                 :        214 : method_vectorcall_FASTCALL_KEYWORDS(
         415                 :            :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
         416                 :            : {
         417                 :        214 :     PyThreadState *tstate = _PyThreadState_GET();
         418                 :        214 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
         419         [ -  + ]:        214 :     if (method_check_args(func, args, nargs, NULL)) {
         420                 :          0 :         return NULL;
         421                 :            :     }
         422                 :            :     _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
         423                 :        214 :                                         method_enter_call(tstate, func);
         424         [ -  + ]:        214 :     if (meth == NULL) {
         425                 :          0 :         return NULL;
         426                 :            :     }
         427                 :        214 :     PyObject *result = meth(args[0], args+1, nargs-1, kwnames);
         428                 :        214 :     _Py_LeaveRecursiveCallTstate(tstate);
         429                 :        214 :     return result;
         430                 :            : }
         431                 :            :
         432                 :            : static PyObject *
         433                 :      25391 : method_vectorcall_NOARGS(
         434                 :            :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
         435                 :            : {
         436                 :      25391 :     PyThreadState *tstate = _PyThreadState_GET();
         437                 :      25391 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
         438         [ -  + ]:      25391 :     if (method_check_args(func, args, nargs, kwnames)) {
         439                 :          0 :         return NULL;
         440                 :            :     }
         441         [ -  + ]:      25391 :     if (nargs != 1) {
         442                 :          0 :         PyObject *funcstr = _PyObject_FunctionStr(func);
         443         [ #  # ]:          0 :         if (funcstr != NULL) {
         444                 :          0 :             PyErr_Format(PyExc_TypeError,
         445                 :            :                 "%U takes no arguments (%zd given)", funcstr, nargs-1);
         446                 :          0 :             Py_DECREF(funcstr);
         447                 :            :         }
         448                 :          0 :         return NULL;
         449                 :            :     }
         450                 :      25391 :     PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
         451         [ -  + ]:      25391 :     if (meth == NULL) {
         452                 :          0 :         return NULL;
         453                 :            :     }
         454                 :      25391 :     PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], NULL);
         455                 :      25391 :     _Py_LeaveRecursiveCallTstate(tstate);
         456                 :      25391 :     return result;
         457                 :            : }
         458                 :            :
         459                 :            : static PyObject *
         460                 :     593863 : method_vectorcall_O(
         461                 :            :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
         462                 :            : {
         463                 :     593863 :     PyThreadState *tstate = _PyThreadState_GET();
         464                 :     593863 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
         465         [ -  + ]:     593863 :     if (method_check_args(func, args, nargs, kwnames)) {
         466                 :          0 :         return NULL;
         467                 :            :     }
         468         [ -  + ]:     593863 :     if (nargs != 2) {
         469                 :          0 :         PyObject *funcstr = _PyObject_FunctionStr(func);
         470         [ #  # ]:          0 :         if (funcstr != NULL) {
         471                 :          0 :             PyErr_Format(PyExc_TypeError,
         472                 :            :                 "%U takes exactly one argument (%zd given)",
         473                 :            :                 funcstr, nargs-1);
         474                 :          0 :             Py_DECREF(funcstr);
         475                 :            :         }
         476                 :          0 :         return NULL;
         477                 :            :     }
         478                 :     593863 :     PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
         479         [ -  + ]:     593863 :     if (meth == NULL) {
         480                 :          0 :         return NULL;
         481                 :            :     }
         482                 :     593863 :     PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], args[1]);
         483                 :     593863 :     _Py_LeaveRecursiveCallTstate(tstate);
         484                 :     593863 :     return result;
         485                 :            : }
         486                 :            :
         487                 :            :
         488                 :            : /* Instances of classmethod_descriptor are unlikely to be called directly.
         489                 :            :    For one, the analogous class "classmethod" (for Python classes) is not
         490                 :            :    callable. Second, users are not likely to access a classmethod_descriptor
         491                 :            :    directly, since it means pulling it from the class __dict__.
         492                 :            :
         493                 :            :    This is just an excuse to say that this doesn't need to be optimized:
         494                 :            :    we implement this simply by calling __get__ and then calling the result.
         495                 :            : */
         496                 :            : static PyObject *
         497                 :          0 : classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
         498                 :            :                       PyObject *kwds)
         499                 :            : {
         500                 :          0 :     Py_ssize_t argc = PyTuple_GET_SIZE(args);
         501         [ #  # ]:          0 :     if (argc < 1) {
         502                 :          0 :         PyErr_Format(PyExc_TypeError,
         503                 :            :                      "descriptor '%V' of '%.100s' "
         504                 :            :                      "object needs an argument",
         505                 :            :                      descr_name((PyDescrObject *)descr), "?",
         506                 :          0 :                      PyDescr_TYPE(descr)->tp_name);
         507                 :          0 :         return NULL;
         508                 :            :     }
         509                 :          0 :     PyObject *self = PyTuple_GET_ITEM(args, 0);
         510                 :          0 :     PyObject *bound = classmethod_get(descr, NULL, self);
         511         [ #  # ]:          0 :     if (bound == NULL) {
         512                 :          0 :         return NULL;
         513                 :            :     }
         514                 :          0 :     PyObject *res = PyObject_VectorcallDict(bound, _PyTuple_ITEMS(args)+1,
         515                 :          0 :                                            argc-1, kwds);
         516                 :          0 :     Py_DECREF(bound);
         517                 :          0 :     return res;
         518                 :            : }
         519                 :            :
         520                 :            : Py_LOCAL_INLINE(PyObject *)
         521                 :      18077 : wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self,
         522                 :            :                       PyObject *args, PyObject *kwds)
         523                 :            : {
         524                 :      18077 :     wrapperfunc wrapper = descr->d_base->wrapper;
         525                 :            :
         526         [ +  + ]:      18077 :     if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
         527                 :         55 :         wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper;
         528                 :         55 :         return (*wk)(self, args, descr->d_wrapped, kwds);
         529                 :            :     }
         530                 :            :
         531   [ -  +  -  -  :      18022 :     if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) {
                       -  - ]
         532                 :          0 :         PyErr_Format(PyExc_TypeError,
         533                 :            :                      "wrapper %s() takes no keyword arguments",
         534                 :          0 :                      descr->d_base->name);
         535                 :          0 :         return NULL;
         536                 :            :     }
         537                 :      18022 :     return (*wrapper)(self, args, descr->d_wrapped);
         538                 :            : }
         539                 :            :
         540                 :            : static PyObject *
         541                 :      15634 : wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
         542                 :            : {
         543                 :            :     Py_ssize_t argc;
         544                 :            :     PyObject *self, *result;
         545                 :            :
         546                 :            :     /* Make sure that the first argument is acceptable as 'self' */
         547                 :            :     assert(PyTuple_Check(args));
         548                 :      15634 :     argc = PyTuple_GET_SIZE(args);
         549         [ -  + ]:      15634 :     if (argc < 1) {
         550                 :          0 :         PyErr_Format(PyExc_TypeError,
         551                 :            :                      "descriptor '%V' of '%.100s' "
         552                 :            :                      "object needs an argument",
         553                 :            :                      descr_name((PyDescrObject *)descr), "?",
         554                 :          0 :                      PyDescr_TYPE(descr)->tp_name);
         555                 :          0 :         return NULL;
         556                 :            :     }
         557                 :      15634 :     self = PyTuple_GET_ITEM(args, 0);
         558         [ -  + ]:      15634 :     if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
         559                 :      15634 :                                   (PyObject *)PyDescr_TYPE(descr))) {
         560                 :          0 :         PyErr_Format(PyExc_TypeError,
         561                 :            :                      "descriptor '%V' "
         562                 :            :                      "requires a '%.100s' object "
         563                 :            :                      "but received a '%.100s'",
         564                 :            :                      descr_name((PyDescrObject *)descr), "?",
         565                 :          0 :                      PyDescr_TYPE(descr)->tp_name,
         566                 :          0 :                      Py_TYPE(self)->tp_name);
         567                 :          0 :         return NULL;
         568                 :            :     }
         569                 :            :
         570                 :      15634 :     args = PyTuple_GetSlice(args, 1, argc);
         571         [ -  + ]:      15634 :     if (args == NULL) {
         572                 :          0 :         return NULL;
         573                 :            :     }
         574                 :      15634 :     result = wrapperdescr_raw_call(descr, self, args, kwds);
         575                 :      15634 :     Py_DECREF(args);
         576                 :      15634 :     return result;
         577                 :            : }
         578                 :            :
         579                 :            :
         580                 :            : static PyObject *
         581                 :          0 : method_get_doc(PyMethodDescrObject *descr, void *closure)
         582                 :            : {
         583                 :          0 :     return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
         584                 :            : }
         585                 :            :
         586                 :            : static PyObject *
         587                 :          0 : method_get_text_signature(PyMethodDescrObject *descr, void *closure)
         588                 :            : {
         589                 :          0 :     return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
         590                 :            : }
         591                 :            :
         592                 :            : static PyObject *
         593                 :          0 : calculate_qualname(PyDescrObject *descr)
         594                 :            : {
         595                 :            :     PyObject *type_qualname, *res;
         596                 :            :
         597   [ #  #  #  # ]:          0 :     if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) {
         598                 :          0 :         PyErr_SetString(PyExc_TypeError,
         599                 :            :                         "<descriptor>.__name__ is not a unicode object");
         600                 :          0 :         return NULL;
         601                 :            :     }
         602                 :            :
         603                 :          0 :     type_qualname = PyObject_GetAttr(
         604                 :          0 :             (PyObject *)descr->d_type, &_Py_ID(__qualname__));
         605         [ #  # ]:          0 :     if (type_qualname == NULL)
         606                 :          0 :         return NULL;
         607                 :            :
         608         [ #  # ]:          0 :     if (!PyUnicode_Check(type_qualname)) {
         609                 :          0 :         PyErr_SetString(PyExc_TypeError, "<descriptor>.__objclass__."
         610                 :            :                         "__qualname__ is not a unicode object");
         611                 :          0 :         Py_XDECREF(type_qualname);
         612                 :          0 :         return NULL;
         613                 :            :     }
         614                 :            :
         615                 :          0 :     res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name);
         616                 :          0 :     Py_DECREF(type_qualname);
         617                 :          0 :     return res;
         618                 :            : }
         619                 :            :
         620                 :            : static PyObject *
         621                 :          0 : descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
         622                 :            : {
         623         [ #  # ]:          0 :     if (descr->d_qualname == NULL)
         624                 :          0 :         descr->d_qualname = calculate_qualname(descr);
         625                 :          0 :     return Py_XNewRef(descr->d_qualname);
         626                 :            : }
         627                 :            :
         628                 :            : static PyObject *
         629                 :          0 : descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
         630                 :            : {
         631                 :          0 :     return Py_BuildValue("N(OO)", _PyEval_GetBuiltin(&_Py_ID(getattr)),
         632                 :            :                          PyDescr_TYPE(descr), PyDescr_NAME(descr));
         633                 :            : }
         634                 :            :
         635                 :            : static PyMethodDef descr_methods[] = {
         636                 :            :     {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL},
         637                 :            :     {NULL, NULL}
         638                 :            : };
         639                 :            :
         640                 :            : static PyMemberDef descr_members[] = {
         641                 :            :     {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
         642                 :            :     {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
         643                 :            :     {0}
         644                 :            : };
         645                 :            :
         646                 :            : static PyGetSetDef method_getset[] = {
         647                 :            :     {"__doc__", (getter)method_get_doc},
         648                 :            :     {"__qualname__", (getter)descr_get_qualname},
         649                 :            :     {"__text_signature__", (getter)method_get_text_signature},
         650                 :            :     {0}
         651                 :            : };
         652                 :            :
         653                 :            : static PyObject *
         654                 :          0 : member_get_doc(PyMemberDescrObject *descr, void *closure)
         655                 :            : {
         656         [ #  # ]:          0 :     if (descr->d_member->doc == NULL) {
         657                 :          0 :         Py_RETURN_NONE;
         658                 :            :     }
         659                 :          0 :     return PyUnicode_FromString(descr->d_member->doc);
         660                 :            : }
         661                 :            :
         662                 :            : static PyGetSetDef member_getset[] = {
         663                 :            :     {"__doc__", (getter)member_get_doc},
         664                 :            :     {"__qualname__", (getter)descr_get_qualname},
         665                 :            :     {0}
         666                 :            : };
         667                 :            :
         668                 :            : static PyObject *
         669                 :          0 : getset_get_doc(PyGetSetDescrObject *descr, void *closure)
         670                 :            : {
         671         [ #  # ]:          0 :     if (descr->d_getset->doc == NULL) {
         672                 :          0 :         Py_RETURN_NONE;
         673                 :            :     }
         674                 :          0 :     return PyUnicode_FromString(descr->d_getset->doc);
         675                 :            : }
         676                 :            :
         677                 :            : static PyGetSetDef getset_getset[] = {
         678                 :            :     {"__doc__", (getter)getset_get_doc},
         679                 :            :     {"__qualname__", (getter)descr_get_qualname},
         680                 :            :     {0}
         681                 :            : };
         682                 :            :
         683                 :            : static PyObject *
         684                 :          0 : wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
         685                 :            : {
         686                 :          0 :     return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc);
         687                 :            : }
         688                 :            :
         689                 :            : static PyObject *
         690                 :          0 : wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
         691                 :            : {
         692                 :          0 :     return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
         693                 :            : }
         694                 :            :
         695                 :            : static PyGetSetDef wrapperdescr_getset[] = {
         696                 :            :     {"__doc__", (getter)wrapperdescr_get_doc},
         697                 :            :     {"__qualname__", (getter)descr_get_qualname},
         698                 :            :     {"__text_signature__", (getter)wrapperdescr_get_text_signature},
         699                 :            :     {0}
         700                 :            : };
         701                 :            :
         702                 :            : static int
         703                 :     667958 : descr_traverse(PyObject *self, visitproc visit, void *arg)
         704                 :            : {
         705                 :     667958 :     PyDescrObject *descr = (PyDescrObject *)self;
         706   [ +  -  -  + ]:     667958 :     Py_VISIT(descr->d_type);
         707                 :     667958 :     return 0;
         708                 :            : }
         709                 :            :
         710                 :            : PyTypeObject PyMethodDescr_Type = {
         711                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
         712                 :            :     "method_descriptor",
         713                 :            :     sizeof(PyMethodDescrObject),
         714                 :            :     0,
         715                 :            :     (destructor)descr_dealloc,                  /* tp_dealloc */
         716                 :            :     offsetof(PyMethodDescrObject, vectorcall),  /* tp_vectorcall_offset */
         717                 :            :     0,                                          /* tp_getattr */
         718                 :            :     0,                                          /* tp_setattr */
         719                 :            :     0,                                          /* tp_as_async */
         720                 :            :     (reprfunc)method_repr,                      /* tp_repr */
         721                 :            :     0,                                          /* tp_as_number */
         722                 :            :     0,                                          /* tp_as_sequence */
         723                 :            :     0,                                          /* tp_as_mapping */
         724                 :            :     0,                                          /* tp_hash */
         725                 :            :     PyVectorcall_Call,                          /* tp_call */
         726                 :            :     0,                                          /* tp_str */
         727                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
         728                 :            :     0,                                          /* tp_setattro */
         729                 :            :     0,                                          /* tp_as_buffer */
         730                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
         731                 :            :     Py_TPFLAGS_HAVE_VECTORCALL |
         732                 :            :     Py_TPFLAGS_METHOD_DESCRIPTOR,               /* tp_flags */
         733                 :            :     0,                                          /* tp_doc */
         734                 :            :     descr_traverse,                             /* tp_traverse */
         735                 :            :     0,                                          /* tp_clear */
         736                 :            :     0,                                          /* tp_richcompare */
         737                 :            :     0,                                          /* tp_weaklistoffset */
         738                 :            :     0,                                          /* tp_iter */
         739                 :            :     0,                                          /* tp_iternext */
         740                 :            :     descr_methods,                              /* tp_methods */
         741                 :            :     descr_members,                              /* tp_members */
         742                 :            :     method_getset,                              /* tp_getset */
         743                 :            :     0,                                          /* tp_base */
         744                 :            :     0,                                          /* tp_dict */
         745                 :            :     (descrgetfunc)method_get,                   /* tp_descr_get */
         746                 :            :     0,                                          /* tp_descr_set */
         747                 :            : };
         748                 :            :
         749                 :            : /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
         750                 :            : PyTypeObject PyClassMethodDescr_Type = {
         751                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
         752                 :            :     "classmethod_descriptor",
         753                 :            :     sizeof(PyMethodDescrObject),
         754                 :            :     0,
         755                 :            :     (destructor)descr_dealloc,                  /* tp_dealloc */
         756                 :            :     0,                                          /* tp_vectorcall_offset */
         757                 :            :     0,                                          /* tp_getattr */
         758                 :            :     0,                                          /* tp_setattr */
         759                 :            :     0,                                          /* tp_as_async */
         760                 :            :     (reprfunc)method_repr,                      /* tp_repr */
         761                 :            :     0,                                          /* tp_as_number */
         762                 :            :     0,                                          /* tp_as_sequence */
         763                 :            :     0,                                          /* tp_as_mapping */
         764                 :            :     0,                                          /* tp_hash */
         765                 :            :     (ternaryfunc)classmethoddescr_call,         /* tp_call */
         766                 :            :     0,                                          /* tp_str */
         767                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
         768                 :            :     0,                                          /* tp_setattro */
         769                 :            :     0,                                          /* tp_as_buffer */
         770                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
         771                 :            :     0,                                          /* tp_doc */
         772                 :            :     descr_traverse,                             /* tp_traverse */
         773                 :            :     0,                                          /* tp_clear */
         774                 :            :     0,                                          /* tp_richcompare */
         775                 :            :     0,                                          /* tp_weaklistoffset */
         776                 :            :     0,                                          /* tp_iter */
         777                 :            :     0,                                          /* tp_iternext */
         778                 :            :     0,                                          /* tp_methods */
         779                 :            :     descr_members,                              /* tp_members */
         780                 :            :     method_getset,                              /* tp_getset */
         781                 :            :     0,                                          /* tp_base */
         782                 :            :     0,                                          /* tp_dict */
         783                 :            :     (descrgetfunc)classmethod_get,              /* tp_descr_get */
         784                 :            :     0,                                          /* tp_descr_set */
         785                 :            : };
         786                 :            :
         787                 :            : PyTypeObject PyMemberDescr_Type = {
         788                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
         789                 :            :     "member_descriptor",
         790                 :            :     sizeof(PyMemberDescrObject),
         791                 :            :     0,
         792                 :            :     (destructor)descr_dealloc,                  /* tp_dealloc */
         793                 :            :     0,                                          /* tp_vectorcall_offset */
         794                 :            :     0,                                          /* tp_getattr */
         795                 :            :     0,                                          /* tp_setattr */
         796                 :            :     0,                                          /* tp_as_async */
         797                 :            :     (reprfunc)member_repr,                      /* tp_repr */
         798                 :            :     0,                                          /* tp_as_number */
         799                 :            :     0,                                          /* tp_as_sequence */
         800                 :            :     0,                                          /* tp_as_mapping */
         801                 :            :     0,                                          /* tp_hash */
         802                 :            :     0,                                          /* tp_call */
         803                 :            :     0,                                          /* tp_str */
         804                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
         805                 :            :     0,                                          /* tp_setattro */
         806                 :            :     0,                                          /* tp_as_buffer */
         807                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
         808                 :            :     0,                                          /* tp_doc */
         809                 :            :     descr_traverse,                             /* tp_traverse */
         810                 :            :     0,                                          /* tp_clear */
         811                 :            :     0,                                          /* tp_richcompare */
         812                 :            :     0,                                          /* tp_weaklistoffset */
         813                 :            :     0,                                          /* tp_iter */
         814                 :            :     0,                                          /* tp_iternext */
         815                 :            :     descr_methods,                              /* tp_methods */
         816                 :            :     descr_members,                              /* tp_members */
         817                 :            :     member_getset,                              /* tp_getset */
         818                 :            :     0,                                          /* tp_base */
         819                 :            :     0,                                          /* tp_dict */
         820                 :            :     (descrgetfunc)member_get,                   /* tp_descr_get */
         821                 :            :     (descrsetfunc)member_set,                   /* tp_descr_set */
         822                 :            : };
         823                 :            :
         824                 :            : PyTypeObject PyGetSetDescr_Type = {
         825                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
         826                 :            :     "getset_descriptor",
         827                 :            :     sizeof(PyGetSetDescrObject),
         828                 :            :     0,
         829                 :            :     (destructor)descr_dealloc,                  /* tp_dealloc */
         830                 :            :     0,                                          /* tp_vectorcall_offset */
         831                 :            :     0,                                          /* tp_getattr */
         832                 :            :     0,                                          /* tp_setattr */
         833                 :            :     0,                                          /* tp_as_async */
         834                 :            :     (reprfunc)getset_repr,                      /* tp_repr */
         835                 :            :     0,                                          /* tp_as_number */
         836                 :            :     0,                                          /* tp_as_sequence */
         837                 :            :     0,                                          /* tp_as_mapping */
         838                 :            :     0,                                          /* tp_hash */
         839                 :            :     0,                                          /* tp_call */
         840                 :            :     0,                                          /* tp_str */
         841                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
         842                 :            :     0,                                          /* tp_setattro */
         843                 :            :     0,                                          /* tp_as_buffer */
         844                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
         845                 :            :     0,                                          /* tp_doc */
         846                 :            :     descr_traverse,                             /* tp_traverse */
         847                 :            :     0,                                          /* tp_clear */
         848                 :            :     0,                                          /* tp_richcompare */
         849                 :            :     0,                                          /* tp_weaklistoffset */
         850                 :            :     0,                                          /* tp_iter */
         851                 :            :     0,                                          /* tp_iternext */
         852                 :            :     0,                                          /* tp_methods */
         853                 :            :     descr_members,                              /* tp_members */
         854                 :            :     getset_getset,                              /* tp_getset */
         855                 :            :     0,                                          /* tp_base */
         856                 :            :     0,                                          /* tp_dict */
         857                 :            :     (descrgetfunc)getset_get,                   /* tp_descr_get */
         858                 :            :     (descrsetfunc)getset_set,                   /* tp_descr_set */
         859                 :            : };
         860                 :            :
         861                 :            : PyTypeObject PyWrapperDescr_Type = {
         862                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
         863                 :            :     "wrapper_descriptor",
         864                 :            :     sizeof(PyWrapperDescrObject),
         865                 :            :     0,
         866                 :            :     (destructor)descr_dealloc,                  /* tp_dealloc */
         867                 :            :     0,                                          /* tp_vectorcall_offset */
         868                 :            :     0,                                          /* tp_getattr */
         869                 :            :     0,                                          /* tp_setattr */
         870                 :            :     0,                                          /* tp_as_async */
         871                 :            :     (reprfunc)wrapperdescr_repr,                /* tp_repr */
         872                 :            :     0,                                          /* tp_as_number */
         873                 :            :     0,                                          /* tp_as_sequence */
         874                 :            :     0,                                          /* tp_as_mapping */
         875                 :            :     0,                                          /* tp_hash */
         876                 :            :     (ternaryfunc)wrapperdescr_call,             /* tp_call */
         877                 :            :     0,                                          /* tp_str */
         878                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
         879                 :            :     0,                                          /* tp_setattro */
         880                 :            :     0,                                          /* tp_as_buffer */
         881                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
         882                 :            :     Py_TPFLAGS_METHOD_DESCRIPTOR,               /* tp_flags */
         883                 :            :     0,                                          /* tp_doc */
         884                 :            :     descr_traverse,                             /* tp_traverse */
         885                 :            :     0,                                          /* tp_clear */
         886                 :            :     0,                                          /* tp_richcompare */
         887                 :            :     0,                                          /* tp_weaklistoffset */
         888                 :            :     0,                                          /* tp_iter */
         889                 :            :     0,                                          /* tp_iternext */
         890                 :            :     descr_methods,                              /* tp_methods */
         891                 :            :     descr_members,                              /* tp_members */
         892                 :            :     wrapperdescr_getset,                        /* tp_getset */
         893                 :            :     0,                                          /* tp_base */
         894                 :            :     0,                                          /* tp_dict */
         895                 :            :     (descrgetfunc)wrapperdescr_get,             /* tp_descr_get */
         896                 :            :     0,                                          /* tp_descr_set */
         897                 :            : };
         898                 :            :
         899                 :            : static PyDescrObject *
         900                 :      66753 : descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
         901                 :            : {
         902                 :            :     PyDescrObject *descr;
         903                 :            :
         904                 :      66753 :     descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
         905         [ +  - ]:      66753 :     if (descr != NULL) {
         906                 :      66753 :         descr->d_type = (PyTypeObject*)Py_XNewRef(type);
         907                 :      66753 :         descr->d_name = PyUnicode_InternFromString(name);
         908         [ -  + ]:      66753 :         if (descr->d_name == NULL) {
         909                 :          0 :             Py_SETREF(descr, NULL);
         910                 :            :         }
         911                 :            :         else {
         912                 :      66753 :             descr->d_qualname = NULL;
         913                 :            :         }
         914                 :            :     }
         915                 :      66753 :     return descr;
         916                 :            : }
         917                 :            :
         918                 :            : PyObject *
         919                 :      19360 : PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
         920                 :            : {
         921                 :            :     /* Figure out correct vectorcall function to use */
         922                 :            :     vectorcallfunc vectorcall;
         923   [ +  +  +  +  :      19360 :     switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS |
                 +  +  +  - ]
         924                 :            :                                 METH_O | METH_KEYWORDS | METH_METHOD))
         925                 :            :     {
         926                 :       1980 :         case METH_VARARGS:
         927                 :       1980 :             vectorcall = method_vectorcall_VARARGS;
         928                 :       1980 :             break;
         929                 :        305 :         case METH_VARARGS | METH_KEYWORDS:
         930                 :        305 :             vectorcall = method_vectorcall_VARARGS_KEYWORDS;
         931                 :        305 :             break;
         932                 :       2169 :         case METH_FASTCALL:
         933                 :       2169 :             vectorcall = method_vectorcall_FASTCALL;
         934                 :       2169 :             break;
         935                 :       1030 :         case METH_FASTCALL | METH_KEYWORDS:
         936                 :       1030 :             vectorcall = method_vectorcall_FASTCALL_KEYWORDS;
         937                 :       1030 :             break;
         938                 :      10053 :         case METH_NOARGS:
         939                 :      10053 :             vectorcall = method_vectorcall_NOARGS;
         940                 :      10053 :             break;
         941                 :       3538 :         case METH_O:
         942                 :       3538 :             vectorcall = method_vectorcall_O;
         943                 :       3538 :             break;
         944                 :        285 :         case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
         945                 :        285 :             vectorcall = method_vectorcall_FASTCALL_KEYWORDS_METHOD;
         946                 :        285 :             break;
         947                 :          0 :         default:
         948                 :          0 :             PyErr_Format(PyExc_SystemError,
         949                 :            :                          "%s() method: bad call flags", method->ml_name);
         950                 :          0 :             return NULL;
         951                 :            :     }
         952                 :            :
         953                 :            :     PyMethodDescrObject *descr;
         954                 :            :
         955                 :      19360 :     descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
         956                 :            :                                              type, method->ml_name);
         957         [ +  - ]:      19360 :     if (descr != NULL) {
         958                 :      19360 :         descr->d_method = method;
         959                 :      19360 :         descr->vectorcall = vectorcall;
         960                 :            :     }
         961                 :      19360 :     return (PyObject *)descr;
         962                 :            : }
         963                 :            :
         964                 :            : PyObject *
         965                 :        750 : PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
         966                 :            : {
         967                 :            :     PyMethodDescrObject *descr;
         968                 :            :
         969                 :        750 :     descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
         970                 :            :                                              type, method->ml_name);
         971         [ +  - ]:        750 :     if (descr != NULL)
         972                 :        750 :         descr->d_method = method;
         973                 :        750 :     return (PyObject *)descr;
         974                 :            : }
         975                 :            :
         976                 :            : PyObject *
         977                 :       8438 : PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
         978                 :            : {
         979                 :            :     PyMemberDescrObject *descr;
         980                 :            :
         981                 :       8438 :     descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
         982                 :            :                                              type, member->name);
         983         [ +  - ]:       8438 :     if (descr != NULL)
         984                 :       8438 :         descr->d_member = member;
         985                 :       8438 :     return (PyObject *)descr;
         986                 :            : }
         987                 :            :
         988                 :            : PyObject *
         989                 :       7816 : PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
         990                 :            : {
         991                 :            :     PyGetSetDescrObject *descr;
         992                 :            :
         993                 :       7816 :     descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
         994                 :            :                                              type, getset->name);
         995         [ +  - ]:       7816 :     if (descr != NULL)
         996                 :       7816 :         descr->d_getset = getset;
         997                 :       7816 :     return (PyObject *)descr;
         998                 :            : }
         999                 :            :
        1000                 :            : PyObject *
        1001                 :      30389 : PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
        1002                 :            : {
        1003                 :            :     PyWrapperDescrObject *descr;
        1004                 :            :
        1005                 :      30389 :     descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
        1006                 :            :                                              type, base->name);
        1007         [ +  - ]:      30389 :     if (descr != NULL) {
        1008                 :      30389 :         descr->d_base = base;
        1009                 :      30389 :         descr->d_wrapped = wrapped;
        1010                 :            :     }
        1011                 :      30389 :     return (PyObject *)descr;
        1012                 :            : }
        1013                 :            :
        1014                 :            : int
        1015                 :    2841780 : PyDescr_IsData(PyObject *ob)
        1016                 :            : {
        1017                 :    2841780 :     return Py_TYPE(ob)->tp_descr_set != NULL;
        1018                 :            : }
        1019                 :            :
        1020                 :            : /* --- mappingproxy: read-only proxy for mappings --- */
        1021                 :            :
        1022                 :            : /* This has no reason to be in this file except that adding new files is a
        1023                 :            :    bit of a pain */
        1024                 :            :
        1025                 :            : typedef struct {
        1026                 :            :     PyObject_HEAD
        1027                 :            :     PyObject *mapping;
        1028                 :            : } mappingproxyobject;
        1029                 :            :
        1030                 :            : static Py_ssize_t
        1031                 :         15 : mappingproxy_len(mappingproxyobject *pp)
        1032                 :            : {
        1033                 :         15 :     return PyObject_Size(pp->mapping);
        1034                 :            : }
        1035                 :            :
        1036                 :            : static PyObject *
        1037                 :       2405 : mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
        1038                 :            : {
        1039                 :       2405 :     return PyObject_GetItem(pp->mapping, key);
        1040                 :            : }
        1041                 :            :
        1042                 :            : static PyMappingMethods mappingproxy_as_mapping = {
        1043                 :            :     (lenfunc)mappingproxy_len,                  /* mp_length */
        1044                 :            :     (binaryfunc)mappingproxy_getitem,           /* mp_subscript */
        1045                 :            :     0,                                          /* mp_ass_subscript */
        1046                 :            : };
        1047                 :            :
        1048                 :            : static PyObject *
        1049                 :          0 : mappingproxy_or(PyObject *left, PyObject *right)
        1050                 :            : {
        1051         [ #  # ]:          0 :     if (PyObject_TypeCheck(left, &PyDictProxy_Type)) {
        1052                 :          0 :         left = ((mappingproxyobject*)left)->mapping;
        1053                 :            :     }
        1054         [ #  # ]:          0 :     if (PyObject_TypeCheck(right, &PyDictProxy_Type)) {
        1055                 :          0 :         right = ((mappingproxyobject*)right)->mapping;
        1056                 :            :     }
        1057                 :          0 :     return PyNumber_Or(left, right);
        1058                 :            : }
        1059                 :            :
        1060                 :            : static PyObject *
        1061                 :          0 : mappingproxy_ior(PyObject *self, PyObject *Py_UNUSED(other))
        1062                 :            : {
        1063                 :          0 :     return PyErr_Format(PyExc_TypeError,
        1064                 :          0 :         "'|=' is not supported by %s; use '|' instead", Py_TYPE(self)->tp_name);
        1065                 :            : }
        1066                 :            :
        1067                 :            : static PyNumberMethods mappingproxy_as_number = {
        1068                 :            :     .nb_or = mappingproxy_or,
        1069                 :            :     .nb_inplace_or = mappingproxy_ior,
        1070                 :            : };
        1071                 :            :
        1072                 :            : static int
        1073                 :       1151 : mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
        1074                 :            : {
        1075         [ +  - ]:       1151 :     if (PyDict_CheckExact(pp->mapping))
        1076                 :       1151 :         return PyDict_Contains(pp->mapping, key);
        1077                 :            :     else
        1078                 :          0 :         return PySequence_Contains(pp->mapping, key);
        1079                 :            : }
        1080                 :            :
        1081                 :            : static PySequenceMethods mappingproxy_as_sequence = {
        1082                 :            :     0,                                          /* sq_length */
        1083                 :            :     0,                                          /* sq_concat */
        1084                 :            :     0,                                          /* sq_repeat */
        1085                 :            :     0,                                          /* sq_item */
        1086                 :            :     0,                                          /* sq_slice */
        1087                 :            :     0,                                          /* sq_ass_item */
        1088                 :            :     0,                                          /* sq_ass_slice */
        1089                 :            :     (objobjproc)mappingproxy_contains,                 /* sq_contains */
        1090                 :            :     0,                                          /* sq_inplace_concat */
        1091                 :            :     0,                                          /* sq_inplace_repeat */
        1092                 :            : };
        1093                 :            :
        1094                 :            : static PyObject *
        1095                 :       1042 : mappingproxy_get(mappingproxyobject *pp, PyObject *const *args, Py_ssize_t nargs)
        1096                 :            : {
        1097                 :            :     /* newargs: mapping, key, default=None */
        1098                 :            :     PyObject *newargs[3];
        1099                 :       1042 :     newargs[0] = pp->mapping;
        1100                 :       1042 :     newargs[2] = Py_None;
        1101                 :            :
        1102         [ -  + ]:       1042 :     if (!_PyArg_UnpackStack(args, nargs, "get", 1, 2,
        1103                 :            :                             &newargs[1], &newargs[2]))
        1104                 :            :     {
        1105                 :          0 :         return NULL;
        1106                 :            :     }
        1107                 :       1042 :     return _PyObject_VectorcallMethod(&_Py_ID(get), newargs,
        1108                 :            :                                         3 | PY_VECTORCALL_ARGUMENTS_OFFSET,
        1109                 :            :                                         NULL);
        1110                 :            : }
        1111                 :            :
        1112                 :            : static PyObject *
        1113                 :         65 : mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
        1114                 :            : {
        1115                 :         65 :     return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(keys));
        1116                 :            : }
        1117                 :            :
        1118                 :            : static PyObject *
        1119                 :          0 : mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
        1120                 :            : {
        1121                 :          0 :     return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(values));
        1122                 :            : }
        1123                 :            :
        1124                 :            : static PyObject *
        1125                 :        995 : mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
        1126                 :            : {
        1127                 :        995 :     return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(items));
        1128                 :            : }
        1129                 :            :
        1130                 :            : static PyObject *
        1131                 :          0 : mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
        1132                 :            : {
        1133                 :          0 :     return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(copy));
        1134                 :            : }
        1135                 :            :
        1136                 :            : static PyObject *
        1137                 :          0 : mappingproxy_reversed(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
        1138                 :            : {
        1139                 :          0 :     return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(__reversed__));
        1140                 :            : }
        1141                 :            :
        1142                 :            : /* WARNING: mappingproxy methods must not give access
        1143                 :            :             to the underlying mapping */
        1144                 :            :
        1145                 :            : static PyMethodDef mappingproxy_methods[] = {
        1146                 :            :     {"get",       _PyCFunction_CAST(mappingproxy_get), METH_FASTCALL,
        1147                 :            :      PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d."
        1148                 :            :                "  d defaults to None.")},
        1149                 :            :     {"keys",      (PyCFunction)mappingproxy_keys,       METH_NOARGS,
        1150                 :            :      PyDoc_STR("D.keys() -> a set-like object providing a view on D's keys")},
        1151                 :            :     {"values",    (PyCFunction)mappingproxy_values,     METH_NOARGS,
        1152                 :            :      PyDoc_STR("D.values() -> an object providing a view on D's values")},
        1153                 :            :     {"items",     (PyCFunction)mappingproxy_items,      METH_NOARGS,
        1154                 :            :      PyDoc_STR("D.items() -> a set-like object providing a view on D's items")},
        1155                 :            :     {"copy",      (PyCFunction)mappingproxy_copy,       METH_NOARGS,
        1156                 :            :      PyDoc_STR("D.copy() -> a shallow copy of D")},
        1157                 :            :     {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS,
        1158                 :            :      PyDoc_STR("See PEP 585")},
        1159                 :            :     {"__reversed__", (PyCFunction)mappingproxy_reversed, METH_NOARGS,
        1160                 :            :      PyDoc_STR("D.__reversed__() -> reverse iterator")},
        1161                 :            :     {0}
        1162                 :            : };
        1163                 :            :
        1164                 :            : static void
        1165                 :       4321 : mappingproxy_dealloc(mappingproxyobject *pp)
        1166                 :            : {
        1167                 :       4321 :     _PyObject_GC_UNTRACK(pp);
        1168                 :       4321 :     Py_DECREF(pp->mapping);
        1169                 :       4321 :     PyObject_GC_Del(pp);
        1170                 :       4321 : }
        1171                 :            :
        1172                 :            : static PyObject *
        1173                 :          0 : mappingproxy_getiter(mappingproxyobject *pp)
        1174                 :            : {
        1175                 :          0 :     return PyObject_GetIter(pp->mapping);
        1176                 :            : }
        1177                 :            :
        1178                 :            : static Py_hash_t
        1179                 :          0 : mappingproxy_hash(mappingproxyobject *pp)
        1180                 :            : {
        1181                 :          0 :     return PyObject_Hash(pp->mapping);
        1182                 :            : }
        1183                 :            :
        1184                 :            : static PyObject *
        1185                 :          0 : mappingproxy_str(mappingproxyobject *pp)
        1186                 :            : {
        1187                 :          0 :     return PyObject_Str(pp->mapping);
        1188                 :            : }
        1189                 :            :
        1190                 :            : static PyObject *
        1191                 :          0 : mappingproxy_repr(mappingproxyobject *pp)
        1192                 :            : {
        1193                 :          0 :     return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping);
        1194                 :            : }
        1195                 :            :
        1196                 :            : static int
        1197                 :         78 : mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
        1198                 :            : {
        1199                 :         78 :     mappingproxyobject *pp = (mappingproxyobject *)self;
        1200   [ +  -  -  + ]:         78 :     Py_VISIT(pp->mapping);
        1201                 :         78 :     return 0;
        1202                 :            : }
        1203                 :            :
        1204                 :            : static PyObject *
        1205                 :          0 : mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op)
        1206                 :            : {
        1207                 :          0 :     return PyObject_RichCompare(v->mapping, w, op);
        1208                 :            : }
        1209                 :            :
        1210                 :            : static int
        1211                 :       4321 : mappingproxy_check_mapping(PyObject *mapping)
        1212                 :            : {
        1213         [ +  - ]:       4321 :     if (!PyMapping_Check(mapping)
        1214         [ +  - ]:       4321 :         || PyList_Check(mapping)
        1215         [ -  + ]:       4321 :         || PyTuple_Check(mapping)) {
        1216                 :          0 :         PyErr_Format(PyExc_TypeError,
        1217                 :            :                     "mappingproxy() argument must be a mapping, not %s",
        1218                 :          0 :                     Py_TYPE(mapping)->tp_name);
        1219                 :          0 :         return -1;
        1220                 :            :     }
        1221                 :       4321 :     return 0;
        1222                 :            : }
        1223                 :            :
        1224                 :            : /*[clinic input]
        1225                 :            : @classmethod
        1226                 :            : mappingproxy.__new__ as mappingproxy_new
        1227                 :            :
        1228                 :            :     mapping: object
        1229                 :            :
        1230                 :            : [clinic start generated code]*/
        1231                 :            :
        1232                 :            : static PyObject *
        1233                 :         38 : mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping)
        1234                 :            : /*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/
        1235                 :            : {
        1236                 :            :     mappingproxyobject *mappingproxy;
        1237                 :            :
        1238         [ -  + ]:         38 :     if (mappingproxy_check_mapping(mapping) == -1)
        1239                 :          0 :         return NULL;
        1240                 :            :
        1241                 :         38 :     mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
        1242         [ -  + ]:         38 :     if (mappingproxy == NULL)
        1243                 :          0 :         return NULL;
        1244                 :         38 :     mappingproxy->mapping = Py_NewRef(mapping);
        1245                 :         38 :     _PyObject_GC_TRACK(mappingproxy);
        1246                 :         38 :     return (PyObject *)mappingproxy;
        1247                 :            : }
        1248                 :            :
        1249                 :            : PyObject *
        1250                 :       4283 : PyDictProxy_New(PyObject *mapping)
        1251                 :            : {
        1252                 :            :     mappingproxyobject *pp;
        1253                 :            :
        1254         [ -  + ]:       4283 :     if (mappingproxy_check_mapping(mapping) == -1)
        1255                 :          0 :         return NULL;
        1256                 :            :
        1257                 :       4283 :     pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
        1258         [ +  - ]:       4283 :     if (pp != NULL) {
        1259                 :       4283 :         pp->mapping = Py_NewRef(mapping);
        1260                 :       4283 :         _PyObject_GC_TRACK(pp);
        1261                 :            :     }
        1262                 :       4283 :     return (PyObject *)pp;
        1263                 :            : }
        1264                 :            :
        1265                 :            :
        1266                 :            : /* --- Wrapper object for "slot" methods --- */
        1267                 :            :
        1268                 :            : /* This has no reason to be in this file except that adding new files is a
        1269                 :            :    bit of a pain */
        1270                 :            :
        1271                 :            : typedef struct {
        1272                 :            :     PyObject_HEAD
        1273                 :            :     PyWrapperDescrObject *descr;
        1274                 :            :     PyObject *self;
        1275                 :            : } wrapperobject;
        1276                 :            :
        1277                 :            : #define Wrapper_Check(v) Py_IS_TYPE(v, &_PyMethodWrapper_Type)
        1278                 :            :
        1279                 :            : static void
        1280                 :       2457 : wrapper_dealloc(wrapperobject *wp)
        1281                 :            : {
        1282                 :       2457 :     PyObject_GC_UnTrack(wp);
        1283   [ +  -  -  + ]:       2457 :     Py_TRASHCAN_BEGIN(wp, wrapper_dealloc)
        1284                 :       2457 :     Py_XDECREF(wp->descr);
        1285                 :       2457 :     Py_XDECREF(wp->self);
        1286                 :       2457 :     PyObject_GC_Del(wp);
        1287         [ +  - ]:       2457 :     Py_TRASHCAN_END
        1288                 :       2457 : }
        1289                 :            :
        1290                 :            : static PyObject *
        1291                 :          0 : wrapper_richcompare(PyObject *a, PyObject *b, int op)
        1292                 :            : {
        1293                 :            :     wrapperobject *wa, *wb;
        1294                 :            :     int eq;
        1295                 :            :
        1296                 :            :     assert(a != NULL && b != NULL);
        1297                 :            :
        1298                 :            :     /* both arguments should be wrapperobjects */
        1299   [ #  #  #  # ]:          0 :     if ((op != Py_EQ && op != Py_NE)
        1300   [ #  #  #  # ]:          0 :         || !Wrapper_Check(a) || !Wrapper_Check(b))
        1301                 :            :     {
        1302                 :          0 :         Py_RETURN_NOTIMPLEMENTED;
        1303                 :            :     }
        1304                 :            :
        1305                 :          0 :     wa = (wrapperobject *)a;
        1306                 :          0 :     wb = (wrapperobject *)b;
        1307   [ #  #  #  # ]:          0 :     eq = (wa->descr == wb->descr && wa->self == wb->self);
        1308         [ #  # ]:          0 :     if (eq == (op == Py_EQ)) {
        1309                 :          0 :         Py_RETURN_TRUE;
        1310                 :            :     }
        1311                 :            :     else {
        1312                 :          0 :         Py_RETURN_FALSE;
        1313                 :            :     }
        1314                 :            : }
        1315                 :            :
        1316                 :            : static Py_hash_t
        1317                 :          0 : wrapper_hash(wrapperobject *wp)
        1318                 :            : {
        1319                 :            :     Py_hash_t x, y;
        1320                 :          0 :     x = _Py_HashPointer(wp->self);
        1321                 :          0 :     y = _Py_HashPointer(wp->descr);
        1322                 :          0 :     x = x ^ y;
        1323         [ #  # ]:          0 :     if (x == -1)
        1324                 :          0 :         x = -2;
        1325                 :          0 :     return x;
        1326                 :            : }
        1327                 :            :
        1328                 :            : static PyObject *
        1329                 :          0 : wrapper_repr(wrapperobject *wp)
        1330                 :            : {
        1331                 :          0 :     return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
        1332                 :          0 :                                wp->descr->d_base->name,
        1333                 :          0 :                                Py_TYPE(wp->self)->tp_name,
        1334                 :            :                                wp->self);
        1335                 :            : }
        1336                 :            :
        1337                 :            : static PyObject *
        1338                 :          0 : wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
        1339                 :            : {
        1340                 :          0 :     return Py_BuildValue("N(OO)", _PyEval_GetBuiltin(&_Py_ID(getattr)),
        1341                 :          0 :                          wp->self, PyDescr_NAME(wp->descr));
        1342                 :            : }
        1343                 :            :
        1344                 :            : static PyMethodDef wrapper_methods[] = {
        1345                 :            :     {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
        1346                 :            :     {NULL, NULL}
        1347                 :            : };
        1348                 :            :
        1349                 :            : static PyMemberDef wrapper_members[] = {
        1350                 :            :     {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
        1351                 :            :     {0}
        1352                 :            : };
        1353                 :            :
        1354                 :            : static PyObject *
        1355                 :          0 : wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored))
        1356                 :            : {
        1357                 :          0 :     PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
        1358                 :            :
        1359                 :          0 :     return Py_NewRef(c);
        1360                 :            : }
        1361                 :            :
        1362                 :            : static PyObject *
        1363                 :          0 : wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
        1364                 :            : {
        1365                 :          0 :     const char *s = wp->descr->d_base->name;
        1366                 :            :
        1367                 :          0 :     return PyUnicode_FromString(s);
        1368                 :            : }
        1369                 :            :
        1370                 :            : static PyObject *
        1371                 :          0 : wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored))
        1372                 :            : {
        1373                 :          0 :     return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
        1374                 :            : }
        1375                 :            :
        1376                 :            : static PyObject *
        1377                 :          0 : wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
        1378                 :            : {
        1379                 :          0 :     return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
        1380                 :            : }
        1381                 :            :
        1382                 :            : static PyObject *
        1383                 :          0 : wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored))
        1384                 :            : {
        1385                 :          0 :     return descr_get_qualname((PyDescrObject *)wp->descr, NULL);
        1386                 :            : }
        1387                 :            :
        1388                 :            : static PyGetSetDef wrapper_getsets[] = {
        1389                 :            :     {"__objclass__", (getter)wrapper_objclass},
        1390                 :            :     {"__name__", (getter)wrapper_name},
        1391                 :            :     {"__qualname__", (getter)wrapper_qualname},
        1392                 :            :     {"__doc__", (getter)wrapper_doc},
        1393                 :            :     {"__text_signature__", (getter)wrapper_text_signature},
        1394                 :            :     {0}
        1395                 :            : };
        1396                 :            :
        1397                 :            : static PyObject *
        1398                 :       2443 : wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
        1399                 :            : {
        1400                 :       2443 :     return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
        1401                 :            : }
        1402                 :            :
        1403                 :            : static int
        1404                 :         74 : wrapper_traverse(PyObject *self, visitproc visit, void *arg)
        1405                 :            : {
        1406                 :         74 :     wrapperobject *wp = (wrapperobject *)self;
        1407   [ +  -  -  + ]:         74 :     Py_VISIT(wp->descr);
        1408   [ +  -  -  + ]:         74 :     Py_VISIT(wp->self);
        1409                 :         74 :     return 0;
        1410                 :            : }
        1411                 :            :
        1412                 :            : PyTypeObject _PyMethodWrapper_Type = {
        1413                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
        1414                 :            :     "method-wrapper",                           /* tp_name */
        1415                 :            :     sizeof(wrapperobject),                      /* tp_basicsize */
        1416                 :            :     0,                                          /* tp_itemsize */
        1417                 :            :     /* methods */
        1418                 :            :     (destructor)wrapper_dealloc,                /* tp_dealloc */
        1419                 :            :     0,                                          /* tp_vectorcall_offset */
        1420                 :            :     0,                                          /* tp_getattr */
        1421                 :            :     0,                                          /* tp_setattr */
        1422                 :            :     0,                                          /* tp_as_async */
        1423                 :            :     (reprfunc)wrapper_repr,                     /* tp_repr */
        1424                 :            :     0,                                          /* tp_as_number */
        1425                 :            :     0,                                          /* tp_as_sequence */
        1426                 :            :     0,                                          /* tp_as_mapping */
        1427                 :            :     (hashfunc)wrapper_hash,                     /* tp_hash */
        1428                 :            :     (ternaryfunc)wrapper_call,                  /* tp_call */
        1429                 :            :     0,                                          /* tp_str */
        1430                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
        1431                 :            :     0,                                          /* tp_setattro */
        1432                 :            :     0,                                          /* tp_as_buffer */
        1433                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
        1434                 :            :     0,                                          /* tp_doc */
        1435                 :            :     wrapper_traverse,                           /* tp_traverse */
        1436                 :            :     0,                                          /* tp_clear */
        1437                 :            :     wrapper_richcompare,                        /* tp_richcompare */
        1438                 :            :     0,                                          /* tp_weaklistoffset */
        1439                 :            :     0,                                          /* tp_iter */
        1440                 :            :     0,                                          /* tp_iternext */
        1441                 :            :     wrapper_methods,                            /* tp_methods */
        1442                 :            :     wrapper_members,                            /* tp_members */
        1443                 :            :     wrapper_getsets,                            /* tp_getset */
        1444                 :            :     0,                                          /* tp_base */
        1445                 :            :     0,                                          /* tp_dict */
        1446                 :            :     0,                                          /* tp_descr_get */
        1447                 :            :     0,                                          /* tp_descr_set */
        1448                 :            : };
        1449                 :            :
        1450                 :            : PyObject *
        1451                 :       2457 : PyWrapper_New(PyObject *d, PyObject *self)
        1452                 :            : {
        1453                 :            :     wrapperobject *wp;
        1454                 :            :     PyWrapperDescrObject *descr;
        1455                 :            :
        1456                 :            :     assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
        1457                 :       2457 :     descr = (PyWrapperDescrObject *)d;
        1458                 :            :     assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
        1459                 :            :                                     (PyObject *)PyDescr_TYPE(descr)));
        1460                 :            :
        1461                 :       2457 :     wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
        1462         [ +  - ]:       2457 :     if (wp != NULL) {
        1463                 :       2457 :         wp->descr = (PyWrapperDescrObject*)Py_NewRef(descr);
        1464                 :       2457 :         wp->self = Py_NewRef(self);
        1465                 :       2457 :         _PyObject_GC_TRACK(wp);
        1466                 :            :     }
        1467                 :       2457 :     return (PyObject *)wp;
        1468                 :            : }
        1469                 :            :
        1470                 :            :
        1471                 :            : /* A built-in 'property' type */
        1472                 :            :
        1473                 :            : /*
        1474                 :            : class property(object):
        1475                 :            :
        1476                 :            :     def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        1477                 :            :         if doc is None and fget is not None and hasattr(fget, "__doc__"):
        1478                 :            :             doc = fget.__doc__
        1479                 :            :         self.__get = fget
        1480                 :            :         self.__set = fset
        1481                 :            :         self.__del = fdel
        1482                 :            :         self.__doc__ = doc
        1483                 :            :
        1484                 :            :     def __get__(self, inst, type=None):
        1485                 :            :         if inst is None:
        1486                 :            :             return self
        1487                 :            :         if self.__get is None:
        1488                 :            :             raise AttributeError, "property has no getter"
        1489                 :            :         return self.__get(inst)
        1490                 :            :
        1491                 :            :     def __set__(self, inst, value):
        1492                 :            :         if self.__set is None:
        1493                 :            :             raise AttributeError, "property has no setter"
        1494                 :            :         return self.__set(inst, value)
        1495                 :            :
        1496                 :            :     def __delete__(self, inst):
        1497                 :            :         if self.__del is None:
        1498                 :            :             raise AttributeError, "property has no deleter"
        1499                 :            :         return self.__del(inst)
        1500                 :            :
        1501                 :            : */
        1502                 :            :
        1503                 :            : static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
        1504                 :            :                                   PyObject *);
        1505                 :            :
        1506                 :            : static PyMemberDef property_members[] = {
        1507                 :            :     {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
        1508                 :            :     {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
        1509                 :            :     {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
        1510                 :            :     {"__doc__",  T_OBJECT, offsetof(propertyobject, prop_doc), 0},
        1511                 :            :     {0}
        1512                 :            : };
        1513                 :            :
        1514                 :            :
        1515                 :            : PyDoc_STRVAR(getter_doc,
        1516                 :            :              "Descriptor to obtain a copy of the property with a different getter.");
        1517                 :            :
        1518                 :            : static PyObject *
        1519                 :          0 : property_getter(PyObject *self, PyObject *getter)
        1520                 :            : {
        1521                 :          0 :     return property_copy(self, getter, NULL, NULL);
        1522                 :            : }
        1523                 :            :
        1524                 :            :
        1525                 :            : PyDoc_STRVAR(setter_doc,
        1526                 :            :              "Descriptor to obtain a copy of the property with a different setter.");
        1527                 :            :
        1528                 :            : static PyObject *
        1529                 :         78 : property_setter(PyObject *self, PyObject *setter)
        1530                 :            : {
        1531                 :         78 :     return property_copy(self, NULL, setter, NULL);
        1532                 :            : }
        1533                 :            :
        1534                 :            :
        1535                 :            : PyDoc_STRVAR(deleter_doc,
        1536                 :            :              "Descriptor to obtain a copy of the property with a different deleter.");
        1537                 :            :
        1538                 :            : static PyObject *
        1539                 :          0 : property_deleter(PyObject *self, PyObject *deleter)
        1540                 :            : {
        1541                 :          0 :     return property_copy(self, NULL, NULL, deleter);
        1542                 :            : }
        1543                 :            :
        1544                 :            :
        1545                 :            : PyDoc_STRVAR(set_name_doc,
        1546                 :            :              "Method to set name of a property.");
        1547                 :            :
        1548                 :            : static PyObject *
        1549                 :        368 : property_set_name(PyObject *self, PyObject *args) {
        1550         [ -  + ]:        368 :     if (PyTuple_GET_SIZE(args) != 2) {
        1551                 :          0 :         PyErr_Format(
        1552                 :            :                 PyExc_TypeError,
        1553                 :            :                 "__set_name__() takes 2 positional arguments but %d were given",
        1554                 :            :                 PyTuple_GET_SIZE(args));
        1555                 :          0 :         return NULL;
        1556                 :            :     }
        1557                 :            :
        1558                 :        368 :     propertyobject *prop = (propertyobject *)self;
        1559                 :        368 :     PyObject *name = PyTuple_GET_ITEM(args, 1);
        1560                 :            :
        1561                 :        368 :     Py_XSETREF(prop->prop_name, Py_XNewRef(name));
        1562                 :            :
        1563                 :        368 :     Py_RETURN_NONE;
        1564                 :            : }
        1565                 :            :
        1566                 :            : static PyMethodDef property_methods[] = {
        1567                 :            :     {"getter", property_getter, METH_O, getter_doc},
        1568                 :            :     {"setter", property_setter, METH_O, setter_doc},
        1569                 :            :     {"deleter", property_deleter, METH_O, deleter_doc},
        1570                 :            :     {"__set_name__", property_set_name, METH_VARARGS, set_name_doc},
        1571                 :            :     {0}
        1572                 :            : };
        1573                 :            :
        1574                 :            :
        1575                 :            : static void
        1576                 :        416 : property_dealloc(PyObject *self)
        1577                 :            : {
        1578                 :        416 :     propertyobject *gs = (propertyobject *)self;
        1579                 :            :
        1580                 :        416 :     _PyObject_GC_UNTRACK(self);
        1581                 :        416 :     Py_XDECREF(gs->prop_get);
        1582                 :        416 :     Py_XDECREF(gs->prop_set);
        1583                 :        416 :     Py_XDECREF(gs->prop_del);
        1584                 :        416 :     Py_XDECREF(gs->prop_doc);
        1585                 :        416 :     Py_XDECREF(gs->prop_name);
        1586                 :        416 :     Py_TYPE(self)->tp_free(self);
        1587                 :        416 : }
        1588                 :            :
        1589                 :            : static PyObject *
        1590                 :       1253 : property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
        1591                 :            : {
        1592   [ +  +  -  + ]:       1253 :     if (obj == NULL || obj == Py_None) {
        1593                 :         13 :         return Py_NewRef(self);
        1594                 :            :     }
        1595                 :            :
        1596                 :       1240 :     propertyobject *gs = (propertyobject *)self;
        1597         [ -  + ]:       1240 :     if (gs->prop_get == NULL) {
        1598                 :          0 :         PyObject *qualname = PyType_GetQualName(Py_TYPE(obj));
        1599   [ #  #  #  # ]:          0 :         if (gs->prop_name != NULL && qualname != NULL) {
        1600                 :          0 :             PyErr_Format(PyExc_AttributeError,
        1601                 :            :                          "property %R of %R object has no getter",
        1602                 :            :                          gs->prop_name,
        1603                 :            :                          qualname);
        1604                 :            :         }
        1605         [ #  # ]:          0 :         else if (qualname != NULL) {
        1606                 :          0 :             PyErr_Format(PyExc_AttributeError,
        1607                 :            :                          "property of %R object has no getter",
        1608                 :            :                          qualname);
        1609                 :            :         } else {
        1610                 :          0 :             PyErr_SetString(PyExc_AttributeError,
        1611                 :            :                             "property has no getter");
        1612                 :            :         }
        1613                 :          0 :         Py_XDECREF(qualname);
        1614                 :          0 :         return NULL;
        1615                 :            :     }
        1616                 :            :
        1617                 :       1240 :     return PyObject_CallOneArg(gs->prop_get, obj);
        1618                 :            : }
        1619                 :            :
        1620                 :            : static int
        1621                 :        101 : property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
        1622                 :            : {
        1623                 :        101 :     propertyobject *gs = (propertyobject *)self;
        1624                 :            :     PyObject *func, *res;
        1625                 :            :
        1626         [ -  + ]:        101 :     if (value == NULL) {
        1627                 :          0 :         func = gs->prop_del;
        1628                 :            :     }
        1629                 :            :     else {
        1630                 :        101 :         func = gs->prop_set;
        1631                 :            :     }
        1632                 :            :
        1633         [ -  + ]:        101 :     if (func == NULL) {
        1634                 :          0 :         PyObject *qualname = NULL;
        1635         [ #  # ]:          0 :         if (obj != NULL) {
        1636                 :          0 :             qualname = PyType_GetQualName(Py_TYPE(obj));
        1637                 :            :         }
        1638   [ #  #  #  # ]:          0 :         if (gs->prop_name != NULL && qualname != NULL) {
        1639         [ #  # ]:          0 :             PyErr_Format(PyExc_AttributeError,
        1640                 :            :                         value == NULL ?
        1641                 :            :                         "property %R of %R object has no deleter" :
        1642                 :            :                         "property %R of %R object has no setter",
        1643                 :            :                         gs->prop_name,
        1644                 :            :                         qualname);
        1645                 :            :         }
        1646         [ #  # ]:          0 :         else if (qualname != NULL) {
        1647         [ #  # ]:          0 :             PyErr_Format(PyExc_AttributeError,
        1648                 :            :                             value == NULL ?
        1649                 :            :                             "property of %R object has no deleter" :
        1650                 :            :                             "property of %R object has no setter",
        1651                 :            :                             qualname);
        1652                 :            :         }
        1653                 :            :         else {
        1654         [ #  # ]:          0 :             PyErr_SetString(PyExc_AttributeError,
        1655                 :            :                          value == NULL ?
        1656                 :            :                          "property has no deleter" :
        1657                 :            :                          "property has no setter");
        1658                 :            :         }
        1659                 :          0 :         Py_XDECREF(qualname);
        1660                 :          0 :         return -1;
        1661                 :            :     }
        1662                 :            :
        1663         [ -  + ]:        101 :     if (value == NULL) {
        1664                 :          0 :         res = PyObject_CallOneArg(func, obj);
        1665                 :            :     }
        1666                 :            :     else {
        1667                 :            :         EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
        1668                 :        101 :         PyObject *args[] = { obj, value };
        1669                 :        101 :         res = PyObject_Vectorcall(func, args, 2, NULL);
        1670                 :            :     }
        1671                 :            :
        1672         [ -  + ]:        101 :     if (res == NULL) {
        1673                 :          0 :         return -1;
        1674                 :            :     }
        1675                 :            :
        1676                 :        101 :     Py_DECREF(res);
        1677                 :        101 :     return 0;
        1678                 :            : }
        1679                 :            :
        1680                 :            : static PyObject *
        1681                 :         78 : property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
        1682                 :            : {
        1683                 :         78 :     propertyobject *pold = (propertyobject *)old;
        1684                 :            :     PyObject *new, *type, *doc;
        1685                 :            :
        1686                 :         78 :     type = PyObject_Type(old);
        1687         [ -  + ]:         78 :     if (type == NULL)
        1688                 :          0 :         return NULL;
        1689                 :            :
        1690   [ -  +  -  - ]:         78 :     if (get == NULL || get == Py_None) {
        1691                 :         78 :         Py_XDECREF(get);
        1692         [ +  - ]:         78 :         get = pold->prop_get ? pold->prop_get : Py_None;
        1693                 :            :     }
        1694   [ +  -  -  + ]:         78 :     if (set == NULL || set == Py_None) {
        1695                 :          0 :         Py_XDECREF(set);
        1696         [ #  # ]:          0 :         set = pold->prop_set ? pold->prop_set : Py_None;
        1697                 :            :     }
        1698   [ -  +  -  - ]:         78 :     if (del == NULL || del == Py_None) {
        1699                 :         78 :         Py_XDECREF(del);
        1700         [ -  + ]:         78 :         del = pold->prop_del ? pold->prop_del : Py_None;
        1701                 :            :     }
        1702   [ +  +  +  - ]:         78 :     if (pold->getter_doc && get != Py_None) {
        1703                 :            :         /* make _init use __doc__ from getter */
        1704                 :         17 :         doc = Py_None;
        1705                 :            :     }
        1706                 :            :     else {
        1707         [ -  + ]:         61 :         doc = pold->prop_doc ? pold->prop_doc : Py_None;
        1708                 :            :     }
        1709                 :            :
        1710                 :         78 :     new =  PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
        1711                 :         78 :     Py_DECREF(type);
        1712         [ -  + ]:         78 :     if (new == NULL)
        1713                 :          0 :         return NULL;
        1714                 :            :
        1715         [ +  - ]:         78 :     if (PyObject_TypeCheck((new), &PyProperty_Type)) {
        1716                 :         78 :         Py_XSETREF(((propertyobject *) new)->prop_name, Py_XNewRef(pold->prop_name));
        1717                 :            :     }
        1718                 :         78 :     return new;
        1719                 :            : }
        1720                 :            :
        1721                 :            : /*[clinic input]
        1722                 :            : property.__init__ as property_init
        1723                 :            :
        1724                 :            :     fget: object(c_default="NULL") = None
        1725                 :            :         function to be used for getting an attribute value
        1726                 :            :     fset: object(c_default="NULL") = None
        1727                 :            :         function to be used for setting an attribute value
        1728                 :            :     fdel: object(c_default="NULL") = None
        1729                 :            :         function to be used for del'ing an attribute
        1730                 :            :     doc: object(c_default="NULL") = None
        1731                 :            :         docstring
        1732                 :            :
        1733                 :            : Property attribute.
        1734                 :            :
        1735                 :            : Typical use is to define a managed attribute x:
        1736                 :            :
        1737                 :            : class C(object):
        1738                 :            :     def getx(self): return self._x
        1739                 :            :     def setx(self, value): self._x = value
        1740                 :            :     def delx(self): del self._x
        1741                 :            :     x = property(getx, setx, delx, "I'm the 'x' property.")
        1742                 :            :
        1743                 :            : Decorators make defining new properties or modifying existing ones easy:
        1744                 :            :
        1745                 :            : class C(object):
        1746                 :            :     @property
        1747                 :            :     def x(self):
        1748                 :            :         "I am the 'x' property."
        1749                 :            :         return self._x
        1750                 :            :     @x.setter
        1751                 :            :     def x(self, value):
        1752                 :            :         self._x = value
        1753                 :            :     @x.deleter
        1754                 :            :     def x(self):
        1755                 :            :         del self._x
        1756                 :            : [clinic start generated code]*/
        1757                 :            :
        1758                 :            : static int
        1759                 :        438 : property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
        1760                 :            :                    PyObject *fdel, PyObject *doc)
        1761                 :            : /*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
        1762                 :            : {
        1763         [ -  + ]:        438 :     if (fget == Py_None)
        1764                 :          0 :         fget = NULL;
        1765         [ -  + ]:        438 :     if (fset == Py_None)
        1766                 :          0 :         fset = NULL;
        1767         [ +  + ]:        438 :     if (fdel == Py_None)
        1768                 :         78 :         fdel = NULL;
        1769                 :            :
        1770                 :        438 :     Py_XSETREF(self->prop_get, Py_XNewRef(fget));
        1771                 :        438 :     Py_XSETREF(self->prop_set, Py_XNewRef(fset));
        1772                 :        438 :     Py_XSETREF(self->prop_del, Py_XNewRef(fdel));
        1773                 :        438 :     Py_XSETREF(self->prop_doc, NULL);
        1774                 :        438 :     Py_XSETREF(self->prop_name, NULL);
        1775                 :            :
        1776                 :        438 :     self->getter_doc = 0;
        1777                 :        438 :     PyObject *prop_doc = NULL;
        1778                 :            :
        1779   [ +  +  +  + ]:        438 :     if (doc != NULL && doc != Py_None) {
        1780                 :          2 :         prop_doc = Py_XNewRef(doc);
        1781                 :            :     }
        1782                 :            :     /* if no docstring given and the getter has one, use that one */
        1783         [ +  - ]:        436 :     else if (fget != NULL) {
        1784                 :        436 :         int rc = _PyObject_LookupAttr(fget, &_Py_ID(__doc__), &prop_doc);
        1785         [ -  + ]:        436 :         if (rc <= 0) {
        1786                 :          0 :             return rc;
        1787                 :            :         }
        1788         [ +  + ]:        436 :         if (prop_doc == Py_None) {
        1789                 :        283 :             prop_doc = NULL;
        1790                 :        283 :             Py_DECREF(Py_None);
        1791                 :            :         }
        1792         [ +  + ]:        436 :         if (prop_doc != NULL){
        1793                 :        153 :             self->getter_doc = 1;
        1794                 :            :         }
        1795                 :            :     }
        1796                 :            :
        1797                 :            :     /* At this point `prop_doc` is either NULL or
        1798                 :            :        a non-None object with incremented ref counter */
        1799                 :            :
        1800         [ +  - ]:        438 :     if (Py_IS_TYPE(self, &PyProperty_Type)) {
        1801                 :        438 :         Py_XSETREF(self->prop_doc, prop_doc);
        1802                 :            :     } else {
        1803                 :            :         /* If this is a property subclass, put __doc__
        1804                 :            :            in dict of the subclass instance instead,
        1805                 :            :            otherwise it gets shadowed by __doc__ in the
        1806                 :            :            class's dict. */
        1807                 :            :
        1808         [ #  # ]:          0 :         if (prop_doc == NULL) {
        1809                 :          0 :             prop_doc = Py_NewRef(Py_None);
        1810                 :            :         }
        1811                 :          0 :         int err = PyObject_SetAttr(
        1812                 :            :                     (PyObject *)self, &_Py_ID(__doc__), prop_doc);
        1813                 :          0 :         Py_XDECREF(prop_doc);
        1814         [ #  # ]:          0 :         if (err < 0)
        1815                 :          0 :             return -1;
        1816                 :            :     }
        1817                 :            :
        1818                 :        438 :     return 0;
        1819                 :            : }
        1820                 :            :
        1821                 :            : static PyObject *
        1822                 :         45 : property_get___isabstractmethod__(propertyobject *prop, void *closure)
        1823                 :            : {
        1824                 :         45 :     int res = _PyObject_IsAbstract(prop->prop_get);
        1825         [ -  + ]:         45 :     if (res == -1) {
        1826                 :          0 :         return NULL;
        1827                 :            :     }
        1828         [ +  + ]:         45 :     else if (res) {
        1829                 :          8 :         Py_RETURN_TRUE;
        1830                 :            :     }
        1831                 :            :
        1832                 :         37 :     res = _PyObject_IsAbstract(prop->prop_set);
        1833         [ -  + ]:         37 :     if (res == -1) {
        1834                 :          0 :         return NULL;
        1835                 :            :     }
        1836         [ -  + ]:         37 :     else if (res) {
        1837                 :          0 :         Py_RETURN_TRUE;
        1838                 :            :     }
        1839                 :            :
        1840                 :         37 :     res = _PyObject_IsAbstract(prop->prop_del);
        1841         [ -  + ]:         37 :     if (res == -1) {
        1842                 :          0 :         return NULL;
        1843                 :            :     }
        1844         [ -  + ]:         37 :     else if (res) {
        1845                 :          0 :         Py_RETURN_TRUE;
        1846                 :            :     }
        1847                 :         37 :     Py_RETURN_FALSE;
        1848                 :            : }
        1849                 :            :
        1850                 :            : static PyGetSetDef property_getsetlist[] = {
        1851                 :            :     {"__isabstractmethod__",
        1852                 :            :      (getter)property_get___isabstractmethod__, NULL,
        1853                 :            :      NULL,
        1854                 :            :      NULL},
        1855                 :            :     {NULL} /* Sentinel */
        1856                 :            : };
        1857                 :            :
        1858                 :            : static int
        1859                 :       4882 : property_traverse(PyObject *self, visitproc visit, void *arg)
        1860                 :            : {
        1861                 :       4882 :     propertyobject *pp = (propertyobject *)self;
        1862   [ +  -  -  + ]:       4882 :     Py_VISIT(pp->prop_get);
        1863   [ +  +  -  + ]:       4882 :     Py_VISIT(pp->prop_set);
        1864   [ -  +  -  - ]:       4882 :     Py_VISIT(pp->prop_del);
        1865   [ +  +  -  + ]:       4882 :     Py_VISIT(pp->prop_doc);
        1866   [ +  +  -  + ]:       4882 :     Py_VISIT(pp->prop_name);
        1867                 :       4882 :     return 0;
        1868                 :            : }
        1869                 :            :
        1870                 :            : static int
        1871                 :         21 : property_clear(PyObject *self)
        1872                 :            : {
        1873                 :         21 :     propertyobject *pp = (propertyobject *)self;
        1874         [ +  + ]:         21 :     Py_CLEAR(pp->prop_doc);
        1875                 :         21 :     return 0;
        1876                 :            : }
        1877                 :            :
        1878                 :            : #include "clinic/descrobject.c.h"
        1879                 :            :
        1880                 :            : PyTypeObject PyDictProxy_Type = {
        1881                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
        1882                 :            :     "mappingproxy",                             /* tp_name */
        1883                 :            :     sizeof(mappingproxyobject),                 /* tp_basicsize */
        1884                 :            :     0,                                          /* tp_itemsize */
        1885                 :            :     /* methods */
        1886                 :            :     (destructor)mappingproxy_dealloc,           /* tp_dealloc */
        1887                 :            :     0,                                          /* tp_vectorcall_offset */
        1888                 :            :     0,                                          /* tp_getattr */
        1889                 :            :     0,                                          /* tp_setattr */
        1890                 :            :     0,                                          /* tp_as_async */
        1891                 :            :     (reprfunc)mappingproxy_repr,                /* tp_repr */
        1892                 :            :     &mappingproxy_as_number,                    /* tp_as_number */
        1893                 :            :     &mappingproxy_as_sequence,                  /* tp_as_sequence */
        1894                 :            :     &mappingproxy_as_mapping,                   /* tp_as_mapping */
        1895                 :            :     (hashfunc)mappingproxy_hash,                /* tp_hash */
        1896                 :            :     0,                                          /* tp_call */
        1897                 :            :     (reprfunc)mappingproxy_str,                 /* tp_str */
        1898                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
        1899                 :            :     0,                                          /* tp_setattro */
        1900                 :            :     0,                                          /* tp_as_buffer */
        1901                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        1902                 :            :         Py_TPFLAGS_MAPPING,                     /* tp_flags */
        1903                 :            :     0,                                          /* tp_doc */
        1904                 :            :     mappingproxy_traverse,                      /* tp_traverse */
        1905                 :            :     0,                                          /* tp_clear */
        1906                 :            :     (richcmpfunc)mappingproxy_richcompare,      /* tp_richcompare */
        1907                 :            :     0,                                          /* tp_weaklistoffset */
        1908                 :            :     (getiterfunc)mappingproxy_getiter,          /* tp_iter */
        1909                 :            :     0,                                          /* tp_iternext */
        1910                 :            :     mappingproxy_methods,                       /* tp_methods */
        1911                 :            :     0,                                          /* tp_members */
        1912                 :            :     0,                                          /* tp_getset */
        1913                 :            :     0,                                          /* tp_base */
        1914                 :            :     0,                                          /* tp_dict */
        1915                 :            :     0,                                          /* tp_descr_get */
        1916                 :            :     0,                                          /* tp_descr_set */
        1917                 :            :     0,                                          /* tp_dictoffset */
        1918                 :            :     0,                                          /* tp_init */
        1919                 :            :     0,                                          /* tp_alloc */
        1920                 :            :     mappingproxy_new,                           /* tp_new */
        1921                 :            : };
        1922                 :            :
        1923                 :            : PyTypeObject PyProperty_Type = {
        1924                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
        1925                 :            :     "property",                                 /* tp_name */
        1926                 :            :     sizeof(propertyobject),                     /* tp_basicsize */
        1927                 :            :     0,                                          /* tp_itemsize */
        1928                 :            :     /* methods */
        1929                 :            :     property_dealloc,                           /* tp_dealloc */
        1930                 :            :     0,                                          /* tp_vectorcall_offset */
        1931                 :            :     0,                                          /* tp_getattr */
        1932                 :            :     0,                                          /* tp_setattr */
        1933                 :            :     0,                                          /* tp_as_async */
        1934                 :            :     0,                                          /* tp_repr */
        1935                 :            :     0,                                          /* tp_as_number */
        1936                 :            :     0,                                          /* tp_as_sequence */
        1937                 :            :     0,                                          /* tp_as_mapping */
        1938                 :            :     0,                                          /* tp_hash */
        1939                 :            :     0,                                          /* tp_call */
        1940                 :            :     0,                                          /* tp_str */
        1941                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
        1942                 :            :     0,                                          /* tp_setattro */
        1943                 :            :     0,                                          /* tp_as_buffer */
        1944                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        1945                 :            :         Py_TPFLAGS_BASETYPE,                    /* tp_flags */
        1946                 :            :     property_init__doc__,                       /* tp_doc */
        1947                 :            :     property_traverse,                          /* tp_traverse */
        1948                 :            :     (inquiry)property_clear,                    /* tp_clear */
        1949                 :            :     0,                                          /* tp_richcompare */
        1950                 :            :     0,                                          /* tp_weaklistoffset */
        1951                 :            :     0,                                          /* tp_iter */
        1952                 :            :     0,                                          /* tp_iternext */
        1953                 :            :     property_methods,                           /* tp_methods */
        1954                 :            :     property_members,                           /* tp_members */
        1955                 :            :     property_getsetlist,                        /* tp_getset */
        1956                 :            :     0,                                          /* tp_base */
        1957                 :            :     0,                                          /* tp_dict */
        1958                 :            :     property_descr_get,                         /* tp_descr_get */
        1959                 :            :     property_descr_set,                         /* tp_descr_set */
        1960                 :            :     0,                                          /* tp_dictoffset */
        1961                 :            :     property_init,                              /* tp_init */
        1962                 :            :     PyType_GenericAlloc,                        /* tp_alloc */
        1963                 :            :     PyType_GenericNew,                          /* tp_new */
        1964                 :            :     PyObject_GC_Del,                            /* tp_free */
        1965                 :            : };

Generated by: LCOV version 1.14