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