LCOV - code coverage report
Current view: top level - Objects - descrobject.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 636 689 92.3 %
Date: 2022-07-07 18:19:46 Functions: 88 91 96.7 %

          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     7442590 : descr_dealloc(PyDescrObject *descr)
      38             : {
      39     7442590 :     _PyObject_GC_UNTRACK(descr);
      40     7442590 :     Py_XDECREF(descr->d_type);
      41     7442590 :     Py_XDECREF(descr->d_name);
      42     7442590 :     Py_XDECREF(descr->d_qualname);
      43     7442590 :     PyObject_GC_Del(descr);
      44     7442590 : }
      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          95 : descr_repr(PyDescrObject *descr, const char *format)
      56             : {
      57          95 :     PyObject *name = NULL;
      58          95 :     if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
      59          95 :         name = descr->d_name;
      60             : 
      61          95 :     return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name);
      62             : }
      63             : 
      64             : static PyObject *
      65          90 : method_repr(PyMethodDescrObject *descr)
      66             : {
      67          90 :     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   136035000 : descr_check(PyDescrObject *descr, PyObject *obj)
      94             : {
      95   136035000 :     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   136034000 :     return 0;
     105             : }
     106             : 
     107             : static PyObject *
     108     3387670 : classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
     109             : {
     110             :     /* Ensure a valid type.  Class methods ignore obj. */
     111     3387670 :     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     3387670 :     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     3387670 :     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     3387670 :     PyTypeObject *cls = NULL;
     143     3387670 :     if (descr->d_method->ml_flags & METH_METHOD) {
     144           0 :         cls = descr->d_common.d_type;
     145             :     }
     146     3387670 :     return PyCMethod_New(descr->d_method, type, NULL, cls);
     147             : }
     148             : 
     149             : static PyObject *
     150    25805700 : method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
     151             : {
     152    25805700 :     if (obj == NULL) {
     153      484275 :         return Py_NewRef(descr);
     154             :     }
     155    25321400 :     if (descr_check((PyDescrObject *)descr, obj) < 0) {
     156           3 :         return NULL;
     157             :     }
     158    25321400 :     if (descr->d_method->ml_flags & METH_METHOD) {
     159     3140900 :         if (PyType_Check(type)) {
     160     3140900 :             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    22180500 :         return PyCFunction_NewEx(descr->d_method, obj, NULL);
     170             :     }
     171             : }
     172             : 
     173             : static PyObject *
     174    12158800 : member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
     175             : {
     176    12158800 :     if (obj == NULL) {
     177        5425 :         return Py_NewRef(descr);
     178             :     }
     179    12153400 :     if (descr_check((PyDescrObject *)descr, obj) < 0) {
     180          55 :         return NULL;
     181             :     }
     182             : 
     183    12153300 :     if (descr->d_member->flags & PY_AUDIT_READ) {
     184      283431 :         if (PySys_Audit("object.__getattr__", "Os",
     185      283431 :             obj ? obj : Py_None, descr->d_member->name) < 0) {
     186           0 :             return NULL;
     187             :         }
     188             :     }
     189             : 
     190    12153300 :     return PyMember_GetOne((char *)obj, descr->d_member);
     191             : }
     192             : 
     193             : static PyObject *
     194    42326100 : getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
     195             : {
     196    42326100 :     if (obj == NULL) {
     197       13069 :         return Py_NewRef(descr);
     198             :     }
     199    42313000 :     if (descr_check((PyDescrObject *)descr, obj) < 0) {
     200           0 :         return NULL;
     201             :     }
     202    42313000 :     if (descr->d_getset->get != NULL)
     203    42313000 :         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     8226460 : wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
     214             : {
     215     8226460 :     if (obj == NULL) {
     216      198423 :         return Py_NewRef(descr);
     217             :     }
     218     8028040 :     if (descr_check((PyDescrObject *)descr, obj) < 0) {
     219           0 :         return NULL;
     220             :     }
     221     8028040 :     return PyWrapper_New((PyObject *)descr, obj);
     222             : }
     223             : 
     224             : static int
     225     4596510 : descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value)
     226             : {
     227     4596510 :     assert(obj != NULL);
     228     4596510 :     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     4596510 :     return 0;
     238             : }
     239             : 
     240             : static int
     241     3815840 : member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
     242             : {
     243     3815840 :     if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) {
     244           1 :         return -1;
     245             :     }
     246     3815840 :     return PyMember_SetOne((char *)obj, descr->d_member, value);
     247             : }
     248             : 
     249             : static int
     250      780669 : getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
     251             : {
     252      780669 :     if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) {
     253           1 :         return -1;
     254             :     }
     255      780668 :     if (descr->d_getset->set != NULL) {
     256      780639 :         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    48218800 : method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
     274             : {
     275    48218800 :     assert(!PyErr_Occurred());
     276    48218800 :     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    48218800 :     PyObject *self = args[0];
     286    48218800 :     if (descr_check((PyDescrObject *)func, self) < 0) {
     287         110 :         return -1;
     288             :     }
     289    48218700 :     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    48218700 :     return 0;
     299             : }
     300             : 
     301             : typedef void (*funcptr)(void);
     302             : 
     303             : static inline funcptr
     304    48218700 : method_enter_call(PyThreadState *tstate, PyObject *func)
     305             : {
     306    48218700 :     if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
     307           9 :         return NULL;
     308             :     }
     309    48218700 :     return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth;
     310             : }
     311             : 
     312             : /* Now the actual vectorcall functions */
     313             : static PyObject *
     314    15836200 : method_vectorcall_VARARGS(
     315             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     316             : {
     317    15836200 :     PyThreadState *tstate = _PyThreadState_GET();
     318    15836200 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     319    15836200 :     if (method_check_args(func, args, nargs, kwnames)) {
     320           1 :         return NULL;
     321             :     }
     322    15836200 :     PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
     323    15836200 :     if (argstuple == NULL) {
     324           0 :         return NULL;
     325             :     }
     326    15836200 :     PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
     327    15836200 :     if (meth == NULL) {
     328           1 :         Py_DECREF(argstuple);
     329           1 :         return NULL;
     330             :     }
     331    15836200 :     PyObject *result = _PyCFunction_TrampolineCall(
     332             :         meth, args[0], argstuple);
     333    15836200 :     Py_DECREF(argstuple);
     334    15836200 :     _Py_LeaveRecursiveCallTstate(tstate);
     335    15836200 :     return result;
     336             : }
     337             : 
     338             : static PyObject *
     339     6469060 : method_vectorcall_VARARGS_KEYWORDS(
     340             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     341             : {
     342     6469060 :     PyThreadState *tstate = _PyThreadState_GET();
     343     6469060 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     344     6469060 :     if (method_check_args(func, args, nargs, NULL)) {
     345           6 :         return NULL;
     346             :     }
     347     6469060 :     PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
     348     6469060 :     if (argstuple == NULL) {
     349           0 :         return NULL;
     350             :     }
     351     6469060 :     PyObject *result = NULL;
     352             :     /* Create a temporary dict for keyword arguments */
     353     6469060 :     PyObject *kwdict = NULL;
     354     6469060 :     if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) > 0) {
     355       36071 :         kwdict = _PyStack_AsDict(args + nargs, kwnames);
     356       36071 :         if (kwdict == NULL) {
     357           0 :             goto exit;
     358             :         }
     359             :     }
     360             :     PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords)
     361     6469060 :                                    method_enter_call(tstate, func);
     362     6469060 :     if (meth == NULL) {
     363           1 :         goto exit;
     364             :     }
     365     6469060 :     result = _PyCFunctionWithKeywords_TrampolineCall(
     366             :         meth, args[0], argstuple, kwdict);
     367     6469050 :     _Py_LeaveRecursiveCallTstate(tstate);
     368     6469050 : exit:
     369     6469050 :     Py_DECREF(argstuple);
     370     6469050 :     Py_XDECREF(kwdict);
     371     6469050 :     return result;
     372             : }
     373             : 
     374             : static PyObject *
     375    11259400 : method_vectorcall_FASTCALL_KEYWORDS_METHOD(
     376             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     377             : {
     378    11259400 :     PyThreadState *tstate = _PyThreadState_GET();
     379    11259400 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     380    11259400 :     if (method_check_args(func, args, nargs, NULL)) {
     381           0 :         return NULL;
     382             :     }
     383    11259400 :     PyCMethod meth = (PyCMethod) method_enter_call(tstate, func);
     384    11259400 :     if (meth == NULL) {
     385           0 :         return NULL;
     386             :     }
     387    11259400 :     PyObject *result = meth(args[0],
     388             :                             ((PyMethodDescrObject *)func)->d_common.d_type,
     389    11259400 :                             args+1, nargs-1, kwnames);
     390    11259400 :     _Py_LeaveRecursiveCall();
     391    11259400 :     return result;
     392             : }
     393             : 
     394             : static PyObject *
     395     2275880 : method_vectorcall_FASTCALL(
     396             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     397             : {
     398     2275880 :     PyThreadState *tstate = _PyThreadState_GET();
     399     2275880 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     400     2275880 :     if (method_check_args(func, args, nargs, kwnames)) {
     401          24 :         return NULL;
     402             :     }
     403             :     _PyCFunctionFast meth = (_PyCFunctionFast)
     404     2275860 :                             method_enter_call(tstate, func);
     405     2275860 :     if (meth == NULL) {
     406           1 :         return NULL;
     407             :     }
     408     2275860 :     PyObject *result = meth(args[0], args+1, nargs-1);
     409     2275860 :     _Py_LeaveRecursiveCallTstate(tstate);
     410     2275860 :     return result;
     411             : }
     412             : 
     413             : static PyObject *
     414      852525 : method_vectorcall_FASTCALL_KEYWORDS(
     415             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     416             : {
     417      852525 :     PyThreadState *tstate = _PyThreadState_GET();
     418      852525 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     419      852525 :     if (method_check_args(func, args, nargs, NULL)) {
     420          51 :         return NULL;
     421             :     }
     422             :     _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
     423      852474 :                                         method_enter_call(tstate, func);
     424      852474 :     if (meth == NULL) {
     425           0 :         return NULL;
     426             :     }
     427      852474 :     PyObject *result = meth(args[0], args+1, nargs-1, kwnames);
     428      852474 :     _Py_LeaveRecursiveCallTstate(tstate);
     429      852474 :     return result;
     430             : }
     431             : 
     432             : static PyObject *
     433     8637910 : method_vectorcall_NOARGS(
     434             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     435             : {
     436     8637910 :     PyThreadState *tstate = _PyThreadState_GET();
     437     8637910 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     438     8637910 :     if (method_check_args(func, args, nargs, kwnames)) {
     439          21 :         return NULL;
     440             :     }
     441     8637890 :     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     8637890 :     PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
     451     8637890 :     if (meth == NULL) {
     452           2 :         return NULL;
     453             :     }
     454     8637890 :     PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], NULL);
     455     8637840 :     _Py_LeaveRecursiveCallTstate(tstate);
     456     8637840 :     return result;
     457             : }
     458             : 
     459             : static PyObject *
     460     2887800 : method_vectorcall_O(
     461             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     462             : {
     463     2887800 :     PyThreadState *tstate = _PyThreadState_GET();
     464     2887800 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     465     2887800 :     if (method_check_args(func, args, nargs, kwnames)) {
     466          24 :         return NULL;
     467             :     }
     468     2887780 :     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     2887780 :     PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
     479     2887780 :     if (meth == NULL) {
     480           4 :         return NULL;
     481             :     }
     482     2887780 :     PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], args[1]);
     483     2887770 :     _Py_LeaveRecursiveCallTstate(tstate);
     484     2887770 :     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    12599100 : wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self,
     522             :                       PyObject *args, PyObject *kwds)
     523             : {
     524    12599100 :     wrapperfunc wrapper = descr->d_base->wrapper;
     525             : 
     526    12599100 :     if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
     527     5047910 :         wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper;
     528     5047910 :         return (*wk)(self, args, descr->d_wrapped, kwds);
     529             :     }
     530             : 
     531     7551180 :     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     7551180 :     return (*wrapper)(self, args, descr->d_wrapped);
     538             : }
     539             : 
     540             : static PyObject *
     541     3568990 : 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     3568990 :     assert(PyTuple_Check(args));
     548     3568990 :     argc = PyTuple_GET_SIZE(args);
     549     3568990 :     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     3568980 :     self = PyTuple_GET_ITEM(args, 0);
     558     3568980 :     if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
     559     3568980 :                                   (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     3568980 :     args = PyTuple_GetSlice(args, 1, argc);
     571     3568980 :     if (args == NULL) {
     572           0 :         return NULL;
     573             :     }
     574     3568980 :     result = wrapperdescr_raw_call(descr, self, args, kwds);
     575     3568980 :     Py_DECREF(args);
     576     3568980 :     return result;
     577             : }
     578             : 
     579             : 
     580             : static PyObject *
     581        2473 : method_get_doc(PyMethodDescrObject *descr, void *closure)
     582             : {
     583        2473 :     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   190273000 : descr_traverse(PyObject *self, visitproc visit, void *arg)
     705             : {
     706   190273000 :     PyDescrObject *descr = (PyDescrObject *)self;
     707   190273000 :     Py_VISIT(descr->d_type);
     708   190273000 :     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     8241170 : descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
     902             : {
     903             :     PyDescrObject *descr;
     904             : 
     905     8241170 :     descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
     906     8241170 :     if (descr != NULL) {
     907     8241170 :         Py_XINCREF(type);
     908     8241170 :         descr->d_type = type;
     909     8241170 :         descr->d_name = PyUnicode_InternFromString(name);
     910     8241170 :         if (descr->d_name == NULL) {
     911           0 :             Py_DECREF(descr);
     912           0 :             descr = NULL;
     913             :         }
     914             :         else {
     915     8241170 :             descr->d_qualname = NULL;
     916             :         }
     917             :     }
     918     8241170 :     return descr;
     919             : }
     920             : 
     921             : PyObject *
     922     2273040 : PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
     923             : {
     924             :     /* Figure out correct vectorcall function to use */
     925             :     vectorcallfunc vectorcall;
     926     2273040 :     switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS |
     927             :                                 METH_O | METH_KEYWORDS | METH_METHOD))
     928             :     {
     929      215740 :         case METH_VARARGS:
     930      215740 :             vectorcall = method_vectorcall_VARARGS;
     931      215740 :             break;
     932       31135 :         case METH_VARARGS | METH_KEYWORDS:
     933       31135 :             vectorcall = method_vectorcall_VARARGS_KEYWORDS;
     934       31135 :             break;
     935      248803 :         case METH_FASTCALL:
     936      248803 :             vectorcall = method_vectorcall_FASTCALL;
     937      248803 :             break;
     938      127087 :         case METH_FASTCALL | METH_KEYWORDS:
     939      127087 :             vectorcall = method_vectorcall_FASTCALL_KEYWORDS;
     940      127087 :             break;
     941     1180650 :         case METH_NOARGS:
     942     1180650 :             vectorcall = method_vectorcall_NOARGS;
     943     1180650 :             break;
     944      417044 :         case METH_O:
     945      417044 :             vectorcall = method_vectorcall_O;
     946      417044 :             break;
     947       52577 :         case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
     948       52577 :             vectorcall = method_vectorcall_FASTCALL_KEYWORDS_METHOD;
     949       52577 :             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     2273040 :     descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
     959             :                                              type, method->ml_name);
     960     2273040 :     if (descr != NULL) {
     961     2273040 :         descr->d_method = method;
     962     2273040 :         descr->vectorcall = vectorcall;
     963             :     }
     964     2273040 :     return (PyObject *)descr;
     965             : }
     966             : 
     967             : PyObject *
     968       97156 : PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
     969             : {
     970             :     PyMethodDescrObject *descr;
     971             : 
     972       97156 :     descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
     973             :                                              type, method->ml_name);
     974       97156 :     if (descr != NULL)
     975       97156 :         descr->d_method = method;
     976       97156 :     return (PyObject *)descr;
     977             : }
     978             : 
     979             : PyObject *
     980     1031600 : PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
     981             : {
     982             :     PyMemberDescrObject *descr;
     983             : 
     984     1031600 :     descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
     985             :                                              type, member->name);
     986     1031600 :     if (descr != NULL)
     987     1031600 :         descr->d_member = member;
     988     1031600 :     return (PyObject *)descr;
     989             : }
     990             : 
     991             : PyObject *
     992     1409630 : PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
     993             : {
     994             :     PyGetSetDescrObject *descr;
     995             : 
     996     1409630 :     descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
     997             :                                              type, getset->name);
     998     1409630 :     if (descr != NULL)
     999     1409630 :         descr->d_getset = getset;
    1000     1409630 :     return (PyObject *)descr;
    1001             : }
    1002             : 
    1003             : PyObject *
    1004     3429750 : PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
    1005             : {
    1006             :     PyWrapperDescrObject *descr;
    1007             : 
    1008     3429750 :     descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
    1009             :                                              type, base->name);
    1010     3429750 :     if (descr != NULL) {
    1011     3429750 :         descr->d_base = base;
    1012     3429750 :         descr->d_wrapped = wrapped;
    1013             :     }
    1014     3429750 :     return (PyObject *)descr;
    1015             : }
    1016             : 
    1017             : int
    1018    90303300 : PyDescr_IsData(PyObject *ob)
    1019             : {
    1020    90303300 :     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        6873 : mappingproxy_len(mappingproxyobject *pp)
    1035             : {
    1036        6873 :     return PyObject_Size(pp->mapping);
    1037             : }
    1038             : 
    1039             : static PyObject *
    1040     2111180 : mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
    1041             : {
    1042     2111180 :     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      341782 : mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
    1077             : {
    1078      341782 :     if (PyDict_CheckExact(pp->mapping))
    1079      341773 :         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      658903 : mappingproxy_get(mappingproxyobject *pp, PyObject *const *args, Py_ssize_t nargs)
    1099             : {
    1100             :     /* newargs: mapping, key, default=None */
    1101             :     PyObject *newargs[3];
    1102      658903 :     newargs[0] = pp->mapping;
    1103      658903 :     newargs[2] = Py_None;
    1104             : 
    1105      658903 :     if (!_PyArg_UnpackStack(args, nargs, "get", 1, 2,
    1106             :                             &newargs[1], &newargs[2]))
    1107             :     {
    1108           0 :         return NULL;
    1109             :     }
    1110      658903 :     return _PyObject_VectorcallMethod(&_Py_ID(get), newargs,
    1111             :                                         3 | PY_VECTORCALL_ARGUMENTS_OFFSET,
    1112             :                                         NULL);
    1113             : }
    1114             : 
    1115             : static PyObject *
    1116       96885 : mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
    1117             : {
    1118       96885 :     return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(keys));
    1119             : }
    1120             : 
    1121             : static PyObject *
    1122       15054 : mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
    1123             : {
    1124       15054 :     return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(values));
    1125             : }
    1126             : 
    1127             : static PyObject *
    1128      200002 : mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
    1129             : {
    1130      200002 :     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     1462780 : mappingproxy_dealloc(mappingproxyobject *pp)
    1169             : {
    1170     1462780 :     _PyObject_GC_UNTRACK(pp);
    1171     1462780 :     Py_DECREF(pp->mapping);
    1172     1462780 :     PyObject_GC_Del(pp);
    1173     1462780 : }
    1174             : 
    1175             : static PyObject *
    1176        9103 : mappingproxy_getiter(mappingproxyobject *pp)
    1177             : {
    1178        9103 :     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       77687 : mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
    1201             : {
    1202       77687 :     mappingproxyobject *pp = (mappingproxyobject *)self;
    1203       77687 :     Py_VISIT(pp->mapping);
    1204       77687 :     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     1462790 : mappingproxy_check_mapping(PyObject *mapping)
    1215             : {
    1216     1462790 :     if (!PyMapping_Check(mapping)
    1217     1462780 :         || PyList_Check(mapping)
    1218     1462780 :         || 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     1462780 :     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       27844 : mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping)
    1237             : /*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/
    1238             : {
    1239             :     mappingproxyobject *mappingproxy;
    1240             : 
    1241       27844 :     if (mappingproxy_check_mapping(mapping) == -1)
    1242           4 :         return NULL;
    1243             : 
    1244       27840 :     mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
    1245       27840 :     if (mappingproxy == NULL)
    1246           0 :         return NULL;
    1247       27840 :     Py_INCREF(mapping);
    1248       27840 :     mappingproxy->mapping = mapping;
    1249       27840 :     _PyObject_GC_TRACK(mappingproxy);
    1250       27840 :     return (PyObject *)mappingproxy;
    1251             : }
    1252             : 
    1253             : PyObject *
    1254     1434940 : PyDictProxy_New(PyObject *mapping)
    1255             : {
    1256             :     mappingproxyobject *pp;
    1257             : 
    1258     1434940 :     if (mappingproxy_check_mapping(mapping) == -1)
    1259           0 :         return NULL;
    1260             : 
    1261     1434940 :     pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
    1262     1434940 :     if (pp != NULL) {
    1263     1434940 :         Py_INCREF(mapping);
    1264     1434940 :         pp->mapping = mapping;
    1265     1434940 :         _PyObject_GC_TRACK(pp);
    1266             :     }
    1267     1434940 :     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     8048440 : wrapper_dealloc(wrapperobject *wp)
    1286             : {
    1287     8048440 :     PyObject_GC_UnTrack(wp);
    1288     8048440 :     Py_TRASHCAN_BEGIN(wp, wrapper_dealloc)
    1289     8028040 :     Py_XDECREF(wp->descr);
    1290     8028040 :     Py_XDECREF(wp->self);
    1291     8028040 :     PyObject_GC_Del(wp);
    1292     8028040 :     Py_TRASHCAN_END
    1293     8048440 : }
    1294             : 
    1295             : static PyObject *
    1296          14 : wrapper_richcompare(PyObject *a, PyObject *b, int op)
    1297             : {
    1298             :     wrapperobject *wa, *wb;
    1299             :     int eq;
    1300             : 
    1301          14 :     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      138378 : wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
    1370             : {
    1371      138378 :     const char *s = wp->descr->d_base->name;
    1372             : 
    1373      138378 :     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     9030110 : wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
    1405             : {
    1406     9030110 :     return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
    1407             : }
    1408             : 
    1409             : static int
    1410    11345700 : wrapper_traverse(PyObject *self, visitproc visit, void *arg)
    1411             : {
    1412    11345700 :     wrapperobject *wp = (wrapperobject *)self;
    1413    11345700 :     Py_VISIT(wp->descr);
    1414    11345700 :     Py_VISIT(wp->self);
    1415    11345700 :     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     8028040 : PyWrapper_New(PyObject *d, PyObject *self)
    1458             : {
    1459             :     wrapperobject *wp;
    1460             :     PyWrapperDescrObject *descr;
    1461             : 
    1462     8028040 :     assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
    1463     8028040 :     descr = (PyWrapperDescrObject *)d;
    1464     8028040 :     assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
    1465             :                                     (PyObject *)PyDescr_TYPE(descr)));
    1466             : 
    1467     8028040 :     wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
    1468     8028040 :     if (wp != NULL) {
    1469     8028040 :         Py_INCREF(descr);
    1470     8028040 :         wp->descr = descr;
    1471     8028040 :         Py_INCREF(self);
    1472     8028040 :         wp->self = self;
    1473     8028040 :         _PyObject_GC_TRACK(wp);
    1474             :     }
    1475     8028040 :     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       25011 : property_setter(PyObject *self, PyObject *setter)
    1538             : {
    1539       25011 :     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          77 : property_deleter(PyObject *self, PyObject *deleter)
    1548             : {
    1549          77 :     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      162493 : property_set_name(PyObject *self, PyObject *args) {
    1558      162493 :     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      162490 :     propertyobject *prop = (propertyobject *)self;
    1567      162490 :     PyObject *name = PyTuple_GET_ITEM(args, 1);
    1568             : 
    1569      162490 :     Py_XINCREF(name);
    1570      162490 :     Py_XSETREF(prop->prop_name, name);
    1571             : 
    1572      162490 :     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      179244 : property_dealloc(PyObject *self)
    1586             : {
    1587      179244 :     propertyobject *gs = (propertyobject *)self;
    1588             : 
    1589      179244 :     _PyObject_GC_UNTRACK(self);
    1590      179244 :     Py_XDECREF(gs->prop_get);
    1591      179244 :     Py_XDECREF(gs->prop_set);
    1592      179244 :     Py_XDECREF(gs->prop_del);
    1593      179244 :     Py_XDECREF(gs->prop_doc);
    1594      179244 :     Py_XDECREF(gs->prop_name);
    1595      179244 :     Py_TYPE(self)->tp_free(self);
    1596      179244 : }
    1597             : 
    1598             : static PyObject *
    1599      659036 : property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
    1600             : {
    1601      659036 :     if (obj == NULL || obj == Py_None) {
    1602        2232 :         Py_INCREF(self);
    1603        2232 :         return self;
    1604             :     }
    1605             : 
    1606      656804 :     propertyobject *gs = (propertyobject *)self;
    1607      656804 :     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      656802 :     return PyObject_CallOneArg(gs->prop_get, obj);
    1628             : }
    1629             : 
    1630             : static int
    1631       76487 : property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
    1632             : {
    1633       76487 :     propertyobject *gs = (propertyobject *)self;
    1634             :     PyObject *func, *res;
    1635             : 
    1636       76487 :     if (value == NULL) {
    1637          17 :         func = gs->prop_del;
    1638             :     }
    1639             :     else {
    1640       76470 :         func = gs->prop_set;
    1641             :     }
    1642             : 
    1643       76487 :     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       76383 :     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       76368 :         PyObject *args[] = { obj, value };
    1679       76368 :         res = PyObject_Vectorcall(func, args, 2, NULL);
    1680             :     }
    1681             : 
    1682       76383 :     if (res == NULL) {
    1683          29 :         return -1;
    1684             :     }
    1685             : 
    1686       76354 :     Py_DECREF(res);
    1687       76354 :     return 0;
    1688             : }
    1689             : 
    1690             : static PyObject *
    1691       25104 : property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
    1692             : {
    1693       25104 :     propertyobject *pold = (propertyobject *)old;
    1694             :     PyObject *new, *type, *doc;
    1695             : 
    1696       25104 :     type = PyObject_Type(old);
    1697       25104 :     if (type == NULL)
    1698           0 :         return NULL;
    1699             : 
    1700       25104 :     if (get == NULL || get == Py_None) {
    1701       25088 :         Py_XDECREF(get);
    1702       25088 :         get = pold->prop_get ? pold->prop_get : Py_None;
    1703             :     }
    1704       25104 :     if (set == NULL || set == Py_None) {
    1705          93 :         Py_XDECREF(set);
    1706          93 :         set = pold->prop_set ? pold->prop_set : Py_None;
    1707             :     }
    1708       25104 :     if (del == NULL || del == Py_None) {
    1709       25027 :         Py_XDECREF(del);
    1710       25027 :         del = pold->prop_del ? pold->prop_del : Py_None;
    1711             :     }
    1712       25104 :     if (pold->getter_doc && get != Py_None) {
    1713             :         /* make _init use __doc__ from getter */
    1714        9364 :         doc = Py_None;
    1715             :     }
    1716             :     else {
    1717       15740 :         doc = pold->prop_doc ? pold->prop_doc : Py_None;
    1718             :     }
    1719             : 
    1720       25104 :     new =  PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
    1721       25104 :     Py_DECREF(type);
    1722       25104 :     if (new == NULL)
    1723           0 :         return NULL;
    1724             : 
    1725       25104 :     Py_XINCREF(pold->prop_name);
    1726       25104 :     Py_XSETREF(((propertyobject *) new)->prop_name, pold->prop_name);
    1727       25104 :     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      182166 : 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      182166 :     if (fget == Py_None)
    1773           1 :         fget = NULL;
    1774      182166 :     if (fset == Py_None)
    1775          36 :         fset = NULL;
    1776      182166 :     if (fdel == Py_None)
    1777       25041 :         fdel = NULL;
    1778             : 
    1779      182166 :     Py_XINCREF(fget);
    1780      182166 :     Py_XINCREF(fset);
    1781      182166 :     Py_XINCREF(fdel);
    1782             : 
    1783      182166 :     Py_XSETREF(self->prop_get, fget);
    1784      182166 :     Py_XSETREF(self->prop_set, fset);
    1785      182166 :     Py_XSETREF(self->prop_del, fdel);
    1786      182166 :     Py_XSETREF(self->prop_doc, NULL);
    1787      182166 :     Py_XSETREF(self->prop_name, NULL);
    1788             : 
    1789      182166 :     self->getter_doc = 0;
    1790      182166 :     PyObject *prop_doc = NULL;
    1791             : 
    1792      182166 :     if (doc != NULL && doc != Py_None) {
    1793        1380 :         prop_doc = doc;
    1794        1380 :         Py_XINCREF(prop_doc);
    1795             :     }
    1796             :     /* if no docstring given and the getter has one, use that one */
    1797      180786 :     else if (fget != NULL) {
    1798      180780 :         int rc = _PyObject_LookupAttr(fget, &_Py_ID(__doc__), &prop_doc);
    1799      180780 :         if (rc <= 0) {
    1800           0 :             return rc;
    1801             :         }
    1802      180780 :         if (prop_doc == Py_None) {
    1803      115911 :             prop_doc = NULL;
    1804      115911 :             Py_DECREF(Py_None);
    1805             :         }
    1806      180780 :         if (prop_doc != NULL){
    1807       64869 :             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      182166 :     if (Py_IS_TYPE(self, &PyProperty_Type)) {
    1815      182087 :         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          79 :         if (prop_doc == NULL) {
    1823          11 :             prop_doc = Py_None;
    1824          11 :             Py_INCREF(prop_doc);
    1825             :         }
    1826          79 :         int err = PyObject_SetAttr(
    1827             :                     (PyObject *)self, &_Py_ID(__doc__), prop_doc);
    1828          79 :         Py_XDECREF(prop_doc);
    1829          79 :         if (err < 0)
    1830           1 :             return -1;
    1831             :     }
    1832             : 
    1833      182165 :     return 0;
    1834             : }
    1835             : 
    1836             : static PyObject *
    1837       15808 : property_get___isabstractmethod__(propertyobject *prop, void *closure)
    1838             : {
    1839       15808 :     int res = _PyObject_IsAbstract(prop->prop_get);
    1840       15808 :     if (res == -1) {
    1841           1 :         return NULL;
    1842             :     }
    1843       15807 :     else if (res) {
    1844         293 :         Py_RETURN_TRUE;
    1845             :     }
    1846             : 
    1847       15514 :     res = _PyObject_IsAbstract(prop->prop_set);
    1848       15514 :     if (res == -1) {
    1849           0 :         return NULL;
    1850             :     }
    1851       15514 :     else if (res) {
    1852           4 :         Py_RETURN_TRUE;
    1853             :     }
    1854             : 
    1855       15510 :     res = _PyObject_IsAbstract(prop->prop_del);
    1856       15510 :     if (res == -1) {
    1857           0 :         return NULL;
    1858             :     }
    1859       15510 :     else if (res) {
    1860           0 :         Py_RETURN_TRUE;
    1861             :     }
    1862       15510 :     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     4463200 : property_traverse(PyObject *self, visitproc visit, void *arg)
    1875             : {
    1876     4463200 :     propertyobject *pp = (propertyobject *)self;
    1877     4463200 :     Py_VISIT(pp->prop_get);
    1878     4463200 :     Py_VISIT(pp->prop_set);
    1879     4463200 :     Py_VISIT(pp->prop_del);
    1880     4463200 :     Py_VISIT(pp->prop_doc);
    1881     4463200 :     Py_VISIT(pp->prop_name);
    1882     4463200 :     return 0;
    1883             : }
    1884             : 
    1885             : static int
    1886        2651 : property_clear(PyObject *self)
    1887             : {
    1888        2651 :     propertyobject *pp = (propertyobject *)self;
    1889        2651 :     Py_CLEAR(pp->prop_doc);
    1890        2651 :     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