blob: e129d0c48f27d0c8b34c9446a94379dd37fdfe83 [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,
81 "descriptor '%V' for '%s' objects "
82 "doesn't apply to '%s' object",
83 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,
102 "descriptor '%V' for type '%s' "
103 "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,
111 "descriptor '%V' for type '%s' "
112 "needs a type, not a '%s' as arg 2",
113 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,
120 "descriptor '%V' for type '%s' "
121 "doesn't apply to type '%s'",
122 descr_name((PyDescrObject *)descr), "?",
123 PyDescr_TYPE(descr)->tp_name,
124 ((PyTypeObject *)type)->tp_name);
125 return NULL;
126 }
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200127 return PyCFunction_NewEx(descr->d_method, type, NULL);
Tim Petersbca1cbc2002-12-09 22:56:13 +0000128}
129
130static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000131method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 if (descr_check((PyDescrObject *)descr, obj, &res))
136 return res;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200137 return PyCFunction_NewEx(descr->d_method, obj, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000138}
139
140static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000141member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 if (descr_check((PyDescrObject *)descr, obj, &res))
146 return res;
147 return PyMember_GetOne((char *)obj, descr->d_member);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000148}
149
150static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000151getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 if (descr_check((PyDescrObject *)descr, obj, &res))
156 return res;
157 if (descr->d_getset->get != NULL)
158 return descr->d_getset->get(obj, descr->d_getset->closure);
159 PyErr_Format(PyExc_AttributeError,
160 "attribute '%V' of '%.100s' objects is not readable",
161 descr_name((PyDescrObject *)descr), "?",
162 PyDescr_TYPE(descr)->tp_name);
163 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000164}
165
166static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000167wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 if (descr_check((PyDescrObject *)descr, obj, &res))
172 return res;
173 return PyWrapper_New((PyObject *)descr, obj);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000174}
175
176static int
177descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 int *pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 assert(obj != NULL);
181 if (!PyObject_TypeCheck(obj, descr->d_type)) {
182 PyErr_Format(PyExc_TypeError,
183 "descriptor '%V' for '%.100s' objects "
184 "doesn't apply to '%.100s' object",
185 descr_name(descr), "?",
186 descr->d_type->tp_name,
187 obj->ob_type->tp_name);
188 *pres = -1;
189 return 1;
190 }
191 return 0;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000192}
193
194static int
195member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
200 return res;
201 return PyMember_SetOne((char *)obj, descr->d_member, value);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000202}
203
204static int
205getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
210 return res;
211 if (descr->d_getset->set != NULL)
212 return descr->d_getset->set(obj, value,
213 descr->d_getset->closure);
214 PyErr_Format(PyExc_AttributeError,
215 "attribute '%V' of '%.100s' objects is not writable",
216 descr_name((PyDescrObject *)descr), "?",
217 PyDescr_TYPE(descr)->tp_name);
218 return -1;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000219}
220
221static PyObject *
Victor Stinnerc5257232017-01-18 10:38:09 +0100222methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000223{
Victor Stinnerc5257232017-01-18 10:38:09 +0100224 Py_ssize_t nargs;
225 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 /* Make sure that the first argument is acceptable as 'self' */
228 assert(PyTuple_Check(args));
Victor Stinnerc5257232017-01-18 10:38:09 +0100229 nargs = PyTuple_GET_SIZE(args);
230 if (nargs < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 PyErr_Format(PyExc_TypeError,
232 "descriptor '%V' of '%.100s' "
233 "object needs an argument",
234 descr_name((PyDescrObject *)descr), "?",
235 PyDescr_TYPE(descr)->tp_name);
236 return NULL;
237 }
238 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200239 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200240 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 PyErr_Format(PyExc_TypeError,
242 "descriptor '%V' "
243 "requires a '%.100s' object "
244 "but received a '%.100s'",
245 descr_name((PyDescrObject *)descr), "?",
246 PyDescr_TYPE(descr)->tp_name,
247 self->ob_type->tp_name);
248 return NULL;
249 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000250
Victor Stinnerc5257232017-01-18 10:38:09 +0100251 result = _PyMethodDef_RawFastCallDict(descr->d_method, self,
Victor Stinnerd17a6932018-11-09 16:56:48 +0100252 &_PyTuple_ITEMS(args)[1], nargs - 1,
Victor Stinnerc5257232017-01-18 10:38:09 +0100253 kwargs);
254 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000256}
257
INADA Naoki5566bbb2017-02-03 07:43:03 +0900258// same to methoddescr_call(), but use FASTCALL convention.
259PyObject *
260_PyMethodDescr_FastCallKeywords(PyObject *descrobj,
Serhiy Storchakaa5552f02017-12-15 13:11:11 +0200261 PyObject *const *args, Py_ssize_t nargs,
INADA Naoki5566bbb2017-02-03 07:43:03 +0900262 PyObject *kwnames)
263{
264 assert(Py_TYPE(descrobj) == &PyMethodDescr_Type);
265 PyMethodDescrObject *descr = (PyMethodDescrObject *)descrobj;
266 PyObject *self, *result;
267
268 /* Make sure that the first argument is acceptable as 'self' */
269 if (nargs < 1) {
270 PyErr_Format(PyExc_TypeError,
271 "descriptor '%V' of '%.100s' "
272 "object needs an argument",
273 descr_name((PyDescrObject *)descr), "?",
274 PyDescr_TYPE(descr)->tp_name);
275 return NULL;
276 }
277 self = args[0];
278 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
279 (PyObject *)PyDescr_TYPE(descr))) {
280 PyErr_Format(PyExc_TypeError,
281 "descriptor '%V' "
282 "requires a '%.100s' object "
283 "but received a '%.100s'",
284 descr_name((PyDescrObject *)descr), "?",
285 PyDescr_TYPE(descr)->tp_name,
286 self->ob_type->tp_name);
287 return NULL;
288 }
289
290 result = _PyMethodDef_RawFastCallKeywords(descr->d_method, self,
291 args+1, nargs-1, kwnames);
292 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
293 return result;
294}
295
Tim Peters6d6c1a32001-08-02 04:15:00 +0000296static PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000297classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 PyObject *kwds)
Tim Petersbca1cbc2002-12-09 22:56:13 +0000299{
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400300 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300301 PyObject *self, *result;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000302
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400303 /* Make sure that the first argument is acceptable as 'self' */
304 assert(PyTuple_Check(args));
305 argc = PyTuple_GET_SIZE(args);
306 if (argc < 1) {
307 PyErr_Format(PyExc_TypeError,
308 "descriptor '%V' of '%.100s' "
309 "object needs an argument",
310 descr_name((PyDescrObject *)descr), "?",
311 PyDescr_TYPE(descr)->tp_name);
312 return NULL;
313 }
314 self = PyTuple_GET_ITEM(args, 0);
315 if (!PyType_Check(self)) {
316 PyErr_Format(PyExc_TypeError,
317 "descriptor '%V' requires a type "
318 "but received a '%.100s'",
319 descr_name((PyDescrObject *)descr), "?",
320 PyDescr_TYPE(descr)->tp_name,
321 self->ob_type->tp_name);
322 return NULL;
323 }
324 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) {
325 PyErr_Format(PyExc_TypeError,
326 "descriptor '%V' "
327 "requires a subtype of '%.100s' "
328 "but received '%.100s",
329 descr_name((PyDescrObject *)descr), "?",
330 PyDescr_TYPE(descr)->tp_name,
331 self->ob_type->tp_name);
332 return NULL;
333 }
334
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300335 result = _PyMethodDef_RawFastCallDict(descr->d_method, self,
Victor Stinnerd17a6932018-11-09 16:56:48 +0100336 &_PyTuple_ITEMS(args)[1], argc - 1,
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300337 kwds);
338 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 return result;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000340}
341
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300342Py_LOCAL_INLINE(PyObject *)
343wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self,
344 PyObject *args, PyObject *kwds)
345{
346 wrapperfunc wrapper = descr->d_base->wrapper;
347
348 if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
Serhiy Storchaka1c607152018-11-27 21:34:27 +0200349 wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300350 return (*wk)(self, args, descr->d_wrapped, kwds);
351 }
352
353 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) {
354 PyErr_Format(PyExc_TypeError,
355 "wrapper %s() takes no keyword arguments",
356 descr->d_base->name);
357 return NULL;
358 }
359 return (*wrapper)(self, args, descr->d_wrapped);
360}
361
Tim Petersbca1cbc2002-12-09 22:56:13 +0000362static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000363wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300366 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 /* Make sure that the first argument is acceptable as 'self' */
369 assert(PyTuple_Check(args));
370 argc = PyTuple_GET_SIZE(args);
371 if (argc < 1) {
372 PyErr_Format(PyExc_TypeError,
373 "descriptor '%V' of '%.100s' "
374 "object needs an argument",
375 descr_name((PyDescrObject *)descr), "?",
376 PyDescr_TYPE(descr)->tp_name);
377 return NULL;
378 }
379 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200380 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200381 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 PyErr_Format(PyExc_TypeError,
383 "descriptor '%V' "
384 "requires a '%.100s' object "
385 "but received a '%.100s'",
386 descr_name((PyDescrObject *)descr), "?",
387 PyDescr_TYPE(descr)->tp_name,
388 self->ob_type->tp_name);
389 return NULL;
390 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000391
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300392 args = PyTuple_GetSlice(args, 1, argc);
393 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 return NULL;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300395 }
396 result = wrapperdescr_raw_call(descr, self, args, kwds);
397 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000399}
400
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300401
Tim Peters6d6c1a32001-08-02 04:15:00 +0000402static PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000403method_get_doc(PyMethodDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000404{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800405 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800406}
407
408static PyObject *
409method_get_text_signature(PyMethodDescrObject *descr, void *closure)
410{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800411 return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000412}
413
Antoine Pitrou9d574812011-12-12 13:47:25 +0100414static PyObject *
415calculate_qualname(PyDescrObject *descr)
416{
417 PyObject *type_qualname, *res;
418 _Py_IDENTIFIER(__qualname__);
419
420 if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) {
421 PyErr_SetString(PyExc_TypeError,
422 "<descriptor>.__name__ is not a unicode object");
423 return NULL;
424 }
425
426 type_qualname = _PyObject_GetAttrId((PyObject *)descr->d_type,
427 &PyId___qualname__);
428 if (type_qualname == NULL)
429 return NULL;
430
431 if (!PyUnicode_Check(type_qualname)) {
432 PyErr_SetString(PyExc_TypeError, "<descriptor>.__objclass__."
433 "__qualname__ is not a unicode object");
434 Py_XDECREF(type_qualname);
435 return NULL;
436 }
437
438 res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name);
439 Py_DECREF(type_qualname);
440 return res;
441}
442
443static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200444descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +0100445{
446 if (descr->d_qualname == NULL)
447 descr->d_qualname = calculate_qualname(descr);
448 Py_XINCREF(descr->d_qualname);
449 return descr->d_qualname;
450}
451
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100452static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530453descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100454{
455 PyObject *builtins;
456 PyObject *getattr;
457 _Py_IDENTIFIER(getattr);
458
459 builtins = PyEval_GetBuiltins();
460 getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
461 return Py_BuildValue("O(OO)", getattr, PyDescr_TYPE(descr),
462 PyDescr_NAME(descr));
463}
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 */
546 0, /* tp_print */
547 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 */
560 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
561 0, /* tp_doc */
562 descr_traverse, /* tp_traverse */
563 0, /* tp_clear */
564 0, /* tp_richcompare */
565 0, /* tp_weaklistoffset */
566 0, /* tp_iter */
567 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100568 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 descr_members, /* tp_members */
570 method_getset, /* tp_getset */
571 0, /* tp_base */
572 0, /* tp_dict */
573 (descrgetfunc)method_get, /* tp_descr_get */
574 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000575};
576
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000577/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000578PyTypeObject PyClassMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 PyVarObject_HEAD_INIT(&PyType_Type, 0)
580 "classmethod_descriptor",
581 sizeof(PyMethodDescrObject),
582 0,
583 (destructor)descr_dealloc, /* tp_dealloc */
584 0, /* tp_print */
585 0, /* tp_getattr */
586 0, /* tp_setattr */
587 0, /* tp_reserved */
588 (reprfunc)method_repr, /* tp_repr */
589 0, /* tp_as_number */
590 0, /* tp_as_sequence */
591 0, /* tp_as_mapping */
592 0, /* tp_hash */
593 (ternaryfunc)classmethoddescr_call, /* tp_call */
594 0, /* tp_str */
595 PyObject_GenericGetAttr, /* tp_getattro */
596 0, /* tp_setattro */
597 0, /* tp_as_buffer */
598 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
599 0, /* tp_doc */
600 descr_traverse, /* tp_traverse */
601 0, /* tp_clear */
602 0, /* tp_richcompare */
603 0, /* tp_weaklistoffset */
604 0, /* tp_iter */
605 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100606 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 descr_members, /* tp_members */
608 method_getset, /* tp_getset */
609 0, /* tp_base */
610 0, /* tp_dict */
611 (descrgetfunc)classmethod_get, /* tp_descr_get */
612 0, /* tp_descr_set */
Tim Petersbca1cbc2002-12-09 22:56:13 +0000613};
614
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000615PyTypeObject PyMemberDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 PyVarObject_HEAD_INIT(&PyType_Type, 0)
617 "member_descriptor",
618 sizeof(PyMemberDescrObject),
619 0,
620 (destructor)descr_dealloc, /* tp_dealloc */
621 0, /* tp_print */
622 0, /* tp_getattr */
623 0, /* tp_setattr */
624 0, /* tp_reserved */
625 (reprfunc)member_repr, /* tp_repr */
626 0, /* tp_as_number */
627 0, /* tp_as_sequence */
628 0, /* tp_as_mapping */
629 0, /* tp_hash */
630 0, /* tp_call */
631 0, /* tp_str */
632 PyObject_GenericGetAttr, /* tp_getattro */
633 0, /* tp_setattro */
634 0, /* tp_as_buffer */
635 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
636 0, /* tp_doc */
637 descr_traverse, /* tp_traverse */
638 0, /* tp_clear */
639 0, /* tp_richcompare */
640 0, /* tp_weaklistoffset */
641 0, /* tp_iter */
642 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100643 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 descr_members, /* tp_members */
645 member_getset, /* tp_getset */
646 0, /* tp_base */
647 0, /* tp_dict */
648 (descrgetfunc)member_get, /* tp_descr_get */
649 (descrsetfunc)member_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000650};
651
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000652PyTypeObject PyGetSetDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000653 PyVarObject_HEAD_INIT(&PyType_Type, 0)
654 "getset_descriptor",
655 sizeof(PyGetSetDescrObject),
656 0,
657 (destructor)descr_dealloc, /* tp_dealloc */
658 0, /* tp_print */
659 0, /* tp_getattr */
660 0, /* tp_setattr */
661 0, /* tp_reserved */
662 (reprfunc)getset_repr, /* tp_repr */
663 0, /* tp_as_number */
664 0, /* tp_as_sequence */
665 0, /* tp_as_mapping */
666 0, /* tp_hash */
667 0, /* tp_call */
668 0, /* tp_str */
669 PyObject_GenericGetAttr, /* tp_getattro */
670 0, /* tp_setattro */
671 0, /* tp_as_buffer */
672 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
673 0, /* tp_doc */
674 descr_traverse, /* tp_traverse */
675 0, /* tp_clear */
676 0, /* tp_richcompare */
677 0, /* tp_weaklistoffset */
678 0, /* tp_iter */
679 0, /* tp_iternext */
680 0, /* tp_methods */
681 descr_members, /* tp_members */
682 getset_getset, /* tp_getset */
683 0, /* tp_base */
684 0, /* tp_dict */
685 (descrgetfunc)getset_get, /* tp_descr_get */
686 (descrsetfunc)getset_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000687};
688
Guido van Rossumf4593e02001-10-03 12:09:30 +0000689PyTypeObject PyWrapperDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 PyVarObject_HEAD_INIT(&PyType_Type, 0)
691 "wrapper_descriptor",
692 sizeof(PyWrapperDescrObject),
693 0,
694 (destructor)descr_dealloc, /* tp_dealloc */
695 0, /* tp_print */
696 0, /* tp_getattr */
697 0, /* tp_setattr */
698 0, /* tp_reserved */
699 (reprfunc)wrapperdescr_repr, /* tp_repr */
700 0, /* tp_as_number */
701 0, /* tp_as_sequence */
702 0, /* tp_as_mapping */
703 0, /* tp_hash */
704 (ternaryfunc)wrapperdescr_call, /* tp_call */
705 0, /* tp_str */
706 PyObject_GenericGetAttr, /* tp_getattro */
707 0, /* tp_setattro */
708 0, /* tp_as_buffer */
709 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
710 0, /* tp_doc */
711 descr_traverse, /* tp_traverse */
712 0, /* tp_clear */
713 0, /* tp_richcompare */
714 0, /* tp_weaklistoffset */
715 0, /* tp_iter */
716 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100717 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 descr_members, /* tp_members */
719 wrapperdescr_getset, /* tp_getset */
720 0, /* tp_base */
721 0, /* tp_dict */
722 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
723 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000724};
725
726static PyDescrObject *
Jeremy Hyltonaf68c872005-12-10 18:50:16 +0000727descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000729 PyDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
732 if (descr != NULL) {
733 Py_XINCREF(type);
734 descr->d_type = type;
735 descr->d_name = PyUnicode_InternFromString(name);
736 if (descr->d_name == NULL) {
737 Py_DECREF(descr);
738 descr = NULL;
739 }
Benjamin Petersonf2fe7f02011-12-17 08:02:20 -0500740 else {
741 descr->d_qualname = NULL;
742 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 }
744 return descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000745}
746
747PyObject *
748PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 PyMethodDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
753 type, method->ml_name);
754 if (descr != NULL)
755 descr->d_method = method;
756 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000757}
758
759PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000760PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
761{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 PyMethodDescrObject *descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
765 type, method->ml_name);
766 if (descr != NULL)
767 descr->d_method = method;
768 return (PyObject *)descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000769}
770
771PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000772PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000773{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000774 PyMemberDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
777 type, member->name);
778 if (descr != NULL)
779 descr->d_member = member;
780 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000781}
782
783PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000784PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 PyGetSetDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
789 type, getset->name);
790 if (descr != NULL)
791 descr->d_getset = getset;
792 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000793}
794
795PyObject *
796PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
801 type, base->name);
802 if (descr != NULL) {
803 descr->d_base = base;
804 descr->d_wrapped = wrapped;
805 }
806 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000807}
808
Tim Peters6d6c1a32001-08-02 04:15:00 +0000809
Victor Stinner0db176f2012-04-16 00:16:30 +0200810/* --- mappingproxy: read-only proxy for mappings --- */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000811
812/* This has no reason to be in this file except that adding new files is a
813 bit of a pain */
814
815typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000816 PyObject_HEAD
Victor Stinner0db176f2012-04-16 00:16:30 +0200817 PyObject *mapping;
818} mappingproxyobject;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000819
Martin v. Löwis18e16552006-02-15 17:27:45 +0000820static Py_ssize_t
Victor Stinner0db176f2012-04-16 00:16:30 +0200821mappingproxy_len(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000822{
Victor Stinner0db176f2012-04-16 00:16:30 +0200823 return PyObject_Size(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000824}
825
826static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200827mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000828{
Victor Stinner0db176f2012-04-16 00:16:30 +0200829 return PyObject_GetItem(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000830}
831
Victor Stinner0db176f2012-04-16 00:16:30 +0200832static PyMappingMethods mappingproxy_as_mapping = {
833 (lenfunc)mappingproxy_len, /* mp_length */
834 (binaryfunc)mappingproxy_getitem, /* mp_subscript */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 0, /* mp_ass_subscript */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000836};
837
838static int
Victor Stinner0db176f2012-04-16 00:16:30 +0200839mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000840{
Victor Stinner0db176f2012-04-16 00:16:30 +0200841 if (PyDict_CheckExact(pp->mapping))
842 return PyDict_Contains(pp->mapping, key);
843 else
844 return PySequence_Contains(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000845}
846
Victor Stinner0db176f2012-04-16 00:16:30 +0200847static PySequenceMethods mappingproxy_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 0, /* sq_length */
849 0, /* sq_concat */
850 0, /* sq_repeat */
851 0, /* sq_item */
852 0, /* sq_slice */
853 0, /* sq_ass_item */
854 0, /* sq_ass_slice */
Victor Stinner0db176f2012-04-16 00:16:30 +0200855 (objobjproc)mappingproxy_contains, /* sq_contains */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 0, /* sq_inplace_concat */
857 0, /* sq_inplace_repeat */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000858};
859
860static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200861mappingproxy_get(mappingproxyobject *pp, PyObject *args)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 PyObject *key, *def = Py_None;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200864 _Py_IDENTIFIER(get);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000866 if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def))
867 return NULL;
Victor Stinner7e425412016-12-09 00:36:19 +0100868 return _PyObject_CallMethodIdObjArgs(pp->mapping, &PyId_get,
869 key, def, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000870}
871
872static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530873mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000874{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200875 _Py_IDENTIFIER(keys);
Victor Stinner0db176f2012-04-16 00:16:30 +0200876 return _PyObject_CallMethodId(pp->mapping, &PyId_keys, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000877}
878
879static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530880mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000881{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200882 _Py_IDENTIFIER(values);
Victor Stinner0db176f2012-04-16 00:16:30 +0200883 return _PyObject_CallMethodId(pp->mapping, &PyId_values, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000884}
885
886static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530887mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000888{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200889 _Py_IDENTIFIER(items);
Victor Stinner0db176f2012-04-16 00:16:30 +0200890 return _PyObject_CallMethodId(pp->mapping, &PyId_items, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000891}
892
893static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530894mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000895{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200896 _Py_IDENTIFIER(copy);
Victor Stinner0db176f2012-04-16 00:16:30 +0200897 return _PyObject_CallMethodId(pp->mapping, &PyId_copy, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000898}
899
Victor Stinner0db176f2012-04-16 00:16:30 +0200900/* WARNING: mappingproxy methods must not give access
901 to the underlying mapping */
902
903static PyMethodDef mappingproxy_methods[] = {
904 {"get", (PyCFunction)mappingproxy_get, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000905 PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d."
Victor Stinner0db176f2012-04-16 00:16:30 +0200906 " d defaults to None.")},
907 {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 PyDoc_STR("D.keys() -> list of D's keys")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200909 {"values", (PyCFunction)mappingproxy_values, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910 PyDoc_STR("D.values() -> list of D's values")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200911 {"items", (PyCFunction)mappingproxy_items, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
Victor Stinner0db176f2012-04-16 00:16:30 +0200913 {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 PyDoc_STR("D.copy() -> a shallow copy of D")},
915 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000916};
917
918static void
Victor Stinner0db176f2012-04-16 00:16:30 +0200919mappingproxy_dealloc(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000920{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 _PyObject_GC_UNTRACK(pp);
Victor Stinner0db176f2012-04-16 00:16:30 +0200922 Py_DECREF(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 PyObject_GC_Del(pp);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000924}
925
926static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200927mappingproxy_getiter(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000928{
Victor Stinner0db176f2012-04-16 00:16:30 +0200929 return PyObject_GetIter(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000930}
931
Neil Schemenauer26775122001-10-21 22:26:43 +0000932static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200933mappingproxy_str(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000934{
Victor Stinner0db176f2012-04-16 00:16:30 +0200935 return PyObject_Str(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000936}
937
Ezio Melottiac53ab62010-12-18 14:59:43 +0000938static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200939mappingproxy_repr(mappingproxyobject *pp)
Ezio Melottiac53ab62010-12-18 14:59:43 +0000940{
Victor Stinner0db176f2012-04-16 00:16:30 +0200941 return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping);
Ezio Melottiac53ab62010-12-18 14:59:43 +0000942}
943
Guido van Rossum048eb752001-10-02 21:24:57 +0000944static int
Victor Stinner0db176f2012-04-16 00:16:30 +0200945mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
Guido van Rossum048eb752001-10-02 21:24:57 +0000946{
Victor Stinner0db176f2012-04-16 00:16:30 +0200947 mappingproxyobject *pp = (mappingproxyobject *)self;
948 Py_VISIT(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000950}
951
Raymond Hettinger29a6d442002-08-31 15:51:04 +0000952static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200953mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op)
Raymond Hettinger29a6d442002-08-31 15:51:04 +0000954{
Victor Stinner0db176f2012-04-16 00:16:30 +0200955 return PyObject_RichCompare(v->mapping, w, op);
956}
957
958static int
959mappingproxy_check_mapping(PyObject *mapping)
960{
961 if (!PyMapping_Check(mapping)
962 || PyList_Check(mapping)
963 || PyTuple_Check(mapping)) {
964 PyErr_Format(PyExc_TypeError,
965 "mappingproxy() argument must be a mapping, not %s",
966 Py_TYPE(mapping)->tp_name);
967 return -1;
968 }
969 return 0;
970}
971
Serhiy Storchaka18b250f2017-03-19 08:51:07 +0200972/*[clinic input]
973@classmethod
974mappingproxy.__new__ as mappingproxy_new
Victor Stinner0db176f2012-04-16 00:16:30 +0200975
Serhiy Storchaka18b250f2017-03-19 08:51:07 +0200976 mapping: object
977
978[clinic start generated code]*/
979
980static PyObject *
981mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping)
982/*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/
983{
984 mappingproxyobject *mappingproxy;
Victor Stinner0db176f2012-04-16 00:16:30 +0200985
986 if (mappingproxy_check_mapping(mapping) == -1)
987 return NULL;
988
989 mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
990 if (mappingproxy == NULL)
991 return NULL;
992 Py_INCREF(mapping);
993 mappingproxy->mapping = mapping;
994 _PyObject_GC_TRACK(mappingproxy);
995 return (PyObject *)mappingproxy;
Raymond Hettinger29a6d442002-08-31 15:51:04 +0000996}
997
Tim Peters6d6c1a32001-08-02 04:15:00 +0000998PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200999PyDictProxy_New(PyObject *mapping)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001000{
Victor Stinner0db176f2012-04-16 00:16:30 +02001001 mappingproxyobject *pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001002
Victor Stinner0db176f2012-04-16 00:16:30 +02001003 if (mappingproxy_check_mapping(mapping) == -1)
1004 return NULL;
1005
1006 pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 if (pp != NULL) {
Victor Stinner0db176f2012-04-16 00:16:30 +02001008 Py_INCREF(mapping);
1009 pp->mapping = mapping;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 _PyObject_GC_TRACK(pp);
1011 }
1012 return (PyObject *)pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001013}
1014
1015
1016/* --- Wrapper object for "slot" methods --- */
1017
1018/* This has no reason to be in this file except that adding new files is a
1019 bit of a pain */
1020
1021typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 PyObject_HEAD
1023 PyWrapperDescrObject *descr;
1024 PyObject *self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001025} wrapperobject;
1026
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001027#define Wrapper_Check(v) (Py_TYPE(v) == &_PyMethodWrapper_Type)
Mark Dickinson211c6252009-02-01 10:28:51 +00001028
Tim Peters6d6c1a32001-08-02 04:15:00 +00001029static void
1030wrapper_dealloc(wrapperobject *wp)
1031{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 PyObject_GC_UnTrack(wp);
1033 Py_TRASHCAN_SAFE_BEGIN(wp)
1034 Py_XDECREF(wp->descr);
1035 Py_XDECREF(wp->self);
1036 PyObject_GC_Del(wp);
1037 Py_TRASHCAN_SAFE_END(wp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001038}
1039
Mark Dickinson211c6252009-02-01 10:28:51 +00001040static PyObject *
1041wrapper_richcompare(PyObject *a, PyObject *b, int op)
Armin Rigoc6686b72005-11-07 08:38:00 +00001042{
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001043 wrapperobject *wa, *wb;
1044 int eq;
Mark Dickinson211c6252009-02-01 10:28:51 +00001045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +00001047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 /* both arguments should be wrapperobjects */
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001049 if ((op != Py_EQ && op != Py_NE)
1050 || !Wrapper_Check(a) || !Wrapper_Check(b))
1051 {
stratakise8b19652017-11-02 11:32:54 +01001052 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 }
Mark Dickinson211c6252009-02-01 10:28:51 +00001054
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001055 wa = (wrapperobject *)a;
1056 wb = (wrapperobject *)b;
1057 eq = (wa->descr == wb->descr && wa->self == wb->self);
1058 if (eq == (op == Py_EQ)) {
1059 Py_RETURN_TRUE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 }
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001061 else {
1062 Py_RETURN_FALSE;
1063 }
Armin Rigoc6686b72005-11-07 08:38:00 +00001064}
1065
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001066static Py_hash_t
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001067wrapper_hash(wrapperobject *wp)
1068{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001069 Py_hash_t x, y;
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001070 x = _Py_HashPointer(wp->self);
1071 y = _Py_HashPointer(wp->descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 x = x ^ y;
1073 if (x == -1)
1074 x = -2;
1075 return x;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001076}
1077
Armin Rigoc6686b72005-11-07 08:38:00 +00001078static PyObject *
1079wrapper_repr(wrapperobject *wp)
1080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001081 return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
1082 wp->descr->d_base->name,
1083 wp->self->ob_type->tp_name,
1084 wp->self);
Armin Rigoc6686b72005-11-07 08:38:00 +00001085}
1086
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001087static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301088wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001089{
1090 PyObject *builtins;
1091 PyObject *getattr;
1092 _Py_IDENTIFIER(getattr);
1093
1094 builtins = PyEval_GetBuiltins();
1095 getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
1096 return Py_BuildValue("O(OO)", getattr, wp->self, PyDescr_NAME(wp->descr));
1097}
1098
1099static PyMethodDef wrapper_methods[] = {
1100 {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
1101 {NULL, NULL}
1102};
1103
Armin Rigoc6686b72005-11-07 08:38:00 +00001104static PyMemberDef wrapper_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
1106 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001107};
1108
1109static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001110wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored))
Armin Rigoc6686b72005-11-07 08:38:00 +00001111{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112 PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
Armin Rigoc6686b72005-11-07 08:38:00 +00001113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 Py_INCREF(c);
1115 return c;
Armin Rigoc6686b72005-11-07 08:38:00 +00001116}
1117
1118static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001119wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 const char *s = wp->descr->d_base->name;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 return PyUnicode_FromString(s);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001124}
1125
1126static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001127wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001128{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001129 return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -08001130}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001131
Larry Hastings5c661892014-01-24 06:17:25 -08001132static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001133wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
Larry Hastings5c661892014-01-24 06:17:25 -08001134{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001135 return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001136}
1137
Antoine Pitrou9d574812011-12-12 13:47:25 +01001138static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001139wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +01001140{
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001141 return descr_get_qualname((PyDescrObject *)wp->descr, NULL);
Antoine Pitrou9d574812011-12-12 13:47:25 +01001142}
1143
Guido van Rossum32d34c82001-09-20 21:45:26 +00001144static PyGetSetDef wrapper_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 {"__objclass__", (getter)wrapper_objclass},
1146 {"__name__", (getter)wrapper_name},
Antoine Pitrou9d574812011-12-12 13:47:25 +01001147 {"__qualname__", (getter)wrapper_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 {"__doc__", (getter)wrapper_doc},
Larry Hastings5c661892014-01-24 06:17:25 -08001149 {"__text_signature__", (getter)wrapper_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001151};
1152
1153static PyObject *
1154wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
1155{
Serhiy Storchaka5e02c782017-09-21 14:25:36 +03001156 return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001157}
1158
Guido van Rossum048eb752001-10-02 21:24:57 +00001159static int
1160wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1161{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 wrapperobject *wp = (wrapperobject *)self;
1163 Py_VISIT(wp->descr);
1164 Py_VISIT(wp->self);
1165 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001166}
1167
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001168PyTypeObject _PyMethodWrapper_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1170 "method-wrapper", /* tp_name */
1171 sizeof(wrapperobject), /* tp_basicsize */
1172 0, /* tp_itemsize */
1173 /* methods */
1174 (destructor)wrapper_dealloc, /* tp_dealloc */
1175 0, /* tp_print */
1176 0, /* tp_getattr */
1177 0, /* tp_setattr */
1178 0, /* tp_reserved */
1179 (reprfunc)wrapper_repr, /* tp_repr */
1180 0, /* tp_as_number */
1181 0, /* tp_as_sequence */
1182 0, /* tp_as_mapping */
1183 (hashfunc)wrapper_hash, /* tp_hash */
1184 (ternaryfunc)wrapper_call, /* tp_call */
1185 0, /* tp_str */
1186 PyObject_GenericGetAttr, /* tp_getattro */
1187 0, /* tp_setattro */
1188 0, /* tp_as_buffer */
1189 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1190 0, /* tp_doc */
1191 wrapper_traverse, /* tp_traverse */
1192 0, /* tp_clear */
1193 wrapper_richcompare, /* tp_richcompare */
1194 0, /* tp_weaklistoffset */
1195 0, /* tp_iter */
1196 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001197 wrapper_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 wrapper_members, /* tp_members */
1199 wrapper_getsets, /* tp_getset */
1200 0, /* tp_base */
1201 0, /* tp_dict */
1202 0, /* tp_descr_get */
1203 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001204};
1205
1206PyObject *
1207PyWrapper_New(PyObject *d, PyObject *self)
1208{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 wrapperobject *wp;
1210 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1213 descr = (PyWrapperDescrObject *)d;
Victor Stinner3249dec2011-05-01 23:19:15 +02001214 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +02001215 (PyObject *)PyDescr_TYPE(descr)));
Tim Peters6d6c1a32001-08-02 04:15:00 +00001216
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001217 wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 if (wp != NULL) {
1219 Py_INCREF(descr);
1220 wp->descr = descr;
1221 Py_INCREF(self);
1222 wp->self = self;
1223 _PyObject_GC_TRACK(wp);
1224 }
1225 return (PyObject *)wp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001226}
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001227
1228
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001229/* A built-in 'property' type */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001230
1231/*
Serhiy Storchakad741a882015-06-11 00:06:39 +03001232class property(object):
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
1235 if doc is None and fget is not None and hasattr(fget, "__doc__"):
Serhiy Storchakad741a882015-06-11 00:06:39 +03001236 doc = fget.__doc__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 self.__get = fget
1238 self.__set = fset
1239 self.__del = fdel
1240 self.__doc__ = doc
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 def __get__(self, inst, type=None):
1243 if inst is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001244 return self
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 if self.__get is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001246 raise AttributeError, "unreadable attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 return self.__get(inst)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 def __set__(self, inst, value):
1250 if self.__set is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001251 raise AttributeError, "can't set attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 return self.__set(inst, value)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 def __delete__(self, inst):
1255 if self.__del is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001256 raise AttributeError, "can't delete attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 return self.__del(inst)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001258
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001259*/
1260
1261typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 PyObject_HEAD
1263 PyObject *prop_get;
1264 PyObject *prop_set;
1265 PyObject *prop_del;
1266 PyObject *prop_doc;
1267 int getter_doc;
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001268} propertyobject;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001269
Christian Heimes0449f632007-12-15 01:27:15 +00001270static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
Benjamin Peterson93964832010-06-28 03:07:10 +00001271 PyObject *);
Christian Heimes0449f632007-12-15 01:27:15 +00001272
Tim Peters66c1a522001-09-24 21:17:50 +00001273static PyMemberDef property_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
1275 {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
1276 {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
Raymond Hettingereac503a2015-05-13 01:09:59 -07001277 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 {0}
Tim Peters66c1a522001-09-24 21:17:50 +00001279};
1280
Christian Heimes0449f632007-12-15 01:27:15 +00001281
Guido van Rossum58da9312007-11-10 23:39:45 +00001282PyDoc_STRVAR(getter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 "Descriptor to change the getter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001284
Neal Norwitz32dde222008-04-15 06:43:13 +00001285static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001286property_getter(PyObject *self, PyObject *getter)
1287{
Benjamin Peterson93964832010-06-28 03:07:10 +00001288 return property_copy(self, getter, NULL, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001289}
1290
Christian Heimes0449f632007-12-15 01:27:15 +00001291
Guido van Rossum58da9312007-11-10 23:39:45 +00001292PyDoc_STRVAR(setter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 "Descriptor to change the setter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001294
Neal Norwitz32dde222008-04-15 06:43:13 +00001295static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001296property_setter(PyObject *self, PyObject *setter)
1297{
Benjamin Peterson93964832010-06-28 03:07:10 +00001298 return property_copy(self, NULL, setter, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001299}
1300
Christian Heimes0449f632007-12-15 01:27:15 +00001301
Guido van Rossum58da9312007-11-10 23:39:45 +00001302PyDoc_STRVAR(deleter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 "Descriptor to change the deleter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001304
Neal Norwitz32dde222008-04-15 06:43:13 +00001305static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001306property_deleter(PyObject *self, PyObject *deleter)
1307{
Benjamin Peterson93964832010-06-28 03:07:10 +00001308 return property_copy(self, NULL, NULL, deleter);
Guido van Rossum58da9312007-11-10 23:39:45 +00001309}
1310
1311
Guido van Rossum58da9312007-11-10 23:39:45 +00001312static PyMethodDef property_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 {"getter", property_getter, METH_O, getter_doc},
1314 {"setter", property_setter, METH_O, setter_doc},
1315 {"deleter", property_deleter, METH_O, deleter_doc},
1316 {0}
Guido van Rossum58da9312007-11-10 23:39:45 +00001317};
1318
Tim Peters66c1a522001-09-24 21:17:50 +00001319
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001320static void
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001321property_dealloc(PyObject *self)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 propertyobject *gs = (propertyobject *)self;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 _PyObject_GC_UNTRACK(self);
1326 Py_XDECREF(gs->prop_get);
1327 Py_XDECREF(gs->prop_set);
1328 Py_XDECREF(gs->prop_del);
1329 Py_XDECREF(gs->prop_doc);
1330 self->ob_type->tp_free(self);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001331}
1332
1333static PyObject *
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001334property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 if (obj == NULL || obj == Py_None) {
1337 Py_INCREF(self);
1338 return self;
1339 }
Victor Stinnere972c132018-10-01 03:03:22 -07001340
1341 propertyobject *gs = (propertyobject *)self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 if (gs->prop_get == NULL) {
1343 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1344 return NULL;
1345 }
Victor Stinnere972c132018-10-01 03:03:22 -07001346
1347 PyObject *args[1] = {obj};
1348 return _PyObject_FastCall(gs->prop_get, args, 1);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001349}
1350
1351static int
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001352property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 propertyobject *gs = (propertyobject *)self;
1355 PyObject *func, *res;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 if (value == NULL)
1358 func = gs->prop_del;
1359 else
1360 func = gs->prop_set;
1361 if (func == NULL) {
1362 PyErr_SetString(PyExc_AttributeError,
1363 value == NULL ?
1364 "can't delete attribute" :
1365 "can't set attribute");
1366 return -1;
1367 }
1368 if (value == NULL)
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01001369 res = PyObject_CallFunctionObjArgs(func, obj, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 else
Benjamin Peterson9b955de2010-12-07 04:04:02 +00001371 res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 if (res == NULL)
1373 return -1;
1374 Py_DECREF(res);
1375 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001376}
1377
Christian Heimes0449f632007-12-15 01:27:15 +00001378static PyObject *
Benjamin Peterson93964832010-06-28 03:07:10 +00001379property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
Christian Heimes0449f632007-12-15 01:27:15 +00001380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 propertyobject *pold = (propertyobject *)old;
Benjamin Peterson93964832010-06-28 03:07:10 +00001382 PyObject *new, *type, *doc;
Christian Heimes0449f632007-12-15 01:27:15 +00001383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 type = PyObject_Type(old);
1385 if (type == NULL)
1386 return NULL;
Christian Heimes0449f632007-12-15 01:27:15 +00001387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 if (get == NULL || get == Py_None) {
1389 Py_XDECREF(get);
1390 get = pold->prop_get ? pold->prop_get : Py_None;
1391 }
1392 if (set == NULL || set == Py_None) {
1393 Py_XDECREF(set);
1394 set = pold->prop_set ? pold->prop_set : Py_None;
1395 }
1396 if (del == NULL || del == Py_None) {
1397 Py_XDECREF(del);
1398 del = pold->prop_del ? pold->prop_del : Py_None;
1399 }
Benjamin Peterson93964832010-06-28 03:07:10 +00001400 if (pold->getter_doc && get != Py_None) {
1401 /* make _init use __doc__ from getter */
1402 doc = Py_None;
1403 }
1404 else {
1405 doc = pold->prop_doc ? pold->prop_doc : Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 }
R. David Murrayb18500d2009-05-04 22:59:07 +00001407
Victor Stinner5abaa2b2016-12-09 16:22:32 +01001408 new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 Py_DECREF(type);
1410 if (new == NULL)
1411 return NULL;
1412 return new;
Christian Heimes0449f632007-12-15 01:27:15 +00001413}
1414
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001415/*[clinic input]
1416property.__init__ as property_init
1417
1418 fget: object(c_default="NULL") = None
1419 function to be used for getting an attribute value
1420 fset: object(c_default="NULL") = None
1421 function to be used for setting an attribute value
1422 fdel: object(c_default="NULL") = None
1423 function to be used for del'ing an attribute
1424 doc: object(c_default="NULL") = None
1425 docstring
1426
1427Property attribute.
1428
1429Typical use is to define a managed attribute x:
1430
1431class C(object):
1432 def getx(self): return self._x
1433 def setx(self, value): self._x = value
1434 def delx(self): del self._x
1435 x = property(getx, setx, delx, "I'm the 'x' property.")
1436
1437Decorators make defining new properties or modifying existing ones easy:
1438
1439class C(object):
1440 @property
1441 def x(self):
1442 "I am the 'x' property."
1443 return self._x
1444 @x.setter
1445 def x(self, value):
1446 self._x = value
1447 @x.deleter
1448 def x(self):
1449 del self._x
1450[clinic start generated code]*/
1451
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001452static int
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001453property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1454 PyObject *fdel, PyObject *doc)
1455/*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001456{
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001457 if (fget == Py_None)
1458 fget = NULL;
1459 if (fset == Py_None)
1460 fset = NULL;
1461 if (fdel == Py_None)
1462 fdel = NULL;
Tim Peters66c1a522001-09-24 21:17:50 +00001463
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001464 Py_XINCREF(fget);
1465 Py_XINCREF(fset);
1466 Py_XINCREF(fdel);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 Py_XINCREF(doc);
Christian Heimes0449f632007-12-15 01:27:15 +00001468
Oren Milmand019bc82018-02-13 12:28:33 +02001469 Py_XSETREF(self->prop_get, fget);
1470 Py_XSETREF(self->prop_set, fset);
1471 Py_XSETREF(self->prop_del, fdel);
1472 Py_XSETREF(self->prop_doc, doc);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001473 self->getter_doc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 /* if no docstring given and the getter has one, use that one */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001476 if ((doc == NULL || doc == Py_None) && fget != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001477 _Py_IDENTIFIER(__doc__);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001478 PyObject *get_doc = _PyObject_GetAttrId(fget, &PyId___doc__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 if (get_doc) {
1480 if (Py_TYPE(self) == &PyProperty_Type) {
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001481 Py_XSETREF(self->prop_doc, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 }
1483 else {
1484 /* If this is a property subclass, put __doc__
1485 in dict of the subclass instance instead,
1486 otherwise it gets shadowed by __doc__ in the
1487 class's dict. */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001488 int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 Py_DECREF(get_doc);
1490 if (err < 0)
1491 return -1;
1492 }
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001493 self->getter_doc = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 }
1495 else if (PyErr_ExceptionMatches(PyExc_Exception)) {
1496 PyErr_Clear();
1497 }
1498 else {
1499 return -1;
1500 }
1501 }
1502
1503 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001504}
1505
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001506static PyObject *
1507property_get___isabstractmethod__(propertyobject *prop, void *closure)
1508{
1509 int res = _PyObject_IsAbstract(prop->prop_get);
1510 if (res == -1) {
1511 return NULL;
1512 }
1513 else if (res) {
1514 Py_RETURN_TRUE;
1515 }
1516
1517 res = _PyObject_IsAbstract(prop->prop_set);
1518 if (res == -1) {
1519 return NULL;
1520 }
1521 else if (res) {
1522 Py_RETURN_TRUE;
1523 }
1524
1525 res = _PyObject_IsAbstract(prop->prop_del);
1526 if (res == -1) {
1527 return NULL;
1528 }
1529 else if (res) {
1530 Py_RETURN_TRUE;
1531 }
1532 Py_RETURN_FALSE;
1533}
1534
1535static PyGetSetDef property_getsetlist[] = {
1536 {"__isabstractmethod__",
1537 (getter)property_get___isabstractmethod__, NULL,
1538 NULL,
1539 NULL},
1540 {NULL} /* Sentinel */
1541};
1542
Guido van Rossum048eb752001-10-02 21:24:57 +00001543static int
1544property_traverse(PyObject *self, visitproc visit, void *arg)
1545{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 propertyobject *pp = (propertyobject *)self;
1547 Py_VISIT(pp->prop_get);
1548 Py_VISIT(pp->prop_set);
1549 Py_VISIT(pp->prop_del);
1550 Py_VISIT(pp->prop_doc);
1551 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001552}
1553
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001554static int
1555property_clear(PyObject *self)
1556{
1557 propertyobject *pp = (propertyobject *)self;
1558 Py_CLEAR(pp->prop_doc);
1559 return 0;
1560}
1561
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001562#include "clinic/descrobject.c.h"
1563
1564PyTypeObject PyDictProxy_Type = {
1565 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1566 "mappingproxy", /* tp_name */
1567 sizeof(mappingproxyobject), /* tp_basicsize */
1568 0, /* tp_itemsize */
1569 /* methods */
1570 (destructor)mappingproxy_dealloc, /* tp_dealloc */
1571 0, /* tp_print */
1572 0, /* tp_getattr */
1573 0, /* tp_setattr */
1574 0, /* tp_reserved */
1575 (reprfunc)mappingproxy_repr, /* tp_repr */
1576 0, /* tp_as_number */
1577 &mappingproxy_as_sequence, /* tp_as_sequence */
1578 &mappingproxy_as_mapping, /* tp_as_mapping */
1579 0, /* tp_hash */
1580 0, /* tp_call */
1581 (reprfunc)mappingproxy_str, /* tp_str */
1582 PyObject_GenericGetAttr, /* tp_getattro */
1583 0, /* tp_setattro */
1584 0, /* tp_as_buffer */
1585 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1586 0, /* tp_doc */
1587 mappingproxy_traverse, /* tp_traverse */
1588 0, /* tp_clear */
1589 (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
1590 0, /* tp_weaklistoffset */
1591 (getiterfunc)mappingproxy_getiter, /* tp_iter */
1592 0, /* tp_iternext */
1593 mappingproxy_methods, /* tp_methods */
1594 0, /* tp_members */
1595 0, /* tp_getset */
1596 0, /* tp_base */
1597 0, /* tp_dict */
1598 0, /* tp_descr_get */
1599 0, /* tp_descr_set */
1600 0, /* tp_dictoffset */
1601 0, /* tp_init */
1602 0, /* tp_alloc */
1603 mappingproxy_new, /* tp_new */
1604};
1605
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001606PyTypeObject PyProperty_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1608 "property", /* tp_name */
1609 sizeof(propertyobject), /* tp_basicsize */
1610 0, /* tp_itemsize */
1611 /* methods */
1612 property_dealloc, /* tp_dealloc */
1613 0, /* tp_print */
1614 0, /* tp_getattr */
1615 0, /* tp_setattr */
1616 0, /* tp_reserved */
1617 0, /* tp_repr */
1618 0, /* tp_as_number */
1619 0, /* tp_as_sequence */
1620 0, /* tp_as_mapping */
1621 0, /* tp_hash */
1622 0, /* tp_call */
1623 0, /* tp_str */
1624 PyObject_GenericGetAttr, /* tp_getattro */
1625 0, /* tp_setattro */
1626 0, /* tp_as_buffer */
1627 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1628 Py_TPFLAGS_BASETYPE, /* tp_flags */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001629 property_init__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 property_traverse, /* tp_traverse */
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001631 (inquiry)property_clear, /* tp_clear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 0, /* tp_richcompare */
1633 0, /* tp_weaklistoffset */
1634 0, /* tp_iter */
1635 0, /* tp_iternext */
1636 property_methods, /* tp_methods */
1637 property_members, /* tp_members */
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001638 property_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 0, /* tp_base */
1640 0, /* tp_dict */
1641 property_descr_get, /* tp_descr_get */
1642 property_descr_set, /* tp_descr_set */
1643 0, /* tp_dictoffset */
1644 property_init, /* tp_init */
1645 PyType_GenericAlloc, /* tp_alloc */
1646 PyType_GenericNew, /* tp_new */
1647 PyObject_GC_Del, /* tp_free */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001648};