blob: 8f1a823768f393bb322f006fc8102a51d63a135c [file] [log] [blame]
Tim Peters6d6c1a32001-08-02 04:15:00 +00001/* Descriptors -- a new, flexible way to describe attributes */
2
3#include "Python.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +01004#include "pycore_object.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01005#include "pycore_pystate.h"
Victor Stinnerec13b932018-11-25 23:56:17 +01006#include "pycore_tupleobject.h"
Tim Peters6d6c1a32001-08-02 04:15:00 +00007#include "structmember.h" /* Why is this not included in Python.h? */
8
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02009/*[clinic input]
10class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type"
11class property "propertyobject *" "&PyProperty_Type"
12[clinic start generated code]*/
13/*[clinic end generated code: output=da39a3ee5e6b4b0d input=556352653fd4c02e]*/
14
Tim Peters6d6c1a32001-08-02 04:15:00 +000015static void
16descr_dealloc(PyDescrObject *descr)
17{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000018 _PyObject_GC_UNTRACK(descr);
19 Py_XDECREF(descr->d_type);
20 Py_XDECREF(descr->d_name);
Antoine Pitrou9d574812011-12-12 13:47:25 +010021 Py_XDECREF(descr->d_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000022 PyObject_GC_Del(descr);
Tim Peters6d6c1a32001-08-02 04:15:00 +000023}
24
Walter Dörwaldd7fb7642007-06-11 16:36:59 +000025static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +000026descr_name(PyDescrObject *descr)
27{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
29 return descr->d_name;
30 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +000031}
32
33static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020034descr_repr(PyDescrObject *descr, const char *format)
Tim Peters6d6c1a32001-08-02 04:15:00 +000035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000036 PyObject *name = NULL;
37 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
38 name = descr->d_name;
Walter Dörwaldd7fb7642007-06-11 16:36:59 +000039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040 return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name);
Tim Peters6d6c1a32001-08-02 04:15:00 +000041}
42
43static PyObject *
44method_repr(PyMethodDescrObject *descr)
45{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000046 return descr_repr((PyDescrObject *)descr,
47 "<method '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000048}
49
50static PyObject *
51member_repr(PyMemberDescrObject *descr)
52{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000053 return descr_repr((PyDescrObject *)descr,
54 "<member '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000055}
56
57static PyObject *
58getset_repr(PyGetSetDescrObject *descr)
59{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 return descr_repr((PyDescrObject *)descr,
61 "<attribute '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000062}
63
64static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +000065wrapperdescr_repr(PyWrapperDescrObject *descr)
Tim Peters6d6c1a32001-08-02 04:15:00 +000066{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 return descr_repr((PyDescrObject *)descr,
68 "<slot wrapper '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000069}
70
71static int
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +000072descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +000073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 if (obj == NULL) {
75 Py_INCREF(descr);
76 *pres = (PyObject *)descr;
77 return 1;
78 }
79 if (!PyObject_TypeCheck(obj, descr->d_type)) {
80 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +090081 "descriptor '%V' for '%.100s' objects "
82 "doesn't apply to a '%.100s' object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 descr_name((PyDescrObject *)descr), "?",
84 descr->d_type->tp_name,
85 obj->ob_type->tp_name);
86 *pres = NULL;
87 return 1;
88 }
89 return 0;
Tim Peters6d6c1a32001-08-02 04:15:00 +000090}
91
92static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +000093classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Petersbca1cbc2002-12-09 22:56:13 +000094{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 /* Ensure a valid type. Class methods ignore obj. */
96 if (type == NULL) {
97 if (obj != NULL)
98 type = (PyObject *)obj->ob_type;
99 else {
100 /* Wot - no type?! */
101 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900102 "descriptor '%V' for type '%.100s' "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000103 "needs either an object or a type",
104 descr_name((PyDescrObject *)descr), "?",
105 PyDescr_TYPE(descr)->tp_name);
106 return NULL;
107 }
108 }
109 if (!PyType_Check(type)) {
110 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900111 "descriptor '%V' for type '%.100s' "
112 "needs a type, not a '%.100s' as arg 2",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 descr_name((PyDescrObject *)descr), "?",
114 PyDescr_TYPE(descr)->tp_name,
115 type->ob_type->tp_name);
116 return NULL;
117 }
118 if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) {
119 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900120 "descriptor '%V' requires a subtype of '%.100s' "
121 "but received '%.100s'",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 descr_name((PyDescrObject *)descr), "?",
123 PyDescr_TYPE(descr)->tp_name,
124 ((PyTypeObject *)type)->tp_name);
125 return NULL;
126 }
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200127 return PyCFunction_NewEx(descr->d_method, type, NULL);
Tim Petersbca1cbc2002-12-09 22:56:13 +0000128}
129
130static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000131method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 if (descr_check((PyDescrObject *)descr, obj, &res))
136 return res;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200137 return PyCFunction_NewEx(descr->d_method, obj, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000138}
139
140static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000141member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 if (descr_check((PyDescrObject *)descr, obj, &res))
146 return res;
147 return PyMember_GetOne((char *)obj, descr->d_member);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000148}
149
150static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000151getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 if (descr_check((PyDescrObject *)descr, obj, &res))
156 return res;
157 if (descr->d_getset->get != NULL)
158 return descr->d_getset->get(obj, descr->d_getset->closure);
159 PyErr_Format(PyExc_AttributeError,
160 "attribute '%V' of '%.100s' objects is not readable",
161 descr_name((PyDescrObject *)descr), "?",
162 PyDescr_TYPE(descr)->tp_name);
163 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000164}
165
166static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000167wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 if (descr_check((PyDescrObject *)descr, obj, &res))
172 return res;
173 return PyWrapper_New((PyObject *)descr, obj);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000174}
175
176static int
177descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 int *pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 assert(obj != NULL);
181 if (!PyObject_TypeCheck(obj, descr->d_type)) {
182 PyErr_Format(PyExc_TypeError,
183 "descriptor '%V' for '%.100s' objects "
Inada Naoki62f95882019-04-01 17:56:11 +0900184 "doesn't apply to a '%.100s' object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 descr_name(descr), "?",
186 descr->d_type->tp_name,
187 obj->ob_type->tp_name);
188 *pres = -1;
189 return 1;
190 }
191 return 0;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000192}
193
194static int
195member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
200 return res;
201 return PyMember_SetOne((char *)obj, descr->d_member, value);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000202}
203
204static int
205getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
210 return res;
211 if (descr->d_getset->set != NULL)
212 return descr->d_getset->set(obj, value,
213 descr->d_getset->closure);
214 PyErr_Format(PyExc_AttributeError,
215 "attribute '%V' of '%.100s' objects is not writable",
216 descr_name((PyDescrObject *)descr), "?",
217 PyDescr_TYPE(descr)->tp_name);
218 return -1;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000219}
220
221static PyObject *
Victor Stinnerc5257232017-01-18 10:38:09 +0100222methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000223{
Victor Stinnerc5257232017-01-18 10:38:09 +0100224 Py_ssize_t nargs;
225 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 /* Make sure that the first argument is acceptable as 'self' */
228 assert(PyTuple_Check(args));
Victor Stinnerc5257232017-01-18 10:38:09 +0100229 nargs = PyTuple_GET_SIZE(args);
230 if (nargs < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 PyErr_Format(PyExc_TypeError,
232 "descriptor '%V' of '%.100s' "
233 "object needs an argument",
234 descr_name((PyDescrObject *)descr), "?",
235 PyDescr_TYPE(descr)->tp_name);
236 return NULL;
237 }
238 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200239 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200240 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900242 "descriptor '%V' for '%.100s' objects "
243 "doesn't apply to a '%.100s' object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 descr_name((PyDescrObject *)descr), "?",
245 PyDescr_TYPE(descr)->tp_name,
246 self->ob_type->tp_name);
247 return NULL;
248 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000249
Victor Stinnerc5257232017-01-18 10:38:09 +0100250 result = _PyMethodDef_RawFastCallDict(descr->d_method, self,
Victor Stinnerd17a6932018-11-09 16:56:48 +0100251 &_PyTuple_ITEMS(args)[1], nargs - 1,
Victor Stinnerc5257232017-01-18 10:38:09 +0100252 kwargs);
253 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000255}
256
INADA Naoki5566bbb2017-02-03 07:43:03 +0900257// same to methoddescr_call(), but use FASTCALL convention.
258PyObject *
259_PyMethodDescr_FastCallKeywords(PyObject *descrobj,
Serhiy Storchakaa5552f02017-12-15 13:11:11 +0200260 PyObject *const *args, Py_ssize_t nargs,
INADA Naoki5566bbb2017-02-03 07:43:03 +0900261 PyObject *kwnames)
262{
263 assert(Py_TYPE(descrobj) == &PyMethodDescr_Type);
264 PyMethodDescrObject *descr = (PyMethodDescrObject *)descrobj;
265 PyObject *self, *result;
266
267 /* Make sure that the first argument is acceptable as 'self' */
268 if (nargs < 1) {
269 PyErr_Format(PyExc_TypeError,
270 "descriptor '%V' of '%.100s' "
271 "object needs an argument",
272 descr_name((PyDescrObject *)descr), "?",
273 PyDescr_TYPE(descr)->tp_name);
274 return NULL;
275 }
276 self = args[0];
277 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
278 (PyObject *)PyDescr_TYPE(descr))) {
279 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900280 "descriptor '%V' for '%.100s' objects "
281 "doesn't apply to a '%.100s' object",
INADA Naoki5566bbb2017-02-03 07:43:03 +0900282 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
Tim Peters6d6c1a32001-08-02 04:15:00 +0000294static PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000295classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 PyObject *kwds)
Tim Petersbca1cbc2002-12-09 22:56:13 +0000297{
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400298 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300299 PyObject *self, *result;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000300
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400301 /* 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 "
Inada Naoki871309c2019-03-26 18:26:33 +0900316 "but received a '%.100s' instance",
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400317 descr_name((PyDescrObject *)descr), "?",
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400318 self->ob_type->tp_name);
319 return NULL;
320 }
321 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) {
322 PyErr_Format(PyExc_TypeError,
Inada Naoki871309c2019-03-26 18:26:33 +0900323 "descriptor '%V' requires a subtype of '%.100s' "
324 "but received '%.100s'",
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400325 descr_name((PyDescrObject *)descr), "?",
326 PyDescr_TYPE(descr)->tp_name,
Inada Naoki871309c2019-03-26 18:26:33 +0900327 ((PyTypeObject*)self)->tp_name);
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400328 return NULL;
329 }
330
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300331 result = _PyMethodDef_RawFastCallDict(descr->d_method, self,
Victor Stinnerd17a6932018-11-09 16:56:48 +0100332 &_PyTuple_ITEMS(args)[1], argc - 1,
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300333 kwds);
334 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 return result;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000336}
337
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300338Py_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) {
Serhiy Storchaka1c607152018-11-27 21:34:27 +0200345 wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300346 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
Tim Petersbca1cbc2002-12-09 22:56:13 +0000358static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000359wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300362 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 /* 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);
Victor Stinner3249dec2011-05-01 23:19:15 +0200376 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200377 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 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 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000387
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300388 args = PyTuple_GetSlice(args, 1, argc);
389 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 return NULL;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300391 }
392 result = wrapperdescr_raw_call(descr, self, args, kwds);
393 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000395}
396
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300397
Tim Peters6d6c1a32001-08-02 04:15:00 +0000398static PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000399method_get_doc(PyMethodDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000400{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800401 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800402}
403
404static PyObject *
405method_get_text_signature(PyMethodDescrObject *descr, void *closure)
406{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800407 return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000408}
409
Antoine Pitrou9d574812011-12-12 13:47:25 +0100410static 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 *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200440descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +0100441{
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
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100448static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530449descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100450{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100451 _Py_IDENTIFIER(getattr);
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200452 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
453 PyDescr_TYPE(descr), PyDescr_NAME(descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100454}
455
456static PyMethodDef descr_methods[] = {
457 {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL},
458 {NULL, NULL}
459};
460
Guido van Rossum6f799372001-09-20 20:46:19 +0000461static PyMemberDef descr_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
463 {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
464 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000465};
466
Guido van Rossum32d34c82001-09-20 21:45:26 +0000467static PyGetSetDef method_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 {"__doc__", (getter)method_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100469 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800470 {"__text_signature__", (getter)method_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 {0}
Guido van Rossum6f799372001-09-20 20:46:19 +0000472};
473
474static PyObject *
475member_get_doc(PyMemberDescrObject *descr, void *closure)
476{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 if (descr->d_member->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200478 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 }
480 return PyUnicode_FromString(descr->d_member->doc);
Guido van Rossum6f799372001-09-20 20:46:19 +0000481}
482
Guido van Rossum32d34c82001-09-20 21:45:26 +0000483static PyGetSetDef member_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 {"__doc__", (getter)member_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100485 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000487};
488
489static PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000490getset_get_doc(PyGetSetDescrObject *descr, void *closure)
491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 if (descr->d_getset->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200493 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 }
495 return PyUnicode_FromString(descr->d_getset->doc);
Guido van Rossum32d34c82001-09-20 21:45:26 +0000496}
497
498static PyGetSetDef getset_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 {"__doc__", (getter)getset_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100500 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 {0}
Guido van Rossum32d34c82001-09-20 21:45:26 +0000502};
503
504static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000505wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000506{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800507 return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800508}
509
510static PyObject *
511wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
512{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800513 return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000514}
515
Armin Rigoc6686b72005-11-07 08:38:00 +0000516static PyGetSetDef wrapperdescr_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 {"__doc__", (getter)wrapperdescr_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100518 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800519 {"__text_signature__", (getter)wrapperdescr_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000521};
522
Guido van Rossum048eb752001-10-02 21:24:57 +0000523static int
524descr_traverse(PyObject *self, visitproc visit, void *arg)
525{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 PyDescrObject *descr = (PyDescrObject *)self;
527 Py_VISIT(descr->d_type);
528 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000529}
530
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000531PyTypeObject PyMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 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 */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100559 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 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 */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000566};
567
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000568/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000569PyTypeObject PyClassMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 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 */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100597 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 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 */
Tim Petersbca1cbc2002-12-09 22:56:13 +0000604};
605
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000606PyTypeObject PyMemberDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 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 */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100634 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 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 */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000641};
642
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000643PyTypeObject PyGetSetDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 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 */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000678};
679
Guido van Rossumf4593e02001-10-03 12:09:30 +0000680PyTypeObject PyWrapperDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 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 */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100708 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 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 */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000715};
716
717static PyDescrObject *
Jeremy Hyltonaf68c872005-12-10 18:50:16 +0000718descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 PyDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000721
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 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 }
Benjamin Petersonf2fe7f02011-12-17 08:02:20 -0500731 else {
732 descr->d_qualname = NULL;
733 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 }
735 return descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000736}
737
738PyObject *
739PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 PyMethodDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
744 type, method->ml_name);
745 if (descr != NULL)
746 descr->d_method = method;
747 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000748}
749
750PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000751PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
752{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000753 PyMethodDescrObject *descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
756 type, method->ml_name);
757 if (descr != NULL)
758 descr->d_method = method;
759 return (PyObject *)descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000760}
761
762PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000763PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000764{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 PyMemberDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000767 descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
768 type, member->name);
769 if (descr != NULL)
770 descr->d_member = member;
771 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000772}
773
774PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000775PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000777 PyGetSetDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
780 type, getset->name);
781 if (descr != NULL)
782 descr->d_getset = getset;
783 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000784}
785
786PyObject *
787PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 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;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000798}
799
Tim Peters6d6c1a32001-08-02 04:15:00 +0000800
Victor Stinner0db176f2012-04-16 00:16:30 +0200801/* --- mappingproxy: read-only proxy for mappings --- */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000802
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 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 PyObject_HEAD
Victor Stinner0db176f2012-04-16 00:16:30 +0200808 PyObject *mapping;
809} mappingproxyobject;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000810
Martin v. Löwis18e16552006-02-15 17:27:45 +0000811static Py_ssize_t
Victor Stinner0db176f2012-04-16 00:16:30 +0200812mappingproxy_len(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000813{
Victor Stinner0db176f2012-04-16 00:16:30 +0200814 return PyObject_Size(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000815}
816
817static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200818mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000819{
Victor Stinner0db176f2012-04-16 00:16:30 +0200820 return PyObject_GetItem(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000821}
822
Victor Stinner0db176f2012-04-16 00:16:30 +0200823static PyMappingMethods mappingproxy_as_mapping = {
824 (lenfunc)mappingproxy_len, /* mp_length */
825 (binaryfunc)mappingproxy_getitem, /* mp_subscript */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 0, /* mp_ass_subscript */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000827};
828
829static int
Victor Stinner0db176f2012-04-16 00:16:30 +0200830mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000831{
Victor Stinner0db176f2012-04-16 00:16:30 +0200832 if (PyDict_CheckExact(pp->mapping))
833 return PyDict_Contains(pp->mapping, key);
834 else
835 return PySequence_Contains(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000836}
837
Victor Stinner0db176f2012-04-16 00:16:30 +0200838static PySequenceMethods mappingproxy_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 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 */
Victor Stinner0db176f2012-04-16 00:16:30 +0200846 (objobjproc)mappingproxy_contains, /* sq_contains */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 0, /* sq_inplace_concat */
848 0, /* sq_inplace_repeat */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000849};
850
851static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200852mappingproxy_get(mappingproxyobject *pp, PyObject *args)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 PyObject *key, *def = Py_None;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200855 _Py_IDENTIFIER(get);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def))
858 return NULL;
Victor Stinner7e425412016-12-09 00:36:19 +0100859 return _PyObject_CallMethodIdObjArgs(pp->mapping, &PyId_get,
860 key, def, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000861}
862
863static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530864mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000865{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200866 _Py_IDENTIFIER(keys);
Victor Stinner0db176f2012-04-16 00:16:30 +0200867 return _PyObject_CallMethodId(pp->mapping, &PyId_keys, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000868}
869
870static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530871mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000872{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200873 _Py_IDENTIFIER(values);
Victor Stinner0db176f2012-04-16 00:16:30 +0200874 return _PyObject_CallMethodId(pp->mapping, &PyId_values, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000875}
876
877static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530878mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000879{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200880 _Py_IDENTIFIER(items);
Victor Stinner0db176f2012-04-16 00:16:30 +0200881 return _PyObject_CallMethodId(pp->mapping, &PyId_items, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000882}
883
884static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530885mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000886{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200887 _Py_IDENTIFIER(copy);
Victor Stinner0db176f2012-04-16 00:16:30 +0200888 return _PyObject_CallMethodId(pp->mapping, &PyId_copy, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000889}
890
Victor Stinner0db176f2012-04-16 00:16:30 +0200891/* WARNING: mappingproxy methods must not give access
892 to the underlying mapping */
893
894static PyMethodDef mappingproxy_methods[] = {
895 {"get", (PyCFunction)mappingproxy_get, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d."
Victor Stinner0db176f2012-04-16 00:16:30 +0200897 " d defaults to None.")},
898 {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 PyDoc_STR("D.keys() -> list of D's keys")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200900 {"values", (PyCFunction)mappingproxy_values, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 PyDoc_STR("D.values() -> list of D's values")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200902 {"items", (PyCFunction)mappingproxy_items, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200904 {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000905 PyDoc_STR("D.copy() -> a shallow copy of D")},
906 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000907};
908
909static void
Victor Stinner0db176f2012-04-16 00:16:30 +0200910mappingproxy_dealloc(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000911{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 _PyObject_GC_UNTRACK(pp);
Victor Stinner0db176f2012-04-16 00:16:30 +0200913 Py_DECREF(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 PyObject_GC_Del(pp);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000915}
916
917static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200918mappingproxy_getiter(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000919{
Victor Stinner0db176f2012-04-16 00:16:30 +0200920 return PyObject_GetIter(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000921}
922
Neil Schemenauer26775122001-10-21 22:26:43 +0000923static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200924mappingproxy_str(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000925{
Victor Stinner0db176f2012-04-16 00:16:30 +0200926 return PyObject_Str(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000927}
928
Ezio Melottiac53ab62010-12-18 14:59:43 +0000929static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200930mappingproxy_repr(mappingproxyobject *pp)
Ezio Melottiac53ab62010-12-18 14:59:43 +0000931{
Victor Stinner0db176f2012-04-16 00:16:30 +0200932 return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping);
Ezio Melottiac53ab62010-12-18 14:59:43 +0000933}
934
Guido van Rossum048eb752001-10-02 21:24:57 +0000935static int
Victor Stinner0db176f2012-04-16 00:16:30 +0200936mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
Guido van Rossum048eb752001-10-02 21:24:57 +0000937{
Victor Stinner0db176f2012-04-16 00:16:30 +0200938 mappingproxyobject *pp = (mappingproxyobject *)self;
939 Py_VISIT(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000941}
942
Raymond Hettinger29a6d442002-08-31 15:51:04 +0000943static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200944mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op)
Raymond Hettinger29a6d442002-08-31 15:51:04 +0000945{
Victor Stinner0db176f2012-04-16 00:16:30 +0200946 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
Serhiy Storchaka18b250f2017-03-19 08:51:07 +0200963/*[clinic input]
964@classmethod
965mappingproxy.__new__ as mappingproxy_new
Victor Stinner0db176f2012-04-16 00:16:30 +0200966
Serhiy Storchaka18b250f2017-03-19 08:51:07 +0200967 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;
Victor Stinner0db176f2012-04-16 00:16:30 +0200976
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;
Raymond Hettinger29a6d442002-08-31 15:51:04 +0000987}
988
Tim Peters6d6c1a32001-08-02 04:15:00 +0000989PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200990PyDictProxy_New(PyObject *mapping)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000991{
Victor Stinner0db176f2012-04-16 00:16:30 +0200992 mappingproxyobject *pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000993
Victor Stinner0db176f2012-04-16 00:16:30 +0200994 if (mappingproxy_check_mapping(mapping) == -1)
995 return NULL;
996
997 pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 if (pp != NULL) {
Victor Stinner0db176f2012-04-16 00:16:30 +0200999 Py_INCREF(mapping);
1000 pp->mapping = mapping;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 _PyObject_GC_TRACK(pp);
1002 }
1003 return (PyObject *)pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001004}
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 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 PyObject_HEAD
1014 PyWrapperDescrObject *descr;
1015 PyObject *self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001016} wrapperobject;
1017
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001018#define Wrapper_Check(v) (Py_TYPE(v) == &_PyMethodWrapper_Type)
Mark Dickinson211c6252009-02-01 10:28:51 +00001019
Tim Peters6d6c1a32001-08-02 04:15:00 +00001020static void
1021wrapper_dealloc(wrapperobject *wp)
1022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 PyObject_GC_UnTrack(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001024 Py_TRASHCAN_BEGIN(wp, wrapper_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 Py_XDECREF(wp->descr);
1026 Py_XDECREF(wp->self);
1027 PyObject_GC_Del(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001028 Py_TRASHCAN_END
Tim Peters6d6c1a32001-08-02 04:15:00 +00001029}
1030
Mark Dickinson211c6252009-02-01 10:28:51 +00001031static PyObject *
1032wrapper_richcompare(PyObject *a, PyObject *b, int op)
Armin Rigoc6686b72005-11-07 08:38:00 +00001033{
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001034 wrapperobject *wa, *wb;
1035 int eq;
Mark Dickinson211c6252009-02-01 10:28:51 +00001036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +00001038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 /* both arguments should be wrapperobjects */
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001040 if ((op != Py_EQ && op != Py_NE)
1041 || !Wrapper_Check(a) || !Wrapper_Check(b))
1042 {
stratakise8b19652017-11-02 11:32:54 +01001043 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 }
Mark Dickinson211c6252009-02-01 10:28:51 +00001045
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001046 wa = (wrapperobject *)a;
1047 wb = (wrapperobject *)b;
1048 eq = (wa->descr == wb->descr && wa->self == wb->self);
1049 if (eq == (op == Py_EQ)) {
1050 Py_RETURN_TRUE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 }
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001052 else {
1053 Py_RETURN_FALSE;
1054 }
Armin Rigoc6686b72005-11-07 08:38:00 +00001055}
1056
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001057static Py_hash_t
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001058wrapper_hash(wrapperobject *wp)
1059{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001060 Py_hash_t x, y;
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001061 x = _Py_HashPointer(wp->self);
1062 y = _Py_HashPointer(wp->descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 x = x ^ y;
1064 if (x == -1)
1065 x = -2;
1066 return x;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001067}
1068
Armin Rigoc6686b72005-11-07 08:38:00 +00001069static PyObject *
1070wrapper_repr(wrapperobject *wp)
1071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
1073 wp->descr->d_base->name,
1074 wp->self->ob_type->tp_name,
1075 wp->self);
Armin Rigoc6686b72005-11-07 08:38:00 +00001076}
1077
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001078static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301079wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001080{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001081 _Py_IDENTIFIER(getattr);
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02001082 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
1083 wp->self, PyDescr_NAME(wp->descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001084}
1085
1086static PyMethodDef wrapper_methods[] = {
1087 {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
1088 {NULL, NULL}
1089};
1090
Armin Rigoc6686b72005-11-07 08:38:00 +00001091static PyMemberDef wrapper_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
1093 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001094};
1095
1096static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001097wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored))
Armin Rigoc6686b72005-11-07 08:38:00 +00001098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
Armin Rigoc6686b72005-11-07 08:38:00 +00001100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 Py_INCREF(c);
1102 return c;
Armin Rigoc6686b72005-11-07 08:38:00 +00001103}
1104
1105static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001106wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001107{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 const char *s = wp->descr->d_base->name;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 return PyUnicode_FromString(s);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001111}
1112
1113static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001114wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001115{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001116 return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -08001117}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001118
Larry Hastings5c661892014-01-24 06:17:25 -08001119static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001120wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
Larry Hastings5c661892014-01-24 06:17:25 -08001121{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001122 return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001123}
1124
Antoine Pitrou9d574812011-12-12 13:47:25 +01001125static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001126wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +01001127{
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001128 return descr_get_qualname((PyDescrObject *)wp->descr, NULL);
Antoine Pitrou9d574812011-12-12 13:47:25 +01001129}
1130
Guido van Rossum32d34c82001-09-20 21:45:26 +00001131static PyGetSetDef wrapper_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 {"__objclass__", (getter)wrapper_objclass},
1133 {"__name__", (getter)wrapper_name},
Antoine Pitrou9d574812011-12-12 13:47:25 +01001134 {"__qualname__", (getter)wrapper_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 {"__doc__", (getter)wrapper_doc},
Larry Hastings5c661892014-01-24 06:17:25 -08001136 {"__text_signature__", (getter)wrapper_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001138};
1139
1140static PyObject *
1141wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
1142{
Serhiy Storchaka5e02c782017-09-21 14:25:36 +03001143 return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001144}
1145
Guido van Rossum048eb752001-10-02 21:24:57 +00001146static int
1147wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 wrapperobject *wp = (wrapperobject *)self;
1150 Py_VISIT(wp->descr);
1151 Py_VISIT(wp->self);
1152 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001153}
1154
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001155PyTypeObject _PyMethodWrapper_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1157 "method-wrapper", /* tp_name */
1158 sizeof(wrapperobject), /* tp_basicsize */
1159 0, /* tp_itemsize */
1160 /* methods */
1161 (destructor)wrapper_dealloc, /* tp_dealloc */
1162 0, /* tp_print */
1163 0, /* tp_getattr */
1164 0, /* tp_setattr */
1165 0, /* tp_reserved */
1166 (reprfunc)wrapper_repr, /* tp_repr */
1167 0, /* tp_as_number */
1168 0, /* tp_as_sequence */
1169 0, /* tp_as_mapping */
1170 (hashfunc)wrapper_hash, /* tp_hash */
1171 (ternaryfunc)wrapper_call, /* tp_call */
1172 0, /* tp_str */
1173 PyObject_GenericGetAttr, /* tp_getattro */
1174 0, /* tp_setattro */
1175 0, /* tp_as_buffer */
1176 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1177 0, /* tp_doc */
1178 wrapper_traverse, /* tp_traverse */
1179 0, /* tp_clear */
1180 wrapper_richcompare, /* tp_richcompare */
1181 0, /* tp_weaklistoffset */
1182 0, /* tp_iter */
1183 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001184 wrapper_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 wrapper_members, /* tp_members */
1186 wrapper_getsets, /* tp_getset */
1187 0, /* tp_base */
1188 0, /* tp_dict */
1189 0, /* tp_descr_get */
1190 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001191};
1192
1193PyObject *
1194PyWrapper_New(PyObject *d, PyObject *self)
1195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 wrapperobject *wp;
1197 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1200 descr = (PyWrapperDescrObject *)d;
Victor Stinner3249dec2011-05-01 23:19:15 +02001201 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +02001202 (PyObject *)PyDescr_TYPE(descr)));
Tim Peters6d6c1a32001-08-02 04:15:00 +00001203
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001204 wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 if (wp != NULL) {
1206 Py_INCREF(descr);
1207 wp->descr = descr;
1208 Py_INCREF(self);
1209 wp->self = self;
1210 _PyObject_GC_TRACK(wp);
1211 }
1212 return (PyObject *)wp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001213}
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001214
1215
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001216/* A built-in 'property' type */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001217
1218/*
Serhiy Storchakad741a882015-06-11 00:06:39 +03001219class property(object):
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
1222 if doc is None and fget is not None and hasattr(fget, "__doc__"):
Serhiy Storchakad741a882015-06-11 00:06:39 +03001223 doc = fget.__doc__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 self.__get = fget
1225 self.__set = fset
1226 self.__del = fdel
1227 self.__doc__ = doc
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 def __get__(self, inst, type=None):
1230 if inst is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001231 return self
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 if self.__get is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001233 raise AttributeError, "unreadable attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 return self.__get(inst)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 def __set__(self, inst, value):
1237 if self.__set is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001238 raise AttributeError, "can't set attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 return self.__set(inst, value)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 def __delete__(self, inst):
1242 if self.__del is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001243 raise AttributeError, "can't delete attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 return self.__del(inst)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001245
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001246*/
1247
1248typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 PyObject_HEAD
1250 PyObject *prop_get;
1251 PyObject *prop_set;
1252 PyObject *prop_del;
1253 PyObject *prop_doc;
1254 int getter_doc;
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001255} propertyobject;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001256
Christian Heimes0449f632007-12-15 01:27:15 +00001257static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
Benjamin Peterson93964832010-06-28 03:07:10 +00001258 PyObject *);
Christian Heimes0449f632007-12-15 01:27:15 +00001259
Tim Peters66c1a522001-09-24 21:17:50 +00001260static PyMemberDef property_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
1262 {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
1263 {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
Raymond Hettingereac503a2015-05-13 01:09:59 -07001264 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 {0}
Tim Peters66c1a522001-09-24 21:17:50 +00001266};
1267
Christian Heimes0449f632007-12-15 01:27:15 +00001268
Guido van Rossum58da9312007-11-10 23:39:45 +00001269PyDoc_STRVAR(getter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 "Descriptor to change the getter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001271
Neal Norwitz32dde222008-04-15 06:43:13 +00001272static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001273property_getter(PyObject *self, PyObject *getter)
1274{
Benjamin Peterson93964832010-06-28 03:07:10 +00001275 return property_copy(self, getter, NULL, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001276}
1277
Christian Heimes0449f632007-12-15 01:27:15 +00001278
Guido van Rossum58da9312007-11-10 23:39:45 +00001279PyDoc_STRVAR(setter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 "Descriptor to change the setter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001281
Neal Norwitz32dde222008-04-15 06:43:13 +00001282static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001283property_setter(PyObject *self, PyObject *setter)
1284{
Benjamin Peterson93964832010-06-28 03:07:10 +00001285 return property_copy(self, NULL, setter, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001286}
1287
Christian Heimes0449f632007-12-15 01:27:15 +00001288
Guido van Rossum58da9312007-11-10 23:39:45 +00001289PyDoc_STRVAR(deleter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 "Descriptor to change the deleter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001291
Neal Norwitz32dde222008-04-15 06:43:13 +00001292static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001293property_deleter(PyObject *self, PyObject *deleter)
1294{
Benjamin Peterson93964832010-06-28 03:07:10 +00001295 return property_copy(self, NULL, NULL, deleter);
Guido van Rossum58da9312007-11-10 23:39:45 +00001296}
1297
1298
Guido van Rossum58da9312007-11-10 23:39:45 +00001299static PyMethodDef property_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 {"getter", property_getter, METH_O, getter_doc},
1301 {"setter", property_setter, METH_O, setter_doc},
1302 {"deleter", property_deleter, METH_O, deleter_doc},
1303 {0}
Guido van Rossum58da9312007-11-10 23:39:45 +00001304};
1305
Tim Peters66c1a522001-09-24 21:17:50 +00001306
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001307static void
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001308property_dealloc(PyObject *self)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 propertyobject *gs = (propertyobject *)self;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 _PyObject_GC_UNTRACK(self);
1313 Py_XDECREF(gs->prop_get);
1314 Py_XDECREF(gs->prop_set);
1315 Py_XDECREF(gs->prop_del);
1316 Py_XDECREF(gs->prop_doc);
1317 self->ob_type->tp_free(self);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001318}
1319
1320static PyObject *
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001321property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 if (obj == NULL || obj == Py_None) {
1324 Py_INCREF(self);
1325 return self;
1326 }
Victor Stinnere972c132018-10-01 03:03:22 -07001327
1328 propertyobject *gs = (propertyobject *)self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 if (gs->prop_get == NULL) {
1330 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1331 return NULL;
1332 }
Victor Stinnere972c132018-10-01 03:03:22 -07001333
1334 PyObject *args[1] = {obj};
1335 return _PyObject_FastCall(gs->prop_get, args, 1);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001336}
1337
1338static int
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001339property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 propertyobject *gs = (propertyobject *)self;
1342 PyObject *func, *res;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 if (value == NULL)
1345 func = gs->prop_del;
1346 else
1347 func = gs->prop_set;
1348 if (func == NULL) {
1349 PyErr_SetString(PyExc_AttributeError,
1350 value == NULL ?
1351 "can't delete attribute" :
1352 "can't set attribute");
1353 return -1;
1354 }
1355 if (value == NULL)
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01001356 res = PyObject_CallFunctionObjArgs(func, obj, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 else
Benjamin Peterson9b955de2010-12-07 04:04:02 +00001358 res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 if (res == NULL)
1360 return -1;
1361 Py_DECREF(res);
1362 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001363}
1364
Christian Heimes0449f632007-12-15 01:27:15 +00001365static PyObject *
Benjamin Peterson93964832010-06-28 03:07:10 +00001366property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
Christian Heimes0449f632007-12-15 01:27:15 +00001367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 propertyobject *pold = (propertyobject *)old;
Benjamin Peterson93964832010-06-28 03:07:10 +00001369 PyObject *new, *type, *doc;
Christian Heimes0449f632007-12-15 01:27:15 +00001370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 type = PyObject_Type(old);
1372 if (type == NULL)
1373 return NULL;
Christian Heimes0449f632007-12-15 01:27:15 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 if (get == NULL || get == Py_None) {
1376 Py_XDECREF(get);
1377 get = pold->prop_get ? pold->prop_get : Py_None;
1378 }
1379 if (set == NULL || set == Py_None) {
1380 Py_XDECREF(set);
1381 set = pold->prop_set ? pold->prop_set : Py_None;
1382 }
1383 if (del == NULL || del == Py_None) {
1384 Py_XDECREF(del);
1385 del = pold->prop_del ? pold->prop_del : Py_None;
1386 }
Benjamin Peterson93964832010-06-28 03:07:10 +00001387 if (pold->getter_doc && get != Py_None) {
1388 /* make _init use __doc__ from getter */
1389 doc = Py_None;
1390 }
1391 else {
1392 doc = pold->prop_doc ? pold->prop_doc : Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 }
R. David Murrayb18500d2009-05-04 22:59:07 +00001394
Victor Stinner5abaa2b2016-12-09 16:22:32 +01001395 new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 Py_DECREF(type);
1397 if (new == NULL)
1398 return NULL;
1399 return new;
Christian Heimes0449f632007-12-15 01:27:15 +00001400}
1401
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001402/*[clinic input]
1403property.__init__ as property_init
1404
1405 fget: object(c_default="NULL") = None
1406 function to be used for getting an attribute value
1407 fset: object(c_default="NULL") = None
1408 function to be used for setting an attribute value
1409 fdel: object(c_default="NULL") = None
1410 function to be used for del'ing an attribute
1411 doc: object(c_default="NULL") = None
1412 docstring
1413
1414Property attribute.
1415
1416Typical use is to define a managed attribute x:
1417
1418class C(object):
1419 def getx(self): return self._x
1420 def setx(self, value): self._x = value
1421 def delx(self): del self._x
1422 x = property(getx, setx, delx, "I'm the 'x' property.")
1423
1424Decorators make defining new properties or modifying existing ones easy:
1425
1426class C(object):
1427 @property
1428 def x(self):
1429 "I am the 'x' property."
1430 return self._x
1431 @x.setter
1432 def x(self, value):
1433 self._x = value
1434 @x.deleter
1435 def x(self):
1436 del self._x
1437[clinic start generated code]*/
1438
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001439static int
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001440property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1441 PyObject *fdel, PyObject *doc)
1442/*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001443{
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001444 if (fget == Py_None)
1445 fget = NULL;
1446 if (fset == Py_None)
1447 fset = NULL;
1448 if (fdel == Py_None)
1449 fdel = NULL;
Tim Peters66c1a522001-09-24 21:17:50 +00001450
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001451 Py_XINCREF(fget);
1452 Py_XINCREF(fset);
1453 Py_XINCREF(fdel);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 Py_XINCREF(doc);
Christian Heimes0449f632007-12-15 01:27:15 +00001455
Oren Milmand019bc82018-02-13 12:28:33 +02001456 Py_XSETREF(self->prop_get, fget);
1457 Py_XSETREF(self->prop_set, fset);
1458 Py_XSETREF(self->prop_del, fdel);
1459 Py_XSETREF(self->prop_doc, doc);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001460 self->getter_doc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 /* if no docstring given and the getter has one, use that one */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001463 if ((doc == NULL || doc == Py_None) && fget != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001464 _Py_IDENTIFIER(__doc__);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001465 PyObject *get_doc = _PyObject_GetAttrId(fget, &PyId___doc__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 if (get_doc) {
1467 if (Py_TYPE(self) == &PyProperty_Type) {
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001468 Py_XSETREF(self->prop_doc, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 }
1470 else {
1471 /* If this is a property subclass, put __doc__
1472 in dict of the subclass instance instead,
1473 otherwise it gets shadowed by __doc__ in the
1474 class's dict. */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001475 int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 Py_DECREF(get_doc);
1477 if (err < 0)
1478 return -1;
1479 }
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001480 self->getter_doc = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 }
1482 else if (PyErr_ExceptionMatches(PyExc_Exception)) {
1483 PyErr_Clear();
1484 }
1485 else {
1486 return -1;
1487 }
1488 }
1489
1490 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001491}
1492
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001493static PyObject *
1494property_get___isabstractmethod__(propertyobject *prop, void *closure)
1495{
1496 int res = _PyObject_IsAbstract(prop->prop_get);
1497 if (res == -1) {
1498 return NULL;
1499 }
1500 else if (res) {
1501 Py_RETURN_TRUE;
1502 }
1503
1504 res = _PyObject_IsAbstract(prop->prop_set);
1505 if (res == -1) {
1506 return NULL;
1507 }
1508 else if (res) {
1509 Py_RETURN_TRUE;
1510 }
1511
1512 res = _PyObject_IsAbstract(prop->prop_del);
1513 if (res == -1) {
1514 return NULL;
1515 }
1516 else if (res) {
1517 Py_RETURN_TRUE;
1518 }
1519 Py_RETURN_FALSE;
1520}
1521
1522static PyGetSetDef property_getsetlist[] = {
1523 {"__isabstractmethod__",
1524 (getter)property_get___isabstractmethod__, NULL,
1525 NULL,
1526 NULL},
1527 {NULL} /* Sentinel */
1528};
1529
Guido van Rossum048eb752001-10-02 21:24:57 +00001530static int
1531property_traverse(PyObject *self, visitproc visit, void *arg)
1532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 propertyobject *pp = (propertyobject *)self;
1534 Py_VISIT(pp->prop_get);
1535 Py_VISIT(pp->prop_set);
1536 Py_VISIT(pp->prop_del);
1537 Py_VISIT(pp->prop_doc);
1538 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001539}
1540
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001541static int
1542property_clear(PyObject *self)
1543{
1544 propertyobject *pp = (propertyobject *)self;
1545 Py_CLEAR(pp->prop_doc);
1546 return 0;
1547}
1548
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001549#include "clinic/descrobject.c.h"
1550
1551PyTypeObject PyDictProxy_Type = {
1552 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1553 "mappingproxy", /* tp_name */
1554 sizeof(mappingproxyobject), /* tp_basicsize */
1555 0, /* tp_itemsize */
1556 /* methods */
1557 (destructor)mappingproxy_dealloc, /* tp_dealloc */
1558 0, /* tp_print */
1559 0, /* tp_getattr */
1560 0, /* tp_setattr */
1561 0, /* tp_reserved */
1562 (reprfunc)mappingproxy_repr, /* tp_repr */
1563 0, /* tp_as_number */
1564 &mappingproxy_as_sequence, /* tp_as_sequence */
1565 &mappingproxy_as_mapping, /* tp_as_mapping */
1566 0, /* tp_hash */
1567 0, /* tp_call */
1568 (reprfunc)mappingproxy_str, /* tp_str */
1569 PyObject_GenericGetAttr, /* tp_getattro */
1570 0, /* tp_setattro */
1571 0, /* tp_as_buffer */
1572 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1573 0, /* tp_doc */
1574 mappingproxy_traverse, /* tp_traverse */
1575 0, /* tp_clear */
1576 (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
1577 0, /* tp_weaklistoffset */
1578 (getiterfunc)mappingproxy_getiter, /* tp_iter */
1579 0, /* tp_iternext */
1580 mappingproxy_methods, /* tp_methods */
1581 0, /* tp_members */
1582 0, /* tp_getset */
1583 0, /* tp_base */
1584 0, /* tp_dict */
1585 0, /* tp_descr_get */
1586 0, /* tp_descr_set */
1587 0, /* tp_dictoffset */
1588 0, /* tp_init */
1589 0, /* tp_alloc */
1590 mappingproxy_new, /* tp_new */
1591};
1592
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001593PyTypeObject PyProperty_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1595 "property", /* tp_name */
1596 sizeof(propertyobject), /* tp_basicsize */
1597 0, /* tp_itemsize */
1598 /* methods */
1599 property_dealloc, /* tp_dealloc */
1600 0, /* tp_print */
1601 0, /* tp_getattr */
1602 0, /* tp_setattr */
1603 0, /* tp_reserved */
1604 0, /* tp_repr */
1605 0, /* tp_as_number */
1606 0, /* tp_as_sequence */
1607 0, /* tp_as_mapping */
1608 0, /* tp_hash */
1609 0, /* tp_call */
1610 0, /* tp_str */
1611 PyObject_GenericGetAttr, /* tp_getattro */
1612 0, /* tp_setattro */
1613 0, /* tp_as_buffer */
1614 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1615 Py_TPFLAGS_BASETYPE, /* tp_flags */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001616 property_init__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617 property_traverse, /* tp_traverse */
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001618 (inquiry)property_clear, /* tp_clear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 0, /* tp_richcompare */
1620 0, /* tp_weaklistoffset */
1621 0, /* tp_iter */
1622 0, /* tp_iternext */
1623 property_methods, /* tp_methods */
1624 property_members, /* tp_members */
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001625 property_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 0, /* tp_base */
1627 0, /* tp_dict */
1628 property_descr_get, /* tp_descr_get */
1629 property_descr_set, /* tp_descr_set */
1630 0, /* tp_dictoffset */
1631 property_init, /* tp_init */
1632 PyType_GenericAlloc, /* tp_alloc */
1633 PyType_GenericNew, /* tp_new */
1634 PyObject_GC_Del, /* tp_free */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001635};