blob: 9e1b281c4603d6d319102d6db05d7b579b64ecb1 [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 Demeyer0d722f32019-07-05 14:48:24 +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 Demeyer0d722f32019-07-05 14:48:24 +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 Demeyer0d722f32019-07-05 14:48:24 +0200288 if (method_check_args(func, args, nargs, kwnames)) {
INADA Naoki5566bbb2017-02-03 07:43:03 +0900289 return NULL;
290 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +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 Demeyer0d722f32019-07-05 14:48:24 +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
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200306static PyObject *
307method_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
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200422/* Instances of classmethod_descriptor are unlikely to be called directly.
423 For one, the analogous class "classmethod" (for Python classes) is not
424 callable. Second, users are not likely to access a classmethod_descriptor
425 directly, since it means pulling it from the class __dict__.
426
427 This is just an excuse to say that this doesn't need to be optimized:
428 we implement this simply by calling __get__ and then calling the result.
429*/
Tim Peters6d6c1a32001-08-02 04:15:00 +0000430static PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000431classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 PyObject *kwds)
Tim Petersbca1cbc2002-12-09 22:56:13 +0000433{
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200434 Py_ssize_t argc = PyTuple_GET_SIZE(args);
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400435 if (argc < 1) {
436 PyErr_Format(PyExc_TypeError,
437 "descriptor '%V' of '%.100s' "
438 "object needs an argument",
439 descr_name((PyDescrObject *)descr), "?",
440 PyDescr_TYPE(descr)->tp_name);
441 return NULL;
442 }
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200443 PyObject *self = PyTuple_GET_ITEM(args, 0);
444 PyObject *bound = classmethod_get(descr, NULL, self);
445 if (bound == NULL) {
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400446 return NULL;
447 }
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200448 PyObject *res = _PyObject_FastCallDict(bound, _PyTuple_ITEMS(args)+1,
449 argc-1, kwds);
450 Py_DECREF(bound);
451 return res;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000452}
453
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300454Py_LOCAL_INLINE(PyObject *)
455wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self,
456 PyObject *args, PyObject *kwds)
457{
458 wrapperfunc wrapper = descr->d_base->wrapper;
459
460 if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
Serhiy Storchaka1c607152018-11-27 21:34:27 +0200461 wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300462 return (*wk)(self, args, descr->d_wrapped, kwds);
463 }
464
465 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) {
466 PyErr_Format(PyExc_TypeError,
467 "wrapper %s() takes no keyword arguments",
468 descr->d_base->name);
469 return NULL;
470 }
471 return (*wrapper)(self, args, descr->d_wrapped);
472}
473
Tim Petersbca1cbc2002-12-09 22:56:13 +0000474static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000475wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
476{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300478 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 /* Make sure that the first argument is acceptable as 'self' */
481 assert(PyTuple_Check(args));
482 argc = PyTuple_GET_SIZE(args);
483 if (argc < 1) {
484 PyErr_Format(PyExc_TypeError,
485 "descriptor '%V' of '%.100s' "
486 "object needs an argument",
487 descr_name((PyDescrObject *)descr), "?",
488 PyDescr_TYPE(descr)->tp_name);
489 return NULL;
490 }
491 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200492 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200493 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 PyErr_Format(PyExc_TypeError,
495 "descriptor '%V' "
496 "requires a '%.100s' object "
497 "but received a '%.100s'",
498 descr_name((PyDescrObject *)descr), "?",
499 PyDescr_TYPE(descr)->tp_name,
500 self->ob_type->tp_name);
501 return NULL;
502 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000503
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300504 args = PyTuple_GetSlice(args, 1, argc);
505 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 return NULL;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300507 }
508 result = wrapperdescr_raw_call(descr, self, args, kwds);
509 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000511}
512
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300513
Tim Peters6d6c1a32001-08-02 04:15:00 +0000514static PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000515method_get_doc(PyMethodDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000516{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800517 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800518}
519
520static PyObject *
521method_get_text_signature(PyMethodDescrObject *descr, void *closure)
522{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800523 return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000524}
525
Antoine Pitrou9d574812011-12-12 13:47:25 +0100526static PyObject *
527calculate_qualname(PyDescrObject *descr)
528{
529 PyObject *type_qualname, *res;
530 _Py_IDENTIFIER(__qualname__);
531
532 if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) {
533 PyErr_SetString(PyExc_TypeError,
534 "<descriptor>.__name__ is not a unicode object");
535 return NULL;
536 }
537
538 type_qualname = _PyObject_GetAttrId((PyObject *)descr->d_type,
539 &PyId___qualname__);
540 if (type_qualname == NULL)
541 return NULL;
542
543 if (!PyUnicode_Check(type_qualname)) {
544 PyErr_SetString(PyExc_TypeError, "<descriptor>.__objclass__."
545 "__qualname__ is not a unicode object");
546 Py_XDECREF(type_qualname);
547 return NULL;
548 }
549
550 res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name);
551 Py_DECREF(type_qualname);
552 return res;
553}
554
555static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200556descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +0100557{
558 if (descr->d_qualname == NULL)
559 descr->d_qualname = calculate_qualname(descr);
560 Py_XINCREF(descr->d_qualname);
561 return descr->d_qualname;
562}
563
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100564static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530565descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100566{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100567 _Py_IDENTIFIER(getattr);
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200568 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
569 PyDescr_TYPE(descr), PyDescr_NAME(descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100570}
571
572static PyMethodDef descr_methods[] = {
573 {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL},
574 {NULL, NULL}
575};
576
Guido van Rossum6f799372001-09-20 20:46:19 +0000577static PyMemberDef descr_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
579 {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
580 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000581};
582
Guido van Rossum32d34c82001-09-20 21:45:26 +0000583static PyGetSetDef method_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 {"__doc__", (getter)method_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100585 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800586 {"__text_signature__", (getter)method_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 {0}
Guido van Rossum6f799372001-09-20 20:46:19 +0000588};
589
590static PyObject *
591member_get_doc(PyMemberDescrObject *descr, void *closure)
592{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 if (descr->d_member->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200594 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 }
596 return PyUnicode_FromString(descr->d_member->doc);
Guido van Rossum6f799372001-09-20 20:46:19 +0000597}
598
Guido van Rossum32d34c82001-09-20 21:45:26 +0000599static PyGetSetDef member_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 {"__doc__", (getter)member_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100601 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000603};
604
605static PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000606getset_get_doc(PyGetSetDescrObject *descr, void *closure)
607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 if (descr->d_getset->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200609 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 }
611 return PyUnicode_FromString(descr->d_getset->doc);
Guido van Rossum32d34c82001-09-20 21:45:26 +0000612}
613
614static PyGetSetDef getset_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 {"__doc__", (getter)getset_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100616 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 {0}
Guido van Rossum32d34c82001-09-20 21:45:26 +0000618};
619
620static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000621wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000622{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800623 return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800624}
625
626static PyObject *
627wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
628{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800629 return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000630}
631
Armin Rigoc6686b72005-11-07 08:38:00 +0000632static PyGetSetDef wrapperdescr_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 {"__doc__", (getter)wrapperdescr_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100634 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800635 {"__text_signature__", (getter)wrapperdescr_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000637};
638
Guido van Rossum048eb752001-10-02 21:24:57 +0000639static int
640descr_traverse(PyObject *self, visitproc visit, void *arg)
641{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 PyDescrObject *descr = (PyDescrObject *)self;
643 Py_VISIT(descr->d_type);
644 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000645}
646
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000647PyTypeObject PyMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 PyVarObject_HEAD_INIT(&PyType_Type, 0)
649 "method_descriptor",
650 sizeof(PyMethodDescrObject),
651 0,
652 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200653 offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 0, /* tp_getattr */
655 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200656 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000657 (reprfunc)method_repr, /* tp_repr */
658 0, /* tp_as_number */
659 0, /* tp_as_sequence */
660 0, /* tp_as_mapping */
661 0, /* tp_hash */
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200662 PyVectorcall_Call, /* tp_call */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 0, /* tp_str */
664 PyObject_GenericGetAttr, /* tp_getattro */
665 0, /* tp_setattro */
666 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200667 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200668 _Py_TPFLAGS_HAVE_VECTORCALL |
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200669 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 0, /* tp_doc */
671 descr_traverse, /* tp_traverse */
672 0, /* tp_clear */
673 0, /* tp_richcompare */
674 0, /* tp_weaklistoffset */
675 0, /* tp_iter */
676 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100677 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 descr_members, /* tp_members */
679 method_getset, /* tp_getset */
680 0, /* tp_base */
681 0, /* tp_dict */
682 (descrgetfunc)method_get, /* tp_descr_get */
683 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000684};
685
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000686/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000687PyTypeObject PyClassMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 PyVarObject_HEAD_INIT(&PyType_Type, 0)
689 "classmethod_descriptor",
690 sizeof(PyMethodDescrObject),
691 0,
692 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200693 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 0, /* tp_getattr */
695 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200696 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 (reprfunc)method_repr, /* tp_repr */
698 0, /* tp_as_number */
699 0, /* tp_as_sequence */
700 0, /* tp_as_mapping */
701 0, /* tp_hash */
702 (ternaryfunc)classmethoddescr_call, /* tp_call */
703 0, /* tp_str */
704 PyObject_GenericGetAttr, /* tp_getattro */
705 0, /* tp_setattro */
706 0, /* tp_as_buffer */
707 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
708 0, /* tp_doc */
709 descr_traverse, /* tp_traverse */
710 0, /* tp_clear */
711 0, /* tp_richcompare */
712 0, /* tp_weaklistoffset */
713 0, /* tp_iter */
714 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100715 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 descr_members, /* tp_members */
717 method_getset, /* tp_getset */
718 0, /* tp_base */
719 0, /* tp_dict */
720 (descrgetfunc)classmethod_get, /* tp_descr_get */
721 0, /* tp_descr_set */
Tim Petersbca1cbc2002-12-09 22:56:13 +0000722};
723
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000724PyTypeObject PyMemberDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 PyVarObject_HEAD_INIT(&PyType_Type, 0)
726 "member_descriptor",
727 sizeof(PyMemberDescrObject),
728 0,
729 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200730 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 0, /* tp_getattr */
732 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200733 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 (reprfunc)member_repr, /* tp_repr */
735 0, /* tp_as_number */
736 0, /* tp_as_sequence */
737 0, /* tp_as_mapping */
738 0, /* tp_hash */
739 0, /* tp_call */
740 0, /* tp_str */
741 PyObject_GenericGetAttr, /* tp_getattro */
742 0, /* tp_setattro */
743 0, /* tp_as_buffer */
744 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
745 0, /* tp_doc */
746 descr_traverse, /* tp_traverse */
747 0, /* tp_clear */
748 0, /* tp_richcompare */
749 0, /* tp_weaklistoffset */
750 0, /* tp_iter */
751 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100752 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000753 descr_members, /* tp_members */
754 member_getset, /* tp_getset */
755 0, /* tp_base */
756 0, /* tp_dict */
757 (descrgetfunc)member_get, /* tp_descr_get */
758 (descrsetfunc)member_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000759};
760
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000761PyTypeObject PyGetSetDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 PyVarObject_HEAD_INIT(&PyType_Type, 0)
763 "getset_descriptor",
764 sizeof(PyGetSetDescrObject),
765 0,
766 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200767 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000768 0, /* tp_getattr */
769 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200770 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 (reprfunc)getset_repr, /* tp_repr */
772 0, /* tp_as_number */
773 0, /* tp_as_sequence */
774 0, /* tp_as_mapping */
775 0, /* tp_hash */
776 0, /* tp_call */
777 0, /* tp_str */
778 PyObject_GenericGetAttr, /* tp_getattro */
779 0, /* tp_setattro */
780 0, /* tp_as_buffer */
781 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
782 0, /* tp_doc */
783 descr_traverse, /* tp_traverse */
784 0, /* tp_clear */
785 0, /* tp_richcompare */
786 0, /* tp_weaklistoffset */
787 0, /* tp_iter */
788 0, /* tp_iternext */
789 0, /* tp_methods */
790 descr_members, /* tp_members */
791 getset_getset, /* tp_getset */
792 0, /* tp_base */
793 0, /* tp_dict */
794 (descrgetfunc)getset_get, /* tp_descr_get */
795 (descrsetfunc)getset_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000796};
797
Guido van Rossumf4593e02001-10-03 12:09:30 +0000798PyTypeObject PyWrapperDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 PyVarObject_HEAD_INIT(&PyType_Type, 0)
800 "wrapper_descriptor",
801 sizeof(PyWrapperDescrObject),
802 0,
803 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200804 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 0, /* tp_getattr */
806 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200807 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 (reprfunc)wrapperdescr_repr, /* tp_repr */
809 0, /* tp_as_number */
810 0, /* tp_as_sequence */
811 0, /* tp_as_mapping */
812 0, /* tp_hash */
813 (ternaryfunc)wrapperdescr_call, /* tp_call */
814 0, /* tp_str */
815 PyObject_GenericGetAttr, /* tp_getattro */
816 0, /* tp_setattro */
817 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200818 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
819 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 0, /* tp_doc */
821 descr_traverse, /* tp_traverse */
822 0, /* tp_clear */
823 0, /* tp_richcompare */
824 0, /* tp_weaklistoffset */
825 0, /* tp_iter */
826 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100827 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000828 descr_members, /* tp_members */
829 wrapperdescr_getset, /* tp_getset */
830 0, /* tp_base */
831 0, /* tp_dict */
832 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
833 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000834};
835
836static PyDescrObject *
Jeremy Hyltonaf68c872005-12-10 18:50:16 +0000837descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000838{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 PyDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
842 if (descr != NULL) {
843 Py_XINCREF(type);
844 descr->d_type = type;
845 descr->d_name = PyUnicode_InternFromString(name);
846 if (descr->d_name == NULL) {
847 Py_DECREF(descr);
848 descr = NULL;
849 }
Benjamin Petersonf2fe7f02011-12-17 08:02:20 -0500850 else {
851 descr->d_qualname = NULL;
852 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 }
854 return descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000855}
856
857PyObject *
858PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
859{
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200860 /* Figure out correct vectorcall function to use */
861 vectorcallfunc vectorcall;
862 switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS))
863 {
864 case METH_VARARGS:
865 vectorcall = method_vectorcall_VARARGS;
866 break;
867 case METH_VARARGS | METH_KEYWORDS:
868 vectorcall = method_vectorcall_VARARGS_KEYWORDS;
869 break;
870 case METH_FASTCALL:
871 vectorcall = method_vectorcall_FASTCALL;
872 break;
873 case METH_FASTCALL | METH_KEYWORDS:
874 vectorcall = method_vectorcall_FASTCALL_KEYWORDS;
875 break;
876 case METH_NOARGS:
877 vectorcall = method_vectorcall_NOARGS;
878 break;
879 case METH_O:
880 vectorcall = method_vectorcall_O;
881 break;
882 default:
883 PyErr_SetString(PyExc_SystemError, "bad call flags");
884 return NULL;
885 }
886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000887 PyMethodDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
890 type, method->ml_name);
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200891 if (descr != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 descr->d_method = method;
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200893 descr->vectorcall = vectorcall;
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200894 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000896}
897
898PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000899PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
900{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 PyMethodDescrObject *descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
904 type, method->ml_name);
905 if (descr != NULL)
906 descr->d_method = method;
907 return (PyObject *)descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000908}
909
910PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000911PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000912{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 PyMemberDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000915 descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
916 type, member->name);
917 if (descr != NULL)
918 descr->d_member = member;
919 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000920}
921
922PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000923PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000924{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 PyGetSetDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
928 type, getset->name);
929 if (descr != NULL)
930 descr->d_getset = getset;
931 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000932}
933
934PyObject *
935PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
936{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
940 type, base->name);
941 if (descr != NULL) {
942 descr->d_base = base;
943 descr->d_wrapped = wrapped;
944 }
945 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000946}
947
Tim Peters6d6c1a32001-08-02 04:15:00 +0000948
Victor Stinner0db176f2012-04-16 00:16:30 +0200949/* --- mappingproxy: read-only proxy for mappings --- */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000950
951/* This has no reason to be in this file except that adding new files is a
952 bit of a pain */
953
954typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 PyObject_HEAD
Victor Stinner0db176f2012-04-16 00:16:30 +0200956 PyObject *mapping;
957} mappingproxyobject;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000958
Martin v. Löwis18e16552006-02-15 17:27:45 +0000959static Py_ssize_t
Victor Stinner0db176f2012-04-16 00:16:30 +0200960mappingproxy_len(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000961{
Victor Stinner0db176f2012-04-16 00:16:30 +0200962 return PyObject_Size(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000963}
964
965static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200966mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000967{
Victor Stinner0db176f2012-04-16 00:16:30 +0200968 return PyObject_GetItem(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000969}
970
Victor Stinner0db176f2012-04-16 00:16:30 +0200971static PyMappingMethods mappingproxy_as_mapping = {
972 (lenfunc)mappingproxy_len, /* mp_length */
973 (binaryfunc)mappingproxy_getitem, /* mp_subscript */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 0, /* mp_ass_subscript */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000975};
976
977static int
Victor Stinner0db176f2012-04-16 00:16:30 +0200978mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000979{
Victor Stinner0db176f2012-04-16 00:16:30 +0200980 if (PyDict_CheckExact(pp->mapping))
981 return PyDict_Contains(pp->mapping, key);
982 else
983 return PySequence_Contains(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000984}
985
Victor Stinner0db176f2012-04-16 00:16:30 +0200986static PySequenceMethods mappingproxy_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 0, /* sq_length */
988 0, /* sq_concat */
989 0, /* sq_repeat */
990 0, /* sq_item */
991 0, /* sq_slice */
992 0, /* sq_ass_item */
993 0, /* sq_ass_slice */
Victor Stinner0db176f2012-04-16 00:16:30 +0200994 (objobjproc)mappingproxy_contains, /* sq_contains */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 0, /* sq_inplace_concat */
996 0, /* sq_inplace_repeat */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000997};
998
999static PyObject *
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001000mappingproxy_get(mappingproxyobject *pp, PyObject *const *args, Py_ssize_t nargs)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001001{
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001002 /* newargs: mapping, key, default=None */
1003 PyObject *newargs[3];
1004 newargs[0] = pp->mapping;
1005 newargs[2] = Py_None;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001006
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001007 if (!_PyArg_UnpackStack(args, nargs, "get", 1, 2,
1008 &newargs[1], &newargs[2]))
1009 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 return NULL;
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001011 }
1012 _Py_IDENTIFIER(get);
1013 return _PyObject_VectorcallMethodId(&PyId_get, newargs,
1014 3 | PY_VECTORCALL_ARGUMENTS_OFFSET,
1015 NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001016}
1017
1018static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301019mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001020{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001021 _Py_IDENTIFIER(keys);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001022 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_keys);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001023}
1024
1025static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301026mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001027{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001028 _Py_IDENTIFIER(values);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001029 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_values);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001030}
1031
1032static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301033mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001034{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001035 _Py_IDENTIFIER(items);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001036 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_items);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001037}
1038
1039static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301040mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001041{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001042 _Py_IDENTIFIER(copy);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001043 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_copy);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001044}
1045
Victor Stinner0db176f2012-04-16 00:16:30 +02001046/* WARNING: mappingproxy methods must not give access
1047 to the underlying mapping */
1048
1049static PyMethodDef mappingproxy_methods[] = {
Zackery Spytz43d564c2019-08-13 23:51:06 -06001050 {"get", (PyCFunction)(void(*)(void))mappingproxy_get, METH_FASTCALL,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d."
Victor Stinner0db176f2012-04-16 00:16:30 +02001052 " d defaults to None.")},
1053 {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 PyDoc_STR("D.keys() -> list of D's keys")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001055 {"values", (PyCFunction)mappingproxy_values, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 PyDoc_STR("D.values() -> list of D's values")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001057 {"items", (PyCFunction)mappingproxy_items, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001059 {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 PyDoc_STR("D.copy() -> a shallow copy of D")},
1061 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001062};
1063
1064static void
Victor Stinner0db176f2012-04-16 00:16:30 +02001065mappingproxy_dealloc(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001066{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 _PyObject_GC_UNTRACK(pp);
Victor Stinner0db176f2012-04-16 00:16:30 +02001068 Py_DECREF(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 PyObject_GC_Del(pp);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001070}
1071
1072static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001073mappingproxy_getiter(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001074{
Victor Stinner0db176f2012-04-16 00:16:30 +02001075 return PyObject_GetIter(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001076}
1077
Neil Schemenauer26775122001-10-21 22:26:43 +00001078static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001079mappingproxy_str(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001080{
Victor Stinner0db176f2012-04-16 00:16:30 +02001081 return PyObject_Str(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001082}
1083
Ezio Melottiac53ab62010-12-18 14:59:43 +00001084static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001085mappingproxy_repr(mappingproxyobject *pp)
Ezio Melottiac53ab62010-12-18 14:59:43 +00001086{
Victor Stinner0db176f2012-04-16 00:16:30 +02001087 return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping);
Ezio Melottiac53ab62010-12-18 14:59:43 +00001088}
1089
Guido van Rossum048eb752001-10-02 21:24:57 +00001090static int
Victor Stinner0db176f2012-04-16 00:16:30 +02001091mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
Guido van Rossum048eb752001-10-02 21:24:57 +00001092{
Victor Stinner0db176f2012-04-16 00:16:30 +02001093 mappingproxyobject *pp = (mappingproxyobject *)self;
1094 Py_VISIT(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001096}
1097
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001098static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001099mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op)
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001100{
Victor Stinner0db176f2012-04-16 00:16:30 +02001101 return PyObject_RichCompare(v->mapping, w, op);
1102}
1103
1104static int
1105mappingproxy_check_mapping(PyObject *mapping)
1106{
1107 if (!PyMapping_Check(mapping)
1108 || PyList_Check(mapping)
1109 || PyTuple_Check(mapping)) {
1110 PyErr_Format(PyExc_TypeError,
1111 "mappingproxy() argument must be a mapping, not %s",
1112 Py_TYPE(mapping)->tp_name);
1113 return -1;
1114 }
1115 return 0;
1116}
1117
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001118/*[clinic input]
1119@classmethod
1120mappingproxy.__new__ as mappingproxy_new
Victor Stinner0db176f2012-04-16 00:16:30 +02001121
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001122 mapping: object
1123
1124[clinic start generated code]*/
1125
1126static PyObject *
1127mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping)
1128/*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/
1129{
1130 mappingproxyobject *mappingproxy;
Victor Stinner0db176f2012-04-16 00:16:30 +02001131
1132 if (mappingproxy_check_mapping(mapping) == -1)
1133 return NULL;
1134
1135 mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
1136 if (mappingproxy == NULL)
1137 return NULL;
1138 Py_INCREF(mapping);
1139 mappingproxy->mapping = mapping;
1140 _PyObject_GC_TRACK(mappingproxy);
1141 return (PyObject *)mappingproxy;
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001142}
1143
Tim Peters6d6c1a32001-08-02 04:15:00 +00001144PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001145PyDictProxy_New(PyObject *mapping)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001146{
Victor Stinner0db176f2012-04-16 00:16:30 +02001147 mappingproxyobject *pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001148
Victor Stinner0db176f2012-04-16 00:16:30 +02001149 if (mappingproxy_check_mapping(mapping) == -1)
1150 return NULL;
1151
1152 pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 if (pp != NULL) {
Victor Stinner0db176f2012-04-16 00:16:30 +02001154 Py_INCREF(mapping);
1155 pp->mapping = mapping;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 _PyObject_GC_TRACK(pp);
1157 }
1158 return (PyObject *)pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001159}
1160
1161
1162/* --- Wrapper object for "slot" methods --- */
1163
1164/* This has no reason to be in this file except that adding new files is a
1165 bit of a pain */
1166
1167typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 PyObject_HEAD
1169 PyWrapperDescrObject *descr;
1170 PyObject *self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001171} wrapperobject;
1172
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001173#define Wrapper_Check(v) (Py_TYPE(v) == &_PyMethodWrapper_Type)
Mark Dickinson211c6252009-02-01 10:28:51 +00001174
Tim Peters6d6c1a32001-08-02 04:15:00 +00001175static void
1176wrapper_dealloc(wrapperobject *wp)
1177{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 PyObject_GC_UnTrack(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001179 Py_TRASHCAN_BEGIN(wp, wrapper_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 Py_XDECREF(wp->descr);
1181 Py_XDECREF(wp->self);
1182 PyObject_GC_Del(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001183 Py_TRASHCAN_END
Tim Peters6d6c1a32001-08-02 04:15:00 +00001184}
1185
Mark Dickinson211c6252009-02-01 10:28:51 +00001186static PyObject *
1187wrapper_richcompare(PyObject *a, PyObject *b, int op)
Armin Rigoc6686b72005-11-07 08:38:00 +00001188{
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001189 wrapperobject *wa, *wb;
1190 int eq;
Mark Dickinson211c6252009-02-01 10:28:51 +00001191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +00001193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 /* both arguments should be wrapperobjects */
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001195 if ((op != Py_EQ && op != Py_NE)
1196 || !Wrapper_Check(a) || !Wrapper_Check(b))
1197 {
stratakise8b19652017-11-02 11:32:54 +01001198 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 }
Mark Dickinson211c6252009-02-01 10:28:51 +00001200
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001201 wa = (wrapperobject *)a;
1202 wb = (wrapperobject *)b;
1203 eq = (wa->descr == wb->descr && wa->self == wb->self);
1204 if (eq == (op == Py_EQ)) {
1205 Py_RETURN_TRUE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 }
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001207 else {
1208 Py_RETURN_FALSE;
1209 }
Armin Rigoc6686b72005-11-07 08:38:00 +00001210}
1211
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001212static Py_hash_t
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001213wrapper_hash(wrapperobject *wp)
1214{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001215 Py_hash_t x, y;
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001216 x = _Py_HashPointer(wp->self);
1217 y = _Py_HashPointer(wp->descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 x = x ^ y;
1219 if (x == -1)
1220 x = -2;
1221 return x;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001222}
1223
Armin Rigoc6686b72005-11-07 08:38:00 +00001224static PyObject *
1225wrapper_repr(wrapperobject *wp)
1226{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
1228 wp->descr->d_base->name,
1229 wp->self->ob_type->tp_name,
1230 wp->self);
Armin Rigoc6686b72005-11-07 08:38:00 +00001231}
1232
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001233static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301234wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001235{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001236 _Py_IDENTIFIER(getattr);
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02001237 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
1238 wp->self, PyDescr_NAME(wp->descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001239}
1240
1241static PyMethodDef wrapper_methods[] = {
1242 {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
1243 {NULL, NULL}
1244};
1245
Armin Rigoc6686b72005-11-07 08:38:00 +00001246static PyMemberDef wrapper_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
1248 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001249};
1250
1251static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001252wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored))
Armin Rigoc6686b72005-11-07 08:38:00 +00001253{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
Armin Rigoc6686b72005-11-07 08:38:00 +00001255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 Py_INCREF(c);
1257 return c;
Armin Rigoc6686b72005-11-07 08:38:00 +00001258}
1259
1260static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001261wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001262{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 const char *s = wp->descr->d_base->name;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 return PyUnicode_FromString(s);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001266}
1267
1268static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001269wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001270{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001271 return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -08001272}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001273
Larry Hastings5c661892014-01-24 06:17:25 -08001274static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001275wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
Larry Hastings5c661892014-01-24 06:17:25 -08001276{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001277 return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001278}
1279
Antoine Pitrou9d574812011-12-12 13:47:25 +01001280static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001281wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +01001282{
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001283 return descr_get_qualname((PyDescrObject *)wp->descr, NULL);
Antoine Pitrou9d574812011-12-12 13:47:25 +01001284}
1285
Guido van Rossum32d34c82001-09-20 21:45:26 +00001286static PyGetSetDef wrapper_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 {"__objclass__", (getter)wrapper_objclass},
1288 {"__name__", (getter)wrapper_name},
Antoine Pitrou9d574812011-12-12 13:47:25 +01001289 {"__qualname__", (getter)wrapper_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 {"__doc__", (getter)wrapper_doc},
Larry Hastings5c661892014-01-24 06:17:25 -08001291 {"__text_signature__", (getter)wrapper_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001293};
1294
1295static PyObject *
1296wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
1297{
Serhiy Storchaka5e02c782017-09-21 14:25:36 +03001298 return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001299}
1300
Guido van Rossum048eb752001-10-02 21:24:57 +00001301static int
1302wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 wrapperobject *wp = (wrapperobject *)self;
1305 Py_VISIT(wp->descr);
1306 Py_VISIT(wp->self);
1307 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001308}
1309
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001310PyTypeObject _PyMethodWrapper_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1312 "method-wrapper", /* tp_name */
1313 sizeof(wrapperobject), /* tp_basicsize */
1314 0, /* tp_itemsize */
1315 /* methods */
1316 (destructor)wrapper_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001317 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 0, /* tp_getattr */
1319 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001320 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 (reprfunc)wrapper_repr, /* tp_repr */
1322 0, /* tp_as_number */
1323 0, /* tp_as_sequence */
1324 0, /* tp_as_mapping */
1325 (hashfunc)wrapper_hash, /* tp_hash */
1326 (ternaryfunc)wrapper_call, /* tp_call */
1327 0, /* tp_str */
1328 PyObject_GenericGetAttr, /* tp_getattro */
1329 0, /* tp_setattro */
1330 0, /* tp_as_buffer */
1331 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1332 0, /* tp_doc */
1333 wrapper_traverse, /* tp_traverse */
1334 0, /* tp_clear */
1335 wrapper_richcompare, /* tp_richcompare */
1336 0, /* tp_weaklistoffset */
1337 0, /* tp_iter */
1338 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001339 wrapper_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 wrapper_members, /* tp_members */
1341 wrapper_getsets, /* tp_getset */
1342 0, /* tp_base */
1343 0, /* tp_dict */
1344 0, /* tp_descr_get */
1345 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001346};
1347
1348PyObject *
1349PyWrapper_New(PyObject *d, PyObject *self)
1350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 wrapperobject *wp;
1352 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1355 descr = (PyWrapperDescrObject *)d;
Victor Stinner3249dec2011-05-01 23:19:15 +02001356 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +02001357 (PyObject *)PyDescr_TYPE(descr)));
Tim Peters6d6c1a32001-08-02 04:15:00 +00001358
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001359 wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 if (wp != NULL) {
1361 Py_INCREF(descr);
1362 wp->descr = descr;
1363 Py_INCREF(self);
1364 wp->self = self;
1365 _PyObject_GC_TRACK(wp);
1366 }
1367 return (PyObject *)wp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001368}
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001369
1370
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001371/* A built-in 'property' type */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001372
1373/*
Serhiy Storchakad741a882015-06-11 00:06:39 +03001374class property(object):
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
1377 if doc is None and fget is not None and hasattr(fget, "__doc__"):
Serhiy Storchakad741a882015-06-11 00:06:39 +03001378 doc = fget.__doc__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 self.__get = fget
1380 self.__set = fset
1381 self.__del = fdel
1382 self.__doc__ = doc
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 def __get__(self, inst, type=None):
1385 if inst is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001386 return self
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 if self.__get is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001388 raise AttributeError, "unreadable attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 return self.__get(inst)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 def __set__(self, inst, value):
1392 if self.__set is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001393 raise AttributeError, "can't set attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 return self.__set(inst, value)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 def __delete__(self, inst):
1397 if self.__del is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001398 raise AttributeError, "can't delete attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 return self.__del(inst)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001400
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001401*/
1402
1403typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 PyObject_HEAD
1405 PyObject *prop_get;
1406 PyObject *prop_set;
1407 PyObject *prop_del;
1408 PyObject *prop_doc;
1409 int getter_doc;
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001410} propertyobject;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001411
Christian Heimes0449f632007-12-15 01:27:15 +00001412static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
Benjamin Peterson93964832010-06-28 03:07:10 +00001413 PyObject *);
Christian Heimes0449f632007-12-15 01:27:15 +00001414
Tim Peters66c1a522001-09-24 21:17:50 +00001415static PyMemberDef property_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
1417 {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
1418 {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
Raymond Hettingereac503a2015-05-13 01:09:59 -07001419 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 {0}
Tim Peters66c1a522001-09-24 21:17:50 +00001421};
1422
Christian Heimes0449f632007-12-15 01:27:15 +00001423
Guido van Rossum58da9312007-11-10 23:39:45 +00001424PyDoc_STRVAR(getter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 "Descriptor to change the getter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001426
Neal Norwitz32dde222008-04-15 06:43:13 +00001427static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001428property_getter(PyObject *self, PyObject *getter)
1429{
Benjamin Peterson93964832010-06-28 03:07:10 +00001430 return property_copy(self, getter, NULL, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001431}
1432
Christian Heimes0449f632007-12-15 01:27:15 +00001433
Guido van Rossum58da9312007-11-10 23:39:45 +00001434PyDoc_STRVAR(setter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 "Descriptor to change the setter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001436
Neal Norwitz32dde222008-04-15 06:43:13 +00001437static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001438property_setter(PyObject *self, PyObject *setter)
1439{
Benjamin Peterson93964832010-06-28 03:07:10 +00001440 return property_copy(self, NULL, setter, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001441}
1442
Christian Heimes0449f632007-12-15 01:27:15 +00001443
Guido van Rossum58da9312007-11-10 23:39:45 +00001444PyDoc_STRVAR(deleter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 "Descriptor to change the deleter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001446
Neal Norwitz32dde222008-04-15 06:43:13 +00001447static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001448property_deleter(PyObject *self, PyObject *deleter)
1449{
Benjamin Peterson93964832010-06-28 03:07:10 +00001450 return property_copy(self, NULL, NULL, deleter);
Guido van Rossum58da9312007-11-10 23:39:45 +00001451}
1452
1453
Guido van Rossum58da9312007-11-10 23:39:45 +00001454static PyMethodDef property_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 {"getter", property_getter, METH_O, getter_doc},
1456 {"setter", property_setter, METH_O, setter_doc},
1457 {"deleter", property_deleter, METH_O, deleter_doc},
1458 {0}
Guido van Rossum58da9312007-11-10 23:39:45 +00001459};
1460
Tim Peters66c1a522001-09-24 21:17:50 +00001461
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001462static void
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001463property_dealloc(PyObject *self)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001464{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 propertyobject *gs = (propertyobject *)self;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 _PyObject_GC_UNTRACK(self);
1468 Py_XDECREF(gs->prop_get);
1469 Py_XDECREF(gs->prop_set);
1470 Py_XDECREF(gs->prop_del);
1471 Py_XDECREF(gs->prop_doc);
1472 self->ob_type->tp_free(self);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001473}
1474
1475static PyObject *
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001476property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 if (obj == NULL || obj == Py_None) {
1479 Py_INCREF(self);
1480 return self;
1481 }
Victor Stinnere972c132018-10-01 03:03:22 -07001482
1483 propertyobject *gs = (propertyobject *)self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 if (gs->prop_get == NULL) {
1485 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1486 return NULL;
1487 }
Victor Stinnere972c132018-10-01 03:03:22 -07001488
Jeroen Demeyer196a5302019-07-04 12:31:34 +02001489 return _PyObject_CallOneArg(gs->prop_get, obj);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001490}
1491
1492static int
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001493property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001494{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 propertyobject *gs = (propertyobject *)self;
1496 PyObject *func, *res;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 if (value == NULL)
1499 func = gs->prop_del;
1500 else
1501 func = gs->prop_set;
1502 if (func == NULL) {
1503 PyErr_SetString(PyExc_AttributeError,
1504 value == NULL ?
1505 "can't delete attribute" :
1506 "can't set attribute");
1507 return -1;
1508 }
1509 if (value == NULL)
Jeroen Demeyer196a5302019-07-04 12:31:34 +02001510 res = _PyObject_CallOneArg(func, obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 else
Benjamin Peterson9b955de2010-12-07 04:04:02 +00001512 res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 if (res == NULL)
1514 return -1;
1515 Py_DECREF(res);
1516 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001517}
1518
Christian Heimes0449f632007-12-15 01:27:15 +00001519static PyObject *
Benjamin Peterson93964832010-06-28 03:07:10 +00001520property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
Christian Heimes0449f632007-12-15 01:27:15 +00001521{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 propertyobject *pold = (propertyobject *)old;
Benjamin Peterson93964832010-06-28 03:07:10 +00001523 PyObject *new, *type, *doc;
Christian Heimes0449f632007-12-15 01:27:15 +00001524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 type = PyObject_Type(old);
1526 if (type == NULL)
1527 return NULL;
Christian Heimes0449f632007-12-15 01:27:15 +00001528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 if (get == NULL || get == Py_None) {
1530 Py_XDECREF(get);
1531 get = pold->prop_get ? pold->prop_get : Py_None;
1532 }
1533 if (set == NULL || set == Py_None) {
1534 Py_XDECREF(set);
1535 set = pold->prop_set ? pold->prop_set : Py_None;
1536 }
1537 if (del == NULL || del == Py_None) {
1538 Py_XDECREF(del);
1539 del = pold->prop_del ? pold->prop_del : Py_None;
1540 }
Benjamin Peterson93964832010-06-28 03:07:10 +00001541 if (pold->getter_doc && get != Py_None) {
1542 /* make _init use __doc__ from getter */
1543 doc = Py_None;
1544 }
1545 else {
1546 doc = pold->prop_doc ? pold->prop_doc : Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 }
R. David Murrayb18500d2009-05-04 22:59:07 +00001548
Victor Stinner5abaa2b2016-12-09 16:22:32 +01001549 new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 Py_DECREF(type);
1551 if (new == NULL)
1552 return NULL;
1553 return new;
Christian Heimes0449f632007-12-15 01:27:15 +00001554}
1555
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001556/*[clinic input]
1557property.__init__ as property_init
1558
1559 fget: object(c_default="NULL") = None
1560 function to be used for getting an attribute value
1561 fset: object(c_default="NULL") = None
1562 function to be used for setting an attribute value
1563 fdel: object(c_default="NULL") = None
1564 function to be used for del'ing an attribute
1565 doc: object(c_default="NULL") = None
1566 docstring
1567
1568Property attribute.
1569
1570Typical use is to define a managed attribute x:
1571
1572class C(object):
1573 def getx(self): return self._x
1574 def setx(self, value): self._x = value
1575 def delx(self): del self._x
1576 x = property(getx, setx, delx, "I'm the 'x' property.")
1577
1578Decorators make defining new properties or modifying existing ones easy:
1579
1580class C(object):
1581 @property
1582 def x(self):
1583 "I am the 'x' property."
1584 return self._x
1585 @x.setter
1586 def x(self, value):
1587 self._x = value
1588 @x.deleter
1589 def x(self):
1590 del self._x
1591[clinic start generated code]*/
1592
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001593static int
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001594property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1595 PyObject *fdel, PyObject *doc)
1596/*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001597{
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001598 if (fget == Py_None)
1599 fget = NULL;
1600 if (fset == Py_None)
1601 fset = NULL;
1602 if (fdel == Py_None)
1603 fdel = NULL;
Tim Peters66c1a522001-09-24 21:17:50 +00001604
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001605 Py_XINCREF(fget);
1606 Py_XINCREF(fset);
1607 Py_XINCREF(fdel);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 Py_XINCREF(doc);
Christian Heimes0449f632007-12-15 01:27:15 +00001609
Oren Milmand019bc82018-02-13 12:28:33 +02001610 Py_XSETREF(self->prop_get, fget);
1611 Py_XSETREF(self->prop_set, fset);
1612 Py_XSETREF(self->prop_del, fdel);
1613 Py_XSETREF(self->prop_doc, doc);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001614 self->getter_doc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 /* if no docstring given and the getter has one, use that one */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001617 if ((doc == NULL || doc == Py_None) && fget != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001618 _Py_IDENTIFIER(__doc__);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001619 PyObject *get_doc = _PyObject_GetAttrId(fget, &PyId___doc__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 if (get_doc) {
1621 if (Py_TYPE(self) == &PyProperty_Type) {
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001622 Py_XSETREF(self->prop_doc, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 }
1624 else {
1625 /* If this is a property subclass, put __doc__
1626 in dict of the subclass instance instead,
1627 otherwise it gets shadowed by __doc__ in the
1628 class's dict. */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001629 int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 Py_DECREF(get_doc);
1631 if (err < 0)
1632 return -1;
1633 }
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001634 self->getter_doc = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 }
1636 else if (PyErr_ExceptionMatches(PyExc_Exception)) {
1637 PyErr_Clear();
1638 }
1639 else {
1640 return -1;
1641 }
1642 }
1643
1644 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001645}
1646
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001647static PyObject *
1648property_get___isabstractmethod__(propertyobject *prop, void *closure)
1649{
1650 int res = _PyObject_IsAbstract(prop->prop_get);
1651 if (res == -1) {
1652 return NULL;
1653 }
1654 else if (res) {
1655 Py_RETURN_TRUE;
1656 }
1657
1658 res = _PyObject_IsAbstract(prop->prop_set);
1659 if (res == -1) {
1660 return NULL;
1661 }
1662 else if (res) {
1663 Py_RETURN_TRUE;
1664 }
1665
1666 res = _PyObject_IsAbstract(prop->prop_del);
1667 if (res == -1) {
1668 return NULL;
1669 }
1670 else if (res) {
1671 Py_RETURN_TRUE;
1672 }
1673 Py_RETURN_FALSE;
1674}
1675
1676static PyGetSetDef property_getsetlist[] = {
1677 {"__isabstractmethod__",
1678 (getter)property_get___isabstractmethod__, NULL,
1679 NULL,
1680 NULL},
1681 {NULL} /* Sentinel */
1682};
1683
Guido van Rossum048eb752001-10-02 21:24:57 +00001684static int
1685property_traverse(PyObject *self, visitproc visit, void *arg)
1686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 propertyobject *pp = (propertyobject *)self;
1688 Py_VISIT(pp->prop_get);
1689 Py_VISIT(pp->prop_set);
1690 Py_VISIT(pp->prop_del);
1691 Py_VISIT(pp->prop_doc);
1692 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001693}
1694
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001695static int
1696property_clear(PyObject *self)
1697{
1698 propertyobject *pp = (propertyobject *)self;
1699 Py_CLEAR(pp->prop_doc);
1700 return 0;
1701}
1702
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001703#include "clinic/descrobject.c.h"
1704
1705PyTypeObject PyDictProxy_Type = {
1706 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1707 "mappingproxy", /* tp_name */
1708 sizeof(mappingproxyobject), /* tp_basicsize */
1709 0, /* tp_itemsize */
1710 /* methods */
1711 (destructor)mappingproxy_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001712 0, /* tp_vectorcall_offset */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001713 0, /* tp_getattr */
1714 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001715 0, /* tp_as_async */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001716 (reprfunc)mappingproxy_repr, /* tp_repr */
1717 0, /* tp_as_number */
1718 &mappingproxy_as_sequence, /* tp_as_sequence */
1719 &mappingproxy_as_mapping, /* tp_as_mapping */
1720 0, /* tp_hash */
1721 0, /* tp_call */
1722 (reprfunc)mappingproxy_str, /* tp_str */
1723 PyObject_GenericGetAttr, /* tp_getattro */
1724 0, /* tp_setattro */
1725 0, /* tp_as_buffer */
1726 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1727 0, /* tp_doc */
1728 mappingproxy_traverse, /* tp_traverse */
1729 0, /* tp_clear */
1730 (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
1731 0, /* tp_weaklistoffset */
1732 (getiterfunc)mappingproxy_getiter, /* tp_iter */
1733 0, /* tp_iternext */
1734 mappingproxy_methods, /* tp_methods */
1735 0, /* tp_members */
1736 0, /* tp_getset */
1737 0, /* tp_base */
1738 0, /* tp_dict */
1739 0, /* tp_descr_get */
1740 0, /* tp_descr_set */
1741 0, /* tp_dictoffset */
1742 0, /* tp_init */
1743 0, /* tp_alloc */
1744 mappingproxy_new, /* tp_new */
1745};
1746
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001747PyTypeObject PyProperty_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1749 "property", /* tp_name */
1750 sizeof(propertyobject), /* tp_basicsize */
1751 0, /* tp_itemsize */
1752 /* methods */
1753 property_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001754 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 0, /* tp_getattr */
1756 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001757 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 0, /* tp_repr */
1759 0, /* tp_as_number */
1760 0, /* tp_as_sequence */
1761 0, /* tp_as_mapping */
1762 0, /* tp_hash */
1763 0, /* tp_call */
1764 0, /* tp_str */
1765 PyObject_GenericGetAttr, /* tp_getattro */
1766 0, /* tp_setattro */
1767 0, /* tp_as_buffer */
1768 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1769 Py_TPFLAGS_BASETYPE, /* tp_flags */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001770 property_init__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 property_traverse, /* tp_traverse */
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001772 (inquiry)property_clear, /* tp_clear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 0, /* tp_richcompare */
1774 0, /* tp_weaklistoffset */
1775 0, /* tp_iter */
1776 0, /* tp_iternext */
1777 property_methods, /* tp_methods */
1778 property_members, /* tp_members */
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001779 property_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 0, /* tp_base */
1781 0, /* tp_dict */
1782 property_descr_get, /* tp_descr_get */
1783 property_descr_set, /* tp_descr_set */
1784 0, /* tp_dictoffset */
1785 property_init, /* tp_init */
1786 PyType_GenericAlloc, /* tp_alloc */
1787 PyType_GenericNew, /* tp_new */
1788 PyObject_GC_Del, /* tp_free */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001789};