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