blob: 119be35db08d8ace574b98a04ec7f5eae3730f11 [file] [log] [blame]
Tim Peters6d6c1a32001-08-02 04:15:00 +00001/* Descriptors -- a new, flexible way to describe attributes */
2
3#include "Python.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +01004#include "pycore_object.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01005#include "pycore_pystate.h"
Victor Stinnerec13b932018-11-25 23:56:17 +01006#include "pycore_tupleobject.h"
Tim Peters6d6c1a32001-08-02 04:15:00 +00007#include "structmember.h" /* Why is this not included in Python.h? */
8
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02009/*[clinic input]
10class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type"
11class property "propertyobject *" "&PyProperty_Type"
12[clinic start generated code]*/
13/*[clinic end generated code: output=da39a3ee5e6b4b0d input=556352653fd4c02e]*/
14
Tim Peters6d6c1a32001-08-02 04:15:00 +000015static void
16descr_dealloc(PyDescrObject *descr)
17{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000018 _PyObject_GC_UNTRACK(descr);
19 Py_XDECREF(descr->d_type);
20 Py_XDECREF(descr->d_name);
Antoine Pitrou9d574812011-12-12 13:47:25 +010021 Py_XDECREF(descr->d_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000022 PyObject_GC_Del(descr);
Tim Peters6d6c1a32001-08-02 04:15:00 +000023}
24
Walter Dörwaldd7fb7642007-06-11 16:36:59 +000025static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +000026descr_name(PyDescrObject *descr)
27{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
29 return descr->d_name;
30 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +000031}
32
33static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020034descr_repr(PyDescrObject *descr, const char *format)
Tim Peters6d6c1a32001-08-02 04:15:00 +000035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000036 PyObject *name = NULL;
37 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
38 name = descr->d_name;
Walter Dörwaldd7fb7642007-06-11 16:36:59 +000039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040 return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name);
Tim Peters6d6c1a32001-08-02 04:15:00 +000041}
42
43static PyObject *
44method_repr(PyMethodDescrObject *descr)
45{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000046 return descr_repr((PyDescrObject *)descr,
47 "<method '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000048}
49
50static PyObject *
51member_repr(PyMemberDescrObject *descr)
52{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000053 return descr_repr((PyDescrObject *)descr,
54 "<member '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000055}
56
57static PyObject *
58getset_repr(PyGetSetDescrObject *descr)
59{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 return descr_repr((PyDescrObject *)descr,
61 "<attribute '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000062}
63
64static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +000065wrapperdescr_repr(PyWrapperDescrObject *descr)
Tim Peters6d6c1a32001-08-02 04:15:00 +000066{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 return descr_repr((PyDescrObject *)descr,
68 "<slot wrapper '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000069}
70
71static int
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +000072descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +000073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 if (obj == NULL) {
75 Py_INCREF(descr);
76 *pres = (PyObject *)descr;
77 return 1;
78 }
79 if (!PyObject_TypeCheck(obj, descr->d_type)) {
80 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +090081 "descriptor '%V' for '%.100s' objects "
82 "doesn't apply to a '%.100s' object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 descr_name((PyDescrObject *)descr), "?",
84 descr->d_type->tp_name,
85 obj->ob_type->tp_name);
86 *pres = NULL;
87 return 1;
88 }
89 return 0;
Tim Peters6d6c1a32001-08-02 04:15:00 +000090}
91
92static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +000093classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Petersbca1cbc2002-12-09 22:56:13 +000094{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 /* Ensure a valid type. Class methods ignore obj. */
96 if (type == NULL) {
97 if (obj != NULL)
98 type = (PyObject *)obj->ob_type;
99 else {
100 /* Wot - no type?! */
101 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900102 "descriptor '%V' for type '%.100s' "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000103 "needs either an object or a type",
104 descr_name((PyDescrObject *)descr), "?",
105 PyDescr_TYPE(descr)->tp_name);
106 return NULL;
107 }
108 }
109 if (!PyType_Check(type)) {
110 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900111 "descriptor '%V' for type '%.100s' "
112 "needs a type, not a '%.100s' as arg 2",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 descr_name((PyDescrObject *)descr), "?",
114 PyDescr_TYPE(descr)->tp_name,
115 type->ob_type->tp_name);
116 return NULL;
117 }
118 if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) {
119 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900120 "descriptor '%V' requires a subtype of '%.100s' "
121 "but received '%.100s'",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 descr_name((PyDescrObject *)descr), "?",
123 PyDescr_TYPE(descr)->tp_name,
124 ((PyTypeObject *)type)->tp_name);
125 return NULL;
126 }
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200127 return PyCFunction_NewEx(descr->d_method, type, NULL);
Tim Petersbca1cbc2002-12-09 22:56:13 +0000128}
129
130static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000131method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 if (descr_check((PyDescrObject *)descr, obj, &res))
136 return res;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200137 return PyCFunction_NewEx(descr->d_method, obj, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000138}
139
140static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000141member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 if (descr_check((PyDescrObject *)descr, obj, &res))
146 return res;
Steve Dowerb82e17e2019-05-23 08:45:22 -0700147
148 if (descr->d_member->flags & READ_RESTRICTED) {
149 if (PySys_Audit("object.__getattr__", "Os",
150 obj ? obj : Py_None, descr->d_member->name) < 0) {
151 return NULL;
152 }
153 }
154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 return PyMember_GetOne((char *)obj, descr->d_member);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000156}
157
158static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000159getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 if (descr_check((PyDescrObject *)descr, obj, &res))
164 return res;
165 if (descr->d_getset->get != NULL)
166 return descr->d_getset->get(obj, descr->d_getset->closure);
167 PyErr_Format(PyExc_AttributeError,
168 "attribute '%V' of '%.100s' objects is not readable",
169 descr_name((PyDescrObject *)descr), "?",
170 PyDescr_TYPE(descr)->tp_name);
171 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000172}
173
174static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000175wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000179 if (descr_check((PyDescrObject *)descr, obj, &res))
180 return res;
181 return PyWrapper_New((PyObject *)descr, obj);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000182}
183
184static int
185descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 int *pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 assert(obj != NULL);
189 if (!PyObject_TypeCheck(obj, descr->d_type)) {
190 PyErr_Format(PyExc_TypeError,
191 "descriptor '%V' for '%.100s' objects "
Inada Naoki62f95882019-04-01 17:56:11 +0900192 "doesn't apply to a '%.100s' object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 descr_name(descr), "?",
194 descr->d_type->tp_name,
195 obj->ob_type->tp_name);
196 *pres = -1;
197 return 1;
198 }
199 return 0;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000200}
201
202static int
203member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
208 return res;
209 return PyMember_SetOne((char *)obj, descr->d_member, value);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000210}
211
212static int
213getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
218 return res;
219 if (descr->d_getset->set != NULL)
220 return descr->d_getset->set(obj, value,
221 descr->d_getset->closure);
222 PyErr_Format(PyExc_AttributeError,
223 "attribute '%V' of '%.100s' objects is not writable",
224 descr_name((PyDescrObject *)descr), "?",
225 PyDescr_TYPE(descr)->tp_name);
226 return -1;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000227}
228
Jeroen Demeyerbf8e82f2019-07-23 12:39:51 +0200229
230/* Vectorcall functions for each of the PyMethodDescr calling conventions.
231 *
232 * First, common helpers
233 */
234static const char *
235get_name(PyObject *func) {
236 assert(PyObject_TypeCheck(func, &PyMethodDescr_Type));
237 return ((PyMethodDescrObject *)func)->d_method->ml_name;
238}
239
240typedef void (*funcptr)(void);
241
242static inline int
243method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
244{
245 assert(!PyErr_Occurred());
246 assert(PyObject_TypeCheck(func, &PyMethodDescr_Type));
247 if (nargs < 1) {
248 PyErr_Format(PyExc_TypeError,
249 "descriptor '%.200s' of '%.100s' "
250 "object needs an argument",
251 get_name(func), PyDescr_TYPE(func)->tp_name);
252 return -1;
253 }
254 PyObject *self = args[0];
255 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
256 (PyObject *)PyDescr_TYPE(func)))
257 {
258 PyErr_Format(PyExc_TypeError,
259 "descriptor '%.200s' for '%.100s' objects "
260 "doesn't apply to a '%.100s' object",
261 get_name(func), PyDescr_TYPE(func)->tp_name,
262 Py_TYPE(self)->tp_name);
263 return -1;
264 }
265 if (kwnames && PyTuple_GET_SIZE(kwnames)) {
266 PyErr_Format(PyExc_TypeError,
267 "%.200s() takes no keyword arguments", get_name(func));
268 return -1;
269 }
270 return 0;
271}
272
273static inline funcptr
274method_enter_call(PyObject *func)
275{
276 if (Py_EnterRecursiveCall(" while calling a Python object")) {
277 return NULL;
278 }
279 return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth;
280}
281
282/* Now the actual vectorcall functions */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000283static PyObject *
Jeroen Demeyerbf8e82f2019-07-23 12:39:51 +0200284method_vectorcall_VARARGS(
285 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000286{
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200287 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
Jeroen Demeyerbf8e82f2019-07-23 12:39:51 +0200288 if (method_check_args(func, args, nargs, kwnames)) {
INADA Naoki5566bbb2017-02-03 07:43:03 +0900289 return NULL;
290 }
Jeroen Demeyerbf8e82f2019-07-23 12:39:51 +0200291 PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
292 if (argstuple == NULL) {
INADA Naoki5566bbb2017-02-03 07:43:03 +0900293 return NULL;
294 }
Jeroen Demeyerbf8e82f2019-07-23 12:39:51 +0200295 PyCFunction meth = (PyCFunction)method_enter_call(func);
296 if (meth == NULL) {
297 Py_DECREF(argstuple);
298 return NULL;
299 }
300 PyObject *result = meth(args[0], argstuple);
301 Py_DECREF(argstuple);
302 Py_LeaveRecursiveCall();
INADA Naoki5566bbb2017-02-03 07:43:03 +0900303 return result;
304}
305
Tim Peters6d6c1a32001-08-02 04:15:00 +0000306static PyObject *
Jeroen Demeyerbf8e82f2019-07-23 12:39:51 +0200307method_vectorcall_VARARGS_KEYWORDS(
308 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
309{
310 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
311 if (method_check_args(func, args, nargs, NULL)) {
312 return NULL;
313 }
314 PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
315 if (argstuple == NULL) {
316 return NULL;
317 }
318 PyObject *result = NULL;
319 /* Create a temporary dict for keyword arguments */
320 PyObject *kwdict = NULL;
321 if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) > 0) {
322 kwdict = _PyStack_AsDict(args + nargs, kwnames);
323 if (kwdict == NULL) {
324 goto exit;
325 }
326 }
327 PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords)
328 method_enter_call(func);
329 if (meth == NULL) {
330 goto exit;
331 }
332 result = meth(args[0], argstuple, kwdict);
333 Py_LeaveRecursiveCall();
334exit:
335 Py_DECREF(argstuple);
336 Py_XDECREF(kwdict);
337 return result;
338}
339
340static PyObject *
341method_vectorcall_FASTCALL(
342 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
343{
344 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
345 if (method_check_args(func, args, nargs, kwnames)) {
346 return NULL;
347 }
348 _PyCFunctionFast meth = (_PyCFunctionFast)
349 method_enter_call(func);
350 if (meth == NULL) {
351 return NULL;
352 }
353 PyObject *result = meth(args[0], args+1, nargs-1);
354 Py_LeaveRecursiveCall();
355 return result;
356}
357
358static PyObject *
359method_vectorcall_FASTCALL_KEYWORDS(
360 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
361{
362 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
363 if (method_check_args(func, args, nargs, NULL)) {
364 return NULL;
365 }
366 _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
367 method_enter_call(func);
368 if (meth == NULL) {
369 return NULL;
370 }
371 PyObject *result = meth(args[0], args+1, nargs-1, kwnames);
372 Py_LeaveRecursiveCall();
373 return result;
374}
375
376static PyObject *
377method_vectorcall_NOARGS(
378 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
379{
380 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
381 if (method_check_args(func, args, nargs, kwnames)) {
382 return NULL;
383 }
384 if (nargs != 1) {
385 PyErr_Format(PyExc_TypeError,
386 "%.200s() takes no arguments (%zd given)", get_name(func), nargs-1);
387 return NULL;
388 }
389 PyCFunction meth = (PyCFunction)method_enter_call(func);
390 if (meth == NULL) {
391 return NULL;
392 }
393 PyObject *result = meth(args[0], NULL);
394 Py_LeaveRecursiveCall();
395 return result;
396}
397
398static PyObject *
399method_vectorcall_O(
400 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
401{
402 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
403 if (method_check_args(func, args, nargs, kwnames)) {
404 return NULL;
405 }
406 if (nargs != 2) {
407 PyErr_Format(PyExc_TypeError,
408 "%.200s() takes exactly one argument (%zd given)",
409 get_name(func), nargs-1);
410 return NULL;
411 }
412 PyCFunction meth = (PyCFunction)method_enter_call(func);
413 if (meth == NULL) {
414 return NULL;
415 }
416 PyObject *result = meth(args[0], args[1]);
417 Py_LeaveRecursiveCall();
418 return result;
419}
420
421
422static PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000423classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 PyObject *kwds)
Tim Petersbca1cbc2002-12-09 22:56:13 +0000425{
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400426 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300427 PyObject *self, *result;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000428
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400429 /* Make sure that the first argument is acceptable as 'self' */
430 assert(PyTuple_Check(args));
431 argc = PyTuple_GET_SIZE(args);
432 if (argc < 1) {
433 PyErr_Format(PyExc_TypeError,
434 "descriptor '%V' of '%.100s' "
435 "object needs an argument",
436 descr_name((PyDescrObject *)descr), "?",
437 PyDescr_TYPE(descr)->tp_name);
438 return NULL;
439 }
440 self = PyTuple_GET_ITEM(args, 0);
441 if (!PyType_Check(self)) {
442 PyErr_Format(PyExc_TypeError,
443 "descriptor '%V' requires a type "
Inada Naoki871309c2019-03-26 18:26:33 +0900444 "but received a '%.100s' instance",
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400445 descr_name((PyDescrObject *)descr), "?",
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400446 self->ob_type->tp_name);
447 return NULL;
448 }
449 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) {
450 PyErr_Format(PyExc_TypeError,
Inada Naoki871309c2019-03-26 18:26:33 +0900451 "descriptor '%V' requires a subtype of '%.100s' "
452 "but received '%.100s'",
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400453 descr_name((PyDescrObject *)descr), "?",
454 PyDescr_TYPE(descr)->tp_name,
Inada Naoki871309c2019-03-26 18:26:33 +0900455 ((PyTypeObject*)self)->tp_name);
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400456 return NULL;
457 }
458
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300459 result = _PyMethodDef_RawFastCallDict(descr->d_method, self,
Victor Stinnerd17a6932018-11-09 16:56:48 +0100460 &_PyTuple_ITEMS(args)[1], argc - 1,
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300461 kwds);
462 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 return result;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000464}
465
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300466Py_LOCAL_INLINE(PyObject *)
467wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self,
468 PyObject *args, PyObject *kwds)
469{
470 wrapperfunc wrapper = descr->d_base->wrapper;
471
472 if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
Serhiy Storchaka1c607152018-11-27 21:34:27 +0200473 wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300474 return (*wk)(self, args, descr->d_wrapped, kwds);
475 }
476
477 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) {
478 PyErr_Format(PyExc_TypeError,
479 "wrapper %s() takes no keyword arguments",
480 descr->d_base->name);
481 return NULL;
482 }
483 return (*wrapper)(self, args, descr->d_wrapped);
484}
485
Tim Petersbca1cbc2002-12-09 22:56:13 +0000486static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000487wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300490 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 /* Make sure that the first argument is acceptable as 'self' */
493 assert(PyTuple_Check(args));
494 argc = PyTuple_GET_SIZE(args);
495 if (argc < 1) {
496 PyErr_Format(PyExc_TypeError,
497 "descriptor '%V' of '%.100s' "
498 "object needs an argument",
499 descr_name((PyDescrObject *)descr), "?",
500 PyDescr_TYPE(descr)->tp_name);
501 return NULL;
502 }
503 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200504 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200505 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 PyErr_Format(PyExc_TypeError,
507 "descriptor '%V' "
508 "requires a '%.100s' object "
509 "but received a '%.100s'",
510 descr_name((PyDescrObject *)descr), "?",
511 PyDescr_TYPE(descr)->tp_name,
512 self->ob_type->tp_name);
513 return NULL;
514 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000515
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300516 args = PyTuple_GetSlice(args, 1, argc);
517 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 return NULL;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300519 }
520 result = wrapperdescr_raw_call(descr, self, args, kwds);
521 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000523}
524
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300525
Tim Peters6d6c1a32001-08-02 04:15:00 +0000526static PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000527method_get_doc(PyMethodDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000528{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800529 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800530}
531
532static PyObject *
533method_get_text_signature(PyMethodDescrObject *descr, void *closure)
534{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800535 return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000536}
537
Antoine Pitrou9d574812011-12-12 13:47:25 +0100538static PyObject *
539calculate_qualname(PyDescrObject *descr)
540{
541 PyObject *type_qualname, *res;
542 _Py_IDENTIFIER(__qualname__);
543
544 if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) {
545 PyErr_SetString(PyExc_TypeError,
546 "<descriptor>.__name__ is not a unicode object");
547 return NULL;
548 }
549
550 type_qualname = _PyObject_GetAttrId((PyObject *)descr->d_type,
551 &PyId___qualname__);
552 if (type_qualname == NULL)
553 return NULL;
554
555 if (!PyUnicode_Check(type_qualname)) {
556 PyErr_SetString(PyExc_TypeError, "<descriptor>.__objclass__."
557 "__qualname__ is not a unicode object");
558 Py_XDECREF(type_qualname);
559 return NULL;
560 }
561
562 res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name);
563 Py_DECREF(type_qualname);
564 return res;
565}
566
567static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200568descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +0100569{
570 if (descr->d_qualname == NULL)
571 descr->d_qualname = calculate_qualname(descr);
572 Py_XINCREF(descr->d_qualname);
573 return descr->d_qualname;
574}
575
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100576static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530577descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100578{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100579 _Py_IDENTIFIER(getattr);
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200580 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
581 PyDescr_TYPE(descr), PyDescr_NAME(descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100582}
583
584static PyMethodDef descr_methods[] = {
585 {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL},
586 {NULL, NULL}
587};
588
Guido van Rossum6f799372001-09-20 20:46:19 +0000589static PyMemberDef descr_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
591 {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
592 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000593};
594
Guido van Rossum32d34c82001-09-20 21:45:26 +0000595static PyGetSetDef method_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000596 {"__doc__", (getter)method_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100597 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800598 {"__text_signature__", (getter)method_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 {0}
Guido van Rossum6f799372001-09-20 20:46:19 +0000600};
601
602static PyObject *
603member_get_doc(PyMemberDescrObject *descr, void *closure)
604{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 if (descr->d_member->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200606 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 }
608 return PyUnicode_FromString(descr->d_member->doc);
Guido van Rossum6f799372001-09-20 20:46:19 +0000609}
610
Guido van Rossum32d34c82001-09-20 21:45:26 +0000611static PyGetSetDef member_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 {"__doc__", (getter)member_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100613 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000615};
616
617static PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000618getset_get_doc(PyGetSetDescrObject *descr, void *closure)
619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 if (descr->d_getset->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200621 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 }
623 return PyUnicode_FromString(descr->d_getset->doc);
Guido van Rossum32d34c82001-09-20 21:45:26 +0000624}
625
626static PyGetSetDef getset_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 {"__doc__", (getter)getset_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100628 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 {0}
Guido van Rossum32d34c82001-09-20 21:45:26 +0000630};
631
632static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000633wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000634{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800635 return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800636}
637
638static PyObject *
639wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
640{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800641 return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000642}
643
Armin Rigoc6686b72005-11-07 08:38:00 +0000644static PyGetSetDef wrapperdescr_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 {"__doc__", (getter)wrapperdescr_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100646 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800647 {"__text_signature__", (getter)wrapperdescr_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000649};
650
Guido van Rossum048eb752001-10-02 21:24:57 +0000651static int
652descr_traverse(PyObject *self, visitproc visit, void *arg)
653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 PyDescrObject *descr = (PyDescrObject *)self;
655 Py_VISIT(descr->d_type);
656 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000657}
658
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000659PyTypeObject PyMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 PyVarObject_HEAD_INIT(&PyType_Type, 0)
661 "method_descriptor",
662 sizeof(PyMethodDescrObject),
663 0,
664 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200665 offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 0, /* tp_getattr */
667 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200668 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 (reprfunc)method_repr, /* tp_repr */
670 0, /* tp_as_number */
671 0, /* tp_as_sequence */
672 0, /* tp_as_mapping */
673 0, /* tp_hash */
Jeroen Demeyerbf8e82f2019-07-23 12:39:51 +0200674 PyVectorcall_Call, /* tp_call */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 0, /* tp_str */
676 PyObject_GenericGetAttr, /* tp_getattro */
677 0, /* tp_setattro */
678 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200679 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200680 _Py_TPFLAGS_HAVE_VECTORCALL |
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200681 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 0, /* tp_doc */
683 descr_traverse, /* tp_traverse */
684 0, /* tp_clear */
685 0, /* tp_richcompare */
686 0, /* tp_weaklistoffset */
687 0, /* tp_iter */
688 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100689 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 descr_members, /* tp_members */
691 method_getset, /* tp_getset */
692 0, /* tp_base */
693 0, /* tp_dict */
694 (descrgetfunc)method_get, /* tp_descr_get */
695 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000696};
697
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000698/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000699PyTypeObject PyClassMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 PyVarObject_HEAD_INIT(&PyType_Type, 0)
701 "classmethod_descriptor",
702 sizeof(PyMethodDescrObject),
703 0,
704 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200705 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 0, /* tp_getattr */
707 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200708 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 (reprfunc)method_repr, /* tp_repr */
710 0, /* tp_as_number */
711 0, /* tp_as_sequence */
712 0, /* tp_as_mapping */
713 0, /* tp_hash */
714 (ternaryfunc)classmethoddescr_call, /* tp_call */
715 0, /* tp_str */
716 PyObject_GenericGetAttr, /* tp_getattro */
717 0, /* tp_setattro */
718 0, /* tp_as_buffer */
719 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
720 0, /* tp_doc */
721 descr_traverse, /* tp_traverse */
722 0, /* tp_clear */
723 0, /* tp_richcompare */
724 0, /* tp_weaklistoffset */
725 0, /* tp_iter */
726 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100727 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 descr_members, /* tp_members */
729 method_getset, /* tp_getset */
730 0, /* tp_base */
731 0, /* tp_dict */
732 (descrgetfunc)classmethod_get, /* tp_descr_get */
733 0, /* tp_descr_set */
Tim Petersbca1cbc2002-12-09 22:56:13 +0000734};
735
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000736PyTypeObject PyMemberDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 PyVarObject_HEAD_INIT(&PyType_Type, 0)
738 "member_descriptor",
739 sizeof(PyMemberDescrObject),
740 0,
741 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200742 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 0, /* tp_getattr */
744 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200745 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 (reprfunc)member_repr, /* tp_repr */
747 0, /* tp_as_number */
748 0, /* tp_as_sequence */
749 0, /* tp_as_mapping */
750 0, /* tp_hash */
751 0, /* tp_call */
752 0, /* tp_str */
753 PyObject_GenericGetAttr, /* tp_getattro */
754 0, /* tp_setattro */
755 0, /* tp_as_buffer */
756 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
757 0, /* tp_doc */
758 descr_traverse, /* tp_traverse */
759 0, /* tp_clear */
760 0, /* tp_richcompare */
761 0, /* tp_weaklistoffset */
762 0, /* tp_iter */
763 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100764 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 descr_members, /* tp_members */
766 member_getset, /* tp_getset */
767 0, /* tp_base */
768 0, /* tp_dict */
769 (descrgetfunc)member_get, /* tp_descr_get */
770 (descrsetfunc)member_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000771};
772
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000773PyTypeObject PyGetSetDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000774 PyVarObject_HEAD_INIT(&PyType_Type, 0)
775 "getset_descriptor",
776 sizeof(PyGetSetDescrObject),
777 0,
778 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200779 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 0, /* tp_getattr */
781 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200782 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 (reprfunc)getset_repr, /* tp_repr */
784 0, /* tp_as_number */
785 0, /* tp_as_sequence */
786 0, /* tp_as_mapping */
787 0, /* tp_hash */
788 0, /* tp_call */
789 0, /* tp_str */
790 PyObject_GenericGetAttr, /* tp_getattro */
791 0, /* tp_setattro */
792 0, /* tp_as_buffer */
793 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
794 0, /* tp_doc */
795 descr_traverse, /* tp_traverse */
796 0, /* tp_clear */
797 0, /* tp_richcompare */
798 0, /* tp_weaklistoffset */
799 0, /* tp_iter */
800 0, /* tp_iternext */
801 0, /* tp_methods */
802 descr_members, /* tp_members */
803 getset_getset, /* tp_getset */
804 0, /* tp_base */
805 0, /* tp_dict */
806 (descrgetfunc)getset_get, /* tp_descr_get */
807 (descrsetfunc)getset_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000808};
809
Guido van Rossumf4593e02001-10-03 12:09:30 +0000810PyTypeObject PyWrapperDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 PyVarObject_HEAD_INIT(&PyType_Type, 0)
812 "wrapper_descriptor",
813 sizeof(PyWrapperDescrObject),
814 0,
815 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200816 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 0, /* tp_getattr */
818 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200819 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 (reprfunc)wrapperdescr_repr, /* tp_repr */
821 0, /* tp_as_number */
822 0, /* tp_as_sequence */
823 0, /* tp_as_mapping */
824 0, /* tp_hash */
825 (ternaryfunc)wrapperdescr_call, /* tp_call */
826 0, /* tp_str */
827 PyObject_GenericGetAttr, /* tp_getattro */
828 0, /* tp_setattro */
829 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200830 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
831 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 0, /* tp_doc */
833 descr_traverse, /* tp_traverse */
834 0, /* tp_clear */
835 0, /* tp_richcompare */
836 0, /* tp_weaklistoffset */
837 0, /* tp_iter */
838 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100839 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 descr_members, /* tp_members */
841 wrapperdescr_getset, /* tp_getset */
842 0, /* tp_base */
843 0, /* tp_dict */
844 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
845 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000846};
847
848static PyDescrObject *
Jeremy Hyltonaf68c872005-12-10 18:50:16 +0000849descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000850{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000851 PyDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
854 if (descr != NULL) {
855 Py_XINCREF(type);
856 descr->d_type = type;
857 descr->d_name = PyUnicode_InternFromString(name);
858 if (descr->d_name == NULL) {
859 Py_DECREF(descr);
860 descr = NULL;
861 }
Benjamin Petersonf2fe7f02011-12-17 08:02:20 -0500862 else {
863 descr->d_qualname = NULL;
864 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 }
866 return descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000867}
868
869PyObject *
870PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
871{
Jeroen Demeyerbf8e82f2019-07-23 12:39:51 +0200872 /* Figure out correct vectorcall function to use */
873 vectorcallfunc vectorcall;
874 switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS))
875 {
876 case METH_VARARGS:
877 vectorcall = method_vectorcall_VARARGS;
878 break;
879 case METH_VARARGS | METH_KEYWORDS:
880 vectorcall = method_vectorcall_VARARGS_KEYWORDS;
881 break;
882 case METH_FASTCALL:
883 vectorcall = method_vectorcall_FASTCALL;
884 break;
885 case METH_FASTCALL | METH_KEYWORDS:
886 vectorcall = method_vectorcall_FASTCALL_KEYWORDS;
887 break;
888 case METH_NOARGS:
889 vectorcall = method_vectorcall_NOARGS;
890 break;
891 case METH_O:
892 vectorcall = method_vectorcall_O;
893 break;
894 default:
895 PyErr_SetString(PyExc_SystemError, "bad call flags");
896 return NULL;
897 }
898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 PyMethodDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
902 type, method->ml_name);
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200903 if (descr != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000904 descr->d_method = method;
Jeroen Demeyerbf8e82f2019-07-23 12:39:51 +0200905 descr->vectorcall = vectorcall;
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200906 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000908}
909
910PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000911PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
912{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 PyMethodDescrObject *descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000915 descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
916 type, method->ml_name);
917 if (descr != NULL)
918 descr->d_method = method;
919 return (PyObject *)descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000920}
921
922PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000923PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000924{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 PyMemberDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
928 type, member->name);
929 if (descr != NULL)
930 descr->d_member = member;
931 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000932}
933
934PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000935PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000936{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 PyGetSetDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
940 type, getset->name);
941 if (descr != NULL)
942 descr->d_getset = getset;
943 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000944}
945
946PyObject *
947PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
952 type, base->name);
953 if (descr != NULL) {
954 descr->d_base = base;
955 descr->d_wrapped = wrapped;
956 }
957 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000958}
959
Tim Peters6d6c1a32001-08-02 04:15:00 +0000960
Victor Stinner0db176f2012-04-16 00:16:30 +0200961/* --- mappingproxy: read-only proxy for mappings --- */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000962
963/* This has no reason to be in this file except that adding new files is a
964 bit of a pain */
965
966typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 PyObject_HEAD
Victor Stinner0db176f2012-04-16 00:16:30 +0200968 PyObject *mapping;
969} mappingproxyobject;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000970
Martin v. Löwis18e16552006-02-15 17:27:45 +0000971static Py_ssize_t
Victor Stinner0db176f2012-04-16 00:16:30 +0200972mappingproxy_len(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000973{
Victor Stinner0db176f2012-04-16 00:16:30 +0200974 return PyObject_Size(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000975}
976
977static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200978mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000979{
Victor Stinner0db176f2012-04-16 00:16:30 +0200980 return PyObject_GetItem(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000981}
982
Victor Stinner0db176f2012-04-16 00:16:30 +0200983static PyMappingMethods mappingproxy_as_mapping = {
984 (lenfunc)mappingproxy_len, /* mp_length */
985 (binaryfunc)mappingproxy_getitem, /* mp_subscript */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 0, /* mp_ass_subscript */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000987};
988
989static int
Victor Stinner0db176f2012-04-16 00:16:30 +0200990mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000991{
Victor Stinner0db176f2012-04-16 00:16:30 +0200992 if (PyDict_CheckExact(pp->mapping))
993 return PyDict_Contains(pp->mapping, key);
994 else
995 return PySequence_Contains(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000996}
997
Victor Stinner0db176f2012-04-16 00:16:30 +0200998static PySequenceMethods mappingproxy_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 0, /* sq_length */
1000 0, /* sq_concat */
1001 0, /* sq_repeat */
1002 0, /* sq_item */
1003 0, /* sq_slice */
1004 0, /* sq_ass_item */
1005 0, /* sq_ass_slice */
Victor Stinner0db176f2012-04-16 00:16:30 +02001006 (objobjproc)mappingproxy_contains, /* sq_contains */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 0, /* sq_inplace_concat */
1008 0, /* sq_inplace_repeat */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001009};
1010
1011static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001012mappingproxy_get(mappingproxyobject *pp, PyObject *args)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001013{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 PyObject *key, *def = Py_None;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001015 _Py_IDENTIFIER(get);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def))
1018 return NULL;
Victor Stinner7e425412016-12-09 00:36:19 +01001019 return _PyObject_CallMethodIdObjArgs(pp->mapping, &PyId_get,
1020 key, def, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001021}
1022
1023static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301024mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001025{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001026 _Py_IDENTIFIER(keys);
Victor Stinner0db176f2012-04-16 00:16:30 +02001027 return _PyObject_CallMethodId(pp->mapping, &PyId_keys, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001028}
1029
1030static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301031mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001032{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001033 _Py_IDENTIFIER(values);
Victor Stinner0db176f2012-04-16 00:16:30 +02001034 return _PyObject_CallMethodId(pp->mapping, &PyId_values, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001035}
1036
1037static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301038mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001039{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001040 _Py_IDENTIFIER(items);
Victor Stinner0db176f2012-04-16 00:16:30 +02001041 return _PyObject_CallMethodId(pp->mapping, &PyId_items, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001042}
1043
1044static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301045mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001046{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001047 _Py_IDENTIFIER(copy);
Victor Stinner0db176f2012-04-16 00:16:30 +02001048 return _PyObject_CallMethodId(pp->mapping, &PyId_copy, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001049}
1050
Victor Stinner0db176f2012-04-16 00:16:30 +02001051/* WARNING: mappingproxy methods must not give access
1052 to the underlying mapping */
1053
1054static PyMethodDef mappingproxy_methods[] = {
1055 {"get", (PyCFunction)mappingproxy_get, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d."
Victor Stinner0db176f2012-04-16 00:16:30 +02001057 " d defaults to None.")},
1058 {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 PyDoc_STR("D.keys() -> list of D's keys")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001060 {"values", (PyCFunction)mappingproxy_values, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 PyDoc_STR("D.values() -> list of D's values")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001062 {"items", (PyCFunction)mappingproxy_items, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001064 {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 PyDoc_STR("D.copy() -> a shallow copy of D")},
1066 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001067};
1068
1069static void
Victor Stinner0db176f2012-04-16 00:16:30 +02001070mappingproxy_dealloc(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 _PyObject_GC_UNTRACK(pp);
Victor Stinner0db176f2012-04-16 00:16:30 +02001073 Py_DECREF(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 PyObject_GC_Del(pp);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001075}
1076
1077static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001078mappingproxy_getiter(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001079{
Victor Stinner0db176f2012-04-16 00:16:30 +02001080 return PyObject_GetIter(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001081}
1082
Neil Schemenauer26775122001-10-21 22:26:43 +00001083static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001084mappingproxy_str(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001085{
Victor Stinner0db176f2012-04-16 00:16:30 +02001086 return PyObject_Str(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001087}
1088
Ezio Melottiac53ab62010-12-18 14:59:43 +00001089static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001090mappingproxy_repr(mappingproxyobject *pp)
Ezio Melottiac53ab62010-12-18 14:59:43 +00001091{
Victor Stinner0db176f2012-04-16 00:16:30 +02001092 return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping);
Ezio Melottiac53ab62010-12-18 14:59:43 +00001093}
1094
Guido van Rossum048eb752001-10-02 21:24:57 +00001095static int
Victor Stinner0db176f2012-04-16 00:16:30 +02001096mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
Guido van Rossum048eb752001-10-02 21:24:57 +00001097{
Victor Stinner0db176f2012-04-16 00:16:30 +02001098 mappingproxyobject *pp = (mappingproxyobject *)self;
1099 Py_VISIT(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001101}
1102
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001103static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001104mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op)
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001105{
Victor Stinner0db176f2012-04-16 00:16:30 +02001106 return PyObject_RichCompare(v->mapping, w, op);
1107}
1108
1109static int
1110mappingproxy_check_mapping(PyObject *mapping)
1111{
1112 if (!PyMapping_Check(mapping)
1113 || PyList_Check(mapping)
1114 || PyTuple_Check(mapping)) {
1115 PyErr_Format(PyExc_TypeError,
1116 "mappingproxy() argument must be a mapping, not %s",
1117 Py_TYPE(mapping)->tp_name);
1118 return -1;
1119 }
1120 return 0;
1121}
1122
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001123/*[clinic input]
1124@classmethod
1125mappingproxy.__new__ as mappingproxy_new
Victor Stinner0db176f2012-04-16 00:16:30 +02001126
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001127 mapping: object
1128
1129[clinic start generated code]*/
1130
1131static PyObject *
1132mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping)
1133/*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/
1134{
1135 mappingproxyobject *mappingproxy;
Victor Stinner0db176f2012-04-16 00:16:30 +02001136
1137 if (mappingproxy_check_mapping(mapping) == -1)
1138 return NULL;
1139
1140 mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
1141 if (mappingproxy == NULL)
1142 return NULL;
1143 Py_INCREF(mapping);
1144 mappingproxy->mapping = mapping;
1145 _PyObject_GC_TRACK(mappingproxy);
1146 return (PyObject *)mappingproxy;
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001147}
1148
Tim Peters6d6c1a32001-08-02 04:15:00 +00001149PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001150PyDictProxy_New(PyObject *mapping)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001151{
Victor Stinner0db176f2012-04-16 00:16:30 +02001152 mappingproxyobject *pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001153
Victor Stinner0db176f2012-04-16 00:16:30 +02001154 if (mappingproxy_check_mapping(mapping) == -1)
1155 return NULL;
1156
1157 pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 if (pp != NULL) {
Victor Stinner0db176f2012-04-16 00:16:30 +02001159 Py_INCREF(mapping);
1160 pp->mapping = mapping;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 _PyObject_GC_TRACK(pp);
1162 }
1163 return (PyObject *)pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001164}
1165
1166
1167/* --- Wrapper object for "slot" methods --- */
1168
1169/* This has no reason to be in this file except that adding new files is a
1170 bit of a pain */
1171
1172typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 PyObject_HEAD
1174 PyWrapperDescrObject *descr;
1175 PyObject *self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001176} wrapperobject;
1177
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001178#define Wrapper_Check(v) (Py_TYPE(v) == &_PyMethodWrapper_Type)
Mark Dickinson211c6252009-02-01 10:28:51 +00001179
Tim Peters6d6c1a32001-08-02 04:15:00 +00001180static void
1181wrapper_dealloc(wrapperobject *wp)
1182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 PyObject_GC_UnTrack(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001184 Py_TRASHCAN_BEGIN(wp, wrapper_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 Py_XDECREF(wp->descr);
1186 Py_XDECREF(wp->self);
1187 PyObject_GC_Del(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001188 Py_TRASHCAN_END
Tim Peters6d6c1a32001-08-02 04:15:00 +00001189}
1190
Mark Dickinson211c6252009-02-01 10:28:51 +00001191static PyObject *
1192wrapper_richcompare(PyObject *a, PyObject *b, int op)
Armin Rigoc6686b72005-11-07 08:38:00 +00001193{
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001194 wrapperobject *wa, *wb;
1195 int eq;
Mark Dickinson211c6252009-02-01 10:28:51 +00001196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +00001198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 /* both arguments should be wrapperobjects */
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001200 if ((op != Py_EQ && op != Py_NE)
1201 || !Wrapper_Check(a) || !Wrapper_Check(b))
1202 {
stratakise8b19652017-11-02 11:32:54 +01001203 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 }
Mark Dickinson211c6252009-02-01 10:28:51 +00001205
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001206 wa = (wrapperobject *)a;
1207 wb = (wrapperobject *)b;
1208 eq = (wa->descr == wb->descr && wa->self == wb->self);
1209 if (eq == (op == Py_EQ)) {
1210 Py_RETURN_TRUE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 }
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001212 else {
1213 Py_RETURN_FALSE;
1214 }
Armin Rigoc6686b72005-11-07 08:38:00 +00001215}
1216
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001217static Py_hash_t
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001218wrapper_hash(wrapperobject *wp)
1219{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001220 Py_hash_t x, y;
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001221 x = _Py_HashPointer(wp->self);
1222 y = _Py_HashPointer(wp->descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 x = x ^ y;
1224 if (x == -1)
1225 x = -2;
1226 return x;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001227}
1228
Armin Rigoc6686b72005-11-07 08:38:00 +00001229static PyObject *
1230wrapper_repr(wrapperobject *wp)
1231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
1233 wp->descr->d_base->name,
1234 wp->self->ob_type->tp_name,
1235 wp->self);
Armin Rigoc6686b72005-11-07 08:38:00 +00001236}
1237
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001238static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301239wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001240{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001241 _Py_IDENTIFIER(getattr);
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02001242 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
1243 wp->self, PyDescr_NAME(wp->descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001244}
1245
1246static PyMethodDef wrapper_methods[] = {
1247 {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
1248 {NULL, NULL}
1249};
1250
Armin Rigoc6686b72005-11-07 08:38:00 +00001251static PyMemberDef wrapper_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
1253 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001254};
1255
1256static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001257wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored))
Armin Rigoc6686b72005-11-07 08:38:00 +00001258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
Armin Rigoc6686b72005-11-07 08:38:00 +00001260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 Py_INCREF(c);
1262 return c;
Armin Rigoc6686b72005-11-07 08:38:00 +00001263}
1264
1265static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001266wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001267{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 const char *s = wp->descr->d_base->name;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 return PyUnicode_FromString(s);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001271}
1272
1273static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001274wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001275{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001276 return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -08001277}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001278
Larry Hastings5c661892014-01-24 06:17:25 -08001279static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001280wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
Larry Hastings5c661892014-01-24 06:17:25 -08001281{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001282 return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001283}
1284
Antoine Pitrou9d574812011-12-12 13:47:25 +01001285static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001286wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +01001287{
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001288 return descr_get_qualname((PyDescrObject *)wp->descr, NULL);
Antoine Pitrou9d574812011-12-12 13:47:25 +01001289}
1290
Guido van Rossum32d34c82001-09-20 21:45:26 +00001291static PyGetSetDef wrapper_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 {"__objclass__", (getter)wrapper_objclass},
1293 {"__name__", (getter)wrapper_name},
Antoine Pitrou9d574812011-12-12 13:47:25 +01001294 {"__qualname__", (getter)wrapper_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 {"__doc__", (getter)wrapper_doc},
Larry Hastings5c661892014-01-24 06:17:25 -08001296 {"__text_signature__", (getter)wrapper_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001298};
1299
1300static PyObject *
1301wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
1302{
Serhiy Storchaka5e02c782017-09-21 14:25:36 +03001303 return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001304}
1305
Guido van Rossum048eb752001-10-02 21:24:57 +00001306static int
1307wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1308{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 wrapperobject *wp = (wrapperobject *)self;
1310 Py_VISIT(wp->descr);
1311 Py_VISIT(wp->self);
1312 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001313}
1314
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001315PyTypeObject _PyMethodWrapper_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1317 "method-wrapper", /* tp_name */
1318 sizeof(wrapperobject), /* tp_basicsize */
1319 0, /* tp_itemsize */
1320 /* methods */
1321 (destructor)wrapper_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001322 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 0, /* tp_getattr */
1324 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001325 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 (reprfunc)wrapper_repr, /* tp_repr */
1327 0, /* tp_as_number */
1328 0, /* tp_as_sequence */
1329 0, /* tp_as_mapping */
1330 (hashfunc)wrapper_hash, /* tp_hash */
1331 (ternaryfunc)wrapper_call, /* tp_call */
1332 0, /* tp_str */
1333 PyObject_GenericGetAttr, /* tp_getattro */
1334 0, /* tp_setattro */
1335 0, /* tp_as_buffer */
1336 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1337 0, /* tp_doc */
1338 wrapper_traverse, /* tp_traverse */
1339 0, /* tp_clear */
1340 wrapper_richcompare, /* tp_richcompare */
1341 0, /* tp_weaklistoffset */
1342 0, /* tp_iter */
1343 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001344 wrapper_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 wrapper_members, /* tp_members */
1346 wrapper_getsets, /* tp_getset */
1347 0, /* tp_base */
1348 0, /* tp_dict */
1349 0, /* tp_descr_get */
1350 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001351};
1352
1353PyObject *
1354PyWrapper_New(PyObject *d, PyObject *self)
1355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 wrapperobject *wp;
1357 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1360 descr = (PyWrapperDescrObject *)d;
Victor Stinner3249dec2011-05-01 23:19:15 +02001361 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +02001362 (PyObject *)PyDescr_TYPE(descr)));
Tim Peters6d6c1a32001-08-02 04:15:00 +00001363
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001364 wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 if (wp != NULL) {
1366 Py_INCREF(descr);
1367 wp->descr = descr;
1368 Py_INCREF(self);
1369 wp->self = self;
1370 _PyObject_GC_TRACK(wp);
1371 }
1372 return (PyObject *)wp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001373}
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001374
1375
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001376/* A built-in 'property' type */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001377
1378/*
Serhiy Storchakad741a882015-06-11 00:06:39 +03001379class property(object):
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
1382 if doc is None and fget is not None and hasattr(fget, "__doc__"):
Serhiy Storchakad741a882015-06-11 00:06:39 +03001383 doc = fget.__doc__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 self.__get = fget
1385 self.__set = fset
1386 self.__del = fdel
1387 self.__doc__ = doc
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 def __get__(self, inst, type=None):
1390 if inst is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001391 return self
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 if self.__get is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001393 raise AttributeError, "unreadable attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 return self.__get(inst)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 def __set__(self, inst, value):
1397 if self.__set is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001398 raise AttributeError, "can't set attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 return self.__set(inst, value)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 def __delete__(self, inst):
1402 if self.__del is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001403 raise AttributeError, "can't delete attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 return self.__del(inst)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001405
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001406*/
1407
1408typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 PyObject_HEAD
1410 PyObject *prop_get;
1411 PyObject *prop_set;
1412 PyObject *prop_del;
1413 PyObject *prop_doc;
1414 int getter_doc;
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001415} propertyobject;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001416
Christian Heimes0449f632007-12-15 01:27:15 +00001417static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
Benjamin Peterson93964832010-06-28 03:07:10 +00001418 PyObject *);
Christian Heimes0449f632007-12-15 01:27:15 +00001419
Tim Peters66c1a522001-09-24 21:17:50 +00001420static PyMemberDef property_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
1422 {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
1423 {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
Raymond Hettingereac503a2015-05-13 01:09:59 -07001424 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 {0}
Tim Peters66c1a522001-09-24 21:17:50 +00001426};
1427
Christian Heimes0449f632007-12-15 01:27:15 +00001428
Guido van Rossum58da9312007-11-10 23:39:45 +00001429PyDoc_STRVAR(getter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 "Descriptor to change the getter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001431
Neal Norwitz32dde222008-04-15 06:43:13 +00001432static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001433property_getter(PyObject *self, PyObject *getter)
1434{
Benjamin Peterson93964832010-06-28 03:07:10 +00001435 return property_copy(self, getter, NULL, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001436}
1437
Christian Heimes0449f632007-12-15 01:27:15 +00001438
Guido van Rossum58da9312007-11-10 23:39:45 +00001439PyDoc_STRVAR(setter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 "Descriptor to change the setter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001441
Neal Norwitz32dde222008-04-15 06:43:13 +00001442static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001443property_setter(PyObject *self, PyObject *setter)
1444{
Benjamin Peterson93964832010-06-28 03:07:10 +00001445 return property_copy(self, NULL, setter, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001446}
1447
Christian Heimes0449f632007-12-15 01:27:15 +00001448
Guido van Rossum58da9312007-11-10 23:39:45 +00001449PyDoc_STRVAR(deleter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 "Descriptor to change the deleter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001451
Neal Norwitz32dde222008-04-15 06:43:13 +00001452static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001453property_deleter(PyObject *self, PyObject *deleter)
1454{
Benjamin Peterson93964832010-06-28 03:07:10 +00001455 return property_copy(self, NULL, NULL, deleter);
Guido van Rossum58da9312007-11-10 23:39:45 +00001456}
1457
1458
Guido van Rossum58da9312007-11-10 23:39:45 +00001459static PyMethodDef property_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 {"getter", property_getter, METH_O, getter_doc},
1461 {"setter", property_setter, METH_O, setter_doc},
1462 {"deleter", property_deleter, METH_O, deleter_doc},
1463 {0}
Guido van Rossum58da9312007-11-10 23:39:45 +00001464};
1465
Tim Peters66c1a522001-09-24 21:17:50 +00001466
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001467static void
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001468property_dealloc(PyObject *self)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 propertyobject *gs = (propertyobject *)self;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 _PyObject_GC_UNTRACK(self);
1473 Py_XDECREF(gs->prop_get);
1474 Py_XDECREF(gs->prop_set);
1475 Py_XDECREF(gs->prop_del);
1476 Py_XDECREF(gs->prop_doc);
1477 self->ob_type->tp_free(self);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001478}
1479
1480static PyObject *
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001481property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001482{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 if (obj == NULL || obj == Py_None) {
1484 Py_INCREF(self);
1485 return self;
1486 }
Victor Stinnere972c132018-10-01 03:03:22 -07001487
1488 propertyobject *gs = (propertyobject *)self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 if (gs->prop_get == NULL) {
1490 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1491 return NULL;
1492 }
Victor Stinnere972c132018-10-01 03:03:22 -07001493
1494 PyObject *args[1] = {obj};
1495 return _PyObject_FastCall(gs->prop_get, args, 1);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001496}
1497
1498static int
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001499property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 propertyobject *gs = (propertyobject *)self;
1502 PyObject *func, *res;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 if (value == NULL)
1505 func = gs->prop_del;
1506 else
1507 func = gs->prop_set;
1508 if (func == NULL) {
1509 PyErr_SetString(PyExc_AttributeError,
1510 value == NULL ?
1511 "can't delete attribute" :
1512 "can't set attribute");
1513 return -1;
1514 }
1515 if (value == NULL)
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01001516 res = PyObject_CallFunctionObjArgs(func, obj, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 else
Benjamin Peterson9b955de2010-12-07 04:04:02 +00001518 res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 if (res == NULL)
1520 return -1;
1521 Py_DECREF(res);
1522 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001523}
1524
Christian Heimes0449f632007-12-15 01:27:15 +00001525static PyObject *
Benjamin Peterson93964832010-06-28 03:07:10 +00001526property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
Christian Heimes0449f632007-12-15 01:27:15 +00001527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 propertyobject *pold = (propertyobject *)old;
Benjamin Peterson93964832010-06-28 03:07:10 +00001529 PyObject *new, *type, *doc;
Christian Heimes0449f632007-12-15 01:27:15 +00001530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 type = PyObject_Type(old);
1532 if (type == NULL)
1533 return NULL;
Christian Heimes0449f632007-12-15 01:27:15 +00001534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 if (get == NULL || get == Py_None) {
1536 Py_XDECREF(get);
1537 get = pold->prop_get ? pold->prop_get : Py_None;
1538 }
1539 if (set == NULL || set == Py_None) {
1540 Py_XDECREF(set);
1541 set = pold->prop_set ? pold->prop_set : Py_None;
1542 }
1543 if (del == NULL || del == Py_None) {
1544 Py_XDECREF(del);
1545 del = pold->prop_del ? pold->prop_del : Py_None;
1546 }
Benjamin Peterson93964832010-06-28 03:07:10 +00001547 if (pold->getter_doc && get != Py_None) {
1548 /* make _init use __doc__ from getter */
1549 doc = Py_None;
1550 }
1551 else {
1552 doc = pold->prop_doc ? pold->prop_doc : Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 }
R. David Murrayb18500d2009-05-04 22:59:07 +00001554
Victor Stinner5abaa2b2016-12-09 16:22:32 +01001555 new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 Py_DECREF(type);
1557 if (new == NULL)
1558 return NULL;
1559 return new;
Christian Heimes0449f632007-12-15 01:27:15 +00001560}
1561
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001562/*[clinic input]
1563property.__init__ as property_init
1564
1565 fget: object(c_default="NULL") = None
1566 function to be used for getting an attribute value
1567 fset: object(c_default="NULL") = None
1568 function to be used for setting an attribute value
1569 fdel: object(c_default="NULL") = None
1570 function to be used for del'ing an attribute
1571 doc: object(c_default="NULL") = None
1572 docstring
1573
1574Property attribute.
1575
1576Typical use is to define a managed attribute x:
1577
1578class C(object):
1579 def getx(self): return self._x
1580 def setx(self, value): self._x = value
1581 def delx(self): del self._x
1582 x = property(getx, setx, delx, "I'm the 'x' property.")
1583
1584Decorators make defining new properties or modifying existing ones easy:
1585
1586class C(object):
1587 @property
1588 def x(self):
1589 "I am the 'x' property."
1590 return self._x
1591 @x.setter
1592 def x(self, value):
1593 self._x = value
1594 @x.deleter
1595 def x(self):
1596 del self._x
1597[clinic start generated code]*/
1598
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001599static int
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001600property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1601 PyObject *fdel, PyObject *doc)
1602/*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001603{
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001604 if (fget == Py_None)
1605 fget = NULL;
1606 if (fset == Py_None)
1607 fset = NULL;
1608 if (fdel == Py_None)
1609 fdel = NULL;
Tim Peters66c1a522001-09-24 21:17:50 +00001610
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001611 Py_XINCREF(fget);
1612 Py_XINCREF(fset);
1613 Py_XINCREF(fdel);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 Py_XINCREF(doc);
Christian Heimes0449f632007-12-15 01:27:15 +00001615
Oren Milmand019bc82018-02-13 12:28:33 +02001616 Py_XSETREF(self->prop_get, fget);
1617 Py_XSETREF(self->prop_set, fset);
1618 Py_XSETREF(self->prop_del, fdel);
1619 Py_XSETREF(self->prop_doc, doc);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001620 self->getter_doc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 /* if no docstring given and the getter has one, use that one */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001623 if ((doc == NULL || doc == Py_None) && fget != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001624 _Py_IDENTIFIER(__doc__);
Serhiy Storchaka353053d2019-09-01 14:01:05 +03001625 PyObject *get_doc;
1626 int rc = _PyObject_LookupAttrId(fget, &PyId___doc__, &get_doc);
1627 if (rc <= 0) {
1628 return rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 }
Serhiy Storchaka353053d2019-09-01 14:01:05 +03001630 if (Py_TYPE(self) == &PyProperty_Type) {
1631 Py_XSETREF(self->prop_doc, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 }
1633 else {
Serhiy Storchaka353053d2019-09-01 14:01:05 +03001634 /* If this is a property subclass, put __doc__
1635 in dict of the subclass instance instead,
1636 otherwise it gets shadowed by __doc__ in the
1637 class's dict. */
1638 int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc);
1639 Py_DECREF(get_doc);
1640 if (err < 0)
1641 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 }
Serhiy Storchaka353053d2019-09-01 14:01:05 +03001643 self->getter_doc = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 }
1645
1646 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001647}
1648
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001649static PyObject *
1650property_get___isabstractmethod__(propertyobject *prop, void *closure)
1651{
1652 int res = _PyObject_IsAbstract(prop->prop_get);
1653 if (res == -1) {
1654 return NULL;
1655 }
1656 else if (res) {
1657 Py_RETURN_TRUE;
1658 }
1659
1660 res = _PyObject_IsAbstract(prop->prop_set);
1661 if (res == -1) {
1662 return NULL;
1663 }
1664 else if (res) {
1665 Py_RETURN_TRUE;
1666 }
1667
1668 res = _PyObject_IsAbstract(prop->prop_del);
1669 if (res == -1) {
1670 return NULL;
1671 }
1672 else if (res) {
1673 Py_RETURN_TRUE;
1674 }
1675 Py_RETURN_FALSE;
1676}
1677
1678static PyGetSetDef property_getsetlist[] = {
1679 {"__isabstractmethod__",
1680 (getter)property_get___isabstractmethod__, NULL,
1681 NULL,
1682 NULL},
1683 {NULL} /* Sentinel */
1684};
1685
Guido van Rossum048eb752001-10-02 21:24:57 +00001686static int
1687property_traverse(PyObject *self, visitproc visit, void *arg)
1688{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 propertyobject *pp = (propertyobject *)self;
1690 Py_VISIT(pp->prop_get);
1691 Py_VISIT(pp->prop_set);
1692 Py_VISIT(pp->prop_del);
1693 Py_VISIT(pp->prop_doc);
1694 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001695}
1696
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001697static int
1698property_clear(PyObject *self)
1699{
1700 propertyobject *pp = (propertyobject *)self;
1701 Py_CLEAR(pp->prop_doc);
1702 return 0;
1703}
1704
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001705#include "clinic/descrobject.c.h"
1706
1707PyTypeObject PyDictProxy_Type = {
1708 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1709 "mappingproxy", /* tp_name */
1710 sizeof(mappingproxyobject), /* tp_basicsize */
1711 0, /* tp_itemsize */
1712 /* methods */
1713 (destructor)mappingproxy_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001714 0, /* tp_vectorcall_offset */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001715 0, /* tp_getattr */
1716 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001717 0, /* tp_as_async */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001718 (reprfunc)mappingproxy_repr, /* tp_repr */
1719 0, /* tp_as_number */
1720 &mappingproxy_as_sequence, /* tp_as_sequence */
1721 &mappingproxy_as_mapping, /* tp_as_mapping */
1722 0, /* tp_hash */
1723 0, /* tp_call */
1724 (reprfunc)mappingproxy_str, /* tp_str */
1725 PyObject_GenericGetAttr, /* tp_getattro */
1726 0, /* tp_setattro */
1727 0, /* tp_as_buffer */
1728 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1729 0, /* tp_doc */
1730 mappingproxy_traverse, /* tp_traverse */
1731 0, /* tp_clear */
1732 (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
1733 0, /* tp_weaklistoffset */
1734 (getiterfunc)mappingproxy_getiter, /* tp_iter */
1735 0, /* tp_iternext */
1736 mappingproxy_methods, /* tp_methods */
1737 0, /* tp_members */
1738 0, /* tp_getset */
1739 0, /* tp_base */
1740 0, /* tp_dict */
1741 0, /* tp_descr_get */
1742 0, /* tp_descr_set */
1743 0, /* tp_dictoffset */
1744 0, /* tp_init */
1745 0, /* tp_alloc */
1746 mappingproxy_new, /* tp_new */
1747};
1748
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001749PyTypeObject PyProperty_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1751 "property", /* tp_name */
1752 sizeof(propertyobject), /* tp_basicsize */
1753 0, /* tp_itemsize */
1754 /* methods */
1755 property_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001756 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 0, /* tp_getattr */
1758 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001759 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 0, /* tp_repr */
1761 0, /* tp_as_number */
1762 0, /* tp_as_sequence */
1763 0, /* tp_as_mapping */
1764 0, /* tp_hash */
1765 0, /* tp_call */
1766 0, /* tp_str */
1767 PyObject_GenericGetAttr, /* tp_getattro */
1768 0, /* tp_setattro */
1769 0, /* tp_as_buffer */
1770 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1771 Py_TPFLAGS_BASETYPE, /* tp_flags */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001772 property_init__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 property_traverse, /* tp_traverse */
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001774 (inquiry)property_clear, /* tp_clear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 0, /* tp_richcompare */
1776 0, /* tp_weaklistoffset */
1777 0, /* tp_iter */
1778 0, /* tp_iternext */
1779 property_methods, /* tp_methods */
1780 property_members, /* tp_members */
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001781 property_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 0, /* tp_base */
1783 0, /* tp_dict */
1784 property_descr_get, /* tp_descr_get */
1785 property_descr_set, /* tp_descr_set */
1786 0, /* tp_dictoffset */
1787 property_init, /* tp_init */
1788 PyType_GenericAlloc, /* tp_alloc */
1789 PyType_GenericNew, /* tp_new */
1790 PyObject_GC_Del, /* tp_free */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001791};