blob: 342b993e0903902415910b50f536baac5038be86 [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 */
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200234static inline int
235method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
236{
237 assert(!PyErr_Occurred());
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200238 if (nargs < 1) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100239 PyObject *funcstr = _PyObject_FunctionStr(func);
240 if (funcstr != NULL) {
241 PyErr_Format(PyExc_TypeError,
242 "unbound method %U needs an argument", funcstr);
243 Py_DECREF(funcstr);
244 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200245 return -1;
246 }
247 PyObject *self = args[0];
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100248 PyObject *dummy;
249 if (descr_check((PyDescrObject *)func, self, &dummy)) {
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200250 return -1;
251 }
252 if (kwnames && PyTuple_GET_SIZE(kwnames)) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100253 PyObject *funcstr = _PyObject_FunctionStr(func);
254 if (funcstr != NULL) {
255 PyErr_Format(PyExc_TypeError,
256 "%U takes no keyword arguments", funcstr);
257 Py_DECREF(funcstr);
258 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200259 return -1;
260 }
261 return 0;
262}
263
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100264typedef void (*funcptr)(void);
265
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200266static inline funcptr
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100267method_enter_call(PyThreadState *tstate, PyObject *func)
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200268{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100269 if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200270 return NULL;
271 }
272 return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth;
273}
274
275/* Now the actual vectorcall functions */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000276static PyObject *
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200277method_vectorcall_VARARGS(
278 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000279{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100280 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200281 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200282 if (method_check_args(func, args, nargs, kwnames)) {
INADA Naoki5566bbb2017-02-03 07:43:03 +0900283 return NULL;
284 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200285 PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
286 if (argstuple == NULL) {
INADA Naoki5566bbb2017-02-03 07:43:03 +0900287 return NULL;
288 }
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100289 PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200290 if (meth == NULL) {
291 Py_DECREF(argstuple);
292 return NULL;
293 }
294 PyObject *result = meth(args[0], argstuple);
295 Py_DECREF(argstuple);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100296 _Py_LeaveRecursiveCall(tstate);
INADA Naoki5566bbb2017-02-03 07:43:03 +0900297 return result;
298}
299
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200300static PyObject *
301method_vectorcall_VARARGS_KEYWORDS(
302 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
303{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100304 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200305 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
306 if (method_check_args(func, args, nargs, NULL)) {
307 return NULL;
308 }
309 PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
310 if (argstuple == NULL) {
311 return NULL;
312 }
313 PyObject *result = NULL;
314 /* Create a temporary dict for keyword arguments */
315 PyObject *kwdict = NULL;
316 if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) > 0) {
317 kwdict = _PyStack_AsDict(args + nargs, kwnames);
318 if (kwdict == NULL) {
319 goto exit;
320 }
321 }
322 PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords)
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100323 method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200324 if (meth == NULL) {
325 goto exit;
326 }
327 result = meth(args[0], argstuple, kwdict);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100328 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200329exit:
330 Py_DECREF(argstuple);
331 Py_XDECREF(kwdict);
332 return result;
333}
334
335static PyObject *
336method_vectorcall_FASTCALL(
337 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
338{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100339 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200340 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
341 if (method_check_args(func, args, nargs, kwnames)) {
342 return NULL;
343 }
344 _PyCFunctionFast meth = (_PyCFunctionFast)
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100345 method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200346 if (meth == NULL) {
347 return NULL;
348 }
349 PyObject *result = meth(args[0], args+1, nargs-1);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100350 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200351 return result;
352}
353
354static PyObject *
355method_vectorcall_FASTCALL_KEYWORDS(
356 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
357{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100358 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200359 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
360 if (method_check_args(func, args, nargs, NULL)) {
361 return NULL;
362 }
363 _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100364 method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200365 if (meth == NULL) {
366 return NULL;
367 }
368 PyObject *result = meth(args[0], args+1, nargs-1, kwnames);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100369 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200370 return result;
371}
372
373static PyObject *
374method_vectorcall_NOARGS(
375 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
376{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100377 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200378 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
379 if (method_check_args(func, args, nargs, kwnames)) {
380 return NULL;
381 }
382 if (nargs != 1) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100383 PyObject *funcstr = _PyObject_FunctionStr(func);
384 if (funcstr != NULL) {
385 PyErr_Format(PyExc_TypeError,
386 "%U takes no arguments (%zd given)", funcstr, nargs-1);
387 Py_DECREF(funcstr);
388 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200389 return NULL;
390 }
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100391 PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200392 if (meth == NULL) {
393 return NULL;
394 }
395 PyObject *result = meth(args[0], NULL);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100396 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200397 return result;
398}
399
400static PyObject *
401method_vectorcall_O(
402 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
403{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100404 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200405 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
406 if (method_check_args(func, args, nargs, kwnames)) {
407 return NULL;
408 }
409 if (nargs != 2) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100410 PyObject *funcstr = _PyObject_FunctionStr(func);
411 if (funcstr != NULL) {
412 PyErr_Format(PyExc_TypeError,
413 "%U takes exactly one argument (%zd given)",
414 funcstr, nargs-1);
415 Py_DECREF(funcstr);
416 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200417 return NULL;
418 }
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100419 PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200420 if (meth == NULL) {
421 return NULL;
422 }
423 PyObject *result = meth(args[0], args[1]);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100424 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200425 return result;
426}
427
428
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200429/* Instances of classmethod_descriptor are unlikely to be called directly.
430 For one, the analogous class "classmethod" (for Python classes) is not
431 callable. Second, users are not likely to access a classmethod_descriptor
432 directly, since it means pulling it from the class __dict__.
433
434 This is just an excuse to say that this doesn't need to be optimized:
435 we implement this simply by calling __get__ and then calling the result.
436*/
Tim Peters6d6c1a32001-08-02 04:15:00 +0000437static PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000438classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 PyObject *kwds)
Tim Petersbca1cbc2002-12-09 22:56:13 +0000440{
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200441 Py_ssize_t argc = PyTuple_GET_SIZE(args);
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400442 if (argc < 1) {
443 PyErr_Format(PyExc_TypeError,
444 "descriptor '%V' of '%.100s' "
445 "object needs an argument",
446 descr_name((PyDescrObject *)descr), "?",
447 PyDescr_TYPE(descr)->tp_name);
448 return NULL;
449 }
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200450 PyObject *self = PyTuple_GET_ITEM(args, 0);
451 PyObject *bound = classmethod_get(descr, NULL, self);
452 if (bound == NULL) {
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400453 return NULL;
454 }
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200455 PyObject *res = _PyObject_FastCallDict(bound, _PyTuple_ITEMS(args)+1,
456 argc-1, kwds);
457 Py_DECREF(bound);
458 return res;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000459}
460
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300461Py_LOCAL_INLINE(PyObject *)
462wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self,
463 PyObject *args, PyObject *kwds)
464{
465 wrapperfunc wrapper = descr->d_base->wrapper;
466
467 if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
Serhiy Storchaka1c607152018-11-27 21:34:27 +0200468 wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300469 return (*wk)(self, args, descr->d_wrapped, kwds);
470 }
471
472 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) {
473 PyErr_Format(PyExc_TypeError,
474 "wrapper %s() takes no keyword arguments",
475 descr->d_base->name);
476 return NULL;
477 }
478 return (*wrapper)(self, args, descr->d_wrapped);
479}
480
Tim Petersbca1cbc2002-12-09 22:56:13 +0000481static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000482wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300485 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 /* Make sure that the first argument is acceptable as 'self' */
488 assert(PyTuple_Check(args));
489 argc = PyTuple_GET_SIZE(args);
490 if (argc < 1) {
491 PyErr_Format(PyExc_TypeError,
492 "descriptor '%V' of '%.100s' "
493 "object needs an argument",
494 descr_name((PyDescrObject *)descr), "?",
495 PyDescr_TYPE(descr)->tp_name);
496 return NULL;
497 }
498 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200499 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200500 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 PyErr_Format(PyExc_TypeError,
502 "descriptor '%V' "
503 "requires a '%.100s' object "
504 "but received a '%.100s'",
505 descr_name((PyDescrObject *)descr), "?",
506 PyDescr_TYPE(descr)->tp_name,
507 self->ob_type->tp_name);
508 return NULL;
509 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000510
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300511 args = PyTuple_GetSlice(args, 1, argc);
512 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 return NULL;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300514 }
515 result = wrapperdescr_raw_call(descr, self, args, kwds);
516 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000518}
519
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300520
Tim Peters6d6c1a32001-08-02 04:15:00 +0000521static PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000522method_get_doc(PyMethodDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000523{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800524 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800525}
526
527static PyObject *
528method_get_text_signature(PyMethodDescrObject *descr, void *closure)
529{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800530 return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000531}
532
Antoine Pitrou9d574812011-12-12 13:47:25 +0100533static PyObject *
534calculate_qualname(PyDescrObject *descr)
535{
536 PyObject *type_qualname, *res;
537 _Py_IDENTIFIER(__qualname__);
538
539 if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) {
540 PyErr_SetString(PyExc_TypeError,
541 "<descriptor>.__name__ is not a unicode object");
542 return NULL;
543 }
544
545 type_qualname = _PyObject_GetAttrId((PyObject *)descr->d_type,
546 &PyId___qualname__);
547 if (type_qualname == NULL)
548 return NULL;
549
550 if (!PyUnicode_Check(type_qualname)) {
551 PyErr_SetString(PyExc_TypeError, "<descriptor>.__objclass__."
552 "__qualname__ is not a unicode object");
553 Py_XDECREF(type_qualname);
554 return NULL;
555 }
556
557 res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name);
558 Py_DECREF(type_qualname);
559 return res;
560}
561
562static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200563descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +0100564{
565 if (descr->d_qualname == NULL)
566 descr->d_qualname = calculate_qualname(descr);
567 Py_XINCREF(descr->d_qualname);
568 return descr->d_qualname;
569}
570
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100571static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530572descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100573{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100574 _Py_IDENTIFIER(getattr);
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200575 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
576 PyDescr_TYPE(descr), PyDescr_NAME(descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100577}
578
579static PyMethodDef descr_methods[] = {
580 {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL},
581 {NULL, NULL}
582};
583
Guido van Rossum6f799372001-09-20 20:46:19 +0000584static PyMemberDef descr_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
586 {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
587 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000588};
589
Guido van Rossum32d34c82001-09-20 21:45:26 +0000590static PyGetSetDef method_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 {"__doc__", (getter)method_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100592 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800593 {"__text_signature__", (getter)method_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 {0}
Guido van Rossum6f799372001-09-20 20:46:19 +0000595};
596
597static PyObject *
598member_get_doc(PyMemberDescrObject *descr, void *closure)
599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 if (descr->d_member->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200601 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 }
603 return PyUnicode_FromString(descr->d_member->doc);
Guido van Rossum6f799372001-09-20 20:46:19 +0000604}
605
Guido van Rossum32d34c82001-09-20 21:45:26 +0000606static PyGetSetDef member_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 {"__doc__", (getter)member_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100608 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000610};
611
612static PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000613getset_get_doc(PyGetSetDescrObject *descr, void *closure)
614{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 if (descr->d_getset->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200616 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 }
618 return PyUnicode_FromString(descr->d_getset->doc);
Guido van Rossum32d34c82001-09-20 21:45:26 +0000619}
620
621static PyGetSetDef getset_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 {"__doc__", (getter)getset_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100623 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 {0}
Guido van Rossum32d34c82001-09-20 21:45:26 +0000625};
626
627static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000628wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000629{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800630 return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800631}
632
633static PyObject *
634wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
635{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800636 return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000637}
638
Armin Rigoc6686b72005-11-07 08:38:00 +0000639static PyGetSetDef wrapperdescr_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 {"__doc__", (getter)wrapperdescr_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100641 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800642 {"__text_signature__", (getter)wrapperdescr_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000644};
645
Guido van Rossum048eb752001-10-02 21:24:57 +0000646static int
647descr_traverse(PyObject *self, visitproc visit, void *arg)
648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000649 PyDescrObject *descr = (PyDescrObject *)self;
650 Py_VISIT(descr->d_type);
651 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000652}
653
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000654PyTypeObject PyMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 PyVarObject_HEAD_INIT(&PyType_Type, 0)
656 "method_descriptor",
657 sizeof(PyMethodDescrObject),
658 0,
659 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200660 offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 0, /* tp_getattr */
662 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200663 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 (reprfunc)method_repr, /* tp_repr */
665 0, /* tp_as_number */
666 0, /* tp_as_sequence */
667 0, /* tp_as_mapping */
668 0, /* tp_hash */
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200669 PyVectorcall_Call, /* tp_call */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 0, /* tp_str */
671 PyObject_GenericGetAttr, /* tp_getattro */
672 0, /* tp_setattro */
673 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200674 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200675 _Py_TPFLAGS_HAVE_VECTORCALL |
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200676 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 0, /* tp_doc */
678 descr_traverse, /* tp_traverse */
679 0, /* tp_clear */
680 0, /* tp_richcompare */
681 0, /* tp_weaklistoffset */
682 0, /* tp_iter */
683 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100684 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 descr_members, /* tp_members */
686 method_getset, /* tp_getset */
687 0, /* tp_base */
688 0, /* tp_dict */
689 (descrgetfunc)method_get, /* tp_descr_get */
690 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000691};
692
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000693/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000694PyTypeObject PyClassMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 PyVarObject_HEAD_INIT(&PyType_Type, 0)
696 "classmethod_descriptor",
697 sizeof(PyMethodDescrObject),
698 0,
699 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200700 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 0, /* tp_getattr */
702 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200703 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 (reprfunc)method_repr, /* tp_repr */
705 0, /* tp_as_number */
706 0, /* tp_as_sequence */
707 0, /* tp_as_mapping */
708 0, /* tp_hash */
709 (ternaryfunc)classmethoddescr_call, /* tp_call */
710 0, /* tp_str */
711 PyObject_GenericGetAttr, /* tp_getattro */
712 0, /* tp_setattro */
713 0, /* tp_as_buffer */
714 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
715 0, /* tp_doc */
716 descr_traverse, /* tp_traverse */
717 0, /* tp_clear */
718 0, /* tp_richcompare */
719 0, /* tp_weaklistoffset */
720 0, /* tp_iter */
721 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100722 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 descr_members, /* tp_members */
724 method_getset, /* tp_getset */
725 0, /* tp_base */
726 0, /* tp_dict */
727 (descrgetfunc)classmethod_get, /* tp_descr_get */
728 0, /* tp_descr_set */
Tim Petersbca1cbc2002-12-09 22:56:13 +0000729};
730
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000731PyTypeObject PyMemberDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 PyVarObject_HEAD_INIT(&PyType_Type, 0)
733 "member_descriptor",
734 sizeof(PyMemberDescrObject),
735 0,
736 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200737 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 0, /* tp_getattr */
739 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200740 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 (reprfunc)member_repr, /* tp_repr */
742 0, /* tp_as_number */
743 0, /* tp_as_sequence */
744 0, /* tp_as_mapping */
745 0, /* tp_hash */
746 0, /* tp_call */
747 0, /* tp_str */
748 PyObject_GenericGetAttr, /* tp_getattro */
749 0, /* tp_setattro */
750 0, /* tp_as_buffer */
751 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
752 0, /* tp_doc */
753 descr_traverse, /* tp_traverse */
754 0, /* tp_clear */
755 0, /* tp_richcompare */
756 0, /* tp_weaklistoffset */
757 0, /* tp_iter */
758 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100759 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 descr_members, /* tp_members */
761 member_getset, /* tp_getset */
762 0, /* tp_base */
763 0, /* tp_dict */
764 (descrgetfunc)member_get, /* tp_descr_get */
765 (descrsetfunc)member_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000766};
767
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000768PyTypeObject PyGetSetDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 PyVarObject_HEAD_INIT(&PyType_Type, 0)
770 "getset_descriptor",
771 sizeof(PyGetSetDescrObject),
772 0,
773 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200774 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775 0, /* tp_getattr */
776 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200777 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 (reprfunc)getset_repr, /* tp_repr */
779 0, /* tp_as_number */
780 0, /* tp_as_sequence */
781 0, /* tp_as_mapping */
782 0, /* tp_hash */
783 0, /* tp_call */
784 0, /* tp_str */
785 PyObject_GenericGetAttr, /* tp_getattro */
786 0, /* tp_setattro */
787 0, /* tp_as_buffer */
788 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
789 0, /* tp_doc */
790 descr_traverse, /* tp_traverse */
791 0, /* tp_clear */
792 0, /* tp_richcompare */
793 0, /* tp_weaklistoffset */
794 0, /* tp_iter */
795 0, /* tp_iternext */
796 0, /* tp_methods */
797 descr_members, /* tp_members */
798 getset_getset, /* tp_getset */
799 0, /* tp_base */
800 0, /* tp_dict */
801 (descrgetfunc)getset_get, /* tp_descr_get */
802 (descrsetfunc)getset_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000803};
804
Guido van Rossumf4593e02001-10-03 12:09:30 +0000805PyTypeObject PyWrapperDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 PyVarObject_HEAD_INIT(&PyType_Type, 0)
807 "wrapper_descriptor",
808 sizeof(PyWrapperDescrObject),
809 0,
810 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200811 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000812 0, /* tp_getattr */
813 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200814 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 (reprfunc)wrapperdescr_repr, /* tp_repr */
816 0, /* tp_as_number */
817 0, /* tp_as_sequence */
818 0, /* tp_as_mapping */
819 0, /* tp_hash */
820 (ternaryfunc)wrapperdescr_call, /* tp_call */
821 0, /* tp_str */
822 PyObject_GenericGetAttr, /* tp_getattro */
823 0, /* tp_setattro */
824 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200825 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
826 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 0, /* tp_doc */
828 descr_traverse, /* tp_traverse */
829 0, /* tp_clear */
830 0, /* tp_richcompare */
831 0, /* tp_weaklistoffset */
832 0, /* tp_iter */
833 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100834 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 descr_members, /* tp_members */
836 wrapperdescr_getset, /* tp_getset */
837 0, /* tp_base */
838 0, /* tp_dict */
839 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
840 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000841};
842
843static PyDescrObject *
Jeremy Hyltonaf68c872005-12-10 18:50:16 +0000844descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000845{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 PyDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
849 if (descr != NULL) {
850 Py_XINCREF(type);
851 descr->d_type = type;
852 descr->d_name = PyUnicode_InternFromString(name);
853 if (descr->d_name == NULL) {
854 Py_DECREF(descr);
855 descr = NULL;
856 }
Benjamin Petersonf2fe7f02011-12-17 08:02:20 -0500857 else {
858 descr->d_qualname = NULL;
859 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 }
861 return descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000862}
863
864PyObject *
865PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
866{
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200867 /* Figure out correct vectorcall function to use */
868 vectorcallfunc vectorcall;
869 switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS))
870 {
871 case METH_VARARGS:
872 vectorcall = method_vectorcall_VARARGS;
873 break;
874 case METH_VARARGS | METH_KEYWORDS:
875 vectorcall = method_vectorcall_VARARGS_KEYWORDS;
876 break;
877 case METH_FASTCALL:
878 vectorcall = method_vectorcall_FASTCALL;
879 break;
880 case METH_FASTCALL | METH_KEYWORDS:
881 vectorcall = method_vectorcall_FASTCALL_KEYWORDS;
882 break;
883 case METH_NOARGS:
884 vectorcall = method_vectorcall_NOARGS;
885 break;
886 case METH_O:
887 vectorcall = method_vectorcall_O;
888 break;
889 default:
890 PyErr_SetString(PyExc_SystemError, "bad call flags");
891 return NULL;
892 }
893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 PyMethodDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
897 type, method->ml_name);
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200898 if (descr != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 descr->d_method = method;
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200900 descr->vectorcall = vectorcall;
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200901 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000903}
904
905PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000906PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 PyMethodDescrObject *descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910 descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
911 type, method->ml_name);
912 if (descr != NULL)
913 descr->d_method = method;
914 return (PyObject *)descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000915}
916
917PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000918PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000919{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 PyMemberDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
923 type, member->name);
924 if (descr != NULL)
925 descr->d_member = member;
926 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000927}
928
929PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000930PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000931{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 PyGetSetDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
935 type, getset->name);
936 if (descr != NULL)
937 descr->d_getset = getset;
938 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000939}
940
941PyObject *
942PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
943{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
947 type, base->name);
948 if (descr != NULL) {
949 descr->d_base = base;
950 descr->d_wrapped = wrapped;
951 }
952 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000953}
954
Tim Peters6d6c1a32001-08-02 04:15:00 +0000955
Victor Stinner0db176f2012-04-16 00:16:30 +0200956/* --- mappingproxy: read-only proxy for mappings --- */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000957
958/* This has no reason to be in this file except that adding new files is a
959 bit of a pain */
960
961typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 PyObject_HEAD
Victor Stinner0db176f2012-04-16 00:16:30 +0200963 PyObject *mapping;
964} mappingproxyobject;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000965
Martin v. Löwis18e16552006-02-15 17:27:45 +0000966static Py_ssize_t
Victor Stinner0db176f2012-04-16 00:16:30 +0200967mappingproxy_len(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000968{
Victor Stinner0db176f2012-04-16 00:16:30 +0200969 return PyObject_Size(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000970}
971
972static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200973mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000974{
Victor Stinner0db176f2012-04-16 00:16:30 +0200975 return PyObject_GetItem(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000976}
977
Victor Stinner0db176f2012-04-16 00:16:30 +0200978static PyMappingMethods mappingproxy_as_mapping = {
979 (lenfunc)mappingproxy_len, /* mp_length */
980 (binaryfunc)mappingproxy_getitem, /* mp_subscript */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 0, /* mp_ass_subscript */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000982};
983
984static int
Victor Stinner0db176f2012-04-16 00:16:30 +0200985mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000986{
Victor Stinner0db176f2012-04-16 00:16:30 +0200987 if (PyDict_CheckExact(pp->mapping))
988 return PyDict_Contains(pp->mapping, key);
989 else
990 return PySequence_Contains(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000991}
992
Victor Stinner0db176f2012-04-16 00:16:30 +0200993static PySequenceMethods mappingproxy_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 0, /* sq_length */
995 0, /* sq_concat */
996 0, /* sq_repeat */
997 0, /* sq_item */
998 0, /* sq_slice */
999 0, /* sq_ass_item */
1000 0, /* sq_ass_slice */
Victor Stinner0db176f2012-04-16 00:16:30 +02001001 (objobjproc)mappingproxy_contains, /* sq_contains */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 0, /* sq_inplace_concat */
1003 0, /* sq_inplace_repeat */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001004};
1005
1006static PyObject *
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001007mappingproxy_get(mappingproxyobject *pp, PyObject *const *args, Py_ssize_t nargs)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001008{
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001009 /* newargs: mapping, key, default=None */
1010 PyObject *newargs[3];
1011 newargs[0] = pp->mapping;
1012 newargs[2] = Py_None;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001013
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001014 if (!_PyArg_UnpackStack(args, nargs, "get", 1, 2,
1015 &newargs[1], &newargs[2]))
1016 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 return NULL;
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001018 }
1019 _Py_IDENTIFIER(get);
1020 return _PyObject_VectorcallMethodId(&PyId_get, newargs,
1021 3 | PY_VECTORCALL_ARGUMENTS_OFFSET,
1022 NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001023}
1024
1025static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301026mappingproxy_keys(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(keys);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001029 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_keys);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001030}
1031
1032static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301033mappingproxy_values(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(values);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001036 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_values);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001037}
1038
1039static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301040mappingproxy_items(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(items);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001043 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_items);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001044}
1045
1046static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301047mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001048{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001049 _Py_IDENTIFIER(copy);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001050 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_copy);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001051}
1052
Victor Stinner0db176f2012-04-16 00:16:30 +02001053/* WARNING: mappingproxy methods must not give access
1054 to the underlying mapping */
1055
1056static PyMethodDef mappingproxy_methods[] = {
Zackery Spytz43d564c2019-08-13 23:51:06 -06001057 {"get", (PyCFunction)(void(*)(void))mappingproxy_get, METH_FASTCALL,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d."
Victor Stinner0db176f2012-04-16 00:16:30 +02001059 " d defaults to None.")},
1060 {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 PyDoc_STR("D.keys() -> list of D's keys")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001062 {"values", (PyCFunction)mappingproxy_values, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 PyDoc_STR("D.values() -> list of D's values")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001064 {"items", (PyCFunction)mappingproxy_items, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001066 {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 PyDoc_STR("D.copy() -> a shallow copy of D")},
1068 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001069};
1070
1071static void
Victor Stinner0db176f2012-04-16 00:16:30 +02001072mappingproxy_dealloc(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 _PyObject_GC_UNTRACK(pp);
Victor Stinner0db176f2012-04-16 00:16:30 +02001075 Py_DECREF(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 PyObject_GC_Del(pp);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001077}
1078
1079static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001080mappingproxy_getiter(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001081{
Victor Stinner0db176f2012-04-16 00:16:30 +02001082 return PyObject_GetIter(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001083}
1084
Neil Schemenauer26775122001-10-21 22:26:43 +00001085static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001086mappingproxy_str(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001087{
Victor Stinner0db176f2012-04-16 00:16:30 +02001088 return PyObject_Str(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001089}
1090
Ezio Melottiac53ab62010-12-18 14:59:43 +00001091static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001092mappingproxy_repr(mappingproxyobject *pp)
Ezio Melottiac53ab62010-12-18 14:59:43 +00001093{
Victor Stinner0db176f2012-04-16 00:16:30 +02001094 return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping);
Ezio Melottiac53ab62010-12-18 14:59:43 +00001095}
1096
Guido van Rossum048eb752001-10-02 21:24:57 +00001097static int
Victor Stinner0db176f2012-04-16 00:16:30 +02001098mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
Guido van Rossum048eb752001-10-02 21:24:57 +00001099{
Victor Stinner0db176f2012-04-16 00:16:30 +02001100 mappingproxyobject *pp = (mappingproxyobject *)self;
1101 Py_VISIT(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001103}
1104
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001105static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001106mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op)
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001107{
Victor Stinner0db176f2012-04-16 00:16:30 +02001108 return PyObject_RichCompare(v->mapping, w, op);
1109}
1110
1111static int
1112mappingproxy_check_mapping(PyObject *mapping)
1113{
1114 if (!PyMapping_Check(mapping)
1115 || PyList_Check(mapping)
1116 || PyTuple_Check(mapping)) {
1117 PyErr_Format(PyExc_TypeError,
1118 "mappingproxy() argument must be a mapping, not %s",
1119 Py_TYPE(mapping)->tp_name);
1120 return -1;
1121 }
1122 return 0;
1123}
1124
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001125/*[clinic input]
1126@classmethod
1127mappingproxy.__new__ as mappingproxy_new
Victor Stinner0db176f2012-04-16 00:16:30 +02001128
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001129 mapping: object
1130
1131[clinic start generated code]*/
1132
1133static PyObject *
1134mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping)
1135/*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/
1136{
1137 mappingproxyobject *mappingproxy;
Victor Stinner0db176f2012-04-16 00:16:30 +02001138
1139 if (mappingproxy_check_mapping(mapping) == -1)
1140 return NULL;
1141
1142 mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
1143 if (mappingproxy == NULL)
1144 return NULL;
1145 Py_INCREF(mapping);
1146 mappingproxy->mapping = mapping;
1147 _PyObject_GC_TRACK(mappingproxy);
1148 return (PyObject *)mappingproxy;
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001149}
1150
Tim Peters6d6c1a32001-08-02 04:15:00 +00001151PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001152PyDictProxy_New(PyObject *mapping)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001153{
Victor Stinner0db176f2012-04-16 00:16:30 +02001154 mappingproxyobject *pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001155
Victor Stinner0db176f2012-04-16 00:16:30 +02001156 if (mappingproxy_check_mapping(mapping) == -1)
1157 return NULL;
1158
1159 pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 if (pp != NULL) {
Victor Stinner0db176f2012-04-16 00:16:30 +02001161 Py_INCREF(mapping);
1162 pp->mapping = mapping;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 _PyObject_GC_TRACK(pp);
1164 }
1165 return (PyObject *)pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001166}
1167
1168
1169/* --- Wrapper object for "slot" methods --- */
1170
1171/* This has no reason to be in this file except that adding new files is a
1172 bit of a pain */
1173
1174typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 PyObject_HEAD
1176 PyWrapperDescrObject *descr;
1177 PyObject *self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001178} wrapperobject;
1179
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001180#define Wrapper_Check(v) (Py_TYPE(v) == &_PyMethodWrapper_Type)
Mark Dickinson211c6252009-02-01 10:28:51 +00001181
Tim Peters6d6c1a32001-08-02 04:15:00 +00001182static void
1183wrapper_dealloc(wrapperobject *wp)
1184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 PyObject_GC_UnTrack(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001186 Py_TRASHCAN_BEGIN(wp, wrapper_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 Py_XDECREF(wp->descr);
1188 Py_XDECREF(wp->self);
1189 PyObject_GC_Del(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001190 Py_TRASHCAN_END
Tim Peters6d6c1a32001-08-02 04:15:00 +00001191}
1192
Mark Dickinson211c6252009-02-01 10:28:51 +00001193static PyObject *
1194wrapper_richcompare(PyObject *a, PyObject *b, int op)
Armin Rigoc6686b72005-11-07 08:38:00 +00001195{
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001196 wrapperobject *wa, *wb;
1197 int eq;
Mark Dickinson211c6252009-02-01 10:28:51 +00001198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +00001200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 /* both arguments should be wrapperobjects */
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001202 if ((op != Py_EQ && op != Py_NE)
1203 || !Wrapper_Check(a) || !Wrapper_Check(b))
1204 {
stratakise8b19652017-11-02 11:32:54 +01001205 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 }
Mark Dickinson211c6252009-02-01 10:28:51 +00001207
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001208 wa = (wrapperobject *)a;
1209 wb = (wrapperobject *)b;
1210 eq = (wa->descr == wb->descr && wa->self == wb->self);
1211 if (eq == (op == Py_EQ)) {
1212 Py_RETURN_TRUE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 }
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001214 else {
1215 Py_RETURN_FALSE;
1216 }
Armin Rigoc6686b72005-11-07 08:38:00 +00001217}
1218
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001219static Py_hash_t
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001220wrapper_hash(wrapperobject *wp)
1221{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001222 Py_hash_t x, y;
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001223 x = _Py_HashPointer(wp->self);
1224 y = _Py_HashPointer(wp->descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 x = x ^ y;
1226 if (x == -1)
1227 x = -2;
1228 return x;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001229}
1230
Armin Rigoc6686b72005-11-07 08:38:00 +00001231static PyObject *
1232wrapper_repr(wrapperobject *wp)
1233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
1235 wp->descr->d_base->name,
1236 wp->self->ob_type->tp_name,
1237 wp->self);
Armin Rigoc6686b72005-11-07 08:38:00 +00001238}
1239
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001240static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301241wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001242{
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001243 _Py_IDENTIFIER(getattr);
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02001244 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
1245 wp->self, PyDescr_NAME(wp->descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001246}
1247
1248static PyMethodDef wrapper_methods[] = {
1249 {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
1250 {NULL, NULL}
1251};
1252
Armin Rigoc6686b72005-11-07 08:38:00 +00001253static PyMemberDef wrapper_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
1255 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001256};
1257
1258static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001259wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored))
Armin Rigoc6686b72005-11-07 08:38:00 +00001260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
Armin Rigoc6686b72005-11-07 08:38:00 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 Py_INCREF(c);
1264 return c;
Armin Rigoc6686b72005-11-07 08:38:00 +00001265}
1266
1267static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001268wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001269{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 const char *s = wp->descr->d_base->name;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 return PyUnicode_FromString(s);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001273}
1274
1275static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001276wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001277{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001278 return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -08001279}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001280
Larry Hastings5c661892014-01-24 06:17:25 -08001281static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001282wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
Larry Hastings5c661892014-01-24 06:17:25 -08001283{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001284 return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001285}
1286
Antoine Pitrou9d574812011-12-12 13:47:25 +01001287static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001288wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +01001289{
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001290 return descr_get_qualname((PyDescrObject *)wp->descr, NULL);
Antoine Pitrou9d574812011-12-12 13:47:25 +01001291}
1292
Guido van Rossum32d34c82001-09-20 21:45:26 +00001293static PyGetSetDef wrapper_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 {"__objclass__", (getter)wrapper_objclass},
1295 {"__name__", (getter)wrapper_name},
Antoine Pitrou9d574812011-12-12 13:47:25 +01001296 {"__qualname__", (getter)wrapper_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 {"__doc__", (getter)wrapper_doc},
Larry Hastings5c661892014-01-24 06:17:25 -08001298 {"__text_signature__", (getter)wrapper_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001300};
1301
1302static PyObject *
1303wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
1304{
Serhiy Storchaka5e02c782017-09-21 14:25:36 +03001305 return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001306}
1307
Guido van Rossum048eb752001-10-02 21:24:57 +00001308static int
1309wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1310{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 wrapperobject *wp = (wrapperobject *)self;
1312 Py_VISIT(wp->descr);
1313 Py_VISIT(wp->self);
1314 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001315}
1316
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001317PyTypeObject _PyMethodWrapper_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1319 "method-wrapper", /* tp_name */
1320 sizeof(wrapperobject), /* tp_basicsize */
1321 0, /* tp_itemsize */
1322 /* methods */
1323 (destructor)wrapper_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001324 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 0, /* tp_getattr */
1326 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001327 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 (reprfunc)wrapper_repr, /* tp_repr */
1329 0, /* tp_as_number */
1330 0, /* tp_as_sequence */
1331 0, /* tp_as_mapping */
1332 (hashfunc)wrapper_hash, /* tp_hash */
1333 (ternaryfunc)wrapper_call, /* tp_call */
1334 0, /* tp_str */
1335 PyObject_GenericGetAttr, /* tp_getattro */
1336 0, /* tp_setattro */
1337 0, /* tp_as_buffer */
1338 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1339 0, /* tp_doc */
1340 wrapper_traverse, /* tp_traverse */
1341 0, /* tp_clear */
1342 wrapper_richcompare, /* tp_richcompare */
1343 0, /* tp_weaklistoffset */
1344 0, /* tp_iter */
1345 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001346 wrapper_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 wrapper_members, /* tp_members */
1348 wrapper_getsets, /* tp_getset */
1349 0, /* tp_base */
1350 0, /* tp_dict */
1351 0, /* tp_descr_get */
1352 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001353};
1354
1355PyObject *
1356PyWrapper_New(PyObject *d, PyObject *self)
1357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 wrapperobject *wp;
1359 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1362 descr = (PyWrapperDescrObject *)d;
Victor Stinner3249dec2011-05-01 23:19:15 +02001363 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +02001364 (PyObject *)PyDescr_TYPE(descr)));
Tim Peters6d6c1a32001-08-02 04:15:00 +00001365
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001366 wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 if (wp != NULL) {
1368 Py_INCREF(descr);
1369 wp->descr = descr;
1370 Py_INCREF(self);
1371 wp->self = self;
1372 _PyObject_GC_TRACK(wp);
1373 }
1374 return (PyObject *)wp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001375}
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001376
1377
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001378/* A built-in 'property' type */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001379
1380/*
Serhiy Storchakad741a882015-06-11 00:06:39 +03001381class property(object):
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
1384 if doc is None and fget is not None and hasattr(fget, "__doc__"):
Serhiy Storchakad741a882015-06-11 00:06:39 +03001385 doc = fget.__doc__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 self.__get = fget
1387 self.__set = fset
1388 self.__del = fdel
1389 self.__doc__ = doc
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 def __get__(self, inst, type=None):
1392 if inst is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001393 return self
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 if self.__get is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001395 raise AttributeError, "unreadable attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 return self.__get(inst)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398 def __set__(self, inst, value):
1399 if self.__set is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001400 raise AttributeError, "can't set attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 return self.__set(inst, value)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403 def __delete__(self, inst):
1404 if self.__del is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001405 raise AttributeError, "can't delete attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 return self.__del(inst)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001407
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001408*/
1409
1410typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 PyObject_HEAD
1412 PyObject *prop_get;
1413 PyObject *prop_set;
1414 PyObject *prop_del;
1415 PyObject *prop_doc;
1416 int getter_doc;
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001417} propertyobject;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001418
Christian Heimes0449f632007-12-15 01:27:15 +00001419static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
Benjamin Peterson93964832010-06-28 03:07:10 +00001420 PyObject *);
Christian Heimes0449f632007-12-15 01:27:15 +00001421
Tim Peters66c1a522001-09-24 21:17:50 +00001422static PyMemberDef property_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
1424 {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
1425 {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
Raymond Hettingereac503a2015-05-13 01:09:59 -07001426 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 {0}
Tim Peters66c1a522001-09-24 21:17:50 +00001428};
1429
Christian Heimes0449f632007-12-15 01:27:15 +00001430
Guido van Rossum58da9312007-11-10 23:39:45 +00001431PyDoc_STRVAR(getter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 "Descriptor to change the getter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001433
Neal Norwitz32dde222008-04-15 06:43:13 +00001434static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001435property_getter(PyObject *self, PyObject *getter)
1436{
Benjamin Peterson93964832010-06-28 03:07:10 +00001437 return property_copy(self, getter, NULL, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001438}
1439
Christian Heimes0449f632007-12-15 01:27:15 +00001440
Guido van Rossum58da9312007-11-10 23:39:45 +00001441PyDoc_STRVAR(setter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 "Descriptor to change the setter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001443
Neal Norwitz32dde222008-04-15 06:43:13 +00001444static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001445property_setter(PyObject *self, PyObject *setter)
1446{
Benjamin Peterson93964832010-06-28 03:07:10 +00001447 return property_copy(self, NULL, setter, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001448}
1449
Christian Heimes0449f632007-12-15 01:27:15 +00001450
Guido van Rossum58da9312007-11-10 23:39:45 +00001451PyDoc_STRVAR(deleter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 "Descriptor to change the deleter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001453
Neal Norwitz32dde222008-04-15 06:43:13 +00001454static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001455property_deleter(PyObject *self, PyObject *deleter)
1456{
Benjamin Peterson93964832010-06-28 03:07:10 +00001457 return property_copy(self, NULL, NULL, deleter);
Guido van Rossum58da9312007-11-10 23:39:45 +00001458}
1459
1460
Guido van Rossum58da9312007-11-10 23:39:45 +00001461static PyMethodDef property_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 {"getter", property_getter, METH_O, getter_doc},
1463 {"setter", property_setter, METH_O, setter_doc},
1464 {"deleter", property_deleter, METH_O, deleter_doc},
1465 {0}
Guido van Rossum58da9312007-11-10 23:39:45 +00001466};
1467
Tim Peters66c1a522001-09-24 21:17:50 +00001468
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001469static void
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001470property_dealloc(PyObject *self)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 propertyobject *gs = (propertyobject *)self;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 _PyObject_GC_UNTRACK(self);
1475 Py_XDECREF(gs->prop_get);
1476 Py_XDECREF(gs->prop_set);
1477 Py_XDECREF(gs->prop_del);
1478 Py_XDECREF(gs->prop_doc);
1479 self->ob_type->tp_free(self);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001480}
1481
1482static PyObject *
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001483property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 if (obj == NULL || obj == Py_None) {
1486 Py_INCREF(self);
1487 return self;
1488 }
Victor Stinnere972c132018-10-01 03:03:22 -07001489
1490 propertyobject *gs = (propertyobject *)self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 if (gs->prop_get == NULL) {
1492 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1493 return NULL;
1494 }
Victor Stinnere972c132018-10-01 03:03:22 -07001495
Jeroen Demeyer196a5302019-07-04 12:31:34 +02001496 return _PyObject_CallOneArg(gs->prop_get, obj);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001497}
1498
1499static int
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001500property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 propertyobject *gs = (propertyobject *)self;
1503 PyObject *func, *res;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 if (value == NULL)
1506 func = gs->prop_del;
1507 else
1508 func = gs->prop_set;
1509 if (func == NULL) {
1510 PyErr_SetString(PyExc_AttributeError,
1511 value == NULL ?
1512 "can't delete attribute" :
1513 "can't set attribute");
1514 return -1;
1515 }
1516 if (value == NULL)
Jeroen Demeyer196a5302019-07-04 12:31:34 +02001517 res = _PyObject_CallOneArg(func, obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 else
Benjamin Peterson9b955de2010-12-07 04:04:02 +00001519 res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 if (res == NULL)
1521 return -1;
1522 Py_DECREF(res);
1523 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001524}
1525
Christian Heimes0449f632007-12-15 01:27:15 +00001526static PyObject *
Benjamin Peterson93964832010-06-28 03:07:10 +00001527property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
Christian Heimes0449f632007-12-15 01:27:15 +00001528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 propertyobject *pold = (propertyobject *)old;
Benjamin Peterson93964832010-06-28 03:07:10 +00001530 PyObject *new, *type, *doc;
Christian Heimes0449f632007-12-15 01:27:15 +00001531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 type = PyObject_Type(old);
1533 if (type == NULL)
1534 return NULL;
Christian Heimes0449f632007-12-15 01:27:15 +00001535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 if (get == NULL || get == Py_None) {
1537 Py_XDECREF(get);
1538 get = pold->prop_get ? pold->prop_get : Py_None;
1539 }
1540 if (set == NULL || set == Py_None) {
1541 Py_XDECREF(set);
1542 set = pold->prop_set ? pold->prop_set : Py_None;
1543 }
1544 if (del == NULL || del == Py_None) {
1545 Py_XDECREF(del);
1546 del = pold->prop_del ? pold->prop_del : Py_None;
1547 }
Benjamin Peterson93964832010-06-28 03:07:10 +00001548 if (pold->getter_doc && get != Py_None) {
1549 /* make _init use __doc__ from getter */
1550 doc = Py_None;
1551 }
1552 else {
1553 doc = pold->prop_doc ? pold->prop_doc : Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 }
R. David Murrayb18500d2009-05-04 22:59:07 +00001555
Victor Stinner5abaa2b2016-12-09 16:22:32 +01001556 new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 Py_DECREF(type);
1558 if (new == NULL)
1559 return NULL;
1560 return new;
Christian Heimes0449f632007-12-15 01:27:15 +00001561}
1562
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001563/*[clinic input]
1564property.__init__ as property_init
1565
1566 fget: object(c_default="NULL") = None
1567 function to be used for getting an attribute value
1568 fset: object(c_default="NULL") = None
1569 function to be used for setting an attribute value
1570 fdel: object(c_default="NULL") = None
1571 function to be used for del'ing an attribute
1572 doc: object(c_default="NULL") = None
1573 docstring
1574
1575Property attribute.
1576
1577Typical use is to define a managed attribute x:
1578
1579class C(object):
1580 def getx(self): return self._x
1581 def setx(self, value): self._x = value
1582 def delx(self): del self._x
1583 x = property(getx, setx, delx, "I'm the 'x' property.")
1584
1585Decorators make defining new properties or modifying existing ones easy:
1586
1587class C(object):
1588 @property
1589 def x(self):
1590 "I am the 'x' property."
1591 return self._x
1592 @x.setter
1593 def x(self, value):
1594 self._x = value
1595 @x.deleter
1596 def x(self):
1597 del self._x
1598[clinic start generated code]*/
1599
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001600static int
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001601property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1602 PyObject *fdel, PyObject *doc)
1603/*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001604{
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001605 if (fget == Py_None)
1606 fget = NULL;
1607 if (fset == Py_None)
1608 fset = NULL;
1609 if (fdel == Py_None)
1610 fdel = NULL;
Tim Peters66c1a522001-09-24 21:17:50 +00001611
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001612 Py_XINCREF(fget);
1613 Py_XINCREF(fset);
1614 Py_XINCREF(fdel);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 Py_XINCREF(doc);
Christian Heimes0449f632007-12-15 01:27:15 +00001616
Oren Milmand019bc82018-02-13 12:28:33 +02001617 Py_XSETREF(self->prop_get, fget);
1618 Py_XSETREF(self->prop_set, fset);
1619 Py_XSETREF(self->prop_del, fdel);
1620 Py_XSETREF(self->prop_doc, doc);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001621 self->getter_doc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 /* if no docstring given and the getter has one, use that one */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001624 if ((doc == NULL || doc == Py_None) && fget != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001625 _Py_IDENTIFIER(__doc__);
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001626 PyObject *get_doc;
1627 int rc = _PyObject_LookupAttrId(fget, &PyId___doc__, &get_doc);
1628 if (rc <= 0) {
1629 return rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 }
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001631 if (Py_TYPE(self) == &PyProperty_Type) {
1632 Py_XSETREF(self->prop_doc, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 }
1634 else {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001635 /* If this is a property subclass, put __doc__
1636 in dict of the subclass instance instead,
1637 otherwise it gets shadowed by __doc__ in the
1638 class's dict. */
1639 int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc);
1640 Py_DECREF(get_doc);
1641 if (err < 0)
1642 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 }
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001644 self->getter_doc = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 }
1646
1647 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001648}
1649
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001650static PyObject *
1651property_get___isabstractmethod__(propertyobject *prop, void *closure)
1652{
1653 int res = _PyObject_IsAbstract(prop->prop_get);
1654 if (res == -1) {
1655 return NULL;
1656 }
1657 else if (res) {
1658 Py_RETURN_TRUE;
1659 }
1660
1661 res = _PyObject_IsAbstract(prop->prop_set);
1662 if (res == -1) {
1663 return NULL;
1664 }
1665 else if (res) {
1666 Py_RETURN_TRUE;
1667 }
1668
1669 res = _PyObject_IsAbstract(prop->prop_del);
1670 if (res == -1) {
1671 return NULL;
1672 }
1673 else if (res) {
1674 Py_RETURN_TRUE;
1675 }
1676 Py_RETURN_FALSE;
1677}
1678
1679static PyGetSetDef property_getsetlist[] = {
1680 {"__isabstractmethod__",
1681 (getter)property_get___isabstractmethod__, NULL,
1682 NULL,
1683 NULL},
1684 {NULL} /* Sentinel */
1685};
1686
Guido van Rossum048eb752001-10-02 21:24:57 +00001687static int
1688property_traverse(PyObject *self, visitproc visit, void *arg)
1689{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690 propertyobject *pp = (propertyobject *)self;
1691 Py_VISIT(pp->prop_get);
1692 Py_VISIT(pp->prop_set);
1693 Py_VISIT(pp->prop_del);
1694 Py_VISIT(pp->prop_doc);
1695 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001696}
1697
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001698static int
1699property_clear(PyObject *self)
1700{
1701 propertyobject *pp = (propertyobject *)self;
1702 Py_CLEAR(pp->prop_doc);
1703 return 0;
1704}
1705
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001706#include "clinic/descrobject.c.h"
1707
1708PyTypeObject PyDictProxy_Type = {
1709 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1710 "mappingproxy", /* tp_name */
1711 sizeof(mappingproxyobject), /* tp_basicsize */
1712 0, /* tp_itemsize */
1713 /* methods */
1714 (destructor)mappingproxy_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001715 0, /* tp_vectorcall_offset */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001716 0, /* tp_getattr */
1717 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001718 0, /* tp_as_async */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001719 (reprfunc)mappingproxy_repr, /* tp_repr */
1720 0, /* tp_as_number */
1721 &mappingproxy_as_sequence, /* tp_as_sequence */
1722 &mappingproxy_as_mapping, /* tp_as_mapping */
1723 0, /* tp_hash */
1724 0, /* tp_call */
1725 (reprfunc)mappingproxy_str, /* tp_str */
1726 PyObject_GenericGetAttr, /* tp_getattro */
1727 0, /* tp_setattro */
1728 0, /* tp_as_buffer */
1729 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1730 0, /* tp_doc */
1731 mappingproxy_traverse, /* tp_traverse */
1732 0, /* tp_clear */
1733 (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
1734 0, /* tp_weaklistoffset */
1735 (getiterfunc)mappingproxy_getiter, /* tp_iter */
1736 0, /* tp_iternext */
1737 mappingproxy_methods, /* tp_methods */
1738 0, /* tp_members */
1739 0, /* tp_getset */
1740 0, /* tp_base */
1741 0, /* tp_dict */
1742 0, /* tp_descr_get */
1743 0, /* tp_descr_set */
1744 0, /* tp_dictoffset */
1745 0, /* tp_init */
1746 0, /* tp_alloc */
1747 mappingproxy_new, /* tp_new */
1748};
1749
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001750PyTypeObject PyProperty_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1752 "property", /* tp_name */
1753 sizeof(propertyobject), /* tp_basicsize */
1754 0, /* tp_itemsize */
1755 /* methods */
1756 property_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001757 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 0, /* tp_getattr */
1759 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001760 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 0, /* tp_repr */
1762 0, /* tp_as_number */
1763 0, /* tp_as_sequence */
1764 0, /* tp_as_mapping */
1765 0, /* tp_hash */
1766 0, /* tp_call */
1767 0, /* tp_str */
1768 PyObject_GenericGetAttr, /* tp_getattro */
1769 0, /* tp_setattro */
1770 0, /* tp_as_buffer */
1771 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1772 Py_TPFLAGS_BASETYPE, /* tp_flags */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001773 property_init__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 property_traverse, /* tp_traverse */
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001775 (inquiry)property_clear, /* tp_clear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 0, /* tp_richcompare */
1777 0, /* tp_weaklistoffset */
1778 0, /* tp_iter */
1779 0, /* tp_iternext */
1780 property_methods, /* tp_methods */
1781 property_members, /* tp_members */
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001782 property_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 0, /* tp_base */
1784 0, /* tp_dict */
1785 property_descr_get, /* tp_descr_get */
1786 property_descr_set, /* tp_descr_set */
1787 0, /* tp_dictoffset */
1788 property_init, /* tp_init */
1789 PyType_GenericAlloc, /* tp_alloc */
1790 PyType_GenericNew, /* tp_new */
1791 PyObject_GC_Del, /* tp_free */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001792};