blob: dd3c5014aea79845a997c02b1ae66f4153c545de [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"
Tim Peters6d6c1a32001-08-02 04:15:00 +00006#include "structmember.h" /* Why is this not included in Python.h? */
7
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02008/*[clinic input]
9class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type"
10class property "propertyobject *" "&PyProperty_Type"
11[clinic start generated code]*/
12/*[clinic end generated code: output=da39a3ee5e6b4b0d input=556352653fd4c02e]*/
13
Tim Peters6d6c1a32001-08-02 04:15:00 +000014static void
15descr_dealloc(PyDescrObject *descr)
16{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000017 _PyObject_GC_UNTRACK(descr);
18 Py_XDECREF(descr->d_type);
19 Py_XDECREF(descr->d_name);
Antoine Pitrou9d574812011-12-12 13:47:25 +010020 Py_XDECREF(descr->d_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000021 PyObject_GC_Del(descr);
Tim Peters6d6c1a32001-08-02 04:15:00 +000022}
23
Walter Dörwaldd7fb7642007-06-11 16:36:59 +000024static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +000025descr_name(PyDescrObject *descr)
26{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000027 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
28 return descr->d_name;
29 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +000030}
31
32static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020033descr_repr(PyDescrObject *descr, const char *format)
Tim Peters6d6c1a32001-08-02 04:15:00 +000034{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000035 PyObject *name = NULL;
36 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
37 name = descr->d_name;
Walter Dörwaldd7fb7642007-06-11 16:36:59 +000038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000039 return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name);
Tim Peters6d6c1a32001-08-02 04:15:00 +000040}
41
42static PyObject *
43method_repr(PyMethodDescrObject *descr)
44{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000045 return descr_repr((PyDescrObject *)descr,
46 "<method '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000047}
48
49static PyObject *
50member_repr(PyMemberDescrObject *descr)
51{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052 return descr_repr((PyDescrObject *)descr,
53 "<member '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000054}
55
56static PyObject *
57getset_repr(PyGetSetDescrObject *descr)
58{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059 return descr_repr((PyDescrObject *)descr,
60 "<attribute '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000061}
62
63static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +000064wrapperdescr_repr(PyWrapperDescrObject *descr)
Tim Peters6d6c1a32001-08-02 04:15:00 +000065{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 return descr_repr((PyDescrObject *)descr,
67 "<slot wrapper '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000068}
69
70static int
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +000071descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +000072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000073 if (obj == NULL) {
74 Py_INCREF(descr);
75 *pres = (PyObject *)descr;
76 return 1;
77 }
78 if (!PyObject_TypeCheck(obj, descr->d_type)) {
79 PyErr_Format(PyExc_TypeError,
80 "descriptor '%V' for '%s' objects "
81 "doesn't apply to '%s' object",
82 descr_name((PyDescrObject *)descr), "?",
83 descr->d_type->tp_name,
84 obj->ob_type->tp_name);
85 *pres = NULL;
86 return 1;
87 }
88 return 0;
Tim Peters6d6c1a32001-08-02 04:15:00 +000089}
90
91static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +000092classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Petersbca1cbc2002-12-09 22:56:13 +000093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 /* Ensure a valid type. Class methods ignore obj. */
95 if (type == NULL) {
96 if (obj != NULL)
97 type = (PyObject *)obj->ob_type;
98 else {
99 /* Wot - no type?! */
100 PyErr_Format(PyExc_TypeError,
101 "descriptor '%V' for type '%s' "
102 "needs either an object or a type",
103 descr_name((PyDescrObject *)descr), "?",
104 PyDescr_TYPE(descr)->tp_name);
105 return NULL;
106 }
107 }
108 if (!PyType_Check(type)) {
109 PyErr_Format(PyExc_TypeError,
110 "descriptor '%V' for type '%s' "
111 "needs a type, not a '%s' as arg 2",
112 descr_name((PyDescrObject *)descr), "?",
113 PyDescr_TYPE(descr)->tp_name,
114 type->ob_type->tp_name);
115 return NULL;
116 }
117 if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) {
118 PyErr_Format(PyExc_TypeError,
119 "descriptor '%V' for type '%s' "
120 "doesn't apply to type '%s'",
121 descr_name((PyDescrObject *)descr), "?",
122 PyDescr_TYPE(descr)->tp_name,
123 ((PyTypeObject *)type)->tp_name);
124 return NULL;
125 }
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200126 return PyCFunction_NewEx(descr->d_method, type, NULL);
Tim Petersbca1cbc2002-12-09 22:56:13 +0000127}
128
129static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000130method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000131{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 if (descr_check((PyDescrObject *)descr, obj, &res))
135 return res;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200136 return PyCFunction_NewEx(descr->d_method, obj, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000137}
138
139static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000140member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000141{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 if (descr_check((PyDescrObject *)descr, obj, &res))
145 return res;
146 return PyMember_GetOne((char *)obj, descr->d_member);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000147}
148
149static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000150getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 if (descr_check((PyDescrObject *)descr, obj, &res))
155 return res;
156 if (descr->d_getset->get != NULL)
157 return descr->d_getset->get(obj, descr->d_getset->closure);
158 PyErr_Format(PyExc_AttributeError,
159 "attribute '%V' of '%.100s' objects is not readable",
160 descr_name((PyDescrObject *)descr), "?",
161 PyDescr_TYPE(descr)->tp_name);
162 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000163}
164
165static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000166wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 if (descr_check((PyDescrObject *)descr, obj, &res))
171 return res;
172 return PyWrapper_New((PyObject *)descr, obj);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000173}
174
175static int
176descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 int *pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000179 assert(obj != NULL);
180 if (!PyObject_TypeCheck(obj, descr->d_type)) {
181 PyErr_Format(PyExc_TypeError,
182 "descriptor '%V' for '%.100s' objects "
183 "doesn't apply to '%.100s' object",
184 descr_name(descr), "?",
185 descr->d_type->tp_name,
186 obj->ob_type->tp_name);
187 *pres = -1;
188 return 1;
189 }
190 return 0;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000191}
192
193static int
194member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
199 return res;
200 return PyMember_SetOne((char *)obj, descr->d_member, value);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000201}
202
203static int
204getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
209 return res;
210 if (descr->d_getset->set != NULL)
211 return descr->d_getset->set(obj, value,
212 descr->d_getset->closure);
213 PyErr_Format(PyExc_AttributeError,
214 "attribute '%V' of '%.100s' objects is not writable",
215 descr_name((PyDescrObject *)descr), "?",
216 PyDescr_TYPE(descr)->tp_name);
217 return -1;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000218}
219
220static PyObject *
Victor Stinnerc5257232017-01-18 10:38:09 +0100221methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000222{
Victor Stinnerc5257232017-01-18 10:38:09 +0100223 Py_ssize_t nargs;
224 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 /* Make sure that the first argument is acceptable as 'self' */
227 assert(PyTuple_Check(args));
Victor Stinnerc5257232017-01-18 10:38:09 +0100228 nargs = PyTuple_GET_SIZE(args);
229 if (nargs < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 PyErr_Format(PyExc_TypeError,
231 "descriptor '%V' of '%.100s' "
232 "object needs an argument",
233 descr_name((PyDescrObject *)descr), "?",
234 PyDescr_TYPE(descr)->tp_name);
235 return NULL;
236 }
237 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200238 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200239 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 PyErr_Format(PyExc_TypeError,
241 "descriptor '%V' "
242 "requires a '%.100s' object "
243 "but received a '%.100s'",
244 descr_name((PyDescrObject *)descr), "?",
245 PyDescr_TYPE(descr)->tp_name,
246 self->ob_type->tp_name);
247 return NULL;
248 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000249
Victor Stinnerc5257232017-01-18 10:38:09 +0100250 result = _PyMethodDef_RawFastCallDict(descr->d_method, self,
Victor Stinnerd17a6932018-11-09 16:56:48 +0100251 &_PyTuple_ITEMS(args)[1], nargs - 1,
Victor Stinnerc5257232017-01-18 10:38:09 +0100252 kwargs);
253 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000255}
256
INADA Naoki5566bbb2017-02-03 07:43:03 +0900257// same to methoddescr_call(), but use FASTCALL convention.
258PyObject *
259_PyMethodDescr_FastCallKeywords(PyObject *descrobj,
Serhiy Storchakaa5552f02017-12-15 13:11:11 +0200260 PyObject *const *args, Py_ssize_t nargs,
INADA Naoki5566bbb2017-02-03 07:43:03 +0900261 PyObject *kwnames)
262{
263 assert(Py_TYPE(descrobj) == &PyMethodDescr_Type);
264 PyMethodDescrObject *descr = (PyMethodDescrObject *)descrobj;
265 PyObject *self, *result;
266
267 /* Make sure that the first argument is acceptable as 'self' */
268 if (nargs < 1) {
269 PyErr_Format(PyExc_TypeError,
270 "descriptor '%V' of '%.100s' "
271 "object needs an argument",
272 descr_name((PyDescrObject *)descr), "?",
273 PyDescr_TYPE(descr)->tp_name);
274 return NULL;
275 }
276 self = args[0];
277 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
278 (PyObject *)PyDescr_TYPE(descr))) {
279 PyErr_Format(PyExc_TypeError,
280 "descriptor '%V' "
281 "requires a '%.100s' object "
282 "but received a '%.100s'",
283 descr_name((PyDescrObject *)descr), "?",
284 PyDescr_TYPE(descr)->tp_name,
285 self->ob_type->tp_name);
286 return NULL;
287 }
288
289 result = _PyMethodDef_RawFastCallKeywords(descr->d_method, self,
290 args+1, nargs-1, kwnames);
291 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
292 return result;
293}
294
Tim Peters6d6c1a32001-08-02 04:15:00 +0000295static PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000296classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 PyObject *kwds)
Tim Petersbca1cbc2002-12-09 22:56:13 +0000298{
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400299 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300300 PyObject *self, *result;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000301
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400302 /* Make sure that the first argument is acceptable as 'self' */
303 assert(PyTuple_Check(args));
304 argc = PyTuple_GET_SIZE(args);
305 if (argc < 1) {
306 PyErr_Format(PyExc_TypeError,
307 "descriptor '%V' of '%.100s' "
308 "object needs an argument",
309 descr_name((PyDescrObject *)descr), "?",
310 PyDescr_TYPE(descr)->tp_name);
311 return NULL;
312 }
313 self = PyTuple_GET_ITEM(args, 0);
314 if (!PyType_Check(self)) {
315 PyErr_Format(PyExc_TypeError,
316 "descriptor '%V' requires a type "
317 "but received a '%.100s'",
318 descr_name((PyDescrObject *)descr), "?",
319 PyDescr_TYPE(descr)->tp_name,
320 self->ob_type->tp_name);
321 return NULL;
322 }
323 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) {
324 PyErr_Format(PyExc_TypeError,
325 "descriptor '%V' "
326 "requires a subtype of '%.100s' "
327 "but received '%.100s",
328 descr_name((PyDescrObject *)descr), "?",
329 PyDescr_TYPE(descr)->tp_name,
330 self->ob_type->tp_name);
331 return NULL;
332 }
333
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300334 result = _PyMethodDef_RawFastCallDict(descr->d_method, self,
Victor Stinnerd17a6932018-11-09 16:56:48 +0100335 &_PyTuple_ITEMS(args)[1], argc - 1,
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300336 kwds);
337 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 return result;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000339}
340
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300341Py_LOCAL_INLINE(PyObject *)
342wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self,
343 PyObject *args, PyObject *kwds)
344{
345 wrapperfunc wrapper = descr->d_base->wrapper;
346
347 if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
348 wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
349 return (*wk)(self, args, descr->d_wrapped, kwds);
350 }
351
352 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) {
353 PyErr_Format(PyExc_TypeError,
354 "wrapper %s() takes no keyword arguments",
355 descr->d_base->name);
356 return NULL;
357 }
358 return (*wrapper)(self, args, descr->d_wrapped);
359}
360
Tim Petersbca1cbc2002-12-09 22:56:13 +0000361static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000362wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300365 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 /* Make sure that the first argument is acceptable as 'self' */
368 assert(PyTuple_Check(args));
369 argc = PyTuple_GET_SIZE(args);
370 if (argc < 1) {
371 PyErr_Format(PyExc_TypeError,
372 "descriptor '%V' of '%.100s' "
373 "object needs an argument",
374 descr_name((PyDescrObject *)descr), "?",
375 PyDescr_TYPE(descr)->tp_name);
376 return NULL;
377 }
378 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200379 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200380 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 PyErr_Format(PyExc_TypeError,
382 "descriptor '%V' "
383 "requires a '%.100s' object "
384 "but received a '%.100s'",
385 descr_name((PyDescrObject *)descr), "?",
386 PyDescr_TYPE(descr)->tp_name,
387 self->ob_type->tp_name);
388 return NULL;
389 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000390
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300391 args = PyTuple_GetSlice(args, 1, argc);
392 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 return NULL;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300394 }
395 result = wrapperdescr_raw_call(descr, self, args, kwds);
396 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000398}
399
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300400
Tim Peters6d6c1a32001-08-02 04:15:00 +0000401static PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000402method_get_doc(PyMethodDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000403{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800404 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800405}
406
407static PyObject *
408method_get_text_signature(PyMethodDescrObject *descr, void *closure)
409{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800410 return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000411}
412
Antoine Pitrou9d574812011-12-12 13:47:25 +0100413static PyObject *
414calculate_qualname(PyDescrObject *descr)
415{
416 PyObject *type_qualname, *res;
417 _Py_IDENTIFIER(__qualname__);
418
419 if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) {
420 PyErr_SetString(PyExc_TypeError,
421 "<descriptor>.__name__ is not a unicode object");
422 return NULL;
423 }
424
425 type_qualname = _PyObject_GetAttrId((PyObject *)descr->d_type,
426 &PyId___qualname__);
427 if (type_qualname == NULL)
428 return NULL;
429
430 if (!PyUnicode_Check(type_qualname)) {
431 PyErr_SetString(PyExc_TypeError, "<descriptor>.__objclass__."
432 "__qualname__ is not a unicode object");
433 Py_XDECREF(type_qualname);
434 return NULL;
435 }
436
437 res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name);
438 Py_DECREF(type_qualname);
439 return res;
440}
441
442static PyObject *
443descr_get_qualname(PyDescrObject *descr)
444{
445 if (descr->d_qualname == NULL)
446 descr->d_qualname = calculate_qualname(descr);
447 Py_XINCREF(descr->d_qualname);
448 return descr->d_qualname;
449}
450
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100451static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530452descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100453{
454 PyObject *builtins;
455 PyObject *getattr;
456 _Py_IDENTIFIER(getattr);
457
458 builtins = PyEval_GetBuiltins();
459 getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
460 return Py_BuildValue("O(OO)", getattr, PyDescr_TYPE(descr),
461 PyDescr_NAME(descr));
462}
463
464static PyMethodDef descr_methods[] = {
465 {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL},
466 {NULL, NULL}
467};
468
Guido van Rossum6f799372001-09-20 20:46:19 +0000469static PyMemberDef descr_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
471 {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
472 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000473};
474
Guido van Rossum32d34c82001-09-20 21:45:26 +0000475static PyGetSetDef method_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 {"__doc__", (getter)method_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100477 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800478 {"__text_signature__", (getter)method_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 {0}
Guido van Rossum6f799372001-09-20 20:46:19 +0000480};
481
482static PyObject *
483member_get_doc(PyMemberDescrObject *descr, void *closure)
484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 if (descr->d_member->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200486 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 }
488 return PyUnicode_FromString(descr->d_member->doc);
Guido van Rossum6f799372001-09-20 20:46:19 +0000489}
490
Guido van Rossum32d34c82001-09-20 21:45:26 +0000491static PyGetSetDef member_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 {"__doc__", (getter)member_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100493 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000495};
496
497static PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000498getset_get_doc(PyGetSetDescrObject *descr, void *closure)
499{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 if (descr->d_getset->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200501 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 }
503 return PyUnicode_FromString(descr->d_getset->doc);
Guido van Rossum32d34c82001-09-20 21:45:26 +0000504}
505
506static PyGetSetDef getset_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 {"__doc__", (getter)getset_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100508 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 {0}
Guido van Rossum32d34c82001-09-20 21:45:26 +0000510};
511
512static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000513wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000514{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800515 return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800516}
517
518static PyObject *
519wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
520{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800521 return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000522}
523
Armin Rigoc6686b72005-11-07 08:38:00 +0000524static PyGetSetDef wrapperdescr_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 {"__doc__", (getter)wrapperdescr_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100526 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800527 {"__text_signature__", (getter)wrapperdescr_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000529};
530
Guido van Rossum048eb752001-10-02 21:24:57 +0000531static int
532descr_traverse(PyObject *self, visitproc visit, void *arg)
533{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 PyDescrObject *descr = (PyDescrObject *)self;
535 Py_VISIT(descr->d_type);
536 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000537}
538
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000539PyTypeObject PyMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 PyVarObject_HEAD_INIT(&PyType_Type, 0)
541 "method_descriptor",
542 sizeof(PyMethodDescrObject),
543 0,
544 (destructor)descr_dealloc, /* tp_dealloc */
545 0, /* tp_print */
546 0, /* tp_getattr */
547 0, /* tp_setattr */
548 0, /* tp_reserved */
549 (reprfunc)method_repr, /* tp_repr */
550 0, /* tp_as_number */
551 0, /* tp_as_sequence */
552 0, /* tp_as_mapping */
553 0, /* tp_hash */
554 (ternaryfunc)methoddescr_call, /* tp_call */
555 0, /* tp_str */
556 PyObject_GenericGetAttr, /* tp_getattro */
557 0, /* tp_setattro */
558 0, /* tp_as_buffer */
559 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
560 0, /* tp_doc */
561 descr_traverse, /* tp_traverse */
562 0, /* tp_clear */
563 0, /* tp_richcompare */
564 0, /* tp_weaklistoffset */
565 0, /* tp_iter */
566 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100567 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 descr_members, /* tp_members */
569 method_getset, /* tp_getset */
570 0, /* tp_base */
571 0, /* tp_dict */
572 (descrgetfunc)method_get, /* tp_descr_get */
573 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000574};
575
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000576/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000577PyTypeObject PyClassMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 PyVarObject_HEAD_INIT(&PyType_Type, 0)
579 "classmethod_descriptor",
580 sizeof(PyMethodDescrObject),
581 0,
582 (destructor)descr_dealloc, /* tp_dealloc */
583 0, /* tp_print */
584 0, /* tp_getattr */
585 0, /* tp_setattr */
586 0, /* tp_reserved */
587 (reprfunc)method_repr, /* tp_repr */
588 0, /* tp_as_number */
589 0, /* tp_as_sequence */
590 0, /* tp_as_mapping */
591 0, /* tp_hash */
592 (ternaryfunc)classmethoddescr_call, /* tp_call */
593 0, /* tp_str */
594 PyObject_GenericGetAttr, /* tp_getattro */
595 0, /* tp_setattro */
596 0, /* tp_as_buffer */
597 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
598 0, /* tp_doc */
599 descr_traverse, /* tp_traverse */
600 0, /* tp_clear */
601 0, /* tp_richcompare */
602 0, /* tp_weaklistoffset */
603 0, /* tp_iter */
604 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100605 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 descr_members, /* tp_members */
607 method_getset, /* tp_getset */
608 0, /* tp_base */
609 0, /* tp_dict */
610 (descrgetfunc)classmethod_get, /* tp_descr_get */
611 0, /* tp_descr_set */
Tim Petersbca1cbc2002-12-09 22:56:13 +0000612};
613
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000614PyTypeObject PyMemberDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 PyVarObject_HEAD_INIT(&PyType_Type, 0)
616 "member_descriptor",
617 sizeof(PyMemberDescrObject),
618 0,
619 (destructor)descr_dealloc, /* tp_dealloc */
620 0, /* tp_print */
621 0, /* tp_getattr */
622 0, /* tp_setattr */
623 0, /* tp_reserved */
624 (reprfunc)member_repr, /* tp_repr */
625 0, /* tp_as_number */
626 0, /* tp_as_sequence */
627 0, /* tp_as_mapping */
628 0, /* tp_hash */
629 0, /* tp_call */
630 0, /* tp_str */
631 PyObject_GenericGetAttr, /* tp_getattro */
632 0, /* tp_setattro */
633 0, /* tp_as_buffer */
634 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
635 0, /* tp_doc */
636 descr_traverse, /* tp_traverse */
637 0, /* tp_clear */
638 0, /* tp_richcompare */
639 0, /* tp_weaklistoffset */
640 0, /* tp_iter */
641 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100642 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 descr_members, /* tp_members */
644 member_getset, /* tp_getset */
645 0, /* tp_base */
646 0, /* tp_dict */
647 (descrgetfunc)member_get, /* tp_descr_get */
648 (descrsetfunc)member_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000649};
650
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000651PyTypeObject PyGetSetDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 PyVarObject_HEAD_INIT(&PyType_Type, 0)
653 "getset_descriptor",
654 sizeof(PyGetSetDescrObject),
655 0,
656 (destructor)descr_dealloc, /* tp_dealloc */
657 0, /* tp_print */
658 0, /* tp_getattr */
659 0, /* tp_setattr */
660 0, /* tp_reserved */
661 (reprfunc)getset_repr, /* tp_repr */
662 0, /* tp_as_number */
663 0, /* tp_as_sequence */
664 0, /* tp_as_mapping */
665 0, /* tp_hash */
666 0, /* tp_call */
667 0, /* tp_str */
668 PyObject_GenericGetAttr, /* tp_getattro */
669 0, /* tp_setattro */
670 0, /* tp_as_buffer */
671 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
672 0, /* tp_doc */
673 descr_traverse, /* tp_traverse */
674 0, /* tp_clear */
675 0, /* tp_richcompare */
676 0, /* tp_weaklistoffset */
677 0, /* tp_iter */
678 0, /* tp_iternext */
679 0, /* tp_methods */
680 descr_members, /* tp_members */
681 getset_getset, /* tp_getset */
682 0, /* tp_base */
683 0, /* tp_dict */
684 (descrgetfunc)getset_get, /* tp_descr_get */
685 (descrsetfunc)getset_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000686};
687
Guido van Rossumf4593e02001-10-03 12:09:30 +0000688PyTypeObject PyWrapperDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 PyVarObject_HEAD_INIT(&PyType_Type, 0)
690 "wrapper_descriptor",
691 sizeof(PyWrapperDescrObject),
692 0,
693 (destructor)descr_dealloc, /* tp_dealloc */
694 0, /* tp_print */
695 0, /* tp_getattr */
696 0, /* tp_setattr */
697 0, /* tp_reserved */
698 (reprfunc)wrapperdescr_repr, /* tp_repr */
699 0, /* tp_as_number */
700 0, /* tp_as_sequence */
701 0, /* tp_as_mapping */
702 0, /* tp_hash */
703 (ternaryfunc)wrapperdescr_call, /* tp_call */
704 0, /* tp_str */
705 PyObject_GenericGetAttr, /* tp_getattro */
706 0, /* tp_setattro */
707 0, /* tp_as_buffer */
708 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
709 0, /* tp_doc */
710 descr_traverse, /* tp_traverse */
711 0, /* tp_clear */
712 0, /* tp_richcompare */
713 0, /* tp_weaklistoffset */
714 0, /* tp_iter */
715 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100716 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 descr_members, /* tp_members */
718 wrapperdescr_getset, /* tp_getset */
719 0, /* tp_base */
720 0, /* tp_dict */
721 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
722 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000723};
724
725static PyDescrObject *
Jeremy Hyltonaf68c872005-12-10 18:50:16 +0000726descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 PyDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
731 if (descr != NULL) {
732 Py_XINCREF(type);
733 descr->d_type = type;
734 descr->d_name = PyUnicode_InternFromString(name);
735 if (descr->d_name == NULL) {
736 Py_DECREF(descr);
737 descr = NULL;
738 }
Benjamin Petersonf2fe7f02011-12-17 08:02:20 -0500739 else {
740 descr->d_qualname = NULL;
741 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 }
743 return descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000744}
745
746PyObject *
747PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
748{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 PyMethodDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
752 type, method->ml_name);
753 if (descr != NULL)
754 descr->d_method = method;
755 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000756}
757
758PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000759PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 PyMethodDescrObject *descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000762
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763 descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
764 type, method->ml_name);
765 if (descr != NULL)
766 descr->d_method = method;
767 return (PyObject *)descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000768}
769
770PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000771PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 PyMemberDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775 descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
776 type, member->name);
777 if (descr != NULL)
778 descr->d_member = member;
779 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000780}
781
782PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000783PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000784{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000785 PyGetSetDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
788 type, getset->name);
789 if (descr != NULL)
790 descr->d_getset = getset;
791 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000792}
793
794PyObject *
795PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
796{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000797 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
800 type, base->name);
801 if (descr != NULL) {
802 descr->d_base = base;
803 descr->d_wrapped = wrapped;
804 }
805 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000806}
807
Tim Peters6d6c1a32001-08-02 04:15:00 +0000808
Victor Stinner0db176f2012-04-16 00:16:30 +0200809/* --- mappingproxy: read-only proxy for mappings --- */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000810
811/* This has no reason to be in this file except that adding new files is a
812 bit of a pain */
813
814typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 PyObject_HEAD
Victor Stinner0db176f2012-04-16 00:16:30 +0200816 PyObject *mapping;
817} mappingproxyobject;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000818
Martin v. Löwis18e16552006-02-15 17:27:45 +0000819static Py_ssize_t
Victor Stinner0db176f2012-04-16 00:16:30 +0200820mappingproxy_len(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000821{
Victor Stinner0db176f2012-04-16 00:16:30 +0200822 return PyObject_Size(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000823}
824
825static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200826mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000827{
Victor Stinner0db176f2012-04-16 00:16:30 +0200828 return PyObject_GetItem(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000829}
830
Victor Stinner0db176f2012-04-16 00:16:30 +0200831static PyMappingMethods mappingproxy_as_mapping = {
832 (lenfunc)mappingproxy_len, /* mp_length */
833 (binaryfunc)mappingproxy_getitem, /* mp_subscript */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 0, /* mp_ass_subscript */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000835};
836
837static int
Victor Stinner0db176f2012-04-16 00:16:30 +0200838mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000839{
Victor Stinner0db176f2012-04-16 00:16:30 +0200840 if (PyDict_CheckExact(pp->mapping))
841 return PyDict_Contains(pp->mapping, key);
842 else
843 return PySequence_Contains(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000844}
845
Victor Stinner0db176f2012-04-16 00:16:30 +0200846static PySequenceMethods mappingproxy_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 0, /* sq_length */
848 0, /* sq_concat */
849 0, /* sq_repeat */
850 0, /* sq_item */
851 0, /* sq_slice */
852 0, /* sq_ass_item */
853 0, /* sq_ass_slice */
Victor Stinner0db176f2012-04-16 00:16:30 +0200854 (objobjproc)mappingproxy_contains, /* sq_contains */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 0, /* sq_inplace_concat */
856 0, /* sq_inplace_repeat */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000857};
858
859static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200860mappingproxy_get(mappingproxyobject *pp, PyObject *args)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000861{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000862 PyObject *key, *def = Py_None;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200863 _Py_IDENTIFIER(get);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def))
866 return NULL;
Victor Stinner7e425412016-12-09 00:36:19 +0100867 return _PyObject_CallMethodIdObjArgs(pp->mapping, &PyId_get,
868 key, def, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000869}
870
871static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530872mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000873{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200874 _Py_IDENTIFIER(keys);
Victor Stinner0db176f2012-04-16 00:16:30 +0200875 return _PyObject_CallMethodId(pp->mapping, &PyId_keys, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000876}
877
878static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530879mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000880{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200881 _Py_IDENTIFIER(values);
Victor Stinner0db176f2012-04-16 00:16:30 +0200882 return _PyObject_CallMethodId(pp->mapping, &PyId_values, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000883}
884
885static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530886mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000887{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200888 _Py_IDENTIFIER(items);
Victor Stinner0db176f2012-04-16 00:16:30 +0200889 return _PyObject_CallMethodId(pp->mapping, &PyId_items, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000890}
891
892static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530893mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000894{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200895 _Py_IDENTIFIER(copy);
Victor Stinner0db176f2012-04-16 00:16:30 +0200896 return _PyObject_CallMethodId(pp->mapping, &PyId_copy, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000897}
898
Victor Stinner0db176f2012-04-16 00:16:30 +0200899/* WARNING: mappingproxy methods must not give access
900 to the underlying mapping */
901
902static PyMethodDef mappingproxy_methods[] = {
903 {"get", (PyCFunction)mappingproxy_get, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000904 PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d."
Victor Stinner0db176f2012-04-16 00:16:30 +0200905 " d defaults to None.")},
906 {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 PyDoc_STR("D.keys() -> list of D's keys")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200908 {"values", (PyCFunction)mappingproxy_values, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 PyDoc_STR("D.values() -> list of D's values")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200910 {"items", (PyCFunction)mappingproxy_items, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200912 {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 PyDoc_STR("D.copy() -> a shallow copy of D")},
914 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000915};
916
917static void
Victor Stinner0db176f2012-04-16 00:16:30 +0200918mappingproxy_dealloc(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000919{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 _PyObject_GC_UNTRACK(pp);
Victor Stinner0db176f2012-04-16 00:16:30 +0200921 Py_DECREF(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 PyObject_GC_Del(pp);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000923}
924
925static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200926mappingproxy_getiter(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000927{
Victor Stinner0db176f2012-04-16 00:16:30 +0200928 return PyObject_GetIter(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000929}
930
Neil Schemenauer26775122001-10-21 22:26:43 +0000931static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200932mappingproxy_str(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000933{
Victor Stinner0db176f2012-04-16 00:16:30 +0200934 return PyObject_Str(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000935}
936
Ezio Melottiac53ab62010-12-18 14:59:43 +0000937static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200938mappingproxy_repr(mappingproxyobject *pp)
Ezio Melottiac53ab62010-12-18 14:59:43 +0000939{
Victor Stinner0db176f2012-04-16 00:16:30 +0200940 return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping);
Ezio Melottiac53ab62010-12-18 14:59:43 +0000941}
942
Guido van Rossum048eb752001-10-02 21:24:57 +0000943static int
Victor Stinner0db176f2012-04-16 00:16:30 +0200944mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
Guido van Rossum048eb752001-10-02 21:24:57 +0000945{
Victor Stinner0db176f2012-04-16 00:16:30 +0200946 mappingproxyobject *pp = (mappingproxyobject *)self;
947 Py_VISIT(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000949}
950
Raymond Hettinger29a6d442002-08-31 15:51:04 +0000951static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200952mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op)
Raymond Hettinger29a6d442002-08-31 15:51:04 +0000953{
Victor Stinner0db176f2012-04-16 00:16:30 +0200954 return PyObject_RichCompare(v->mapping, w, op);
955}
956
957static int
958mappingproxy_check_mapping(PyObject *mapping)
959{
960 if (!PyMapping_Check(mapping)
961 || PyList_Check(mapping)
962 || PyTuple_Check(mapping)) {
963 PyErr_Format(PyExc_TypeError,
964 "mappingproxy() argument must be a mapping, not %s",
965 Py_TYPE(mapping)->tp_name);
966 return -1;
967 }
968 return 0;
969}
970
Serhiy Storchaka18b250f2017-03-19 08:51:07 +0200971/*[clinic input]
972@classmethod
973mappingproxy.__new__ as mappingproxy_new
Victor Stinner0db176f2012-04-16 00:16:30 +0200974
Serhiy Storchaka18b250f2017-03-19 08:51:07 +0200975 mapping: object
976
977[clinic start generated code]*/
978
979static PyObject *
980mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping)
981/*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/
982{
983 mappingproxyobject *mappingproxy;
Victor Stinner0db176f2012-04-16 00:16:30 +0200984
985 if (mappingproxy_check_mapping(mapping) == -1)
986 return NULL;
987
988 mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
989 if (mappingproxy == NULL)
990 return NULL;
991 Py_INCREF(mapping);
992 mappingproxy->mapping = mapping;
993 _PyObject_GC_TRACK(mappingproxy);
994 return (PyObject *)mappingproxy;
Raymond Hettinger29a6d442002-08-31 15:51:04 +0000995}
996
Tim Peters6d6c1a32001-08-02 04:15:00 +0000997PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200998PyDictProxy_New(PyObject *mapping)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000999{
Victor Stinner0db176f2012-04-16 00:16:30 +02001000 mappingproxyobject *pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001001
Victor Stinner0db176f2012-04-16 00:16:30 +02001002 if (mappingproxy_check_mapping(mapping) == -1)
1003 return NULL;
1004
1005 pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 if (pp != NULL) {
Victor Stinner0db176f2012-04-16 00:16:30 +02001007 Py_INCREF(mapping);
1008 pp->mapping = mapping;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 _PyObject_GC_TRACK(pp);
1010 }
1011 return (PyObject *)pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001012}
1013
1014
1015/* --- Wrapper object for "slot" methods --- */
1016
1017/* This has no reason to be in this file except that adding new files is a
1018 bit of a pain */
1019
1020typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 PyObject_HEAD
1022 PyWrapperDescrObject *descr;
1023 PyObject *self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001024} wrapperobject;
1025
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001026#define Wrapper_Check(v) (Py_TYPE(v) == &_PyMethodWrapper_Type)
Mark Dickinson211c6252009-02-01 10:28:51 +00001027
Tim Peters6d6c1a32001-08-02 04:15:00 +00001028static void
1029wrapper_dealloc(wrapperobject *wp)
1030{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 PyObject_GC_UnTrack(wp);
1032 Py_TRASHCAN_SAFE_BEGIN(wp)
1033 Py_XDECREF(wp->descr);
1034 Py_XDECREF(wp->self);
1035 PyObject_GC_Del(wp);
1036 Py_TRASHCAN_SAFE_END(wp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001037}
1038
Mark Dickinson211c6252009-02-01 10:28:51 +00001039static PyObject *
1040wrapper_richcompare(PyObject *a, PyObject *b, int op)
Armin Rigoc6686b72005-11-07 08:38:00 +00001041{
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001042 wrapperobject *wa, *wb;
1043 int eq;
Mark Dickinson211c6252009-02-01 10:28:51 +00001044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +00001046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 /* both arguments should be wrapperobjects */
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001048 if ((op != Py_EQ && op != Py_NE)
1049 || !Wrapper_Check(a) || !Wrapper_Check(b))
1050 {
stratakise8b19652017-11-02 11:32:54 +01001051 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 }
Mark Dickinson211c6252009-02-01 10:28:51 +00001053
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001054 wa = (wrapperobject *)a;
1055 wb = (wrapperobject *)b;
1056 eq = (wa->descr == wb->descr && wa->self == wb->self);
1057 if (eq == (op == Py_EQ)) {
1058 Py_RETURN_TRUE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 }
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001060 else {
1061 Py_RETURN_FALSE;
1062 }
Armin Rigoc6686b72005-11-07 08:38:00 +00001063}
1064
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001065static Py_hash_t
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001066wrapper_hash(wrapperobject *wp)
1067{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001068 Py_hash_t x, y;
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001069 x = _Py_HashPointer(wp->self);
1070 y = _Py_HashPointer(wp->descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 x = x ^ y;
1072 if (x == -1)
1073 x = -2;
1074 return x;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001075}
1076
Armin Rigoc6686b72005-11-07 08:38:00 +00001077static PyObject *
1078wrapper_repr(wrapperobject *wp)
1079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
1081 wp->descr->d_base->name,
1082 wp->self->ob_type->tp_name,
1083 wp->self);
Armin Rigoc6686b72005-11-07 08:38:00 +00001084}
1085
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001086static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301087wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001088{
1089 PyObject *builtins;
1090 PyObject *getattr;
1091 _Py_IDENTIFIER(getattr);
1092
1093 builtins = PyEval_GetBuiltins();
1094 getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
1095 return Py_BuildValue("O(OO)", getattr, wp->self, PyDescr_NAME(wp->descr));
1096}
1097
1098static PyMethodDef wrapper_methods[] = {
1099 {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
1100 {NULL, NULL}
1101};
1102
Armin Rigoc6686b72005-11-07 08:38:00 +00001103static PyMemberDef wrapper_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
1105 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001106};
1107
1108static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +00001109wrapper_objclass(wrapperobject *wp)
1110{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111 PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
Armin Rigoc6686b72005-11-07 08:38:00 +00001112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 Py_INCREF(c);
1114 return c;
Armin Rigoc6686b72005-11-07 08:38:00 +00001115}
1116
1117static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +00001118wrapper_name(wrapperobject *wp)
1119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 const char *s = wp->descr->d_base->name;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 return PyUnicode_FromString(s);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001123}
1124
1125static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08001126wrapper_doc(wrapperobject *wp, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001127{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001128 return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -08001129}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001130
Larry Hastings5c661892014-01-24 06:17:25 -08001131static PyObject *
1132wrapper_text_signature(wrapperobject *wp, void *closure)
1133{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001134 return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001135}
1136
Antoine Pitrou9d574812011-12-12 13:47:25 +01001137static PyObject *
1138wrapper_qualname(wrapperobject *wp)
1139{
1140 return descr_get_qualname((PyDescrObject *)wp->descr);
1141}
1142
Guido van Rossum32d34c82001-09-20 21:45:26 +00001143static PyGetSetDef wrapper_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 {"__objclass__", (getter)wrapper_objclass},
1145 {"__name__", (getter)wrapper_name},
Antoine Pitrou9d574812011-12-12 13:47:25 +01001146 {"__qualname__", (getter)wrapper_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 {"__doc__", (getter)wrapper_doc},
Larry Hastings5c661892014-01-24 06:17:25 -08001148 {"__text_signature__", (getter)wrapper_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001150};
1151
1152static PyObject *
1153wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
1154{
Serhiy Storchaka5e02c782017-09-21 14:25:36 +03001155 return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001156}
1157
Guido van Rossum048eb752001-10-02 21:24:57 +00001158static int
1159wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 wrapperobject *wp = (wrapperobject *)self;
1162 Py_VISIT(wp->descr);
1163 Py_VISIT(wp->self);
1164 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001165}
1166
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001167PyTypeObject _PyMethodWrapper_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1169 "method-wrapper", /* tp_name */
1170 sizeof(wrapperobject), /* tp_basicsize */
1171 0, /* tp_itemsize */
1172 /* methods */
1173 (destructor)wrapper_dealloc, /* tp_dealloc */
1174 0, /* tp_print */
1175 0, /* tp_getattr */
1176 0, /* tp_setattr */
1177 0, /* tp_reserved */
1178 (reprfunc)wrapper_repr, /* tp_repr */
1179 0, /* tp_as_number */
1180 0, /* tp_as_sequence */
1181 0, /* tp_as_mapping */
1182 (hashfunc)wrapper_hash, /* tp_hash */
1183 (ternaryfunc)wrapper_call, /* tp_call */
1184 0, /* tp_str */
1185 PyObject_GenericGetAttr, /* tp_getattro */
1186 0, /* tp_setattro */
1187 0, /* tp_as_buffer */
1188 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1189 0, /* tp_doc */
1190 wrapper_traverse, /* tp_traverse */
1191 0, /* tp_clear */
1192 wrapper_richcompare, /* tp_richcompare */
1193 0, /* tp_weaklistoffset */
1194 0, /* tp_iter */
1195 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001196 wrapper_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 wrapper_members, /* tp_members */
1198 wrapper_getsets, /* tp_getset */
1199 0, /* tp_base */
1200 0, /* tp_dict */
1201 0, /* tp_descr_get */
1202 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001203};
1204
1205PyObject *
1206PyWrapper_New(PyObject *d, PyObject *self)
1207{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 wrapperobject *wp;
1209 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1212 descr = (PyWrapperDescrObject *)d;
Victor Stinner3249dec2011-05-01 23:19:15 +02001213 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +02001214 (PyObject *)PyDescr_TYPE(descr)));
Tim Peters6d6c1a32001-08-02 04:15:00 +00001215
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001216 wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 if (wp != NULL) {
1218 Py_INCREF(descr);
1219 wp->descr = descr;
1220 Py_INCREF(self);
1221 wp->self = self;
1222 _PyObject_GC_TRACK(wp);
1223 }
1224 return (PyObject *)wp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001225}
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001226
1227
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001228/* A built-in 'property' type */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001229
1230/*
Serhiy Storchakad741a882015-06-11 00:06:39 +03001231class property(object):
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
1234 if doc is None and fget is not None and hasattr(fget, "__doc__"):
Serhiy Storchakad741a882015-06-11 00:06:39 +03001235 doc = fget.__doc__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 self.__get = fget
1237 self.__set = fset
1238 self.__del = fdel
1239 self.__doc__ = doc
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 def __get__(self, inst, type=None):
1242 if inst is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001243 return self
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 if self.__get is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001245 raise AttributeError, "unreadable attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 return self.__get(inst)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 def __set__(self, inst, value):
1249 if self.__set is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001250 raise AttributeError, "can't set attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 return self.__set(inst, value)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 def __delete__(self, inst):
1254 if self.__del is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001255 raise AttributeError, "can't delete attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 return self.__del(inst)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001257
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001258*/
1259
1260typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 PyObject_HEAD
1262 PyObject *prop_get;
1263 PyObject *prop_set;
1264 PyObject *prop_del;
1265 PyObject *prop_doc;
1266 int getter_doc;
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001267} propertyobject;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001268
Christian Heimes0449f632007-12-15 01:27:15 +00001269static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
Benjamin Peterson93964832010-06-28 03:07:10 +00001270 PyObject *);
Christian Heimes0449f632007-12-15 01:27:15 +00001271
Tim Peters66c1a522001-09-24 21:17:50 +00001272static PyMemberDef property_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
1274 {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
1275 {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
Raymond Hettingereac503a2015-05-13 01:09:59 -07001276 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 {0}
Tim Peters66c1a522001-09-24 21:17:50 +00001278};
1279
Christian Heimes0449f632007-12-15 01:27:15 +00001280
Guido van Rossum58da9312007-11-10 23:39:45 +00001281PyDoc_STRVAR(getter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 "Descriptor to change the getter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001283
Neal Norwitz32dde222008-04-15 06:43:13 +00001284static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001285property_getter(PyObject *self, PyObject *getter)
1286{
Benjamin Peterson93964832010-06-28 03:07:10 +00001287 return property_copy(self, getter, NULL, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001288}
1289
Christian Heimes0449f632007-12-15 01:27:15 +00001290
Guido van Rossum58da9312007-11-10 23:39:45 +00001291PyDoc_STRVAR(setter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 "Descriptor to change the setter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001293
Neal Norwitz32dde222008-04-15 06:43:13 +00001294static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001295property_setter(PyObject *self, PyObject *setter)
1296{
Benjamin Peterson93964832010-06-28 03:07:10 +00001297 return property_copy(self, NULL, setter, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001298}
1299
Christian Heimes0449f632007-12-15 01:27:15 +00001300
Guido van Rossum58da9312007-11-10 23:39:45 +00001301PyDoc_STRVAR(deleter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 "Descriptor to change the deleter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001303
Neal Norwitz32dde222008-04-15 06:43:13 +00001304static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001305property_deleter(PyObject *self, PyObject *deleter)
1306{
Benjamin Peterson93964832010-06-28 03:07:10 +00001307 return property_copy(self, NULL, NULL, deleter);
Guido van Rossum58da9312007-11-10 23:39:45 +00001308}
1309
1310
Guido van Rossum58da9312007-11-10 23:39:45 +00001311static PyMethodDef property_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 {"getter", property_getter, METH_O, getter_doc},
1313 {"setter", property_setter, METH_O, setter_doc},
1314 {"deleter", property_deleter, METH_O, deleter_doc},
1315 {0}
Guido van Rossum58da9312007-11-10 23:39:45 +00001316};
1317
Tim Peters66c1a522001-09-24 21:17:50 +00001318
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001319static void
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001320property_dealloc(PyObject *self)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 propertyobject *gs = (propertyobject *)self;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 _PyObject_GC_UNTRACK(self);
1325 Py_XDECREF(gs->prop_get);
1326 Py_XDECREF(gs->prop_set);
1327 Py_XDECREF(gs->prop_del);
1328 Py_XDECREF(gs->prop_doc);
1329 self->ob_type->tp_free(self);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001330}
1331
1332static PyObject *
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001333property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 if (obj == NULL || obj == Py_None) {
1336 Py_INCREF(self);
1337 return self;
1338 }
Victor Stinnere972c132018-10-01 03:03:22 -07001339
1340 propertyobject *gs = (propertyobject *)self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 if (gs->prop_get == NULL) {
1342 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1343 return NULL;
1344 }
Victor Stinnere972c132018-10-01 03:03:22 -07001345
1346 PyObject *args[1] = {obj};
1347 return _PyObject_FastCall(gs->prop_get, args, 1);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001348}
1349
1350static int
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001351property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 propertyobject *gs = (propertyobject *)self;
1354 PyObject *func, *res;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 if (value == NULL)
1357 func = gs->prop_del;
1358 else
1359 func = gs->prop_set;
1360 if (func == NULL) {
1361 PyErr_SetString(PyExc_AttributeError,
1362 value == NULL ?
1363 "can't delete attribute" :
1364 "can't set attribute");
1365 return -1;
1366 }
1367 if (value == NULL)
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01001368 res = PyObject_CallFunctionObjArgs(func, obj, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 else
Benjamin Peterson9b955de2010-12-07 04:04:02 +00001370 res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 if (res == NULL)
1372 return -1;
1373 Py_DECREF(res);
1374 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001375}
1376
Christian Heimes0449f632007-12-15 01:27:15 +00001377static PyObject *
Benjamin Peterson93964832010-06-28 03:07:10 +00001378property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
Christian Heimes0449f632007-12-15 01:27:15 +00001379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 propertyobject *pold = (propertyobject *)old;
Benjamin Peterson93964832010-06-28 03:07:10 +00001381 PyObject *new, *type, *doc;
Christian Heimes0449f632007-12-15 01:27:15 +00001382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 type = PyObject_Type(old);
1384 if (type == NULL)
1385 return NULL;
Christian Heimes0449f632007-12-15 01:27:15 +00001386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 if (get == NULL || get == Py_None) {
1388 Py_XDECREF(get);
1389 get = pold->prop_get ? pold->prop_get : Py_None;
1390 }
1391 if (set == NULL || set == Py_None) {
1392 Py_XDECREF(set);
1393 set = pold->prop_set ? pold->prop_set : Py_None;
1394 }
1395 if (del == NULL || del == Py_None) {
1396 Py_XDECREF(del);
1397 del = pold->prop_del ? pold->prop_del : Py_None;
1398 }
Benjamin Peterson93964832010-06-28 03:07:10 +00001399 if (pold->getter_doc && get != Py_None) {
1400 /* make _init use __doc__ from getter */
1401 doc = Py_None;
1402 }
1403 else {
1404 doc = pold->prop_doc ? pold->prop_doc : Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 }
R. David Murrayb18500d2009-05-04 22:59:07 +00001406
Victor Stinner5abaa2b2016-12-09 16:22:32 +01001407 new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 Py_DECREF(type);
1409 if (new == NULL)
1410 return NULL;
1411 return new;
Christian Heimes0449f632007-12-15 01:27:15 +00001412}
1413
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001414/*[clinic input]
1415property.__init__ as property_init
1416
1417 fget: object(c_default="NULL") = None
1418 function to be used for getting an attribute value
1419 fset: object(c_default="NULL") = None
1420 function to be used for setting an attribute value
1421 fdel: object(c_default="NULL") = None
1422 function to be used for del'ing an attribute
1423 doc: object(c_default="NULL") = None
1424 docstring
1425
1426Property attribute.
1427
1428Typical use is to define a managed attribute x:
1429
1430class C(object):
1431 def getx(self): return self._x
1432 def setx(self, value): self._x = value
1433 def delx(self): del self._x
1434 x = property(getx, setx, delx, "I'm the 'x' property.")
1435
1436Decorators make defining new properties or modifying existing ones easy:
1437
1438class C(object):
1439 @property
1440 def x(self):
1441 "I am the 'x' property."
1442 return self._x
1443 @x.setter
1444 def x(self, value):
1445 self._x = value
1446 @x.deleter
1447 def x(self):
1448 del self._x
1449[clinic start generated code]*/
1450
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001451static int
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001452property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1453 PyObject *fdel, PyObject *doc)
1454/*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001455{
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001456 if (fget == Py_None)
1457 fget = NULL;
1458 if (fset == Py_None)
1459 fset = NULL;
1460 if (fdel == Py_None)
1461 fdel = NULL;
Tim Peters66c1a522001-09-24 21:17:50 +00001462
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001463 Py_XINCREF(fget);
1464 Py_XINCREF(fset);
1465 Py_XINCREF(fdel);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 Py_XINCREF(doc);
Christian Heimes0449f632007-12-15 01:27:15 +00001467
Oren Milmand019bc82018-02-13 12:28:33 +02001468 Py_XSETREF(self->prop_get, fget);
1469 Py_XSETREF(self->prop_set, fset);
1470 Py_XSETREF(self->prop_del, fdel);
1471 Py_XSETREF(self->prop_doc, doc);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001472 self->getter_doc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 /* if no docstring given and the getter has one, use that one */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001475 if ((doc == NULL || doc == Py_None) && fget != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001476 _Py_IDENTIFIER(__doc__);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001477 PyObject *get_doc = _PyObject_GetAttrId(fget, &PyId___doc__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 if (get_doc) {
1479 if (Py_TYPE(self) == &PyProperty_Type) {
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001480 Py_XSETREF(self->prop_doc, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 }
1482 else {
1483 /* If this is a property subclass, put __doc__
1484 in dict of the subclass instance instead,
1485 otherwise it gets shadowed by __doc__ in the
1486 class's dict. */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001487 int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 Py_DECREF(get_doc);
1489 if (err < 0)
1490 return -1;
1491 }
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001492 self->getter_doc = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 }
1494 else if (PyErr_ExceptionMatches(PyExc_Exception)) {
1495 PyErr_Clear();
1496 }
1497 else {
1498 return -1;
1499 }
1500 }
1501
1502 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001503}
1504
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001505static PyObject *
1506property_get___isabstractmethod__(propertyobject *prop, void *closure)
1507{
1508 int res = _PyObject_IsAbstract(prop->prop_get);
1509 if (res == -1) {
1510 return NULL;
1511 }
1512 else if (res) {
1513 Py_RETURN_TRUE;
1514 }
1515
1516 res = _PyObject_IsAbstract(prop->prop_set);
1517 if (res == -1) {
1518 return NULL;
1519 }
1520 else if (res) {
1521 Py_RETURN_TRUE;
1522 }
1523
1524 res = _PyObject_IsAbstract(prop->prop_del);
1525 if (res == -1) {
1526 return NULL;
1527 }
1528 else if (res) {
1529 Py_RETURN_TRUE;
1530 }
1531 Py_RETURN_FALSE;
1532}
1533
1534static PyGetSetDef property_getsetlist[] = {
1535 {"__isabstractmethod__",
1536 (getter)property_get___isabstractmethod__, NULL,
1537 NULL,
1538 NULL},
1539 {NULL} /* Sentinel */
1540};
1541
Guido van Rossum048eb752001-10-02 21:24:57 +00001542static int
1543property_traverse(PyObject *self, visitproc visit, void *arg)
1544{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 propertyobject *pp = (propertyobject *)self;
1546 Py_VISIT(pp->prop_get);
1547 Py_VISIT(pp->prop_set);
1548 Py_VISIT(pp->prop_del);
1549 Py_VISIT(pp->prop_doc);
1550 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001551}
1552
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001553static int
1554property_clear(PyObject *self)
1555{
1556 propertyobject *pp = (propertyobject *)self;
1557 Py_CLEAR(pp->prop_doc);
1558 return 0;
1559}
1560
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001561#include "clinic/descrobject.c.h"
1562
1563PyTypeObject PyDictProxy_Type = {
1564 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1565 "mappingproxy", /* tp_name */
1566 sizeof(mappingproxyobject), /* tp_basicsize */
1567 0, /* tp_itemsize */
1568 /* methods */
1569 (destructor)mappingproxy_dealloc, /* tp_dealloc */
1570 0, /* tp_print */
1571 0, /* tp_getattr */
1572 0, /* tp_setattr */
1573 0, /* tp_reserved */
1574 (reprfunc)mappingproxy_repr, /* tp_repr */
1575 0, /* tp_as_number */
1576 &mappingproxy_as_sequence, /* tp_as_sequence */
1577 &mappingproxy_as_mapping, /* tp_as_mapping */
1578 0, /* tp_hash */
1579 0, /* tp_call */
1580 (reprfunc)mappingproxy_str, /* tp_str */
1581 PyObject_GenericGetAttr, /* tp_getattro */
1582 0, /* tp_setattro */
1583 0, /* tp_as_buffer */
1584 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1585 0, /* tp_doc */
1586 mappingproxy_traverse, /* tp_traverse */
1587 0, /* tp_clear */
1588 (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
1589 0, /* tp_weaklistoffset */
1590 (getiterfunc)mappingproxy_getiter, /* tp_iter */
1591 0, /* tp_iternext */
1592 mappingproxy_methods, /* tp_methods */
1593 0, /* tp_members */
1594 0, /* tp_getset */
1595 0, /* tp_base */
1596 0, /* tp_dict */
1597 0, /* tp_descr_get */
1598 0, /* tp_descr_set */
1599 0, /* tp_dictoffset */
1600 0, /* tp_init */
1601 0, /* tp_alloc */
1602 mappingproxy_new, /* tp_new */
1603};
1604
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001605PyTypeObject PyProperty_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1607 "property", /* tp_name */
1608 sizeof(propertyobject), /* tp_basicsize */
1609 0, /* tp_itemsize */
1610 /* methods */
1611 property_dealloc, /* tp_dealloc */
1612 0, /* tp_print */
1613 0, /* tp_getattr */
1614 0, /* tp_setattr */
1615 0, /* tp_reserved */
1616 0, /* tp_repr */
1617 0, /* tp_as_number */
1618 0, /* tp_as_sequence */
1619 0, /* tp_as_mapping */
1620 0, /* tp_hash */
1621 0, /* tp_call */
1622 0, /* tp_str */
1623 PyObject_GenericGetAttr, /* tp_getattro */
1624 0, /* tp_setattro */
1625 0, /* tp_as_buffer */
1626 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1627 Py_TPFLAGS_BASETYPE, /* tp_flags */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001628 property_init__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 property_traverse, /* tp_traverse */
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001630 (inquiry)property_clear, /* tp_clear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 0, /* tp_richcompare */
1632 0, /* tp_weaklistoffset */
1633 0, /* tp_iter */
1634 0, /* tp_iternext */
1635 property_methods, /* tp_methods */
1636 property_members, /* tp_members */
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001637 property_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 0, /* tp_base */
1639 0, /* tp_dict */
1640 property_descr_get, /* tp_descr_get */
1641 property_descr_set, /* tp_descr_set */
1642 0, /* tp_dictoffset */
1643 property_init, /* tp_init */
1644 PyType_GenericAlloc, /* tp_alloc */
1645 PyType_GenericNew, /* tp_new */
1646 PyObject_GC_Del, /* tp_free */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001647};