blob: c9754a11b89be19a427b25f941141f2d41f69a48 [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 Stinnere5014be2020-04-14 17:52:15 +02004#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
Victor Stinnerbcda8f12018-11-21 22:27:47 +01005#include "pycore_object.h"
Victor Stinnere5014be2020-04-14 17:52:15 +02006#include "pycore_pystate.h" // _PyThreadState_GET()
Victor Stinnerec13b932018-11-25 23:56:17 +01007#include "pycore_tupleobject.h"
Victor Stinner4a21e572020-04-15 02:35:41 +02008#include "structmember.h" // PyMemberDef
Tim Peters6d6c1a32001-08-02 04:15:00 +00009
Hai Shi46874c22020-01-30 17:20:25 -060010_Py_IDENTIFIER(getattr);
11
Serhiy Storchaka18b250f2017-03-19 08:51:07 +020012/*[clinic input]
13class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type"
14class property "propertyobject *" "&PyProperty_Type"
15[clinic start generated code]*/
16/*[clinic end generated code: output=da39a3ee5e6b4b0d input=556352653fd4c02e]*/
17
Tim Peters6d6c1a32001-08-02 04:15:00 +000018static void
19descr_dealloc(PyDescrObject *descr)
20{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000021 _PyObject_GC_UNTRACK(descr);
22 Py_XDECREF(descr->d_type);
23 Py_XDECREF(descr->d_name);
Antoine Pitrou9d574812011-12-12 13:47:25 +010024 Py_XDECREF(descr->d_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000025 PyObject_GC_Del(descr);
Tim Peters6d6c1a32001-08-02 04:15:00 +000026}
27
Walter Dörwaldd7fb7642007-06-11 16:36:59 +000028static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +000029descr_name(PyDescrObject *descr)
30{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
32 return descr->d_name;
33 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +000034}
35
36static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020037descr_repr(PyDescrObject *descr, const char *format)
Tim Peters6d6c1a32001-08-02 04:15:00 +000038{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000039 PyObject *name = NULL;
40 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
41 name = descr->d_name;
Walter Dörwaldd7fb7642007-06-11 16:36:59 +000042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043 return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name);
Tim Peters6d6c1a32001-08-02 04:15:00 +000044}
45
46static PyObject *
47method_repr(PyMethodDescrObject *descr)
48{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049 return descr_repr((PyDescrObject *)descr,
50 "<method '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000051}
52
53static PyObject *
54member_repr(PyMemberDescrObject *descr)
55{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000056 return descr_repr((PyDescrObject *)descr,
57 "<member '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000058}
59
60static PyObject *
61getset_repr(PyGetSetDescrObject *descr)
62{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 return descr_repr((PyDescrObject *)descr,
64 "<attribute '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000065}
66
67static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +000068wrapperdescr_repr(PyWrapperDescrObject *descr)
Tim Peters6d6c1a32001-08-02 04:15:00 +000069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070 return descr_repr((PyDescrObject *)descr,
71 "<slot wrapper '%V' of '%s' objects>");
Tim Peters6d6c1a32001-08-02 04:15:00 +000072}
73
74static int
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +000075descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +000076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077 if (obj == NULL) {
78 Py_INCREF(descr);
79 *pres = (PyObject *)descr;
80 return 1;
81 }
82 if (!PyObject_TypeCheck(obj, descr->d_type)) {
83 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +090084 "descriptor '%V' for '%.100s' objects "
85 "doesn't apply to a '%.100s' object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000086 descr_name((PyDescrObject *)descr), "?",
87 descr->d_type->tp_name,
Victor Stinner58ac7002020-02-07 03:04:21 +010088 Py_TYPE(obj)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 *pres = NULL;
90 return 1;
91 }
92 return 0;
Tim Peters6d6c1a32001-08-02 04:15:00 +000093}
94
95static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +000096classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Petersbca1cbc2002-12-09 22:56:13 +000097{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 /* Ensure a valid type. Class methods ignore obj. */
99 if (type == NULL) {
100 if (obj != NULL)
Victor Stinner58ac7002020-02-07 03:04:21 +0100101 type = (PyObject *)Py_TYPE(obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 else {
103 /* Wot - no type?! */
104 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900105 "descriptor '%V' for type '%.100s' "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 "needs either an object or a type",
107 descr_name((PyDescrObject *)descr), "?",
108 PyDescr_TYPE(descr)->tp_name);
109 return NULL;
110 }
111 }
112 if (!PyType_Check(type)) {
113 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900114 "descriptor '%V' for type '%.100s' "
115 "needs a type, not a '%.100s' as arg 2",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 descr_name((PyDescrObject *)descr), "?",
117 PyDescr_TYPE(descr)->tp_name,
Victor Stinner58ac7002020-02-07 03:04:21 +0100118 Py_TYPE(type)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 return NULL;
120 }
121 if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) {
122 PyErr_Format(PyExc_TypeError,
Inada Naoki62f95882019-04-01 17:56:11 +0900123 "descriptor '%V' requires a subtype of '%.100s' "
124 "but received '%.100s'",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 descr_name((PyDescrObject *)descr), "?",
126 PyDescr_TYPE(descr)->tp_name,
127 ((PyTypeObject *)type)->tp_name);
128 return NULL;
129 }
Petr Viktorine1becf42020-05-07 15:39:59 +0200130 PyTypeObject *cls = NULL;
131 if (descr->d_method->ml_flags & METH_METHOD) {
132 cls = descr->d_common.d_type;
133 }
134 return PyCMethod_New(descr->d_method, type, NULL, cls);
Tim Petersbca1cbc2002-12-09 22:56:13 +0000135}
136
137static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000138method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142 if (descr_check((PyDescrObject *)descr, obj, &res))
143 return res;
Petr Viktorine1becf42020-05-07 15:39:59 +0200144 if (descr->d_method->ml_flags & METH_METHOD) {
145 if (PyType_Check(type)) {
146 return PyCMethod_New(descr->d_method, obj, NULL, descr->d_common.d_type);
147 } else {
148 PyErr_Format(PyExc_TypeError,
149 "descriptor '%V' needs a type, not '%s', as arg 2",
150 descr_name((PyDescrObject *)descr),
151 Py_TYPE(type)->tp_name);
152 return NULL;
153 }
154 } else {
155 return PyCFunction_NewEx(descr->d_method, obj, NULL);
156 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000157}
158
159static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000160member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000161{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 if (descr_check((PyDescrObject *)descr, obj, &res))
165 return res;
Steve Dowerb82e17e2019-05-23 08:45:22 -0700166
167 if (descr->d_member->flags & READ_RESTRICTED) {
168 if (PySys_Audit("object.__getattr__", "Os",
169 obj ? obj : Py_None, descr->d_member->name) < 0) {
170 return NULL;
171 }
172 }
173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 return PyMember_GetOne((char *)obj, descr->d_member);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000175}
176
177static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000178getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 if (descr_check((PyDescrObject *)descr, obj, &res))
183 return res;
184 if (descr->d_getset->get != NULL)
185 return descr->d_getset->get(obj, descr->d_getset->closure);
186 PyErr_Format(PyExc_AttributeError,
187 "attribute '%V' of '%.100s' objects is not readable",
188 descr_name((PyDescrObject *)descr), "?",
189 PyDescr_TYPE(descr)->tp_name);
190 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000191}
192
193static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000194wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 if (descr_check((PyDescrObject *)descr, obj, &res))
199 return res;
200 return PyWrapper_New((PyObject *)descr, obj);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000201}
202
203static int
204descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 int *pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 assert(obj != NULL);
208 if (!PyObject_TypeCheck(obj, descr->d_type)) {
209 PyErr_Format(PyExc_TypeError,
210 "descriptor '%V' for '%.100s' objects "
Inada Naoki62f95882019-04-01 17:56:11 +0900211 "doesn't apply to a '%.100s' object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 descr_name(descr), "?",
213 descr->d_type->tp_name,
Victor Stinner58ac7002020-02-07 03:04:21 +0100214 Py_TYPE(obj)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 *pres = -1;
216 return 1;
217 }
218 return 0;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000219}
220
221static int
222member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
227 return res;
228 return PyMember_SetOne((char *)obj, descr->d_member, value);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000229}
230
231static int
232getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000236 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
237 return res;
238 if (descr->d_getset->set != NULL)
239 return descr->d_getset->set(obj, value,
240 descr->d_getset->closure);
241 PyErr_Format(PyExc_AttributeError,
242 "attribute '%V' of '%.100s' objects is not writable",
243 descr_name((PyDescrObject *)descr), "?",
244 PyDescr_TYPE(descr)->tp_name);
245 return -1;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000246}
247
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200248
249/* Vectorcall functions for each of the PyMethodDescr calling conventions.
250 *
251 * First, common helpers
252 */
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200253static inline int
254method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
255{
256 assert(!PyErr_Occurred());
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200257 if (nargs < 1) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100258 PyObject *funcstr = _PyObject_FunctionStr(func);
259 if (funcstr != NULL) {
260 PyErr_Format(PyExc_TypeError,
261 "unbound method %U needs an argument", funcstr);
262 Py_DECREF(funcstr);
263 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200264 return -1;
265 }
266 PyObject *self = args[0];
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100267 PyObject *dummy;
268 if (descr_check((PyDescrObject *)func, self, &dummy)) {
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200269 return -1;
270 }
271 if (kwnames && PyTuple_GET_SIZE(kwnames)) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100272 PyObject *funcstr = _PyObject_FunctionStr(func);
273 if (funcstr != NULL) {
274 PyErr_Format(PyExc_TypeError,
275 "%U takes no keyword arguments", funcstr);
276 Py_DECREF(funcstr);
277 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200278 return -1;
279 }
280 return 0;
281}
282
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100283typedef void (*funcptr)(void);
284
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200285static inline funcptr
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100286method_enter_call(PyThreadState *tstate, PyObject *func)
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200287{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100288 if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200289 return NULL;
290 }
291 return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth;
292}
293
294/* Now the actual vectorcall functions */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000295static PyObject *
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200296method_vectorcall_VARARGS(
297 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000298{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100299 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200300 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200301 if (method_check_args(func, args, nargs, kwnames)) {
INADA Naoki5566bbb2017-02-03 07:43:03 +0900302 return NULL;
303 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200304 PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
305 if (argstuple == NULL) {
INADA Naoki5566bbb2017-02-03 07:43:03 +0900306 return NULL;
307 }
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100308 PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200309 if (meth == NULL) {
310 Py_DECREF(argstuple);
311 return NULL;
312 }
313 PyObject *result = meth(args[0], argstuple);
314 Py_DECREF(argstuple);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100315 _Py_LeaveRecursiveCall(tstate);
INADA Naoki5566bbb2017-02-03 07:43:03 +0900316 return result;
317}
318
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200319static PyObject *
320method_vectorcall_VARARGS_KEYWORDS(
321 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
322{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100323 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200324 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
325 if (method_check_args(func, args, nargs, NULL)) {
326 return NULL;
327 }
328 PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
329 if (argstuple == NULL) {
330 return NULL;
331 }
332 PyObject *result = NULL;
333 /* Create a temporary dict for keyword arguments */
334 PyObject *kwdict = NULL;
335 if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) > 0) {
336 kwdict = _PyStack_AsDict(args + nargs, kwnames);
337 if (kwdict == NULL) {
338 goto exit;
339 }
340 }
341 PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords)
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100342 method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200343 if (meth == NULL) {
344 goto exit;
345 }
346 result = meth(args[0], argstuple, kwdict);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100347 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200348exit:
349 Py_DECREF(argstuple);
350 Py_XDECREF(kwdict);
351 return result;
352}
353
354static PyObject *
Petr Viktorine1becf42020-05-07 15:39:59 +0200355method_vectorcall_FASTCALL_KEYWORDS_METHOD(
356 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
357{
358 PyThreadState *tstate = _PyThreadState_GET();
359 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
360 if (method_check_args(func, args, nargs, NULL)) {
361 return NULL;
362 }
363 NULL;
364 PyCMethod meth = (PyCMethod) method_enter_call(tstate, func);
365 if (meth == NULL) {
366 return NULL;
367 }
368 PyObject *result = meth(args[0],
369 ((PyMethodDescrObject *)func)->d_common.d_type,
370 args+1, nargs-1, kwnames);
371 Py_LeaveRecursiveCall();
372 return result;
373}
374
375static PyObject *
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200376method_vectorcall_FASTCALL(
377 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
378{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100379 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200380 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
381 if (method_check_args(func, args, nargs, kwnames)) {
382 return NULL;
383 }
384 _PyCFunctionFast meth = (_PyCFunctionFast)
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100385 method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200386 if (meth == NULL) {
387 return NULL;
388 }
389 PyObject *result = meth(args[0], args+1, nargs-1);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100390 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200391 return result;
392}
393
394static PyObject *
395method_vectorcall_FASTCALL_KEYWORDS(
396 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
397{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100398 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200399 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
400 if (method_check_args(func, args, nargs, NULL)) {
401 return NULL;
402 }
403 _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100404 method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200405 if (meth == NULL) {
406 return NULL;
407 }
408 PyObject *result = meth(args[0], args+1, nargs-1, kwnames);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100409 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200410 return result;
411}
412
413static PyObject *
414method_vectorcall_NOARGS(
415 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
416{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100417 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200418 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
419 if (method_check_args(func, args, nargs, kwnames)) {
420 return NULL;
421 }
422 if (nargs != 1) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100423 PyObject *funcstr = _PyObject_FunctionStr(func);
424 if (funcstr != NULL) {
425 PyErr_Format(PyExc_TypeError,
426 "%U takes no arguments (%zd given)", funcstr, nargs-1);
427 Py_DECREF(funcstr);
428 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200429 return NULL;
430 }
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100431 PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200432 if (meth == NULL) {
433 return NULL;
434 }
435 PyObject *result = meth(args[0], NULL);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100436 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200437 return result;
438}
439
440static PyObject *
441method_vectorcall_O(
442 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
443{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100444 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200445 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
446 if (method_check_args(func, args, nargs, kwnames)) {
447 return NULL;
448 }
449 if (nargs != 2) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100450 PyObject *funcstr = _PyObject_FunctionStr(func);
451 if (funcstr != NULL) {
452 PyErr_Format(PyExc_TypeError,
453 "%U takes exactly one argument (%zd given)",
454 funcstr, nargs-1);
455 Py_DECREF(funcstr);
456 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200457 return NULL;
458 }
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100459 PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200460 if (meth == NULL) {
461 return NULL;
462 }
463 PyObject *result = meth(args[0], args[1]);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100464 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200465 return result;
466}
467
468
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200469/* Instances of classmethod_descriptor are unlikely to be called directly.
470 For one, the analogous class "classmethod" (for Python classes) is not
471 callable. Second, users are not likely to access a classmethod_descriptor
472 directly, since it means pulling it from the class __dict__.
473
474 This is just an excuse to say that this doesn't need to be optimized:
475 we implement this simply by calling __get__ and then calling the result.
476*/
Tim Peters6d6c1a32001-08-02 04:15:00 +0000477static PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000478classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 PyObject *kwds)
Tim Petersbca1cbc2002-12-09 22:56:13 +0000480{
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200481 Py_ssize_t argc = PyTuple_GET_SIZE(args);
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400482 if (argc < 1) {
483 PyErr_Format(PyExc_TypeError,
484 "descriptor '%V' of '%.100s' "
485 "object needs an argument",
486 descr_name((PyDescrObject *)descr), "?",
487 PyDescr_TYPE(descr)->tp_name);
488 return NULL;
489 }
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200490 PyObject *self = PyTuple_GET_ITEM(args, 0);
491 PyObject *bound = classmethod_get(descr, NULL, self);
492 if (bound == NULL) {
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400493 return NULL;
494 }
Petr Viktorinffd97532020-02-11 17:46:57 +0100495 PyObject *res = PyObject_VectorcallDict(bound, _PyTuple_ITEMS(args)+1,
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200496 argc-1, kwds);
497 Py_DECREF(bound);
498 return res;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000499}
500
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300501Py_LOCAL_INLINE(PyObject *)
502wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self,
503 PyObject *args, PyObject *kwds)
504{
505 wrapperfunc wrapper = descr->d_base->wrapper;
506
507 if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
Serhiy Storchaka1c607152018-11-27 21:34:27 +0200508 wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300509 return (*wk)(self, args, descr->d_wrapped, kwds);
510 }
511
512 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) {
513 PyErr_Format(PyExc_TypeError,
514 "wrapper %s() takes no keyword arguments",
515 descr->d_base->name);
516 return NULL;
517 }
518 return (*wrapper)(self, args, descr->d_wrapped);
519}
520
Tim Petersbca1cbc2002-12-09 22:56:13 +0000521static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000522wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
523{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300525 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 /* Make sure that the first argument is acceptable as 'self' */
528 assert(PyTuple_Check(args));
529 argc = PyTuple_GET_SIZE(args);
530 if (argc < 1) {
531 PyErr_Format(PyExc_TypeError,
532 "descriptor '%V' of '%.100s' "
533 "object needs an argument",
534 descr_name((PyDescrObject *)descr), "?",
535 PyDescr_TYPE(descr)->tp_name);
536 return NULL;
537 }
538 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200539 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200540 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 PyErr_Format(PyExc_TypeError,
542 "descriptor '%V' "
543 "requires a '%.100s' object "
544 "but received a '%.100s'",
545 descr_name((PyDescrObject *)descr), "?",
546 PyDescr_TYPE(descr)->tp_name,
Victor Stinner58ac7002020-02-07 03:04:21 +0100547 Py_TYPE(self)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 return NULL;
549 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000550
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300551 args = PyTuple_GetSlice(args, 1, argc);
552 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000553 return NULL;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300554 }
555 result = wrapperdescr_raw_call(descr, self, args, kwds);
556 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000558}
559
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300560
Tim Peters6d6c1a32001-08-02 04:15:00 +0000561static PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000562method_get_doc(PyMethodDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000563{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800564 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800565}
566
567static PyObject *
568method_get_text_signature(PyMethodDescrObject *descr, void *closure)
569{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800570 return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000571}
572
Antoine Pitrou9d574812011-12-12 13:47:25 +0100573static PyObject *
574calculate_qualname(PyDescrObject *descr)
575{
576 PyObject *type_qualname, *res;
577 _Py_IDENTIFIER(__qualname__);
578
579 if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) {
580 PyErr_SetString(PyExc_TypeError,
581 "<descriptor>.__name__ is not a unicode object");
582 return NULL;
583 }
584
585 type_qualname = _PyObject_GetAttrId((PyObject *)descr->d_type,
586 &PyId___qualname__);
587 if (type_qualname == NULL)
588 return NULL;
589
590 if (!PyUnicode_Check(type_qualname)) {
591 PyErr_SetString(PyExc_TypeError, "<descriptor>.__objclass__."
592 "__qualname__ is not a unicode object");
593 Py_XDECREF(type_qualname);
594 return NULL;
595 }
596
597 res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name);
598 Py_DECREF(type_qualname);
599 return res;
600}
601
602static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200603descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +0100604{
605 if (descr->d_qualname == NULL)
606 descr->d_qualname = calculate_qualname(descr);
607 Py_XINCREF(descr->d_qualname);
608 return descr->d_qualname;
609}
610
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100611static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530612descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100613{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200614 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
615 PyDescr_TYPE(descr), PyDescr_NAME(descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100616}
617
618static PyMethodDef descr_methods[] = {
619 {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL},
620 {NULL, NULL}
621};
622
Guido van Rossum6f799372001-09-20 20:46:19 +0000623static PyMemberDef descr_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
625 {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
626 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000627};
628
Guido van Rossum32d34c82001-09-20 21:45:26 +0000629static PyGetSetDef method_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 {"__doc__", (getter)method_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100631 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800632 {"__text_signature__", (getter)method_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 {0}
Guido van Rossum6f799372001-09-20 20:46:19 +0000634};
635
636static PyObject *
637member_get_doc(PyMemberDescrObject *descr, void *closure)
638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 if (descr->d_member->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200640 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 }
642 return PyUnicode_FromString(descr->d_member->doc);
Guido van Rossum6f799372001-09-20 20:46:19 +0000643}
644
Guido van Rossum32d34c82001-09-20 21:45:26 +0000645static PyGetSetDef member_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000646 {"__doc__", (getter)member_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100647 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000649};
650
651static PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000652getset_get_doc(PyGetSetDescrObject *descr, void *closure)
653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 if (descr->d_getset->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200655 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 }
657 return PyUnicode_FromString(descr->d_getset->doc);
Guido van Rossum32d34c82001-09-20 21:45:26 +0000658}
659
660static PyGetSetDef getset_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 {"__doc__", (getter)getset_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100662 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 {0}
Guido van Rossum32d34c82001-09-20 21:45:26 +0000664};
665
666static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000667wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000668{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800669 return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800670}
671
672static PyObject *
673wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
674{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800675 return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000676}
677
Armin Rigoc6686b72005-11-07 08:38:00 +0000678static PyGetSetDef wrapperdescr_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 {"__doc__", (getter)wrapperdescr_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100680 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800681 {"__text_signature__", (getter)wrapperdescr_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000683};
684
Guido van Rossum048eb752001-10-02 21:24:57 +0000685static int
686descr_traverse(PyObject *self, visitproc visit, void *arg)
687{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 PyDescrObject *descr = (PyDescrObject *)self;
689 Py_VISIT(descr->d_type);
690 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000691}
692
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000693PyTypeObject PyMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 PyVarObject_HEAD_INIT(&PyType_Type, 0)
695 "method_descriptor",
696 sizeof(PyMethodDescrObject),
697 0,
698 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200699 offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 0, /* tp_getattr */
701 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200702 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 (reprfunc)method_repr, /* tp_repr */
704 0, /* tp_as_number */
705 0, /* tp_as_sequence */
706 0, /* tp_as_mapping */
707 0, /* tp_hash */
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200708 PyVectorcall_Call, /* tp_call */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 0, /* tp_str */
710 PyObject_GenericGetAttr, /* tp_getattro */
711 0, /* tp_setattro */
712 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200713 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Petr Viktorinffd97532020-02-11 17:46:57 +0100714 Py_TPFLAGS_HAVE_VECTORCALL |
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200715 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 0, /* tp_doc */
717 descr_traverse, /* tp_traverse */
718 0, /* tp_clear */
719 0, /* tp_richcompare */
720 0, /* tp_weaklistoffset */
721 0, /* tp_iter */
722 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100723 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 descr_members, /* tp_members */
725 method_getset, /* tp_getset */
726 0, /* tp_base */
727 0, /* tp_dict */
728 (descrgetfunc)method_get, /* tp_descr_get */
729 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000730};
731
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000732/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000733PyTypeObject PyClassMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 PyVarObject_HEAD_INIT(&PyType_Type, 0)
735 "classmethod_descriptor",
736 sizeof(PyMethodDescrObject),
737 0,
738 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200739 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 0, /* tp_getattr */
741 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200742 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 (reprfunc)method_repr, /* tp_repr */
744 0, /* tp_as_number */
745 0, /* tp_as_sequence */
746 0, /* tp_as_mapping */
747 0, /* tp_hash */
748 (ternaryfunc)classmethoddescr_call, /* tp_call */
749 0, /* tp_str */
750 PyObject_GenericGetAttr, /* tp_getattro */
751 0, /* tp_setattro */
752 0, /* tp_as_buffer */
753 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
754 0, /* tp_doc */
755 descr_traverse, /* tp_traverse */
756 0, /* tp_clear */
757 0, /* tp_richcompare */
758 0, /* tp_weaklistoffset */
759 0, /* tp_iter */
760 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100761 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 descr_members, /* tp_members */
763 method_getset, /* tp_getset */
764 0, /* tp_base */
765 0, /* tp_dict */
766 (descrgetfunc)classmethod_get, /* tp_descr_get */
767 0, /* tp_descr_set */
Tim Petersbca1cbc2002-12-09 22:56:13 +0000768};
769
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000770PyTypeObject PyMemberDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 PyVarObject_HEAD_INIT(&PyType_Type, 0)
772 "member_descriptor",
773 sizeof(PyMemberDescrObject),
774 0,
775 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200776 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000777 0, /* tp_getattr */
778 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200779 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 (reprfunc)member_repr, /* tp_repr */
781 0, /* tp_as_number */
782 0, /* tp_as_sequence */
783 0, /* tp_as_mapping */
784 0, /* tp_hash */
785 0, /* tp_call */
786 0, /* tp_str */
787 PyObject_GenericGetAttr, /* tp_getattro */
788 0, /* tp_setattro */
789 0, /* tp_as_buffer */
790 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
791 0, /* tp_doc */
792 descr_traverse, /* tp_traverse */
793 0, /* tp_clear */
794 0, /* tp_richcompare */
795 0, /* tp_weaklistoffset */
796 0, /* tp_iter */
797 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100798 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 descr_members, /* tp_members */
800 member_getset, /* tp_getset */
801 0, /* tp_base */
802 0, /* tp_dict */
803 (descrgetfunc)member_get, /* tp_descr_get */
804 (descrsetfunc)member_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000805};
806
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000807PyTypeObject PyGetSetDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 PyVarObject_HEAD_INIT(&PyType_Type, 0)
809 "getset_descriptor",
810 sizeof(PyGetSetDescrObject),
811 0,
812 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200813 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000814 0, /* tp_getattr */
815 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200816 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 (reprfunc)getset_repr, /* tp_repr */
818 0, /* tp_as_number */
819 0, /* tp_as_sequence */
820 0, /* tp_as_mapping */
821 0, /* tp_hash */
822 0, /* tp_call */
823 0, /* tp_str */
824 PyObject_GenericGetAttr, /* tp_getattro */
825 0, /* tp_setattro */
826 0, /* tp_as_buffer */
827 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
828 0, /* tp_doc */
829 descr_traverse, /* tp_traverse */
830 0, /* tp_clear */
831 0, /* tp_richcompare */
832 0, /* tp_weaklistoffset */
833 0, /* tp_iter */
834 0, /* tp_iternext */
835 0, /* tp_methods */
836 descr_members, /* tp_members */
837 getset_getset, /* tp_getset */
838 0, /* tp_base */
839 0, /* tp_dict */
840 (descrgetfunc)getset_get, /* tp_descr_get */
841 (descrsetfunc)getset_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000842};
843
Guido van Rossumf4593e02001-10-03 12:09:30 +0000844PyTypeObject PyWrapperDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 PyVarObject_HEAD_INIT(&PyType_Type, 0)
846 "wrapper_descriptor",
847 sizeof(PyWrapperDescrObject),
848 0,
849 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200850 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000851 0, /* tp_getattr */
852 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200853 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 (reprfunc)wrapperdescr_repr, /* tp_repr */
855 0, /* tp_as_number */
856 0, /* tp_as_sequence */
857 0, /* tp_as_mapping */
858 0, /* tp_hash */
859 (ternaryfunc)wrapperdescr_call, /* tp_call */
860 0, /* tp_str */
861 PyObject_GenericGetAttr, /* tp_getattro */
862 0, /* tp_setattro */
863 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200864 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
865 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000866 0, /* tp_doc */
867 descr_traverse, /* tp_traverse */
868 0, /* tp_clear */
869 0, /* tp_richcompare */
870 0, /* tp_weaklistoffset */
871 0, /* tp_iter */
872 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100873 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 descr_members, /* tp_members */
875 wrapperdescr_getset, /* tp_getset */
876 0, /* tp_base */
877 0, /* tp_dict */
878 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
879 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000880};
881
882static PyDescrObject *
Jeremy Hyltonaf68c872005-12-10 18:50:16 +0000883descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000885 PyDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000887 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
888 if (descr != NULL) {
889 Py_XINCREF(type);
890 descr->d_type = type;
891 descr->d_name = PyUnicode_InternFromString(name);
892 if (descr->d_name == NULL) {
893 Py_DECREF(descr);
894 descr = NULL;
895 }
Benjamin Petersonf2fe7f02011-12-17 08:02:20 -0500896 else {
897 descr->d_qualname = NULL;
898 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 }
900 return descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000901}
902
903PyObject *
904PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
905{
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200906 /* Figure out correct vectorcall function to use */
907 vectorcallfunc vectorcall;
Petr Viktorine1becf42020-05-07 15:39:59 +0200908 switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS |
909 METH_O | METH_KEYWORDS | METH_METHOD))
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200910 {
911 case METH_VARARGS:
912 vectorcall = method_vectorcall_VARARGS;
913 break;
914 case METH_VARARGS | METH_KEYWORDS:
915 vectorcall = method_vectorcall_VARARGS_KEYWORDS;
916 break;
917 case METH_FASTCALL:
918 vectorcall = method_vectorcall_FASTCALL;
919 break;
920 case METH_FASTCALL | METH_KEYWORDS:
921 vectorcall = method_vectorcall_FASTCALL_KEYWORDS;
922 break;
923 case METH_NOARGS:
924 vectorcall = method_vectorcall_NOARGS;
925 break;
926 case METH_O:
927 vectorcall = method_vectorcall_O;
928 break;
Petr Viktorine1becf42020-05-07 15:39:59 +0200929 case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
930 vectorcall = method_vectorcall_FASTCALL_KEYWORDS_METHOD;
931 break;
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200932 default:
Victor Stinnerc7d2d692020-03-12 08:38:11 +0100933 PyErr_Format(PyExc_SystemError,
934 "%s() method: bad call flags", method->ml_name);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200935 return NULL;
936 }
937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 PyMethodDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
941 type, method->ml_name);
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200942 if (descr != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 descr->d_method = method;
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200944 descr->vectorcall = vectorcall;
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200945 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000947}
948
949PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000950PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 PyMethodDescrObject *descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
955 type, method->ml_name);
956 if (descr != NULL)
957 descr->d_method = method;
958 return (PyObject *)descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000959}
960
961PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000962PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 PyMemberDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
967 type, member->name);
968 if (descr != NULL)
969 descr->d_member = member;
970 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000971}
972
973PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000974PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 PyGetSetDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
979 type, getset->name);
980 if (descr != NULL)
981 descr->d_getset = getset;
982 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000983}
984
985PyObject *
986PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
991 type, base->name);
992 if (descr != NULL) {
993 descr->d_base = base;
994 descr->d_wrapped = wrapped;
995 }
996 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000997}
998
Tim Peters6d6c1a32001-08-02 04:15:00 +0000999
Victor Stinner0db176f2012-04-16 00:16:30 +02001000/* --- mappingproxy: read-only proxy for mappings --- */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001001
1002/* This has no reason to be in this file except that adding new files is a
1003 bit of a pain */
1004
1005typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 PyObject_HEAD
Victor Stinner0db176f2012-04-16 00:16:30 +02001007 PyObject *mapping;
1008} mappingproxyobject;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001009
Martin v. Löwis18e16552006-02-15 17:27:45 +00001010static Py_ssize_t
Victor Stinner0db176f2012-04-16 00:16:30 +02001011mappingproxy_len(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001012{
Victor Stinner0db176f2012-04-16 00:16:30 +02001013 return PyObject_Size(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001014}
1015
1016static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001017mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001018{
Victor Stinner0db176f2012-04-16 00:16:30 +02001019 return PyObject_GetItem(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001020}
1021
Victor Stinner0db176f2012-04-16 00:16:30 +02001022static PyMappingMethods mappingproxy_as_mapping = {
1023 (lenfunc)mappingproxy_len, /* mp_length */
1024 (binaryfunc)mappingproxy_getitem, /* mp_subscript */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 0, /* mp_ass_subscript */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001026};
1027
Brandt Bucher4663f662020-03-07 11:03:09 -08001028static PyObject *
1029mappingproxy_or(PyObject *left, PyObject *right)
1030{
1031 if (PyObject_TypeCheck(left, &PyDictProxy_Type)) {
1032 left = ((mappingproxyobject*)left)->mapping;
1033 }
1034 if (PyObject_TypeCheck(right, &PyDictProxy_Type)) {
1035 right = ((mappingproxyobject*)right)->mapping;
1036 }
1037 return PyNumber_Or(left, right);
1038}
1039
1040static PyObject *
1041mappingproxy_ior(PyObject *self, PyObject *Py_UNUSED(other))
1042{
1043 return PyErr_Format(PyExc_TypeError,
1044 "'|=' is not supported by %s; use '|' instead", Py_TYPE(self)->tp_name);
1045}
1046
1047static PyNumberMethods mappingproxy_as_number = {
1048 .nb_or = mappingproxy_or,
1049 .nb_inplace_or = mappingproxy_ior,
1050};
1051
Tim Peters6d6c1a32001-08-02 04:15:00 +00001052static int
Victor Stinner0db176f2012-04-16 00:16:30 +02001053mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001054{
Victor Stinner0db176f2012-04-16 00:16:30 +02001055 if (PyDict_CheckExact(pp->mapping))
1056 return PyDict_Contains(pp->mapping, key);
1057 else
1058 return PySequence_Contains(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001059}
1060
Victor Stinner0db176f2012-04-16 00:16:30 +02001061static PySequenceMethods mappingproxy_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 0, /* sq_length */
1063 0, /* sq_concat */
1064 0, /* sq_repeat */
1065 0, /* sq_item */
1066 0, /* sq_slice */
1067 0, /* sq_ass_item */
1068 0, /* sq_ass_slice */
Victor Stinner0db176f2012-04-16 00:16:30 +02001069 (objobjproc)mappingproxy_contains, /* sq_contains */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 0, /* sq_inplace_concat */
1071 0, /* sq_inplace_repeat */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001072};
1073
1074static PyObject *
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001075mappingproxy_get(mappingproxyobject *pp, PyObject *const *args, Py_ssize_t nargs)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001076{
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001077 /* newargs: mapping, key, default=None */
1078 PyObject *newargs[3];
1079 newargs[0] = pp->mapping;
1080 newargs[2] = Py_None;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001081
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001082 if (!_PyArg_UnpackStack(args, nargs, "get", 1, 2,
1083 &newargs[1], &newargs[2]))
1084 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 return NULL;
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001086 }
1087 _Py_IDENTIFIER(get);
1088 return _PyObject_VectorcallMethodId(&PyId_get, newargs,
1089 3 | PY_VECTORCALL_ARGUMENTS_OFFSET,
1090 NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001091}
1092
1093static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301094mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001095{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001096 _Py_IDENTIFIER(keys);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001097 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_keys);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001098}
1099
1100static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301101mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001102{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001103 _Py_IDENTIFIER(values);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001104 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_values);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001105}
1106
1107static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301108mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001109{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001110 _Py_IDENTIFIER(items);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001111 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_items);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001112}
1113
1114static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301115mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001116{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001117 _Py_IDENTIFIER(copy);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001118 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_copy);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001119}
1120
Victor Stinner0db176f2012-04-16 00:16:30 +02001121/* WARNING: mappingproxy methods must not give access
1122 to the underlying mapping */
1123
1124static PyMethodDef mappingproxy_methods[] = {
Zackery Spytz43d564c2019-08-13 23:51:06 -06001125 {"get", (PyCFunction)(void(*)(void))mappingproxy_get, METH_FASTCALL,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d."
Victor Stinner0db176f2012-04-16 00:16:30 +02001127 " d defaults to None.")},
1128 {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 PyDoc_STR("D.keys() -> list of D's keys")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001130 {"values", (PyCFunction)mappingproxy_values, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 PyDoc_STR("D.values() -> list of D's values")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001132 {"items", (PyCFunction)mappingproxy_items, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001134 {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 PyDoc_STR("D.copy() -> a shallow copy of D")},
Guido van Rossum48b069a2020-04-07 09:50:06 -07001136 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS,
1137 PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001139};
1140
1141static void
Victor Stinner0db176f2012-04-16 00:16:30 +02001142mappingproxy_dealloc(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 _PyObject_GC_UNTRACK(pp);
Victor Stinner0db176f2012-04-16 00:16:30 +02001145 Py_DECREF(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 PyObject_GC_Del(pp);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001147}
1148
1149static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001150mappingproxy_getiter(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001151{
Victor Stinner0db176f2012-04-16 00:16:30 +02001152 return PyObject_GetIter(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001153}
1154
Neil Schemenauer26775122001-10-21 22:26:43 +00001155static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001156mappingproxy_str(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001157{
Victor Stinner0db176f2012-04-16 00:16:30 +02001158 return PyObject_Str(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001159}
1160
Ezio Melottiac53ab62010-12-18 14:59:43 +00001161static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001162mappingproxy_repr(mappingproxyobject *pp)
Ezio Melottiac53ab62010-12-18 14:59:43 +00001163{
Victor Stinner0db176f2012-04-16 00:16:30 +02001164 return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping);
Ezio Melottiac53ab62010-12-18 14:59:43 +00001165}
1166
Guido van Rossum048eb752001-10-02 21:24:57 +00001167static int
Victor Stinner0db176f2012-04-16 00:16:30 +02001168mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
Guido van Rossum048eb752001-10-02 21:24:57 +00001169{
Victor Stinner0db176f2012-04-16 00:16:30 +02001170 mappingproxyobject *pp = (mappingproxyobject *)self;
1171 Py_VISIT(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001173}
1174
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001175static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001176mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op)
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001177{
Victor Stinner0db176f2012-04-16 00:16:30 +02001178 return PyObject_RichCompare(v->mapping, w, op);
1179}
1180
1181static int
1182mappingproxy_check_mapping(PyObject *mapping)
1183{
1184 if (!PyMapping_Check(mapping)
1185 || PyList_Check(mapping)
1186 || PyTuple_Check(mapping)) {
1187 PyErr_Format(PyExc_TypeError,
1188 "mappingproxy() argument must be a mapping, not %s",
1189 Py_TYPE(mapping)->tp_name);
1190 return -1;
1191 }
1192 return 0;
1193}
1194
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001195/*[clinic input]
1196@classmethod
1197mappingproxy.__new__ as mappingproxy_new
Victor Stinner0db176f2012-04-16 00:16:30 +02001198
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001199 mapping: object
1200
1201[clinic start generated code]*/
1202
1203static PyObject *
1204mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping)
1205/*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/
1206{
1207 mappingproxyobject *mappingproxy;
Victor Stinner0db176f2012-04-16 00:16:30 +02001208
1209 if (mappingproxy_check_mapping(mapping) == -1)
1210 return NULL;
1211
1212 mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
1213 if (mappingproxy == NULL)
1214 return NULL;
1215 Py_INCREF(mapping);
1216 mappingproxy->mapping = mapping;
1217 _PyObject_GC_TRACK(mappingproxy);
1218 return (PyObject *)mappingproxy;
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001219}
1220
Tim Peters6d6c1a32001-08-02 04:15:00 +00001221PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001222PyDictProxy_New(PyObject *mapping)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001223{
Victor Stinner0db176f2012-04-16 00:16:30 +02001224 mappingproxyobject *pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001225
Victor Stinner0db176f2012-04-16 00:16:30 +02001226 if (mappingproxy_check_mapping(mapping) == -1)
1227 return NULL;
1228
1229 pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 if (pp != NULL) {
Victor Stinner0db176f2012-04-16 00:16:30 +02001231 Py_INCREF(mapping);
1232 pp->mapping = mapping;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 _PyObject_GC_TRACK(pp);
1234 }
1235 return (PyObject *)pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001236}
1237
1238
1239/* --- Wrapper object for "slot" methods --- */
1240
1241/* This has no reason to be in this file except that adding new files is a
1242 bit of a pain */
1243
1244typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 PyObject_HEAD
1246 PyWrapperDescrObject *descr;
1247 PyObject *self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001248} wrapperobject;
1249
Andy Lesterdffe4c02020-03-04 07:15:20 -06001250#define Wrapper_Check(v) Py_IS_TYPE(v, &_PyMethodWrapper_Type)
Mark Dickinson211c6252009-02-01 10:28:51 +00001251
Tim Peters6d6c1a32001-08-02 04:15:00 +00001252static void
1253wrapper_dealloc(wrapperobject *wp)
1254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 PyObject_GC_UnTrack(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001256 Py_TRASHCAN_BEGIN(wp, wrapper_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 Py_XDECREF(wp->descr);
1258 Py_XDECREF(wp->self);
1259 PyObject_GC_Del(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001260 Py_TRASHCAN_END
Tim Peters6d6c1a32001-08-02 04:15:00 +00001261}
1262
Mark Dickinson211c6252009-02-01 10:28:51 +00001263static PyObject *
1264wrapper_richcompare(PyObject *a, PyObject *b, int op)
Armin Rigoc6686b72005-11-07 08:38:00 +00001265{
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001266 wrapperobject *wa, *wb;
1267 int eq;
Mark Dickinson211c6252009-02-01 10:28:51 +00001268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +00001270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 /* both arguments should be wrapperobjects */
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001272 if ((op != Py_EQ && op != Py_NE)
1273 || !Wrapper_Check(a) || !Wrapper_Check(b))
1274 {
stratakise8b19652017-11-02 11:32:54 +01001275 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 }
Mark Dickinson211c6252009-02-01 10:28:51 +00001277
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001278 wa = (wrapperobject *)a;
1279 wb = (wrapperobject *)b;
1280 eq = (wa->descr == wb->descr && wa->self == wb->self);
1281 if (eq == (op == Py_EQ)) {
1282 Py_RETURN_TRUE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 }
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001284 else {
1285 Py_RETURN_FALSE;
1286 }
Armin Rigoc6686b72005-11-07 08:38:00 +00001287}
1288
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001289static Py_hash_t
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001290wrapper_hash(wrapperobject *wp)
1291{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001292 Py_hash_t x, y;
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001293 x = _Py_HashPointer(wp->self);
1294 y = _Py_HashPointer(wp->descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 x = x ^ y;
1296 if (x == -1)
1297 x = -2;
1298 return x;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001299}
1300
Armin Rigoc6686b72005-11-07 08:38:00 +00001301static PyObject *
1302wrapper_repr(wrapperobject *wp)
1303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
1305 wp->descr->d_base->name,
Victor Stinner58ac7002020-02-07 03:04:21 +01001306 Py_TYPE(wp->self)->tp_name,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 wp->self);
Armin Rigoc6686b72005-11-07 08:38:00 +00001308}
1309
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001310static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301311wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001312{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02001313 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
1314 wp->self, PyDescr_NAME(wp->descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001315}
1316
1317static PyMethodDef wrapper_methods[] = {
1318 {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
1319 {NULL, NULL}
1320};
1321
Armin Rigoc6686b72005-11-07 08:38:00 +00001322static PyMemberDef wrapper_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
1324 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001325};
1326
1327static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001328wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored))
Armin Rigoc6686b72005-11-07 08:38:00 +00001329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
Armin Rigoc6686b72005-11-07 08:38:00 +00001331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 Py_INCREF(c);
1333 return c;
Armin Rigoc6686b72005-11-07 08:38:00 +00001334}
1335
1336static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001337wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 const char *s = wp->descr->d_base->name;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 return PyUnicode_FromString(s);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001342}
1343
1344static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001345wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001346{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001347 return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -08001348}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001349
Larry Hastings5c661892014-01-24 06:17:25 -08001350static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001351wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
Larry Hastings5c661892014-01-24 06:17:25 -08001352{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001353 return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001354}
1355
Antoine Pitrou9d574812011-12-12 13:47:25 +01001356static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001357wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +01001358{
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001359 return descr_get_qualname((PyDescrObject *)wp->descr, NULL);
Antoine Pitrou9d574812011-12-12 13:47:25 +01001360}
1361
Guido van Rossum32d34c82001-09-20 21:45:26 +00001362static PyGetSetDef wrapper_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 {"__objclass__", (getter)wrapper_objclass},
1364 {"__name__", (getter)wrapper_name},
Antoine Pitrou9d574812011-12-12 13:47:25 +01001365 {"__qualname__", (getter)wrapper_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 {"__doc__", (getter)wrapper_doc},
Larry Hastings5c661892014-01-24 06:17:25 -08001367 {"__text_signature__", (getter)wrapper_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001369};
1370
1371static PyObject *
1372wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
1373{
Serhiy Storchaka5e02c782017-09-21 14:25:36 +03001374 return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001375}
1376
Guido van Rossum048eb752001-10-02 21:24:57 +00001377static int
1378wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 wrapperobject *wp = (wrapperobject *)self;
1381 Py_VISIT(wp->descr);
1382 Py_VISIT(wp->self);
1383 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001384}
1385
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001386PyTypeObject _PyMethodWrapper_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1388 "method-wrapper", /* tp_name */
1389 sizeof(wrapperobject), /* tp_basicsize */
1390 0, /* tp_itemsize */
1391 /* methods */
1392 (destructor)wrapper_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001393 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 0, /* tp_getattr */
1395 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001396 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 (reprfunc)wrapper_repr, /* tp_repr */
1398 0, /* tp_as_number */
1399 0, /* tp_as_sequence */
1400 0, /* tp_as_mapping */
1401 (hashfunc)wrapper_hash, /* tp_hash */
1402 (ternaryfunc)wrapper_call, /* tp_call */
1403 0, /* tp_str */
1404 PyObject_GenericGetAttr, /* tp_getattro */
1405 0, /* tp_setattro */
1406 0, /* tp_as_buffer */
1407 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1408 0, /* tp_doc */
1409 wrapper_traverse, /* tp_traverse */
1410 0, /* tp_clear */
1411 wrapper_richcompare, /* tp_richcompare */
1412 0, /* tp_weaklistoffset */
1413 0, /* tp_iter */
1414 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001415 wrapper_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 wrapper_members, /* tp_members */
1417 wrapper_getsets, /* tp_getset */
1418 0, /* tp_base */
1419 0, /* tp_dict */
1420 0, /* tp_descr_get */
1421 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001422};
1423
1424PyObject *
1425PyWrapper_New(PyObject *d, PyObject *self)
1426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 wrapperobject *wp;
1428 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1431 descr = (PyWrapperDescrObject *)d;
Victor Stinner3249dec2011-05-01 23:19:15 +02001432 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +02001433 (PyObject *)PyDescr_TYPE(descr)));
Tim Peters6d6c1a32001-08-02 04:15:00 +00001434
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001435 wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 if (wp != NULL) {
1437 Py_INCREF(descr);
1438 wp->descr = descr;
1439 Py_INCREF(self);
1440 wp->self = self;
1441 _PyObject_GC_TRACK(wp);
1442 }
1443 return (PyObject *)wp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001444}
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001445
1446
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001447/* A built-in 'property' type */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001448
1449/*
Serhiy Storchakad741a882015-06-11 00:06:39 +03001450class property(object):
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
1453 if doc is None and fget is not None and hasattr(fget, "__doc__"):
Serhiy Storchakad741a882015-06-11 00:06:39 +03001454 doc = fget.__doc__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 self.__get = fget
1456 self.__set = fset
1457 self.__del = fdel
1458 self.__doc__ = doc
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 def __get__(self, inst, type=None):
1461 if inst is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001462 return self
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 if self.__get is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001464 raise AttributeError, "unreadable attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 return self.__get(inst)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 def __set__(self, inst, value):
1468 if self.__set is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001469 raise AttributeError, "can't set attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 return self.__set(inst, value)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 def __delete__(self, inst):
1473 if self.__del is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001474 raise AttributeError, "can't delete attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 return self.__del(inst)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001476
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001477*/
1478
1479typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 PyObject_HEAD
1481 PyObject *prop_get;
1482 PyObject *prop_set;
1483 PyObject *prop_del;
1484 PyObject *prop_doc;
1485 int getter_doc;
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001486} propertyobject;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001487
Christian Heimes0449f632007-12-15 01:27:15 +00001488static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
Benjamin Peterson93964832010-06-28 03:07:10 +00001489 PyObject *);
Christian Heimes0449f632007-12-15 01:27:15 +00001490
Tim Peters66c1a522001-09-24 21:17:50 +00001491static PyMemberDef property_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
1493 {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
1494 {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
Raymond Hettingereac503a2015-05-13 01:09:59 -07001495 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 {0}
Tim Peters66c1a522001-09-24 21:17:50 +00001497};
1498
Christian Heimes0449f632007-12-15 01:27:15 +00001499
Guido van Rossum58da9312007-11-10 23:39:45 +00001500PyDoc_STRVAR(getter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 "Descriptor to change the getter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001502
Neal Norwitz32dde222008-04-15 06:43:13 +00001503static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001504property_getter(PyObject *self, PyObject *getter)
1505{
Benjamin Peterson93964832010-06-28 03:07:10 +00001506 return property_copy(self, getter, NULL, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001507}
1508
Christian Heimes0449f632007-12-15 01:27:15 +00001509
Guido van Rossum58da9312007-11-10 23:39:45 +00001510PyDoc_STRVAR(setter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 "Descriptor to change the setter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001512
Neal Norwitz32dde222008-04-15 06:43:13 +00001513static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001514property_setter(PyObject *self, PyObject *setter)
1515{
Benjamin Peterson93964832010-06-28 03:07:10 +00001516 return property_copy(self, NULL, setter, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001517}
1518
Christian Heimes0449f632007-12-15 01:27:15 +00001519
Guido van Rossum58da9312007-11-10 23:39:45 +00001520PyDoc_STRVAR(deleter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 "Descriptor to change the deleter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001522
Neal Norwitz32dde222008-04-15 06:43:13 +00001523static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001524property_deleter(PyObject *self, PyObject *deleter)
1525{
Benjamin Peterson93964832010-06-28 03:07:10 +00001526 return property_copy(self, NULL, NULL, deleter);
Guido van Rossum58da9312007-11-10 23:39:45 +00001527}
1528
1529
Guido van Rossum58da9312007-11-10 23:39:45 +00001530static PyMethodDef property_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 {"getter", property_getter, METH_O, getter_doc},
1532 {"setter", property_setter, METH_O, setter_doc},
1533 {"deleter", property_deleter, METH_O, deleter_doc},
1534 {0}
Guido van Rossum58da9312007-11-10 23:39:45 +00001535};
1536
Tim Peters66c1a522001-09-24 21:17:50 +00001537
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001538static void
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001539property_dealloc(PyObject *self)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001540{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 propertyobject *gs = (propertyobject *)self;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 _PyObject_GC_UNTRACK(self);
1544 Py_XDECREF(gs->prop_get);
1545 Py_XDECREF(gs->prop_set);
1546 Py_XDECREF(gs->prop_del);
1547 Py_XDECREF(gs->prop_doc);
Victor Stinner58ac7002020-02-07 03:04:21 +01001548 Py_TYPE(self)->tp_free(self);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001549}
1550
1551static PyObject *
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001552property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001553{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 if (obj == NULL || obj == Py_None) {
1555 Py_INCREF(self);
1556 return self;
1557 }
Victor Stinnere972c132018-10-01 03:03:22 -07001558
1559 propertyobject *gs = (propertyobject *)self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 if (gs->prop_get == NULL) {
1561 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1562 return NULL;
1563 }
Victor Stinnere972c132018-10-01 03:03:22 -07001564
Petr Viktorinffd97532020-02-11 17:46:57 +01001565 return PyObject_CallOneArg(gs->prop_get, obj);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001566}
1567
1568static int
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001569property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001570{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 propertyobject *gs = (propertyobject *)self;
1572 PyObject *func, *res;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 if (value == NULL)
1575 func = gs->prop_del;
1576 else
1577 func = gs->prop_set;
1578 if (func == NULL) {
1579 PyErr_SetString(PyExc_AttributeError,
1580 value == NULL ?
1581 "can't delete attribute" :
1582 "can't set attribute");
1583 return -1;
1584 }
1585 if (value == NULL)
Petr Viktorinffd97532020-02-11 17:46:57 +01001586 res = PyObject_CallOneArg(func, obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 else
Benjamin Peterson9b955de2010-12-07 04:04:02 +00001588 res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 if (res == NULL)
1590 return -1;
1591 Py_DECREF(res);
1592 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001593}
1594
Christian Heimes0449f632007-12-15 01:27:15 +00001595static PyObject *
Benjamin Peterson93964832010-06-28 03:07:10 +00001596property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
Christian Heimes0449f632007-12-15 01:27:15 +00001597{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 propertyobject *pold = (propertyobject *)old;
Benjamin Peterson93964832010-06-28 03:07:10 +00001599 PyObject *new, *type, *doc;
Christian Heimes0449f632007-12-15 01:27:15 +00001600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 type = PyObject_Type(old);
1602 if (type == NULL)
1603 return NULL;
Christian Heimes0449f632007-12-15 01:27:15 +00001604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 if (get == NULL || get == Py_None) {
1606 Py_XDECREF(get);
1607 get = pold->prop_get ? pold->prop_get : Py_None;
1608 }
1609 if (set == NULL || set == Py_None) {
1610 Py_XDECREF(set);
1611 set = pold->prop_set ? pold->prop_set : Py_None;
1612 }
1613 if (del == NULL || del == Py_None) {
1614 Py_XDECREF(del);
1615 del = pold->prop_del ? pold->prop_del : Py_None;
1616 }
Benjamin Peterson93964832010-06-28 03:07:10 +00001617 if (pold->getter_doc && get != Py_None) {
1618 /* make _init use __doc__ from getter */
1619 doc = Py_None;
1620 }
1621 else {
1622 doc = pold->prop_doc ? pold->prop_doc : Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 }
R. David Murrayb18500d2009-05-04 22:59:07 +00001624
Victor Stinner5abaa2b2016-12-09 16:22:32 +01001625 new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 Py_DECREF(type);
1627 if (new == NULL)
1628 return NULL;
1629 return new;
Christian Heimes0449f632007-12-15 01:27:15 +00001630}
1631
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001632/*[clinic input]
1633property.__init__ as property_init
1634
1635 fget: object(c_default="NULL") = None
1636 function to be used for getting an attribute value
1637 fset: object(c_default="NULL") = None
1638 function to be used for setting an attribute value
1639 fdel: object(c_default="NULL") = None
1640 function to be used for del'ing an attribute
1641 doc: object(c_default="NULL") = None
1642 docstring
1643
1644Property attribute.
1645
1646Typical use is to define a managed attribute x:
1647
1648class C(object):
1649 def getx(self): return self._x
1650 def setx(self, value): self._x = value
1651 def delx(self): del self._x
1652 x = property(getx, setx, delx, "I'm the 'x' property.")
1653
1654Decorators make defining new properties or modifying existing ones easy:
1655
1656class C(object):
1657 @property
1658 def x(self):
1659 "I am the 'x' property."
1660 return self._x
1661 @x.setter
1662 def x(self, value):
1663 self._x = value
1664 @x.deleter
1665 def x(self):
1666 del self._x
1667[clinic start generated code]*/
1668
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001669static int
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001670property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1671 PyObject *fdel, PyObject *doc)
1672/*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001673{
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001674 if (fget == Py_None)
1675 fget = NULL;
1676 if (fset == Py_None)
1677 fset = NULL;
1678 if (fdel == Py_None)
1679 fdel = NULL;
Tim Peters66c1a522001-09-24 21:17:50 +00001680
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001681 Py_XINCREF(fget);
1682 Py_XINCREF(fset);
1683 Py_XINCREF(fdel);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001684 Py_XINCREF(doc);
Christian Heimes0449f632007-12-15 01:27:15 +00001685
Oren Milmand019bc82018-02-13 12:28:33 +02001686 Py_XSETREF(self->prop_get, fget);
1687 Py_XSETREF(self->prop_set, fset);
1688 Py_XSETREF(self->prop_del, fdel);
1689 Py_XSETREF(self->prop_doc, doc);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001690 self->getter_doc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692 /* if no docstring given and the getter has one, use that one */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001693 if ((doc == NULL || doc == Py_None) && fget != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001694 _Py_IDENTIFIER(__doc__);
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001695 PyObject *get_doc;
1696 int rc = _PyObject_LookupAttrId(fget, &PyId___doc__, &get_doc);
1697 if (rc <= 0) {
1698 return rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 }
Andy Lesterdffe4c02020-03-04 07:15:20 -06001700 if (Py_IS_TYPE(self, &PyProperty_Type)) {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001701 Py_XSETREF(self->prop_doc, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 }
1703 else {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001704 /* If this is a property subclass, put __doc__
1705 in dict of the subclass instance instead,
1706 otherwise it gets shadowed by __doc__ in the
1707 class's dict. */
1708 int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc);
1709 Py_DECREF(get_doc);
1710 if (err < 0)
1711 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001712 }
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001713 self->getter_doc = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 }
1715
1716 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001717}
1718
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001719static PyObject *
1720property_get___isabstractmethod__(propertyobject *prop, void *closure)
1721{
1722 int res = _PyObject_IsAbstract(prop->prop_get);
1723 if (res == -1) {
1724 return NULL;
1725 }
1726 else if (res) {
1727 Py_RETURN_TRUE;
1728 }
1729
1730 res = _PyObject_IsAbstract(prop->prop_set);
1731 if (res == -1) {
1732 return NULL;
1733 }
1734 else if (res) {
1735 Py_RETURN_TRUE;
1736 }
1737
1738 res = _PyObject_IsAbstract(prop->prop_del);
1739 if (res == -1) {
1740 return NULL;
1741 }
1742 else if (res) {
1743 Py_RETURN_TRUE;
1744 }
1745 Py_RETURN_FALSE;
1746}
1747
1748static PyGetSetDef property_getsetlist[] = {
1749 {"__isabstractmethod__",
1750 (getter)property_get___isabstractmethod__, NULL,
1751 NULL,
1752 NULL},
1753 {NULL} /* Sentinel */
1754};
1755
Guido van Rossum048eb752001-10-02 21:24:57 +00001756static int
1757property_traverse(PyObject *self, visitproc visit, void *arg)
1758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 propertyobject *pp = (propertyobject *)self;
1760 Py_VISIT(pp->prop_get);
1761 Py_VISIT(pp->prop_set);
1762 Py_VISIT(pp->prop_del);
1763 Py_VISIT(pp->prop_doc);
1764 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001765}
1766
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001767static int
1768property_clear(PyObject *self)
1769{
1770 propertyobject *pp = (propertyobject *)self;
1771 Py_CLEAR(pp->prop_doc);
1772 return 0;
1773}
1774
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001775#include "clinic/descrobject.c.h"
1776
1777PyTypeObject PyDictProxy_Type = {
1778 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1779 "mappingproxy", /* tp_name */
1780 sizeof(mappingproxyobject), /* tp_basicsize */
1781 0, /* tp_itemsize */
1782 /* methods */
1783 (destructor)mappingproxy_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001784 0, /* tp_vectorcall_offset */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001785 0, /* tp_getattr */
1786 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001787 0, /* tp_as_async */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001788 (reprfunc)mappingproxy_repr, /* tp_repr */
Brandt Bucher4663f662020-03-07 11:03:09 -08001789 &mappingproxy_as_number, /* tp_as_number */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001790 &mappingproxy_as_sequence, /* tp_as_sequence */
1791 &mappingproxy_as_mapping, /* tp_as_mapping */
1792 0, /* tp_hash */
1793 0, /* tp_call */
1794 (reprfunc)mappingproxy_str, /* tp_str */
1795 PyObject_GenericGetAttr, /* tp_getattro */
1796 0, /* tp_setattro */
1797 0, /* tp_as_buffer */
1798 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1799 0, /* tp_doc */
1800 mappingproxy_traverse, /* tp_traverse */
1801 0, /* tp_clear */
1802 (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
1803 0, /* tp_weaklistoffset */
1804 (getiterfunc)mappingproxy_getiter, /* tp_iter */
1805 0, /* tp_iternext */
1806 mappingproxy_methods, /* tp_methods */
1807 0, /* tp_members */
1808 0, /* tp_getset */
1809 0, /* tp_base */
1810 0, /* tp_dict */
1811 0, /* tp_descr_get */
1812 0, /* tp_descr_set */
1813 0, /* tp_dictoffset */
1814 0, /* tp_init */
1815 0, /* tp_alloc */
1816 mappingproxy_new, /* tp_new */
1817};
1818
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001819PyTypeObject PyProperty_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1821 "property", /* tp_name */
1822 sizeof(propertyobject), /* tp_basicsize */
1823 0, /* tp_itemsize */
1824 /* methods */
1825 property_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001826 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 0, /* tp_getattr */
1828 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001829 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 0, /* tp_repr */
1831 0, /* tp_as_number */
1832 0, /* tp_as_sequence */
1833 0, /* tp_as_mapping */
1834 0, /* tp_hash */
1835 0, /* tp_call */
1836 0, /* tp_str */
1837 PyObject_GenericGetAttr, /* tp_getattro */
1838 0, /* tp_setattro */
1839 0, /* tp_as_buffer */
1840 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1841 Py_TPFLAGS_BASETYPE, /* tp_flags */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001842 property_init__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 property_traverse, /* tp_traverse */
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001844 (inquiry)property_clear, /* tp_clear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 0, /* tp_richcompare */
1846 0, /* tp_weaklistoffset */
1847 0, /* tp_iter */
1848 0, /* tp_iternext */
1849 property_methods, /* tp_methods */
1850 property_members, /* tp_members */
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001851 property_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 0, /* tp_base */
1853 0, /* tp_dict */
1854 property_descr_get, /* tp_descr_get */
1855 property_descr_set, /* tp_descr_set */
1856 0, /* tp_dictoffset */
1857 property_init, /* tp_init */
1858 PyType_GenericAlloc, /* tp_alloc */
1859 PyType_GenericNew, /* tp_new */
1860 PyObject_GC_Del, /* tp_free */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001861};