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