LCOV - code coverage report
Current view: top level - Objects - descrobject.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 630 683 92.2 %
Date: 2022-07-20 13:12:14 Functions: 88 91 96.7 %
Branches: 275 354 77.7 %

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

Generated by: LCOV version 1.14