Coverage Report

Created: 2025-07-11 06:59

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