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