blob: 3aaeaa6e890fdf48a010111bceca396959006df3 [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;
Steve Dowerb82e17e2019-05-23 08:45:22 -0700147
148 if (descr->d_member->flags & READ_RESTRICTED) {
149 if (PySys_Audit("object.__getattr__", "Os",
150 obj ? obj : Py_None, descr->d_member->name) < 0) {
151 return NULL;
152 }
153 }
154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 return PyMember_GetOne((char *)obj, descr->d_member);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000156}
157
158static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000159getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 if (descr_check((PyDescrObject *)descr, obj, &res))
164 return res;
165 if (descr->d_getset->get != NULL)
166 return descr->d_getset->get(obj, descr->d_getset->closure);
167 PyErr_Format(PyExc_AttributeError,
168 "attribute '%V' of '%.100s' objects is not readable",
169 descr_name((PyDescrObject *)descr), "?",
170 PyDescr_TYPE(descr)->tp_name);
171 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000172}
173
174static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000175wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000179 if (descr_check((PyDescrObject *)descr, obj, &res))
180 return res;
181 return PyWrapper_New((PyObject *)descr, obj);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000182}
183
184static int
185descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 int *pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 assert(obj != NULL);
189 if (!PyObject_TypeCheck(obj, descr->d_type)) {
190 PyErr_Format(PyExc_TypeError,
191 "descriptor '%V' for '%.100s' objects "
Inada Naoki62f95882019-04-01 17:56:11 +0900192 "doesn't apply to a '%.100s' object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 descr_name(descr), "?",
194 descr->d_type->tp_name,
195 obj->ob_type->tp_name);
196 *pres = -1;
197 return 1;
198 }
199 return 0;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000200}
201
202static int
203member_set(PyMemberDescrObject *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 return PyMember_SetOne((char *)obj, descr->d_member, value);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000210}
211
212static int
213getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
218 return res;
219 if (descr->d_getset->set != NULL)
220 return descr->d_getset->set(obj, value,
221 descr->d_getset->closure);
222 PyErr_Format(PyExc_AttributeError,
223 "attribute '%V' of '%.100s' objects is not writable",
224 descr_name((PyDescrObject *)descr), "?",
225 PyDescr_TYPE(descr)->tp_name);
226 return -1;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000227}
228
229static PyObject *
Victor Stinnerc5257232017-01-18 10:38:09 +0100230methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000231{
Victor Stinnerc5257232017-01-18 10:38:09 +0100232 Py_ssize_t nargs;
233 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 /* Make sure that the first argument is acceptable as 'self' */
236 assert(PyTuple_Check(args));
Victor Stinnerc5257232017-01-18 10:38:09 +0100237 nargs = PyTuple_GET_SIZE(args);
238 if (nargs < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 PyErr_Format(PyExc_TypeError,
240 "descriptor '%V' of '%.100s' "
241 "object needs an argument",
242 descr_name((PyDescrObject *)descr), "?",
243 PyDescr_TYPE(descr)->tp_name);
244 return NULL;
245 }
246 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200247 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200248 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900250 "descriptor '%V' for '%.100s' objects "
251 "doesn't apply to a '%.100s' object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 descr_name((PyDescrObject *)descr), "?",
253 PyDescr_TYPE(descr)->tp_name,
254 self->ob_type->tp_name);
255 return NULL;
256 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000257
Victor Stinnerc5257232017-01-18 10:38:09 +0100258 result = _PyMethodDef_RawFastCallDict(descr->d_method, self,
Victor Stinnerd17a6932018-11-09 16:56:48 +0100259 &_PyTuple_ITEMS(args)[1], nargs - 1,
Victor Stinnerc5257232017-01-18 10:38:09 +0100260 kwargs);
261 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000263}
264
INADA Naoki5566bbb2017-02-03 07:43:03 +0900265// same to methoddescr_call(), but use FASTCALL convention.
266PyObject *
Jeroen Demeyer37788bc2019-05-30 15:11:22 +0200267_PyMethodDescr_Vectorcall(PyObject *descrobj,
268 PyObject *const *args, size_t nargsf,
269 PyObject *kwnames)
INADA Naoki5566bbb2017-02-03 07:43:03 +0900270{
271 assert(Py_TYPE(descrobj) == &PyMethodDescr_Type);
272 PyMethodDescrObject *descr = (PyMethodDescrObject *)descrobj;
273 PyObject *self, *result;
274
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200275 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
INADA Naoki5566bbb2017-02-03 07:43:03 +0900276 /* Make sure that the first argument is acceptable as 'self' */
277 if (nargs < 1) {
278 PyErr_Format(PyExc_TypeError,
279 "descriptor '%V' of '%.100s' "
280 "object needs an argument",
281 descr_name((PyDescrObject *)descr), "?",
282 PyDescr_TYPE(descr)->tp_name);
283 return NULL;
284 }
285 self = args[0];
286 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
287 (PyObject *)PyDescr_TYPE(descr))) {
288 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900289 "descriptor '%V' for '%.100s' objects "
290 "doesn't apply to a '%.100s' object",
INADA Naoki5566bbb2017-02-03 07:43:03 +0900291 descr_name((PyDescrObject *)descr), "?",
292 PyDescr_TYPE(descr)->tp_name,
293 self->ob_type->tp_name);
294 return NULL;
295 }
296
297 result = _PyMethodDef_RawFastCallKeywords(descr->d_method, self,
298 args+1, nargs-1, kwnames);
299 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
300 return result;
301}
302
Tim Peters6d6c1a32001-08-02 04:15:00 +0000303static PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000304classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 PyObject *kwds)
Tim Petersbca1cbc2002-12-09 22:56:13 +0000306{
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400307 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300308 PyObject *self, *result;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000309
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400310 /* Make sure that the first argument is acceptable as 'self' */
311 assert(PyTuple_Check(args));
312 argc = PyTuple_GET_SIZE(args);
313 if (argc < 1) {
314 PyErr_Format(PyExc_TypeError,
315 "descriptor '%V' of '%.100s' "
316 "object needs an argument",
317 descr_name((PyDescrObject *)descr), "?",
318 PyDescr_TYPE(descr)->tp_name);
319 return NULL;
320 }
321 self = PyTuple_GET_ITEM(args, 0);
322 if (!PyType_Check(self)) {
323 PyErr_Format(PyExc_TypeError,
324 "descriptor '%V' requires a type "
Inada Naoki871309c2019-03-26 18:26:33 +0900325 "but received a '%.100s' instance",
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400326 descr_name((PyDescrObject *)descr), "?",
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400327 self->ob_type->tp_name);
328 return NULL;
329 }
330 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) {
331 PyErr_Format(PyExc_TypeError,
Inada Naoki871309c2019-03-26 18:26:33 +0900332 "descriptor '%V' requires a subtype of '%.100s' "
333 "but received '%.100s'",
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400334 descr_name((PyDescrObject *)descr), "?",
335 PyDescr_TYPE(descr)->tp_name,
Inada Naoki871309c2019-03-26 18:26:33 +0900336 ((PyTypeObject*)self)->tp_name);
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400337 return NULL;
338 }
339
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300340 result = _PyMethodDef_RawFastCallDict(descr->d_method, self,
Victor Stinnerd17a6932018-11-09 16:56:48 +0100341 &_PyTuple_ITEMS(args)[1], argc - 1,
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300342 kwds);
343 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 return result;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000345}
346
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300347Py_LOCAL_INLINE(PyObject *)
348wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self,
349 PyObject *args, PyObject *kwds)
350{
351 wrapperfunc wrapper = descr->d_base->wrapper;
352
353 if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
Serhiy Storchaka1c607152018-11-27 21:34:27 +0200354 wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300355 return (*wk)(self, args, descr->d_wrapped, kwds);
356 }
357
358 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) {
359 PyErr_Format(PyExc_TypeError,
360 "wrapper %s() takes no keyword arguments",
361 descr->d_base->name);
362 return NULL;
363 }
364 return (*wrapper)(self, args, descr->d_wrapped);
365}
366
Tim Petersbca1cbc2002-12-09 22:56:13 +0000367static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000368wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300371 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 /* Make sure that the first argument is acceptable as 'self' */
374 assert(PyTuple_Check(args));
375 argc = PyTuple_GET_SIZE(args);
376 if (argc < 1) {
377 PyErr_Format(PyExc_TypeError,
378 "descriptor '%V' of '%.100s' "
379 "object needs an argument",
380 descr_name((PyDescrObject *)descr), "?",
381 PyDescr_TYPE(descr)->tp_name);
382 return NULL;
383 }
384 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200385 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200386 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 PyErr_Format(PyExc_TypeError,
388 "descriptor '%V' "
389 "requires a '%.100s' object "
390 "but received a '%.100s'",
391 descr_name((PyDescrObject *)descr), "?",
392 PyDescr_TYPE(descr)->tp_name,
393 self->ob_type->tp_name);
394 return NULL;
395 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000396
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300397 args = PyTuple_GetSlice(args, 1, argc);
398 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 return NULL;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300400 }
401 result = wrapperdescr_raw_call(descr, self, args, kwds);
402 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000404}
405
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300406
Tim Peters6d6c1a32001-08-02 04:15:00 +0000407static PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000408method_get_doc(PyMethodDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000409{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800410 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800411}
412
413static PyObject *
414method_get_text_signature(PyMethodDescrObject *descr, void *closure)
415{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800416 return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000417}
418
Antoine Pitrou9d574812011-12-12 13:47:25 +0100419static PyObject *
420calculate_qualname(PyDescrObject *descr)
421{
422 PyObject *type_qualname, *res;
423 _Py_IDENTIFIER(__qualname__);
424
425 if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) {
426 PyErr_SetString(PyExc_TypeError,
427 "<descriptor>.__name__ is not a unicode object");
428 return NULL;
429 }
430
431 type_qualname = _PyObject_GetAttrId((PyObject *)descr->d_type,
432 &PyId___qualname__);
433 if (type_qualname == NULL)
434 return NULL;
435
436 if (!PyUnicode_Check(type_qualname)) {
437 PyErr_SetString(PyExc_TypeError, "<descriptor>.__objclass__."
438 "__qualname__ is not a unicode object");
439 Py_XDECREF(type_qualname);
440 return NULL;
441 }
442
443 res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name);
444 Py_DECREF(type_qualname);
445 return res;
446}
447
448static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200449descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +0100450{
451 if (descr->d_qualname == NULL)
452 descr->d_qualname = calculate_qualname(descr);
453 Py_XINCREF(descr->d_qualname);
454 return descr->d_qualname;
455}
456
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100457static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530458descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100459{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100460 _Py_IDENTIFIER(getattr);
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200461 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
462 PyDescr_TYPE(descr), PyDescr_NAME(descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100463}
464
465static PyMethodDef descr_methods[] = {
466 {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL},
467 {NULL, NULL}
468};
469
Guido van Rossum6f799372001-09-20 20:46:19 +0000470static PyMemberDef descr_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
472 {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
473 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000474};
475
Guido van Rossum32d34c82001-09-20 21:45:26 +0000476static PyGetSetDef method_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 {"__doc__", (getter)method_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100478 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800479 {"__text_signature__", (getter)method_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 {0}
Guido van Rossum6f799372001-09-20 20:46:19 +0000481};
482
483static PyObject *
484member_get_doc(PyMemberDescrObject *descr, void *closure)
485{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 if (descr->d_member->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200487 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 }
489 return PyUnicode_FromString(descr->d_member->doc);
Guido van Rossum6f799372001-09-20 20:46:19 +0000490}
491
Guido van Rossum32d34c82001-09-20 21:45:26 +0000492static PyGetSetDef member_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 {"__doc__", (getter)member_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100494 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000496};
497
498static PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000499getset_get_doc(PyGetSetDescrObject *descr, void *closure)
500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 if (descr->d_getset->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200502 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 }
504 return PyUnicode_FromString(descr->d_getset->doc);
Guido van Rossum32d34c82001-09-20 21:45:26 +0000505}
506
507static PyGetSetDef getset_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 {"__doc__", (getter)getset_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100509 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 {0}
Guido van Rossum32d34c82001-09-20 21:45:26 +0000511};
512
513static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000514wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000515{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800516 return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800517}
518
519static PyObject *
520wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
521{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800522 return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000523}
524
Armin Rigoc6686b72005-11-07 08:38:00 +0000525static PyGetSetDef wrapperdescr_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 {"__doc__", (getter)wrapperdescr_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100527 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800528 {"__text_signature__", (getter)wrapperdescr_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000530};
531
Guido van Rossum048eb752001-10-02 21:24:57 +0000532static int
533descr_traverse(PyObject *self, visitproc visit, void *arg)
534{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 PyDescrObject *descr = (PyDescrObject *)self;
536 Py_VISIT(descr->d_type);
537 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000538}
539
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000540PyTypeObject PyMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 PyVarObject_HEAD_INIT(&PyType_Type, 0)
542 "method_descriptor",
543 sizeof(PyMethodDescrObject),
544 0,
545 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200546 offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 0, /* tp_getattr */
548 0, /* tp_setattr */
549 0, /* tp_reserved */
550 (reprfunc)method_repr, /* tp_repr */
551 0, /* tp_as_number */
552 0, /* tp_as_sequence */
553 0, /* tp_as_mapping */
554 0, /* tp_hash */
555 (ternaryfunc)methoddescr_call, /* tp_call */
556 0, /* tp_str */
557 PyObject_GenericGetAttr, /* tp_getattro */
558 0, /* tp_setattro */
559 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200560 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200561 _Py_TPFLAGS_HAVE_VECTORCALL |
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200562 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 0, /* tp_doc */
564 descr_traverse, /* tp_traverse */
565 0, /* tp_clear */
566 0, /* tp_richcompare */
567 0, /* tp_weaklistoffset */
568 0, /* tp_iter */
569 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100570 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 descr_members, /* tp_members */
572 method_getset, /* tp_getset */
573 0, /* tp_base */
574 0, /* tp_dict */
575 (descrgetfunc)method_get, /* tp_descr_get */
576 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000577};
578
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000579/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000580PyTypeObject PyClassMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 PyVarObject_HEAD_INIT(&PyType_Type, 0)
582 "classmethod_descriptor",
583 sizeof(PyMethodDescrObject),
584 0,
585 (destructor)descr_dealloc, /* tp_dealloc */
586 0, /* tp_print */
587 0, /* tp_getattr */
588 0, /* tp_setattr */
589 0, /* tp_reserved */
590 (reprfunc)method_repr, /* tp_repr */
591 0, /* tp_as_number */
592 0, /* tp_as_sequence */
593 0, /* tp_as_mapping */
594 0, /* tp_hash */
595 (ternaryfunc)classmethoddescr_call, /* tp_call */
596 0, /* tp_str */
597 PyObject_GenericGetAttr, /* tp_getattro */
598 0, /* tp_setattro */
599 0, /* tp_as_buffer */
600 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
601 0, /* tp_doc */
602 descr_traverse, /* tp_traverse */
603 0, /* tp_clear */
604 0, /* tp_richcompare */
605 0, /* tp_weaklistoffset */
606 0, /* tp_iter */
607 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100608 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 descr_members, /* tp_members */
610 method_getset, /* tp_getset */
611 0, /* tp_base */
612 0, /* tp_dict */
613 (descrgetfunc)classmethod_get, /* tp_descr_get */
614 0, /* tp_descr_set */
Tim Petersbca1cbc2002-12-09 22:56:13 +0000615};
616
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000617PyTypeObject PyMemberDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 PyVarObject_HEAD_INIT(&PyType_Type, 0)
619 "member_descriptor",
620 sizeof(PyMemberDescrObject),
621 0,
622 (destructor)descr_dealloc, /* tp_dealloc */
623 0, /* tp_print */
624 0, /* tp_getattr */
625 0, /* tp_setattr */
626 0, /* tp_reserved */
627 (reprfunc)member_repr, /* tp_repr */
628 0, /* tp_as_number */
629 0, /* tp_as_sequence */
630 0, /* tp_as_mapping */
631 0, /* tp_hash */
632 0, /* tp_call */
633 0, /* tp_str */
634 PyObject_GenericGetAttr, /* tp_getattro */
635 0, /* tp_setattro */
636 0, /* tp_as_buffer */
637 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
638 0, /* tp_doc */
639 descr_traverse, /* tp_traverse */
640 0, /* tp_clear */
641 0, /* tp_richcompare */
642 0, /* tp_weaklistoffset */
643 0, /* tp_iter */
644 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100645 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000646 descr_members, /* tp_members */
647 member_getset, /* tp_getset */
648 0, /* tp_base */
649 0, /* tp_dict */
650 (descrgetfunc)member_get, /* tp_descr_get */
651 (descrsetfunc)member_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000652};
653
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000654PyTypeObject PyGetSetDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 PyVarObject_HEAD_INIT(&PyType_Type, 0)
656 "getset_descriptor",
657 sizeof(PyGetSetDescrObject),
658 0,
659 (destructor)descr_dealloc, /* tp_dealloc */
660 0, /* tp_print */
661 0, /* tp_getattr */
662 0, /* tp_setattr */
663 0, /* tp_reserved */
664 (reprfunc)getset_repr, /* tp_repr */
665 0, /* tp_as_number */
666 0, /* tp_as_sequence */
667 0, /* tp_as_mapping */
668 0, /* tp_hash */
669 0, /* tp_call */
670 0, /* tp_str */
671 PyObject_GenericGetAttr, /* tp_getattro */
672 0, /* tp_setattro */
673 0, /* tp_as_buffer */
674 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
675 0, /* tp_doc */
676 descr_traverse, /* tp_traverse */
677 0, /* tp_clear */
678 0, /* tp_richcompare */
679 0, /* tp_weaklistoffset */
680 0, /* tp_iter */
681 0, /* tp_iternext */
682 0, /* tp_methods */
683 descr_members, /* tp_members */
684 getset_getset, /* tp_getset */
685 0, /* tp_base */
686 0, /* tp_dict */
687 (descrgetfunc)getset_get, /* tp_descr_get */
688 (descrsetfunc)getset_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000689};
690
Guido van Rossumf4593e02001-10-03 12:09:30 +0000691PyTypeObject PyWrapperDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 PyVarObject_HEAD_INIT(&PyType_Type, 0)
693 "wrapper_descriptor",
694 sizeof(PyWrapperDescrObject),
695 0,
696 (destructor)descr_dealloc, /* tp_dealloc */
697 0, /* tp_print */
698 0, /* tp_getattr */
699 0, /* tp_setattr */
700 0, /* tp_reserved */
701 (reprfunc)wrapperdescr_repr, /* tp_repr */
702 0, /* tp_as_number */
703 0, /* tp_as_sequence */
704 0, /* tp_as_mapping */
705 0, /* tp_hash */
706 (ternaryfunc)wrapperdescr_call, /* tp_call */
707 0, /* tp_str */
708 PyObject_GenericGetAttr, /* tp_getattro */
709 0, /* tp_setattro */
710 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200711 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
712 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000713 0, /* tp_doc */
714 descr_traverse, /* tp_traverse */
715 0, /* tp_clear */
716 0, /* tp_richcompare */
717 0, /* tp_weaklistoffset */
718 0, /* tp_iter */
719 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100720 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 descr_members, /* tp_members */
722 wrapperdescr_getset, /* tp_getset */
723 0, /* tp_base */
724 0, /* tp_dict */
725 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
726 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000727};
728
729static PyDescrObject *
Jeremy Hyltonaf68c872005-12-10 18:50:16 +0000730descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 PyDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000733
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
735 if (descr != NULL) {
736 Py_XINCREF(type);
737 descr->d_type = type;
738 descr->d_name = PyUnicode_InternFromString(name);
739 if (descr->d_name == NULL) {
740 Py_DECREF(descr);
741 descr = NULL;
742 }
Benjamin Petersonf2fe7f02011-12-17 08:02:20 -0500743 else {
744 descr->d_qualname = NULL;
745 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 }
747 return descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000748}
749
750PyObject *
751PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
752{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000753 PyMethodDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
756 type, method->ml_name);
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200757 if (descr != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 descr->d_method = method;
Jeroen Demeyer37788bc2019-05-30 15:11:22 +0200759 descr->vectorcall = _PyMethodDescr_Vectorcall;
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200760 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000762}
763
764PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000765PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000767 PyMethodDescrObject *descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
770 type, method->ml_name);
771 if (descr != NULL)
772 descr->d_method = method;
773 return (PyObject *)descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000774}
775
776PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000777PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 PyMemberDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
782 type, member->name);
783 if (descr != NULL)
784 descr->d_member = member;
785 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000786}
787
788PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000789PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000790{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 PyGetSetDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000793 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
794 type, getset->name);
795 if (descr != NULL)
796 descr->d_getset = getset;
797 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000798}
799
800PyObject *
801PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
806 type, base->name);
807 if (descr != NULL) {
808 descr->d_base = base;
809 descr->d_wrapped = wrapped;
810 }
811 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000812}
813
Tim Peters6d6c1a32001-08-02 04:15:00 +0000814
Victor Stinner0db176f2012-04-16 00:16:30 +0200815/* --- mappingproxy: read-only proxy for mappings --- */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000816
817/* This has no reason to be in this file except that adding new files is a
818 bit of a pain */
819
820typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000821 PyObject_HEAD
Victor Stinner0db176f2012-04-16 00:16:30 +0200822 PyObject *mapping;
823} mappingproxyobject;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000824
Martin v. Löwis18e16552006-02-15 17:27:45 +0000825static Py_ssize_t
Victor Stinner0db176f2012-04-16 00:16:30 +0200826mappingproxy_len(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000827{
Victor Stinner0db176f2012-04-16 00:16:30 +0200828 return PyObject_Size(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000829}
830
831static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200832mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000833{
Victor Stinner0db176f2012-04-16 00:16:30 +0200834 return PyObject_GetItem(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000835}
836
Victor Stinner0db176f2012-04-16 00:16:30 +0200837static PyMappingMethods mappingproxy_as_mapping = {
838 (lenfunc)mappingproxy_len, /* mp_length */
839 (binaryfunc)mappingproxy_getitem, /* mp_subscript */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 0, /* mp_ass_subscript */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000841};
842
843static int
Victor Stinner0db176f2012-04-16 00:16:30 +0200844mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000845{
Victor Stinner0db176f2012-04-16 00:16:30 +0200846 if (PyDict_CheckExact(pp->mapping))
847 return PyDict_Contains(pp->mapping, key);
848 else
849 return PySequence_Contains(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000850}
851
Victor Stinner0db176f2012-04-16 00:16:30 +0200852static PySequenceMethods mappingproxy_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 0, /* sq_length */
854 0, /* sq_concat */
855 0, /* sq_repeat */
856 0, /* sq_item */
857 0, /* sq_slice */
858 0, /* sq_ass_item */
859 0, /* sq_ass_slice */
Victor Stinner0db176f2012-04-16 00:16:30 +0200860 (objobjproc)mappingproxy_contains, /* sq_contains */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 0, /* sq_inplace_concat */
862 0, /* sq_inplace_repeat */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000863};
864
865static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200866mappingproxy_get(mappingproxyobject *pp, PyObject *args)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000867{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 PyObject *key, *def = Py_None;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200869 _Py_IDENTIFIER(get);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000871 if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def))
872 return NULL;
Victor Stinner7e425412016-12-09 00:36:19 +0100873 return _PyObject_CallMethodIdObjArgs(pp->mapping, &PyId_get,
874 key, def, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000875}
876
877static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530878mappingproxy_keys(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(keys);
Victor Stinner0db176f2012-04-16 00:16:30 +0200881 return _PyObject_CallMethodId(pp->mapping, &PyId_keys, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000882}
883
884static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530885mappingproxy_values(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(values);
Victor Stinner0db176f2012-04-16 00:16:30 +0200888 return _PyObject_CallMethodId(pp->mapping, &PyId_values, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000889}
890
891static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530892mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000893{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200894 _Py_IDENTIFIER(items);
Victor Stinner0db176f2012-04-16 00:16:30 +0200895 return _PyObject_CallMethodId(pp->mapping, &PyId_items, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000896}
897
898static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530899mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000900{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200901 _Py_IDENTIFIER(copy);
Victor Stinner0db176f2012-04-16 00:16:30 +0200902 return _PyObject_CallMethodId(pp->mapping, &PyId_copy, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000903}
904
Victor Stinner0db176f2012-04-16 00:16:30 +0200905/* WARNING: mappingproxy methods must not give access
906 to the underlying mapping */
907
908static PyMethodDef mappingproxy_methods[] = {
909 {"get", (PyCFunction)mappingproxy_get, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910 PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d."
Victor Stinner0db176f2012-04-16 00:16:30 +0200911 " d defaults to None.")},
912 {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 PyDoc_STR("D.keys() -> list of D's keys")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200914 {"values", (PyCFunction)mappingproxy_values, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000915 PyDoc_STR("D.values() -> list of D's values")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200916 {"items", (PyCFunction)mappingproxy_items, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200918 {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919 PyDoc_STR("D.copy() -> a shallow copy of D")},
920 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000921};
922
923static void
Victor Stinner0db176f2012-04-16 00:16:30 +0200924mappingproxy_dealloc(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000925{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 _PyObject_GC_UNTRACK(pp);
Victor Stinner0db176f2012-04-16 00:16:30 +0200927 Py_DECREF(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 PyObject_GC_Del(pp);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000929}
930
931static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200932mappingproxy_getiter(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000933{
Victor Stinner0db176f2012-04-16 00:16:30 +0200934 return PyObject_GetIter(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000935}
936
Neil Schemenauer26775122001-10-21 22:26:43 +0000937static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200938mappingproxy_str(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000939{
Victor Stinner0db176f2012-04-16 00:16:30 +0200940 return PyObject_Str(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000941}
942
Ezio Melottiac53ab62010-12-18 14:59:43 +0000943static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200944mappingproxy_repr(mappingproxyobject *pp)
Ezio Melottiac53ab62010-12-18 14:59:43 +0000945{
Victor Stinner0db176f2012-04-16 00:16:30 +0200946 return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping);
Ezio Melottiac53ab62010-12-18 14:59:43 +0000947}
948
Guido van Rossum048eb752001-10-02 21:24:57 +0000949static int
Victor Stinner0db176f2012-04-16 00:16:30 +0200950mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
Guido van Rossum048eb752001-10-02 21:24:57 +0000951{
Victor Stinner0db176f2012-04-16 00:16:30 +0200952 mappingproxyobject *pp = (mappingproxyobject *)self;
953 Py_VISIT(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000955}
956
Raymond Hettinger29a6d442002-08-31 15:51:04 +0000957static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200958mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op)
Raymond Hettinger29a6d442002-08-31 15:51:04 +0000959{
Victor Stinner0db176f2012-04-16 00:16:30 +0200960 return PyObject_RichCompare(v->mapping, w, op);
961}
962
963static int
964mappingproxy_check_mapping(PyObject *mapping)
965{
966 if (!PyMapping_Check(mapping)
967 || PyList_Check(mapping)
968 || PyTuple_Check(mapping)) {
969 PyErr_Format(PyExc_TypeError,
970 "mappingproxy() argument must be a mapping, not %s",
971 Py_TYPE(mapping)->tp_name);
972 return -1;
973 }
974 return 0;
975}
976
Serhiy Storchaka18b250f2017-03-19 08:51:07 +0200977/*[clinic input]
978@classmethod
979mappingproxy.__new__ as mappingproxy_new
Victor Stinner0db176f2012-04-16 00:16:30 +0200980
Serhiy Storchaka18b250f2017-03-19 08:51:07 +0200981 mapping: object
982
983[clinic start generated code]*/
984
985static PyObject *
986mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping)
987/*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/
988{
989 mappingproxyobject *mappingproxy;
Victor Stinner0db176f2012-04-16 00:16:30 +0200990
991 if (mappingproxy_check_mapping(mapping) == -1)
992 return NULL;
993
994 mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
995 if (mappingproxy == NULL)
996 return NULL;
997 Py_INCREF(mapping);
998 mappingproxy->mapping = mapping;
999 _PyObject_GC_TRACK(mappingproxy);
1000 return (PyObject *)mappingproxy;
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001001}
1002
Tim Peters6d6c1a32001-08-02 04:15:00 +00001003PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001004PyDictProxy_New(PyObject *mapping)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001005{
Victor Stinner0db176f2012-04-16 00:16:30 +02001006 mappingproxyobject *pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001007
Victor Stinner0db176f2012-04-16 00:16:30 +02001008 if (mappingproxy_check_mapping(mapping) == -1)
1009 return NULL;
1010
1011 pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 if (pp != NULL) {
Victor Stinner0db176f2012-04-16 00:16:30 +02001013 Py_INCREF(mapping);
1014 pp->mapping = mapping;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 _PyObject_GC_TRACK(pp);
1016 }
1017 return (PyObject *)pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001018}
1019
1020
1021/* --- Wrapper object for "slot" methods --- */
1022
1023/* This has no reason to be in this file except that adding new files is a
1024 bit of a pain */
1025
1026typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 PyObject_HEAD
1028 PyWrapperDescrObject *descr;
1029 PyObject *self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001030} wrapperobject;
1031
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001032#define Wrapper_Check(v) (Py_TYPE(v) == &_PyMethodWrapper_Type)
Mark Dickinson211c6252009-02-01 10:28:51 +00001033
Tim Peters6d6c1a32001-08-02 04:15:00 +00001034static void
1035wrapper_dealloc(wrapperobject *wp)
1036{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 PyObject_GC_UnTrack(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001038 Py_TRASHCAN_BEGIN(wp, wrapper_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 Py_XDECREF(wp->descr);
1040 Py_XDECREF(wp->self);
1041 PyObject_GC_Del(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001042 Py_TRASHCAN_END
Tim Peters6d6c1a32001-08-02 04:15:00 +00001043}
1044
Mark Dickinson211c6252009-02-01 10:28:51 +00001045static PyObject *
1046wrapper_richcompare(PyObject *a, PyObject *b, int op)
Armin Rigoc6686b72005-11-07 08:38:00 +00001047{
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001048 wrapperobject *wa, *wb;
1049 int eq;
Mark Dickinson211c6252009-02-01 10:28:51 +00001050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +00001052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 /* both arguments should be wrapperobjects */
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001054 if ((op != Py_EQ && op != Py_NE)
1055 || !Wrapper_Check(a) || !Wrapper_Check(b))
1056 {
stratakise8b19652017-11-02 11:32:54 +01001057 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 }
Mark Dickinson211c6252009-02-01 10:28:51 +00001059
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001060 wa = (wrapperobject *)a;
1061 wb = (wrapperobject *)b;
1062 eq = (wa->descr == wb->descr && wa->self == wb->self);
1063 if (eq == (op == Py_EQ)) {
1064 Py_RETURN_TRUE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 }
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001066 else {
1067 Py_RETURN_FALSE;
1068 }
Armin Rigoc6686b72005-11-07 08:38:00 +00001069}
1070
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001071static Py_hash_t
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001072wrapper_hash(wrapperobject *wp)
1073{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001074 Py_hash_t x, y;
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001075 x = _Py_HashPointer(wp->self);
1076 y = _Py_HashPointer(wp->descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 x = x ^ y;
1078 if (x == -1)
1079 x = -2;
1080 return x;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001081}
1082
Armin Rigoc6686b72005-11-07 08:38:00 +00001083static PyObject *
1084wrapper_repr(wrapperobject *wp)
1085{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001086 return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
1087 wp->descr->d_base->name,
1088 wp->self->ob_type->tp_name,
1089 wp->self);
Armin Rigoc6686b72005-11-07 08:38:00 +00001090}
1091
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001092static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301093wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001094{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001095 _Py_IDENTIFIER(getattr);
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02001096 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
1097 wp->self, PyDescr_NAME(wp->descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001098}
1099
1100static PyMethodDef wrapper_methods[] = {
1101 {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
1102 {NULL, NULL}
1103};
1104
Armin Rigoc6686b72005-11-07 08:38:00 +00001105static PyMemberDef wrapper_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
1107 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001108};
1109
1110static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001111wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored))
Armin Rigoc6686b72005-11-07 08:38:00 +00001112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
Armin Rigoc6686b72005-11-07 08:38:00 +00001114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 Py_INCREF(c);
1116 return c;
Armin Rigoc6686b72005-11-07 08:38:00 +00001117}
1118
1119static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001120wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 const char *s = wp->descr->d_base->name;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 return PyUnicode_FromString(s);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001125}
1126
1127static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001128wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001129{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001130 return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -08001131}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001132
Larry Hastings5c661892014-01-24 06:17:25 -08001133static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001134wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
Larry Hastings5c661892014-01-24 06:17:25 -08001135{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001136 return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001137}
1138
Antoine Pitrou9d574812011-12-12 13:47:25 +01001139static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001140wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +01001141{
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001142 return descr_get_qualname((PyDescrObject *)wp->descr, NULL);
Antoine Pitrou9d574812011-12-12 13:47:25 +01001143}
1144
Guido van Rossum32d34c82001-09-20 21:45:26 +00001145static PyGetSetDef wrapper_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 {"__objclass__", (getter)wrapper_objclass},
1147 {"__name__", (getter)wrapper_name},
Antoine Pitrou9d574812011-12-12 13:47:25 +01001148 {"__qualname__", (getter)wrapper_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 {"__doc__", (getter)wrapper_doc},
Larry Hastings5c661892014-01-24 06:17:25 -08001150 {"__text_signature__", (getter)wrapper_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001152};
1153
1154static PyObject *
1155wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
1156{
Serhiy Storchaka5e02c782017-09-21 14:25:36 +03001157 return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001158}
1159
Guido van Rossum048eb752001-10-02 21:24:57 +00001160static int
1161wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1162{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 wrapperobject *wp = (wrapperobject *)self;
1164 Py_VISIT(wp->descr);
1165 Py_VISIT(wp->self);
1166 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001167}
1168
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001169PyTypeObject _PyMethodWrapper_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1171 "method-wrapper", /* tp_name */
1172 sizeof(wrapperobject), /* tp_basicsize */
1173 0, /* tp_itemsize */
1174 /* methods */
1175 (destructor)wrapper_dealloc, /* tp_dealloc */
1176 0, /* tp_print */
1177 0, /* tp_getattr */
1178 0, /* tp_setattr */
1179 0, /* tp_reserved */
1180 (reprfunc)wrapper_repr, /* tp_repr */
1181 0, /* tp_as_number */
1182 0, /* tp_as_sequence */
1183 0, /* tp_as_mapping */
1184 (hashfunc)wrapper_hash, /* tp_hash */
1185 (ternaryfunc)wrapper_call, /* tp_call */
1186 0, /* tp_str */
1187 PyObject_GenericGetAttr, /* tp_getattro */
1188 0, /* tp_setattro */
1189 0, /* tp_as_buffer */
1190 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1191 0, /* tp_doc */
1192 wrapper_traverse, /* tp_traverse */
1193 0, /* tp_clear */
1194 wrapper_richcompare, /* tp_richcompare */
1195 0, /* tp_weaklistoffset */
1196 0, /* tp_iter */
1197 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001198 wrapper_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 wrapper_members, /* tp_members */
1200 wrapper_getsets, /* tp_getset */
1201 0, /* tp_base */
1202 0, /* tp_dict */
1203 0, /* tp_descr_get */
1204 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001205};
1206
1207PyObject *
1208PyWrapper_New(PyObject *d, PyObject *self)
1209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 wrapperobject *wp;
1211 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1214 descr = (PyWrapperDescrObject *)d;
Victor Stinner3249dec2011-05-01 23:19:15 +02001215 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +02001216 (PyObject *)PyDescr_TYPE(descr)));
Tim Peters6d6c1a32001-08-02 04:15:00 +00001217
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001218 wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 if (wp != NULL) {
1220 Py_INCREF(descr);
1221 wp->descr = descr;
1222 Py_INCREF(self);
1223 wp->self = self;
1224 _PyObject_GC_TRACK(wp);
1225 }
1226 return (PyObject *)wp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001227}
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001228
1229
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001230/* A built-in 'property' type */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001231
1232/*
Serhiy Storchakad741a882015-06-11 00:06:39 +03001233class property(object):
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
1236 if doc is None and fget is not None and hasattr(fget, "__doc__"):
Serhiy Storchakad741a882015-06-11 00:06:39 +03001237 doc = fget.__doc__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 self.__get = fget
1239 self.__set = fset
1240 self.__del = fdel
1241 self.__doc__ = doc
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 def __get__(self, inst, type=None):
1244 if inst is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001245 return self
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 if self.__get is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001247 raise AttributeError, "unreadable attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 return self.__get(inst)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 def __set__(self, inst, value):
1251 if self.__set is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001252 raise AttributeError, "can't set attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 return self.__set(inst, value)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 def __delete__(self, inst):
1256 if self.__del is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001257 raise AttributeError, "can't delete attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 return self.__del(inst)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001259
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001260*/
1261
1262typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 PyObject_HEAD
1264 PyObject *prop_get;
1265 PyObject *prop_set;
1266 PyObject *prop_del;
1267 PyObject *prop_doc;
1268 int getter_doc;
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001269} propertyobject;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001270
Christian Heimes0449f632007-12-15 01:27:15 +00001271static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
Benjamin Peterson93964832010-06-28 03:07:10 +00001272 PyObject *);
Christian Heimes0449f632007-12-15 01:27:15 +00001273
Tim Peters66c1a522001-09-24 21:17:50 +00001274static PyMemberDef property_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
1276 {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
1277 {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
Raymond Hettingereac503a2015-05-13 01:09:59 -07001278 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 {0}
Tim Peters66c1a522001-09-24 21:17:50 +00001280};
1281
Christian Heimes0449f632007-12-15 01:27:15 +00001282
Guido van Rossum58da9312007-11-10 23:39:45 +00001283PyDoc_STRVAR(getter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 "Descriptor to change the getter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001285
Neal Norwitz32dde222008-04-15 06:43:13 +00001286static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001287property_getter(PyObject *self, PyObject *getter)
1288{
Benjamin Peterson93964832010-06-28 03:07:10 +00001289 return property_copy(self, getter, NULL, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001290}
1291
Christian Heimes0449f632007-12-15 01:27:15 +00001292
Guido van Rossum58da9312007-11-10 23:39:45 +00001293PyDoc_STRVAR(setter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 "Descriptor to change the setter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001295
Neal Norwitz32dde222008-04-15 06:43:13 +00001296static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001297property_setter(PyObject *self, PyObject *setter)
1298{
Benjamin Peterson93964832010-06-28 03:07:10 +00001299 return property_copy(self, NULL, setter, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001300}
1301
Christian Heimes0449f632007-12-15 01:27:15 +00001302
Guido van Rossum58da9312007-11-10 23:39:45 +00001303PyDoc_STRVAR(deleter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 "Descriptor to change the deleter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001305
Neal Norwitz32dde222008-04-15 06:43:13 +00001306static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001307property_deleter(PyObject *self, PyObject *deleter)
1308{
Benjamin Peterson93964832010-06-28 03:07:10 +00001309 return property_copy(self, NULL, NULL, deleter);
Guido van Rossum58da9312007-11-10 23:39:45 +00001310}
1311
1312
Guido van Rossum58da9312007-11-10 23:39:45 +00001313static PyMethodDef property_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 {"getter", property_getter, METH_O, getter_doc},
1315 {"setter", property_setter, METH_O, setter_doc},
1316 {"deleter", property_deleter, METH_O, deleter_doc},
1317 {0}
Guido van Rossum58da9312007-11-10 23:39:45 +00001318};
1319
Tim Peters66c1a522001-09-24 21:17:50 +00001320
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001321static void
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001322property_dealloc(PyObject *self)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001323{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 propertyobject *gs = (propertyobject *)self;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 _PyObject_GC_UNTRACK(self);
1327 Py_XDECREF(gs->prop_get);
1328 Py_XDECREF(gs->prop_set);
1329 Py_XDECREF(gs->prop_del);
1330 Py_XDECREF(gs->prop_doc);
1331 self->ob_type->tp_free(self);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001332}
1333
1334static PyObject *
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001335property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 if (obj == NULL || obj == Py_None) {
1338 Py_INCREF(self);
1339 return self;
1340 }
Victor Stinnere972c132018-10-01 03:03:22 -07001341
1342 propertyobject *gs = (propertyobject *)self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 if (gs->prop_get == NULL) {
1344 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1345 return NULL;
1346 }
Victor Stinnere972c132018-10-01 03:03:22 -07001347
1348 PyObject *args[1] = {obj};
1349 return _PyObject_FastCall(gs->prop_get, args, 1);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001350}
1351
1352static int
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001353property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 propertyobject *gs = (propertyobject *)self;
1356 PyObject *func, *res;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 if (value == NULL)
1359 func = gs->prop_del;
1360 else
1361 func = gs->prop_set;
1362 if (func == NULL) {
1363 PyErr_SetString(PyExc_AttributeError,
1364 value == NULL ?
1365 "can't delete attribute" :
1366 "can't set attribute");
1367 return -1;
1368 }
1369 if (value == NULL)
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01001370 res = PyObject_CallFunctionObjArgs(func, obj, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 else
Benjamin Peterson9b955de2010-12-07 04:04:02 +00001372 res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 if (res == NULL)
1374 return -1;
1375 Py_DECREF(res);
1376 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001377}
1378
Christian Heimes0449f632007-12-15 01:27:15 +00001379static PyObject *
Benjamin Peterson93964832010-06-28 03:07:10 +00001380property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
Christian Heimes0449f632007-12-15 01:27:15 +00001381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 propertyobject *pold = (propertyobject *)old;
Benjamin Peterson93964832010-06-28 03:07:10 +00001383 PyObject *new, *type, *doc;
Christian Heimes0449f632007-12-15 01:27:15 +00001384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 type = PyObject_Type(old);
1386 if (type == NULL)
1387 return NULL;
Christian Heimes0449f632007-12-15 01:27:15 +00001388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 if (get == NULL || get == Py_None) {
1390 Py_XDECREF(get);
1391 get = pold->prop_get ? pold->prop_get : Py_None;
1392 }
1393 if (set == NULL || set == Py_None) {
1394 Py_XDECREF(set);
1395 set = pold->prop_set ? pold->prop_set : Py_None;
1396 }
1397 if (del == NULL || del == Py_None) {
1398 Py_XDECREF(del);
1399 del = pold->prop_del ? pold->prop_del : Py_None;
1400 }
Benjamin Peterson93964832010-06-28 03:07:10 +00001401 if (pold->getter_doc && get != Py_None) {
1402 /* make _init use __doc__ from getter */
1403 doc = Py_None;
1404 }
1405 else {
1406 doc = pold->prop_doc ? pold->prop_doc : Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 }
R. David Murrayb18500d2009-05-04 22:59:07 +00001408
Victor Stinner5abaa2b2016-12-09 16:22:32 +01001409 new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 Py_DECREF(type);
1411 if (new == NULL)
1412 return NULL;
1413 return new;
Christian Heimes0449f632007-12-15 01:27:15 +00001414}
1415
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001416/*[clinic input]
1417property.__init__ as property_init
1418
1419 fget: object(c_default="NULL") = None
1420 function to be used for getting an attribute value
1421 fset: object(c_default="NULL") = None
1422 function to be used for setting an attribute value
1423 fdel: object(c_default="NULL") = None
1424 function to be used for del'ing an attribute
1425 doc: object(c_default="NULL") = None
1426 docstring
1427
1428Property attribute.
1429
1430Typical use is to define a managed attribute x:
1431
1432class C(object):
1433 def getx(self): return self._x
1434 def setx(self, value): self._x = value
1435 def delx(self): del self._x
1436 x = property(getx, setx, delx, "I'm the 'x' property.")
1437
1438Decorators make defining new properties or modifying existing ones easy:
1439
1440class C(object):
1441 @property
1442 def x(self):
1443 "I am the 'x' property."
1444 return self._x
1445 @x.setter
1446 def x(self, value):
1447 self._x = value
1448 @x.deleter
1449 def x(self):
1450 del self._x
1451[clinic start generated code]*/
1452
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001453static int
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001454property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1455 PyObject *fdel, PyObject *doc)
1456/*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001457{
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001458 if (fget == Py_None)
1459 fget = NULL;
1460 if (fset == Py_None)
1461 fset = NULL;
1462 if (fdel == Py_None)
1463 fdel = NULL;
Tim Peters66c1a522001-09-24 21:17:50 +00001464
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001465 Py_XINCREF(fget);
1466 Py_XINCREF(fset);
1467 Py_XINCREF(fdel);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 Py_XINCREF(doc);
Christian Heimes0449f632007-12-15 01:27:15 +00001469
Oren Milmand019bc82018-02-13 12:28:33 +02001470 Py_XSETREF(self->prop_get, fget);
1471 Py_XSETREF(self->prop_set, fset);
1472 Py_XSETREF(self->prop_del, fdel);
1473 Py_XSETREF(self->prop_doc, doc);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001474 self->getter_doc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 /* if no docstring given and the getter has one, use that one */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001477 if ((doc == NULL || doc == Py_None) && fget != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001478 _Py_IDENTIFIER(__doc__);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001479 PyObject *get_doc = _PyObject_GetAttrId(fget, &PyId___doc__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 if (get_doc) {
1481 if (Py_TYPE(self) == &PyProperty_Type) {
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001482 Py_XSETREF(self->prop_doc, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 }
1484 else {
1485 /* If this is a property subclass, put __doc__
1486 in dict of the subclass instance instead,
1487 otherwise it gets shadowed by __doc__ in the
1488 class's dict. */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001489 int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 Py_DECREF(get_doc);
1491 if (err < 0)
1492 return -1;
1493 }
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001494 self->getter_doc = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 }
1496 else if (PyErr_ExceptionMatches(PyExc_Exception)) {
1497 PyErr_Clear();
1498 }
1499 else {
1500 return -1;
1501 }
1502 }
1503
1504 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001505}
1506
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001507static PyObject *
1508property_get___isabstractmethod__(propertyobject *prop, void *closure)
1509{
1510 int res = _PyObject_IsAbstract(prop->prop_get);
1511 if (res == -1) {
1512 return NULL;
1513 }
1514 else if (res) {
1515 Py_RETURN_TRUE;
1516 }
1517
1518 res = _PyObject_IsAbstract(prop->prop_set);
1519 if (res == -1) {
1520 return NULL;
1521 }
1522 else if (res) {
1523 Py_RETURN_TRUE;
1524 }
1525
1526 res = _PyObject_IsAbstract(prop->prop_del);
1527 if (res == -1) {
1528 return NULL;
1529 }
1530 else if (res) {
1531 Py_RETURN_TRUE;
1532 }
1533 Py_RETURN_FALSE;
1534}
1535
1536static PyGetSetDef property_getsetlist[] = {
1537 {"__isabstractmethod__",
1538 (getter)property_get___isabstractmethod__, NULL,
1539 NULL,
1540 NULL},
1541 {NULL} /* Sentinel */
1542};
1543
Guido van Rossum048eb752001-10-02 21:24:57 +00001544static int
1545property_traverse(PyObject *self, visitproc visit, void *arg)
1546{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 propertyobject *pp = (propertyobject *)self;
1548 Py_VISIT(pp->prop_get);
1549 Py_VISIT(pp->prop_set);
1550 Py_VISIT(pp->prop_del);
1551 Py_VISIT(pp->prop_doc);
1552 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001553}
1554
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001555static int
1556property_clear(PyObject *self)
1557{
1558 propertyobject *pp = (propertyobject *)self;
1559 Py_CLEAR(pp->prop_doc);
1560 return 0;
1561}
1562
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001563#include "clinic/descrobject.c.h"
1564
1565PyTypeObject PyDictProxy_Type = {
1566 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1567 "mappingproxy", /* tp_name */
1568 sizeof(mappingproxyobject), /* tp_basicsize */
1569 0, /* tp_itemsize */
1570 /* methods */
1571 (destructor)mappingproxy_dealloc, /* tp_dealloc */
1572 0, /* tp_print */
1573 0, /* tp_getattr */
1574 0, /* tp_setattr */
1575 0, /* tp_reserved */
1576 (reprfunc)mappingproxy_repr, /* tp_repr */
1577 0, /* tp_as_number */
1578 &mappingproxy_as_sequence, /* tp_as_sequence */
1579 &mappingproxy_as_mapping, /* tp_as_mapping */
1580 0, /* tp_hash */
1581 0, /* tp_call */
1582 (reprfunc)mappingproxy_str, /* tp_str */
1583 PyObject_GenericGetAttr, /* tp_getattro */
1584 0, /* tp_setattro */
1585 0, /* tp_as_buffer */
1586 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1587 0, /* tp_doc */
1588 mappingproxy_traverse, /* tp_traverse */
1589 0, /* tp_clear */
1590 (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
1591 0, /* tp_weaklistoffset */
1592 (getiterfunc)mappingproxy_getiter, /* tp_iter */
1593 0, /* tp_iternext */
1594 mappingproxy_methods, /* tp_methods */
1595 0, /* tp_members */
1596 0, /* tp_getset */
1597 0, /* tp_base */
1598 0, /* tp_dict */
1599 0, /* tp_descr_get */
1600 0, /* tp_descr_set */
1601 0, /* tp_dictoffset */
1602 0, /* tp_init */
1603 0, /* tp_alloc */
1604 mappingproxy_new, /* tp_new */
1605};
1606
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001607PyTypeObject PyProperty_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1609 "property", /* tp_name */
1610 sizeof(propertyobject), /* tp_basicsize */
1611 0, /* tp_itemsize */
1612 /* methods */
1613 property_dealloc, /* tp_dealloc */
1614 0, /* tp_print */
1615 0, /* tp_getattr */
1616 0, /* tp_setattr */
1617 0, /* tp_reserved */
1618 0, /* tp_repr */
1619 0, /* tp_as_number */
1620 0, /* tp_as_sequence */
1621 0, /* tp_as_mapping */
1622 0, /* tp_hash */
1623 0, /* tp_call */
1624 0, /* tp_str */
1625 PyObject_GenericGetAttr, /* tp_getattro */
1626 0, /* tp_setattro */
1627 0, /* tp_as_buffer */
1628 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1629 Py_TPFLAGS_BASETYPE, /* tp_flags */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001630 property_init__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 property_traverse, /* tp_traverse */
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001632 (inquiry)property_clear, /* tp_clear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 0, /* tp_richcompare */
1634 0, /* tp_weaklistoffset */
1635 0, /* tp_iter */
1636 0, /* tp_iternext */
1637 property_methods, /* tp_methods */
1638 property_members, /* tp_members */
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001639 property_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 0, /* tp_base */
1641 0, /* tp_dict */
1642 property_descr_get, /* tp_descr_get */
1643 property_descr_set, /* tp_descr_set */
1644 0, /* tp_dictoffset */
1645 property_init, /* tp_init */
1646 PyType_GenericAlloc, /* tp_alloc */
1647 PyType_GenericNew, /* tp_new */
1648 PyObject_GC_Del, /* tp_free */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001649};