blob: 370b7a75e8b4238da682e915a05702c5a3dff001 [file] [log] [blame]
Tim Peters6d6c1a32001-08-02 04:15:00 +00001/* Descriptors -- a new, flexible way to describe attributes */
2
3#include "Python.h"
Eric Snow2ebc5ce2017-09-07 23:51:28 -06004#include "internal/pystate.h"
Tim Peters6d6c1a32001-08-02 04:15:00 +00005#include "structmember.h" /* Why is this not included in Python.h? */
6
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02007/*[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
Tim Peters6d6c1a32001-08-02 04:15:00 +000013static void
14descr_dealloc(PyDescrObject *descr)
15{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000016 _PyObject_GC_UNTRACK(descr);
17 Py_XDECREF(descr->d_type);
18 Py_XDECREF(descr->d_name);
Antoine Pitrou9d574812011-12-12 13:47:25 +010019 Py_XDECREF(descr->d_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000020 PyObject_GC_Del(descr);
Tim Peters6d6c1a32001-08-02 04:15:00 +000021}
22
Walter Dörwaldd7fb7642007-06-11 16:36:59 +000023static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +000024descr_name(PyDescrObject *descr)
25{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000026 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
27 return descr->d_name;
28 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +000029}
30
31static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020032descr_repr(PyDescrObject *descr, const char *format)
Tim Peters6d6c1a32001-08-02 04:15:00 +000033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000034 PyObject *name = NULL;
35 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
36 name = descr->d_name;
Walter Dörwaldd7fb7642007-06-11 16:36:59 +000037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000038 return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name);
Tim Peters6d6c1a32001-08-02 04:15:00 +000039}
40
41static PyObject *
42method_repr(PyMethodDescrObject *descr)
43{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000044 return descr_repr((PyDescrObject *)descr,
45 "<method '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000046}
47
48static PyObject *
49member_repr(PyMemberDescrObject *descr)
50{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051 return descr_repr((PyDescrObject *)descr,
52 "<member '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000053}
54
55static PyObject *
56getset_repr(PyGetSetDescrObject *descr)
57{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058 return descr_repr((PyDescrObject *)descr,
59 "<attribute '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000060}
61
62static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +000063wrapperdescr_repr(PyWrapperDescrObject *descr)
Tim Peters6d6c1a32001-08-02 04:15:00 +000064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 return descr_repr((PyDescrObject *)descr,
66 "<slot wrapper '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000067}
68
69static int
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +000070descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +000071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000072 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;
Tim Peters6d6c1a32001-08-02 04:15:00 +000088}
89
90static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +000091classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Petersbca1cbc2002-12-09 22:56:13 +000092{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 /* 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 }
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200125 return PyCFunction_NewEx(descr->d_method, type, NULL);
Tim Petersbca1cbc2002-12-09 22:56:13 +0000126}
127
128static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000129method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000130{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000131 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 if (descr_check((PyDescrObject *)descr, obj, &res))
134 return res;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200135 return PyCFunction_NewEx(descr->d_method, obj, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000136}
137
138static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000139member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000140{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 if (descr_check((PyDescrObject *)descr, obj, &res))
144 return res;
145 return PyMember_GetOne((char *)obj, descr->d_member);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000146}
147
148static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000149getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 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;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000162}
163
164static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000165wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 if (descr_check((PyDescrObject *)descr, obj, &res))
170 return res;
171 return PyWrapper_New((PyObject *)descr, obj);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000172}
173
174static int
175descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 int *pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000177{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 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;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000190}
191
192static int
193member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
194{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
198 return res;
199 return PyMember_SetOne((char *)obj, descr->d_member, value);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000200}
201
202static int
203getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 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;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000217}
218
219static PyObject *
Victor Stinnerc5257232017-01-18 10:38:09 +0100220methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000221{
Victor Stinnerc5257232017-01-18 10:38:09 +0100222 Py_ssize_t nargs;
223 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 /* Make sure that the first argument is acceptable as 'self' */
226 assert(PyTuple_Check(args));
Victor Stinnerc5257232017-01-18 10:38:09 +0100227 nargs = PyTuple_GET_SIZE(args);
228 if (nargs < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 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);
Victor Stinner3249dec2011-05-01 23:19:15 +0200237 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200238 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 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 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000248
Victor Stinnerc5257232017-01-18 10:38:09 +0100249 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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000254}
255
INADA Naoki5566bbb2017-02-03 07:43:03 +0900256// same to methoddescr_call(), but use FASTCALL convention.
257PyObject *
258_PyMethodDescr_FastCallKeywords(PyObject *descrobj,
Serhiy Storchakaa5552f02017-12-15 13:11:11 +0200259 PyObject *const *args, Py_ssize_t nargs,
INADA Naoki5566bbb2017-02-03 07:43:03 +0900260 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
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 "
Miss Islington (bot)03440852019-03-26 02:47:08 -0700316 "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,
Miss Islington (bot)03440852019-03-26 02:47:08 -0700323 "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,
Miss Islington (bot)03440852019-03-26 02:47:08 -0700327 ((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,
332 &PyTuple_GET_ITEM(args, 1), argc - 1,
333 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) {
Miss Islington (bot)1659c082018-11-29 06:27:49 -0800345 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 *
Miss Islington (bot)5ceb7012018-11-27 09:58:07 -0800440descr_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 *
449descr_reduce(PyDescrObject *descr)
450{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100451 _Py_IDENTIFIER(getattr);
Serhiy Storchaka3cae16d2018-12-11 10:51:27 +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 *
Victor Stinner0db176f2012-04-16 00:16:30 +0200864mappingproxy_keys(mappingproxyobject *pp)
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 *
Victor Stinner0db176f2012-04-16 00:16:30 +0200871mappingproxy_values(mappingproxyobject *pp)
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 *
Victor Stinner0db176f2012-04-16 00:16:30 +0200878mappingproxy_items(mappingproxyobject *pp)
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 *
Victor Stinner0db176f2012-04-16 00:16:30 +0200885mappingproxy_copy(mappingproxyobject *pp)
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);
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)
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{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 PyWrapperDescrObject *a_descr, *b_descr;
Mark Dickinson211c6252009-02-01 10:28:51 +00001035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +00001037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 /* both arguments should be wrapperobjects */
1039 if (!Wrapper_Check(a) || !Wrapper_Check(b)) {
stratakise8b19652017-11-02 11:32:54 +01001040 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 }
Mark Dickinson211c6252009-02-01 10:28:51 +00001042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 /* 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 }
Mark Dickinson211c6252009-02-01 10:28:51 +00001052
stratakise8b19652017-11-02 11:32:54 +01001053 Py_RETURN_RICHCOMPARE(a_descr, b_descr, op);
Armin Rigoc6686b72005-11-07 08:38:00 +00001054}
1055
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001056static Py_hash_t
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001057wrapper_hash(wrapperobject *wp)
1058{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001059 Py_hash_t x, y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 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;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001070}
1071
Armin Rigoc6686b72005-11-07 08:38:00 +00001072static PyObject *
1073wrapper_repr(wrapperobject *wp)
1074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 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);
Armin Rigoc6686b72005-11-07 08:38:00 +00001079}
1080
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001081static PyObject *
1082wrapper_reduce(wrapperobject *wp)
1083{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001084 _Py_IDENTIFIER(getattr);
Serhiy Storchaka3cae16d2018-12-11 10:51:27 +02001085 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
1086 wp->self, PyDescr_NAME(wp->descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001087}
1088
1089static PyMethodDef wrapper_methods[] = {
1090 {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
1091 {NULL, NULL}
1092};
1093
Armin Rigoc6686b72005-11-07 08:38:00 +00001094static PyMemberDef wrapper_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
1096 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001097};
1098
1099static PyObject *
Miss Islington (bot)5ceb7012018-11-27 09:58:07 -08001100wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored))
Armin Rigoc6686b72005-11-07 08:38:00 +00001101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
Armin Rigoc6686b72005-11-07 08:38:00 +00001103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 Py_INCREF(c);
1105 return c;
Armin Rigoc6686b72005-11-07 08:38:00 +00001106}
1107
1108static PyObject *
Miss Islington (bot)5ceb7012018-11-27 09:58:07 -08001109wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001110{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111 const char *s = wp->descr->d_base->name;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 return PyUnicode_FromString(s);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001114}
1115
1116static PyObject *
Miss Islington (bot)5ceb7012018-11-27 09:58:07 -08001117wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001118{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001119 return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -08001120}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001121
Larry Hastings5c661892014-01-24 06:17:25 -08001122static PyObject *
Miss Islington (bot)5ceb7012018-11-27 09:58:07 -08001123wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
Larry Hastings5c661892014-01-24 06:17:25 -08001124{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001125 return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001126}
1127
Antoine Pitrou9d574812011-12-12 13:47:25 +01001128static PyObject *
Miss Islington (bot)5ceb7012018-11-27 09:58:07 -08001129wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +01001130{
Miss Islington (bot)5ceb7012018-11-27 09:58:07 -08001131 return descr_get_qualname((PyDescrObject *)wp->descr, NULL);
Antoine Pitrou9d574812011-12-12 13:47:25 +01001132}
1133
Guido van Rossum32d34c82001-09-20 21:45:26 +00001134static PyGetSetDef wrapper_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 {"__objclass__", (getter)wrapper_objclass},
1136 {"__name__", (getter)wrapper_name},
Antoine Pitrou9d574812011-12-12 13:47:25 +01001137 {"__qualname__", (getter)wrapper_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 {"__doc__", (getter)wrapper_doc},
Larry Hastings5c661892014-01-24 06:17:25 -08001139 {"__text_signature__", (getter)wrapper_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001141};
1142
1143static PyObject *
1144wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
1145{
Serhiy Storchaka5e02c782017-09-21 14:25:36 +03001146 return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001147}
1148
Guido van Rossum048eb752001-10-02 21:24:57 +00001149static int
1150wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 wrapperobject *wp = (wrapperobject *)self;
1153 Py_VISIT(wp->descr);
1154 Py_VISIT(wp->self);
1155 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001156}
1157
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001158PyTypeObject _PyMethodWrapper_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 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 */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001187 wrapper_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 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 */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001194};
1195
1196PyObject *
1197PyWrapper_New(PyObject *d, PyObject *self)
1198{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 wrapperobject *wp;
1200 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1203 descr = (PyWrapperDescrObject *)d;
Victor Stinner3249dec2011-05-01 23:19:15 +02001204 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +02001205 (PyObject *)PyDescr_TYPE(descr)));
Tim Peters6d6c1a32001-08-02 04:15:00 +00001206
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001207 wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 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;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001216}
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001217
1218
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001219/* A built-in 'property' type */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001220
1221/*
Serhiy Storchakad741a882015-06-11 00:06:39 +03001222class property(object):
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 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__"):
Serhiy Storchakad741a882015-06-11 00:06:39 +03001226 doc = fget.__doc__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 self.__get = fget
1228 self.__set = fset
1229 self.__del = fdel
1230 self.__doc__ = doc
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 def __get__(self, inst, type=None):
1233 if inst is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001234 return self
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 if self.__get is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001236 raise AttributeError, "unreadable attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 return self.__get(inst)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 def __set__(self, inst, value):
1240 if self.__set is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001241 raise AttributeError, "can't set attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 return self.__set(inst, value)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 def __delete__(self, inst):
1245 if self.__del is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001246 raise AttributeError, "can't delete attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 return self.__del(inst)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001248
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001249*/
1250
1251typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 PyObject_HEAD
1253 PyObject *prop_get;
1254 PyObject *prop_set;
1255 PyObject *prop_del;
1256 PyObject *prop_doc;
1257 int getter_doc;
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001258} propertyobject;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001259
Christian Heimes0449f632007-12-15 01:27:15 +00001260static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
Benjamin Peterson93964832010-06-28 03:07:10 +00001261 PyObject *);
Christian Heimes0449f632007-12-15 01:27:15 +00001262
Tim Peters66c1a522001-09-24 21:17:50 +00001263static PyMemberDef property_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 {"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},
Raymond Hettingereac503a2015-05-13 01:09:59 -07001267 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 {0}
Tim Peters66c1a522001-09-24 21:17:50 +00001269};
1270
Christian Heimes0449f632007-12-15 01:27:15 +00001271
Guido van Rossum58da9312007-11-10 23:39:45 +00001272PyDoc_STRVAR(getter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 "Descriptor to change the getter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001274
Neal Norwitz32dde222008-04-15 06:43:13 +00001275static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001276property_getter(PyObject *self, PyObject *getter)
1277{
Benjamin Peterson93964832010-06-28 03:07:10 +00001278 return property_copy(self, getter, NULL, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001279}
1280
Christian Heimes0449f632007-12-15 01:27:15 +00001281
Guido van Rossum58da9312007-11-10 23:39:45 +00001282PyDoc_STRVAR(setter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 "Descriptor to change the setter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001284
Neal Norwitz32dde222008-04-15 06:43:13 +00001285static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001286property_setter(PyObject *self, PyObject *setter)
1287{
Benjamin Peterson93964832010-06-28 03:07:10 +00001288 return property_copy(self, NULL, setter, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001289}
1290
Christian Heimes0449f632007-12-15 01:27:15 +00001291
Guido van Rossum58da9312007-11-10 23:39:45 +00001292PyDoc_STRVAR(deleter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 "Descriptor to change the deleter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001294
Neal Norwitz32dde222008-04-15 06:43:13 +00001295static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001296property_deleter(PyObject *self, PyObject *deleter)
1297{
Benjamin Peterson93964832010-06-28 03:07:10 +00001298 return property_copy(self, NULL, NULL, deleter);
Guido van Rossum58da9312007-11-10 23:39:45 +00001299}
1300
1301
Guido van Rossum58da9312007-11-10 23:39:45 +00001302static PyMethodDef property_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 {"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}
Guido van Rossum58da9312007-11-10 23:39:45 +00001307};
1308
Tim Peters66c1a522001-09-24 21:17:50 +00001309
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001310static void
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001311property_dealloc(PyObject *self)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001312{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 propertyobject *gs = (propertyobject *)self;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 _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);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001321}
1322
1323static PyObject *
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001324property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001325{
Serhiy Storchakaa7a0ad62015-05-24 21:38:06 +03001326 static PyObject * volatile cached_args = NULL;
1327 PyObject *args;
Raymond Hettingerc4e335b2015-04-30 08:08:13 -07001328 PyObject *ret;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 propertyobject *gs = (propertyobject *)self;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 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 }
Serhiy Storchakaa7a0ad62015-05-24 21:38:06 +03001339 args = cached_args;
Serhiy Storchaka7822f152016-05-04 21:42:05 +03001340 cached_args = NULL;
1341 if (!args) {
1342 args = PyTuple_New(1);
1343 if (!args)
Serhiy Storchakaa7a0ad62015-05-24 21:38:06 +03001344 return NULL;
Serhiy Storchaka7822f152016-05-04 21:42:05 +03001345 _PyObject_GC_UNTRACK(args);
Raymond Hettingerc4e335b2015-04-30 08:08:13 -07001346 }
Serhiy Storchakaa7a0ad62015-05-24 21:38:06 +03001347 Py_INCREF(obj);
Raymond Hettingerc4e335b2015-04-30 08:08:13 -07001348 PyTuple_SET_ITEM(args, 0, obj);
1349 ret = PyObject_Call(gs->prop_get, args, NULL);
Serhiy Storchaka7822f152016-05-04 21:42:05 +03001350 if (cached_args == NULL && Py_REFCNT(args) == 1) {
Serhiy Storchakafff9a312017-03-21 08:53:25 +02001351 assert(PyTuple_GET_SIZE(args) == 1);
Serhiy Storchaka7822f152016-05-04 21:42:05 +03001352 assert(PyTuple_GET_ITEM(args, 0) == obj);
1353 cached_args = args;
1354 Py_DECREF(obj);
Serhiy Storchakaa7a0ad62015-05-24 21:38:06 +03001355 }
Serhiy Storchaka7822f152016-05-04 21:42:05 +03001356 else {
1357 assert(Py_REFCNT(args) >= 1);
1358 _PyObject_GC_TRACK(args);
1359 Py_DECREF(args);
1360 }
Raymond Hettingerc4e335b2015-04-30 08:08:13 -07001361 return ret;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001362}
1363
1364static int
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001365property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001366{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 propertyobject *gs = (propertyobject *)self;
1368 PyObject *func, *res;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 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)
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01001382 res = PyObject_CallFunctionObjArgs(func, obj, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 else
Benjamin Peterson9b955de2010-12-07 04:04:02 +00001384 res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 if (res == NULL)
1386 return -1;
1387 Py_DECREF(res);
1388 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001389}
1390
Christian Heimes0449f632007-12-15 01:27:15 +00001391static PyObject *
Benjamin Peterson93964832010-06-28 03:07:10 +00001392property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
Christian Heimes0449f632007-12-15 01:27:15 +00001393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 propertyobject *pold = (propertyobject *)old;
Benjamin Peterson93964832010-06-28 03:07:10 +00001395 PyObject *new, *type, *doc;
Christian Heimes0449f632007-12-15 01:27:15 +00001396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 type = PyObject_Type(old);
1398 if (type == NULL)
1399 return NULL;
Christian Heimes0449f632007-12-15 01:27:15 +00001400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 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 }
Benjamin Peterson93964832010-06-28 03:07:10 +00001413 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;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 }
R. David Murrayb18500d2009-05-04 22:59:07 +00001420
Victor Stinner5abaa2b2016-12-09 16:22:32 +01001421 new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 Py_DECREF(type);
1423 if (new == NULL)
1424 return NULL;
1425 return new;
Christian Heimes0449f632007-12-15 01:27:15 +00001426}
1427
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001428/*[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
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001465static int
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001466property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1467 PyObject *fdel, PyObject *doc)
1468/*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001469{
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001470 if (fget == Py_None)
1471 fget = NULL;
1472 if (fset == Py_None)
1473 fset = NULL;
1474 if (fdel == Py_None)
1475 fdel = NULL;
Tim Peters66c1a522001-09-24 21:17:50 +00001476
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001477 Py_XINCREF(fget);
1478 Py_XINCREF(fset);
1479 Py_XINCREF(fdel);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 Py_XINCREF(doc);
Christian Heimes0449f632007-12-15 01:27:15 +00001481
Miss Islington (bot)ef20abe2018-02-13 03:32:18 -08001482 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);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001486 self->getter_doc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 /* if no docstring given and the getter has one, use that one */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001489 if ((doc == NULL || doc == Py_None) && fget != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001490 _Py_IDENTIFIER(__doc__);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001491 PyObject *get_doc = _PyObject_GetAttrId(fget, &PyId___doc__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 if (get_doc) {
1493 if (Py_TYPE(self) == &PyProperty_Type) {
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001494 Py_XSETREF(self->prop_doc, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 }
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. */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001501 int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 Py_DECREF(get_doc);
1503 if (err < 0)
1504 return -1;
1505 }
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001506 self->getter_doc = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 }
1508 else if (PyErr_ExceptionMatches(PyExc_Exception)) {
1509 PyErr_Clear();
1510 }
1511 else {
1512 return -1;
1513 }
1514 }
1515
1516 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001517}
1518
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001519static PyObject *
1520property_get___isabstractmethod__(propertyobject *prop, void *closure)
1521{
1522 int res = _PyObject_IsAbstract(prop->prop_get);
1523 if (res == -1) {
1524 return NULL;
1525 }
1526 else if (res) {
1527 Py_RETURN_TRUE;
1528 }
1529
1530 res = _PyObject_IsAbstract(prop->prop_set);
1531 if (res == -1) {
1532 return NULL;
1533 }
1534 else if (res) {
1535 Py_RETURN_TRUE;
1536 }
1537
1538 res = _PyObject_IsAbstract(prop->prop_del);
1539 if (res == -1) {
1540 return NULL;
1541 }
1542 else if (res) {
1543 Py_RETURN_TRUE;
1544 }
1545 Py_RETURN_FALSE;
1546}
1547
1548static PyGetSetDef property_getsetlist[] = {
1549 {"__isabstractmethod__",
1550 (getter)property_get___isabstractmethod__, NULL,
1551 NULL,
1552 NULL},
1553 {NULL} /* Sentinel */
1554};
1555
Guido van Rossum048eb752001-10-02 21:24:57 +00001556static int
1557property_traverse(PyObject *self, visitproc visit, void *arg)
1558{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 propertyobject *pp = (propertyobject *)self;
1560 Py_VISIT(pp->prop_get);
1561 Py_VISIT(pp->prop_set);
1562 Py_VISIT(pp->prop_del);
1563 Py_VISIT(pp->prop_doc);
1564 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001565}
1566
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001567static int
1568property_clear(PyObject *self)
1569{
1570 propertyobject *pp = (propertyobject *)self;
1571 Py_CLEAR(pp->prop_doc);
1572 return 0;
1573}
1574
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001575#include "clinic/descrobject.c.h"
1576
1577PyTypeObject PyDictProxy_Type = {
1578 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1579 "mappingproxy", /* tp_name */
1580 sizeof(mappingproxyobject), /* tp_basicsize */
1581 0, /* tp_itemsize */
1582 /* methods */
1583 (destructor)mappingproxy_dealloc, /* tp_dealloc */
1584 0, /* tp_print */
1585 0, /* tp_getattr */
1586 0, /* tp_setattr */
1587 0, /* tp_reserved */
1588 (reprfunc)mappingproxy_repr, /* tp_repr */
1589 0, /* tp_as_number */
1590 &mappingproxy_as_sequence, /* tp_as_sequence */
1591 &mappingproxy_as_mapping, /* tp_as_mapping */
1592 0, /* tp_hash */
1593 0, /* tp_call */
1594 (reprfunc)mappingproxy_str, /* tp_str */
1595 PyObject_GenericGetAttr, /* tp_getattro */
1596 0, /* tp_setattro */
1597 0, /* tp_as_buffer */
1598 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1599 0, /* tp_doc */
1600 mappingproxy_traverse, /* tp_traverse */
1601 0, /* tp_clear */
1602 (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
1603 0, /* tp_weaklistoffset */
1604 (getiterfunc)mappingproxy_getiter, /* tp_iter */
1605 0, /* tp_iternext */
1606 mappingproxy_methods, /* tp_methods */
1607 0, /* tp_members */
1608 0, /* tp_getset */
1609 0, /* tp_base */
1610 0, /* tp_dict */
1611 0, /* tp_descr_get */
1612 0, /* tp_descr_set */
1613 0, /* tp_dictoffset */
1614 0, /* tp_init */
1615 0, /* tp_alloc */
1616 mappingproxy_new, /* tp_new */
1617};
1618
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001619PyTypeObject PyProperty_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1621 "property", /* tp_name */
1622 sizeof(propertyobject), /* tp_basicsize */
1623 0, /* tp_itemsize */
1624 /* methods */
1625 property_dealloc, /* tp_dealloc */
1626 0, /* tp_print */
1627 0, /* tp_getattr */
1628 0, /* tp_setattr */
1629 0, /* tp_reserved */
1630 0, /* tp_repr */
1631 0, /* tp_as_number */
1632 0, /* tp_as_sequence */
1633 0, /* tp_as_mapping */
1634 0, /* tp_hash */
1635 0, /* tp_call */
1636 0, /* tp_str */
1637 PyObject_GenericGetAttr, /* tp_getattro */
1638 0, /* tp_setattro */
1639 0, /* tp_as_buffer */
1640 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1641 Py_TPFLAGS_BASETYPE, /* tp_flags */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001642 property_init__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 property_traverse, /* tp_traverse */
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001644 (inquiry)property_clear, /* tp_clear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 0, /* tp_richcompare */
1646 0, /* tp_weaklistoffset */
1647 0, /* tp_iter */
1648 0, /* tp_iternext */
1649 property_methods, /* tp_methods */
1650 property_members, /* tp_members */
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001651 property_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 0, /* tp_base */
1653 0, /* tp_dict */
1654 property_descr_get, /* tp_descr_get */
1655 property_descr_set, /* tp_descr_set */
1656 0, /* tp_dictoffset */
1657 property_init, /* tp_init */
1658 PyType_GenericAlloc, /* tp_alloc */
1659 PyType_GenericNew, /* tp_new */
1660 PyObject_GC_Del, /* tp_free */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001661};