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