blob: fe7ba79770a6ad4e4e4e93f0f35604f987a63d86 [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"
Tim Peters6d6c1a32001-08-02 04:15:00 +00008#include "structmember.h" /* Why is this not included in Python.h? */
9
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 }
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200130 return PyCFunction_NewEx(descr->d_method, type, NULL);
Tim Petersbca1cbc2002-12-09 22:56:13 +0000131}
132
133static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000134method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 if (descr_check((PyDescrObject *)descr, obj, &res))
139 return res;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200140 return PyCFunction_NewEx(descr->d_method, obj, NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000141}
142
143static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000144member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 if (descr_check((PyDescrObject *)descr, obj, &res))
149 return res;
Steve Dowerb82e17e2019-05-23 08:45:22 -0700150
151 if (descr->d_member->flags & READ_RESTRICTED) {
152 if (PySys_Audit("object.__getattr__", "Os",
153 obj ? obj : Py_None, descr->d_member->name) < 0) {
154 return NULL;
155 }
156 }
157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 return PyMember_GetOne((char *)obj, descr->d_member);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000159}
160
161static PyObject *
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000162getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 PyObject *res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 if (descr_check((PyDescrObject *)descr, obj, &res))
167 return res;
168 if (descr->d_getset->get != NULL)
169 return descr->d_getset->get(obj, descr->d_getset->closure);
170 PyErr_Format(PyExc_AttributeError,
171 "attribute '%V' of '%.100s' objects is not readable",
172 descr_name((PyDescrObject *)descr), "?",
173 PyDescr_TYPE(descr)->tp_name);
174 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000175}
176
177static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000178wrapperdescr_get(PyWrapperDescrObject *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 return PyWrapper_New((PyObject *)descr, obj);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000185}
186
187static int
188descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 int *pres)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000190{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 assert(obj != NULL);
192 if (!PyObject_TypeCheck(obj, descr->d_type)) {
193 PyErr_Format(PyExc_TypeError,
194 "descriptor '%V' for '%.100s' objects "
Inada Naoki62f95882019-04-01 17:56:11 +0900195 "doesn't apply to a '%.100s' object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 descr_name(descr), "?",
197 descr->d_type->tp_name,
Victor Stinner58ac7002020-02-07 03:04:21 +0100198 Py_TYPE(obj)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 *pres = -1;
200 return 1;
201 }
202 return 0;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000203}
204
205static int
206member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
207{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
211 return res;
212 return PyMember_SetOne((char *)obj, descr->d_member, value);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000213}
214
215static int
216getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
217{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000218 int res;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
221 return res;
222 if (descr->d_getset->set != NULL)
223 return descr->d_getset->set(obj, value,
224 descr->d_getset->closure);
225 PyErr_Format(PyExc_AttributeError,
226 "attribute '%V' of '%.100s' objects is not writable",
227 descr_name((PyDescrObject *)descr), "?",
228 PyDescr_TYPE(descr)->tp_name);
229 return -1;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000230}
231
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200232
233/* Vectorcall functions for each of the PyMethodDescr calling conventions.
234 *
235 * First, common helpers
236 */
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200237static inline int
238method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
239{
240 assert(!PyErr_Occurred());
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200241 if (nargs < 1) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100242 PyObject *funcstr = _PyObject_FunctionStr(func);
243 if (funcstr != NULL) {
244 PyErr_Format(PyExc_TypeError,
245 "unbound method %U needs an argument", funcstr);
246 Py_DECREF(funcstr);
247 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200248 return -1;
249 }
250 PyObject *self = args[0];
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100251 PyObject *dummy;
252 if (descr_check((PyDescrObject *)func, self, &dummy)) {
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200253 return -1;
254 }
255 if (kwnames && PyTuple_GET_SIZE(kwnames)) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100256 PyObject *funcstr = _PyObject_FunctionStr(func);
257 if (funcstr != NULL) {
258 PyErr_Format(PyExc_TypeError,
259 "%U takes no keyword arguments", funcstr);
260 Py_DECREF(funcstr);
261 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200262 return -1;
263 }
264 return 0;
265}
266
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100267typedef void (*funcptr)(void);
268
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200269static inline funcptr
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100270method_enter_call(PyThreadState *tstate, PyObject *func)
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200271{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100272 if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200273 return NULL;
274 }
275 return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth;
276}
277
278/* Now the actual vectorcall functions */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000279static PyObject *
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200280method_vectorcall_VARARGS(
281 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000282{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100283 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200284 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200285 if (method_check_args(func, args, nargs, kwnames)) {
INADA Naoki5566bbb2017-02-03 07:43:03 +0900286 return NULL;
287 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200288 PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
289 if (argstuple == NULL) {
INADA Naoki5566bbb2017-02-03 07:43:03 +0900290 return NULL;
291 }
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100292 PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200293 if (meth == NULL) {
294 Py_DECREF(argstuple);
295 return NULL;
296 }
297 PyObject *result = meth(args[0], argstuple);
298 Py_DECREF(argstuple);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100299 _Py_LeaveRecursiveCall(tstate);
INADA Naoki5566bbb2017-02-03 07:43:03 +0900300 return result;
301}
302
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200303static PyObject *
304method_vectorcall_VARARGS_KEYWORDS(
305 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
306{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100307 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200308 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
309 if (method_check_args(func, args, nargs, NULL)) {
310 return NULL;
311 }
312 PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
313 if (argstuple == NULL) {
314 return NULL;
315 }
316 PyObject *result = NULL;
317 /* Create a temporary dict for keyword arguments */
318 PyObject *kwdict = NULL;
319 if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) > 0) {
320 kwdict = _PyStack_AsDict(args + nargs, kwnames);
321 if (kwdict == NULL) {
322 goto exit;
323 }
324 }
325 PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords)
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100326 method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200327 if (meth == NULL) {
328 goto exit;
329 }
330 result = meth(args[0], argstuple, kwdict);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100331 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200332exit:
333 Py_DECREF(argstuple);
334 Py_XDECREF(kwdict);
335 return result;
336}
337
338static PyObject *
339method_vectorcall_FASTCALL(
340 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
341{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100342 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200343 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
344 if (method_check_args(func, args, nargs, kwnames)) {
345 return NULL;
346 }
347 _PyCFunctionFast meth = (_PyCFunctionFast)
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100348 method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200349 if (meth == NULL) {
350 return NULL;
351 }
352 PyObject *result = meth(args[0], args+1, nargs-1);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100353 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200354 return result;
355}
356
357static PyObject *
358method_vectorcall_FASTCALL_KEYWORDS(
359 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
360{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100361 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200362 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
363 if (method_check_args(func, args, nargs, NULL)) {
364 return NULL;
365 }
366 _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100367 method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200368 if (meth == NULL) {
369 return NULL;
370 }
371 PyObject *result = meth(args[0], args+1, nargs-1, kwnames);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100372 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200373 return result;
374}
375
376static PyObject *
377method_vectorcall_NOARGS(
378 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
379{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100380 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200381 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
382 if (method_check_args(func, args, nargs, kwnames)) {
383 return NULL;
384 }
385 if (nargs != 1) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100386 PyObject *funcstr = _PyObject_FunctionStr(func);
387 if (funcstr != NULL) {
388 PyErr_Format(PyExc_TypeError,
389 "%U takes no arguments (%zd given)", funcstr, nargs-1);
390 Py_DECREF(funcstr);
391 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200392 return NULL;
393 }
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100394 PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200395 if (meth == NULL) {
396 return NULL;
397 }
398 PyObject *result = meth(args[0], NULL);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100399 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200400 return result;
401}
402
403static PyObject *
404method_vectorcall_O(
405 PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
406{
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100407 PyThreadState *tstate = _PyThreadState_GET();
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200408 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
409 if (method_check_args(func, args, nargs, kwnames)) {
410 return NULL;
411 }
412 if (nargs != 2) {
Jeroen Demeyerbf17d412019-11-05 16:48:04 +0100413 PyObject *funcstr = _PyObject_FunctionStr(func);
414 if (funcstr != NULL) {
415 PyErr_Format(PyExc_TypeError,
416 "%U takes exactly one argument (%zd given)",
417 funcstr, nargs-1);
418 Py_DECREF(funcstr);
419 }
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200420 return NULL;
421 }
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100422 PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200423 if (meth == NULL) {
424 return NULL;
425 }
426 PyObject *result = meth(args[0], args[1]);
Victor Stinnerbe434dc2019-11-05 00:51:22 +0100427 _Py_LeaveRecursiveCall(tstate);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200428 return result;
429}
430
431
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200432/* Instances of classmethod_descriptor are unlikely to be called directly.
433 For one, the analogous class "classmethod" (for Python classes) is not
434 callable. Second, users are not likely to access a classmethod_descriptor
435 directly, since it means pulling it from the class __dict__.
436
437 This is just an excuse to say that this doesn't need to be optimized:
438 we implement this simply by calling __get__ and then calling the result.
439*/
Tim Peters6d6c1a32001-08-02 04:15:00 +0000440static PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000441classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 PyObject *kwds)
Tim Petersbca1cbc2002-12-09 22:56:13 +0000443{
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200444 Py_ssize_t argc = PyTuple_GET_SIZE(args);
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400445 if (argc < 1) {
446 PyErr_Format(PyExc_TypeError,
447 "descriptor '%V' of '%.100s' "
448 "object needs an argument",
449 descr_name((PyDescrObject *)descr), "?",
450 PyDescr_TYPE(descr)->tp_name);
451 return NULL;
452 }
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200453 PyObject *self = PyTuple_GET_ITEM(args, 0);
454 PyObject *bound = classmethod_get(descr, NULL, self);
455 if (bound == NULL) {
Benjamin Peterson7295c6a2012-05-01 09:51:09 -0400456 return NULL;
457 }
Petr Viktorinffd97532020-02-11 17:46:57 +0100458 PyObject *res = PyObject_VectorcallDict(bound, _PyTuple_ITEMS(args)+1,
Jeroen Demeyer3f345c32019-06-07 12:20:24 +0200459 argc-1, kwds);
460 Py_DECREF(bound);
461 return res;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000462}
463
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300464Py_LOCAL_INLINE(PyObject *)
465wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self,
466 PyObject *args, PyObject *kwds)
467{
468 wrapperfunc wrapper = descr->d_base->wrapper;
469
470 if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
Serhiy Storchaka1c607152018-11-27 21:34:27 +0200471 wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300472 return (*wk)(self, args, descr->d_wrapped, kwds);
473 }
474
475 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) {
476 PyErr_Format(PyExc_TypeError,
477 "wrapper %s() takes no keyword arguments",
478 descr->d_base->name);
479 return NULL;
480 }
481 return (*wrapper)(self, args, descr->d_wrapped);
482}
483
Tim Petersbca1cbc2002-12-09 22:56:13 +0000484static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000485wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
486{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 Py_ssize_t argc;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300488 PyObject *self, *result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 /* Make sure that the first argument is acceptable as 'self' */
491 assert(PyTuple_Check(args));
492 argc = PyTuple_GET_SIZE(args);
493 if (argc < 1) {
494 PyErr_Format(PyExc_TypeError,
495 "descriptor '%V' of '%.100s' "
496 "object needs an argument",
497 descr_name((PyDescrObject *)descr), "?",
498 PyDescr_TYPE(descr)->tp_name);
499 return NULL;
500 }
501 self = PyTuple_GET_ITEM(args, 0);
Victor Stinner3249dec2011-05-01 23:19:15 +0200502 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +0200503 (PyObject *)PyDescr_TYPE(descr))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 PyErr_Format(PyExc_TypeError,
505 "descriptor '%V' "
506 "requires a '%.100s' object "
507 "but received a '%.100s'",
508 descr_name((PyDescrObject *)descr), "?",
509 PyDescr_TYPE(descr)->tp_name,
Victor Stinner58ac7002020-02-07 03:04:21 +0100510 Py_TYPE(self)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 return NULL;
512 }
Tim Peters6d6c1a32001-08-02 04:15:00 +0000513
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300514 args = PyTuple_GetSlice(args, 1, argc);
515 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 return NULL;
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300517 }
518 result = wrapperdescr_raw_call(descr, self, args, kwds);
519 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 return result;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000521}
522
Serhiy Storchaka5e02c782017-09-21 14:25:36 +0300523
Tim Peters6d6c1a32001-08-02 04:15:00 +0000524static PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000525method_get_doc(PyMethodDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000526{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800527 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800528}
529
530static PyObject *
531method_get_text_signature(PyMethodDescrObject *descr, void *closure)
532{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800533 return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000534}
535
Antoine Pitrou9d574812011-12-12 13:47:25 +0100536static PyObject *
537calculate_qualname(PyDescrObject *descr)
538{
539 PyObject *type_qualname, *res;
540 _Py_IDENTIFIER(__qualname__);
541
542 if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) {
543 PyErr_SetString(PyExc_TypeError,
544 "<descriptor>.__name__ is not a unicode object");
545 return NULL;
546 }
547
548 type_qualname = _PyObject_GetAttrId((PyObject *)descr->d_type,
549 &PyId___qualname__);
550 if (type_qualname == NULL)
551 return NULL;
552
553 if (!PyUnicode_Check(type_qualname)) {
554 PyErr_SetString(PyExc_TypeError, "<descriptor>.__objclass__."
555 "__qualname__ is not a unicode object");
556 Py_XDECREF(type_qualname);
557 return NULL;
558 }
559
560 res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name);
561 Py_DECREF(type_qualname);
562 return res;
563}
564
565static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200566descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +0100567{
568 if (descr->d_qualname == NULL)
569 descr->d_qualname = calculate_qualname(descr);
570 Py_XINCREF(descr->d_qualname);
571 return descr->d_qualname;
572}
573
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100574static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530575descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100576{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200577 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
578 PyDescr_TYPE(descr), PyDescr_NAME(descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100579}
580
581static PyMethodDef descr_methods[] = {
582 {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL},
583 {NULL, NULL}
584};
585
Guido van Rossum6f799372001-09-20 20:46:19 +0000586static PyMemberDef descr_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
588 {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
589 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000590};
591
Guido van Rossum32d34c82001-09-20 21:45:26 +0000592static PyGetSetDef method_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 {"__doc__", (getter)method_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100594 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800595 {"__text_signature__", (getter)method_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000596 {0}
Guido van Rossum6f799372001-09-20 20:46:19 +0000597};
598
599static PyObject *
600member_get_doc(PyMemberDescrObject *descr, void *closure)
601{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 if (descr->d_member->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200603 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 }
605 return PyUnicode_FromString(descr->d_member->doc);
Guido van Rossum6f799372001-09-20 20:46:19 +0000606}
607
Guido van Rossum32d34c82001-09-20 21:45:26 +0000608static PyGetSetDef member_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 {"__doc__", (getter)member_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100610 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000612};
613
614static PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000615getset_get_doc(PyGetSetDescrObject *descr, void *closure)
616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 if (descr->d_getset->doc == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200618 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 }
620 return PyUnicode_FromString(descr->d_getset->doc);
Guido van Rossum32d34c82001-09-20 21:45:26 +0000621}
622
623static PyGetSetDef getset_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 {"__doc__", (getter)getset_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100625 {"__qualname__", (getter)descr_get_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 {0}
Guido van Rossum32d34c82001-09-20 21:45:26 +0000627};
628
629static PyObject *
Armin Rigoc6686b72005-11-07 08:38:00 +0000630wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000631{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800632 return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -0800633}
634
635static PyObject *
636wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
637{
Larry Hastings2623c8c2014-02-08 22:15:29 -0800638 return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000639}
640
Armin Rigoc6686b72005-11-07 08:38:00 +0000641static PyGetSetDef wrapperdescr_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 {"__doc__", (getter)wrapperdescr_get_doc},
Antoine Pitrou9d574812011-12-12 13:47:25 +0100643 {"__qualname__", (getter)descr_get_qualname},
Larry Hastings5c661892014-01-24 06:17:25 -0800644 {"__text_signature__", (getter)wrapperdescr_get_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +0000646};
647
Guido van Rossum048eb752001-10-02 21:24:57 +0000648static int
649descr_traverse(PyObject *self, visitproc visit, void *arg)
650{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 PyDescrObject *descr = (PyDescrObject *)self;
652 Py_VISIT(descr->d_type);
653 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +0000654}
655
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000656PyTypeObject PyMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000657 PyVarObject_HEAD_INIT(&PyType_Type, 0)
658 "method_descriptor",
659 sizeof(PyMethodDescrObject),
660 0,
661 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200662 offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 0, /* tp_getattr */
664 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200665 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 (reprfunc)method_repr, /* tp_repr */
667 0, /* tp_as_number */
668 0, /* tp_as_sequence */
669 0, /* tp_as_mapping */
670 0, /* tp_hash */
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200671 PyVectorcall_Call, /* tp_call */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 0, /* tp_str */
673 PyObject_GenericGetAttr, /* tp_getattro */
674 0, /* tp_setattro */
675 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200676 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Petr Viktorinffd97532020-02-11 17:46:57 +0100677 Py_TPFLAGS_HAVE_VECTORCALL |
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200678 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 0, /* tp_doc */
680 descr_traverse, /* tp_traverse */
681 0, /* tp_clear */
682 0, /* tp_richcompare */
683 0, /* tp_weaklistoffset */
684 0, /* tp_iter */
685 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100686 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 descr_members, /* tp_members */
688 method_getset, /* tp_getset */
689 0, /* tp_base */
690 0, /* tp_dict */
691 (descrgetfunc)method_get, /* tp_descr_get */
692 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000693};
694
Guido van Rossumb6e5a0c2003-02-11 18:44:42 +0000695/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000696PyTypeObject PyClassMethodDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 PyVarObject_HEAD_INIT(&PyType_Type, 0)
698 "classmethod_descriptor",
699 sizeof(PyMethodDescrObject),
700 0,
701 (destructor)descr_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200702 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 0, /* tp_getattr */
704 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200705 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 (reprfunc)method_repr, /* tp_repr */
707 0, /* tp_as_number */
708 0, /* tp_as_sequence */
709 0, /* tp_as_mapping */
710 0, /* tp_hash */
711 (ternaryfunc)classmethoddescr_call, /* tp_call */
712 0, /* tp_str */
713 PyObject_GenericGetAttr, /* tp_getattro */
714 0, /* tp_setattro */
715 0, /* tp_as_buffer */
716 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
717 0, /* tp_doc */
718 descr_traverse, /* tp_traverse */
719 0, /* tp_clear */
720 0, /* tp_richcompare */
721 0, /* tp_weaklistoffset */
722 0, /* tp_iter */
723 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100724 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 descr_members, /* tp_members */
726 method_getset, /* tp_getset */
727 0, /* tp_base */
728 0, /* tp_dict */
729 (descrgetfunc)classmethod_get, /* tp_descr_get */
730 0, /* tp_descr_set */
Tim Petersbca1cbc2002-12-09 22:56:13 +0000731};
732
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000733PyTypeObject PyMemberDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 PyVarObject_HEAD_INIT(&PyType_Type, 0)
735 "member_descriptor",
736 sizeof(PyMemberDescrObject),
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)member_repr, /* tp_repr */
744 0, /* tp_as_number */
745 0, /* tp_as_sequence */
746 0, /* tp_as_mapping */
747 0, /* tp_hash */
748 0, /* 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 member_getset, /* tp_getset */
764 0, /* tp_base */
765 0, /* tp_dict */
766 (descrgetfunc)member_get, /* tp_descr_get */
767 (descrsetfunc)member_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000768};
769
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000770PyTypeObject PyGetSetDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 PyVarObject_HEAD_INIT(&PyType_Type, 0)
772 "getset_descriptor",
773 sizeof(PyGetSetDescrObject),
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)getset_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 */
798 0, /* tp_methods */
799 descr_members, /* tp_members */
800 getset_getset, /* tp_getset */
801 0, /* tp_base */
802 0, /* tp_dict */
803 (descrgetfunc)getset_get, /* tp_descr_get */
804 (descrsetfunc)getset_set, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000805};
806
Guido van Rossumf4593e02001-10-03 12:09:30 +0000807PyTypeObject PyWrapperDescr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 PyVarObject_HEAD_INIT(&PyType_Type, 0)
809 "wrapper_descriptor",
810 sizeof(PyWrapperDescrObject),
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)wrapperdescr_repr, /* tp_repr */
818 0, /* tp_as_number */
819 0, /* tp_as_sequence */
820 0, /* tp_as_mapping */
821 0, /* tp_hash */
822 (ternaryfunc)wrapperdescr_call, /* tp_call */
823 0, /* tp_str */
824 PyObject_GenericGetAttr, /* tp_getattro */
825 0, /* tp_setattro */
826 0, /* tp_as_buffer */
Jeroen Demeyereb65e242019-05-28 14:42:53 +0200827 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
828 Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 0, /* tp_doc */
830 descr_traverse, /* tp_traverse */
831 0, /* tp_clear */
832 0, /* tp_richcompare */
833 0, /* tp_weaklistoffset */
834 0, /* tp_iter */
835 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100836 descr_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 descr_members, /* tp_members */
838 wrapperdescr_getset, /* tp_getset */
839 0, /* tp_base */
840 0, /* tp_dict */
841 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
842 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000843};
844
845static PyDescrObject *
Jeremy Hyltonaf68c872005-12-10 18:50:16 +0000846descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 PyDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
851 if (descr != NULL) {
852 Py_XINCREF(type);
853 descr->d_type = type;
854 descr->d_name = PyUnicode_InternFromString(name);
855 if (descr->d_name == NULL) {
856 Py_DECREF(descr);
857 descr = NULL;
858 }
Benjamin Petersonf2fe7f02011-12-17 08:02:20 -0500859 else {
860 descr->d_qualname = NULL;
861 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000862 }
863 return descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000864}
865
866PyObject *
867PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
868{
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200869 /* Figure out correct vectorcall function to use */
870 vectorcallfunc vectorcall;
871 switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS))
872 {
873 case METH_VARARGS:
874 vectorcall = method_vectorcall_VARARGS;
875 break;
876 case METH_VARARGS | METH_KEYWORDS:
877 vectorcall = method_vectorcall_VARARGS_KEYWORDS;
878 break;
879 case METH_FASTCALL:
880 vectorcall = method_vectorcall_FASTCALL;
881 break;
882 case METH_FASTCALL | METH_KEYWORDS:
883 vectorcall = method_vectorcall_FASTCALL_KEYWORDS;
884 break;
885 case METH_NOARGS:
886 vectorcall = method_vectorcall_NOARGS;
887 break;
888 case METH_O:
889 vectorcall = method_vectorcall_O;
890 break;
891 default:
Victor Stinnerc7d2d692020-03-12 08:38:11 +0100892 PyErr_Format(PyExc_SystemError,
893 "%s() method: bad call flags", method->ml_name);
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200894 return NULL;
895 }
896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000897 PyMethodDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
900 type, method->ml_name);
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200901 if (descr != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 descr->d_method = method;
Jeroen Demeyer0d722f32019-07-05 14:48:24 +0200903 descr->vectorcall = vectorcall;
Jeroen Demeyeraacc77f2019-05-29 20:31:52 +0200904 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000905 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000906}
907
908PyObject *
Tim Petersbca1cbc2002-12-09 22:56:13 +0000909PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 PyMethodDescrObject *descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
914 type, method->ml_name);
915 if (descr != NULL)
916 descr->d_method = method;
917 return (PyObject *)descr;
Tim Petersbca1cbc2002-12-09 22:56:13 +0000918}
919
920PyObject *
Guido van Rossum6f799372001-09-20 20:46:19 +0000921PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000922{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 PyMemberDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
926 type, member->name);
927 if (descr != NULL)
928 descr->d_member = member;
929 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000930}
931
932PyObject *
Guido van Rossum32d34c82001-09-20 21:45:26 +0000933PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 PyGetSetDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
938 type, getset->name);
939 if (descr != NULL)
940 descr->d_getset = getset;
941 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000942}
943
944PyObject *
945PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
946{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
950 type, base->name);
951 if (descr != NULL) {
952 descr->d_base = base;
953 descr->d_wrapped = wrapped;
954 }
955 return (PyObject *)descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000956}
957
Tim Peters6d6c1a32001-08-02 04:15:00 +0000958
Victor Stinner0db176f2012-04-16 00:16:30 +0200959/* --- mappingproxy: read-only proxy for mappings --- */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000960
961/* This has no reason to be in this file except that adding new files is a
962 bit of a pain */
963
964typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000965 PyObject_HEAD
Victor Stinner0db176f2012-04-16 00:16:30 +0200966 PyObject *mapping;
967} mappingproxyobject;
Tim Peters6d6c1a32001-08-02 04:15:00 +0000968
Martin v. Löwis18e16552006-02-15 17:27:45 +0000969static Py_ssize_t
Victor Stinner0db176f2012-04-16 00:16:30 +0200970mappingproxy_len(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000971{
Victor Stinner0db176f2012-04-16 00:16:30 +0200972 return PyObject_Size(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000973}
974
975static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +0200976mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000977{
Victor Stinner0db176f2012-04-16 00:16:30 +0200978 return PyObject_GetItem(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000979}
980
Victor Stinner0db176f2012-04-16 00:16:30 +0200981static PyMappingMethods mappingproxy_as_mapping = {
982 (lenfunc)mappingproxy_len, /* mp_length */
983 (binaryfunc)mappingproxy_getitem, /* mp_subscript */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 0, /* mp_ass_subscript */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000985};
986
Brandt Bucher4663f662020-03-07 11:03:09 -0800987static PyObject *
988mappingproxy_or(PyObject *left, PyObject *right)
989{
990 if (PyObject_TypeCheck(left, &PyDictProxy_Type)) {
991 left = ((mappingproxyobject*)left)->mapping;
992 }
993 if (PyObject_TypeCheck(right, &PyDictProxy_Type)) {
994 right = ((mappingproxyobject*)right)->mapping;
995 }
996 return PyNumber_Or(left, right);
997}
998
999static PyObject *
1000mappingproxy_ior(PyObject *self, PyObject *Py_UNUSED(other))
1001{
1002 return PyErr_Format(PyExc_TypeError,
1003 "'|=' is not supported by %s; use '|' instead", Py_TYPE(self)->tp_name);
1004}
1005
1006static PyNumberMethods mappingproxy_as_number = {
1007 .nb_or = mappingproxy_or,
1008 .nb_inplace_or = mappingproxy_ior,
1009};
1010
Tim Peters6d6c1a32001-08-02 04:15:00 +00001011static int
Victor Stinner0db176f2012-04-16 00:16:30 +02001012mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001013{
Victor Stinner0db176f2012-04-16 00:16:30 +02001014 if (PyDict_CheckExact(pp->mapping))
1015 return PyDict_Contains(pp->mapping, key);
1016 else
1017 return PySequence_Contains(pp->mapping, key);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001018}
1019
Victor Stinner0db176f2012-04-16 00:16:30 +02001020static PySequenceMethods mappingproxy_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 0, /* sq_length */
1022 0, /* sq_concat */
1023 0, /* sq_repeat */
1024 0, /* sq_item */
1025 0, /* sq_slice */
1026 0, /* sq_ass_item */
1027 0, /* sq_ass_slice */
Victor Stinner0db176f2012-04-16 00:16:30 +02001028 (objobjproc)mappingproxy_contains, /* sq_contains */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 0, /* sq_inplace_concat */
1030 0, /* sq_inplace_repeat */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001031};
1032
1033static PyObject *
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001034mappingproxy_get(mappingproxyobject *pp, PyObject *const *args, Py_ssize_t nargs)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001035{
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001036 /* newargs: mapping, key, default=None */
1037 PyObject *newargs[3];
1038 newargs[0] = pp->mapping;
1039 newargs[2] = Py_None;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001040
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001041 if (!_PyArg_UnpackStack(args, nargs, "get", 1, 2,
1042 &newargs[1], &newargs[2]))
1043 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 return NULL;
Jeroen Demeyerb1263d52019-06-28 11:49:00 +02001045 }
1046 _Py_IDENTIFIER(get);
1047 return _PyObject_VectorcallMethodId(&PyId_get, newargs,
1048 3 | PY_VECTORCALL_ARGUMENTS_OFFSET,
1049 NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001050}
1051
1052static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301053mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001054{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001055 _Py_IDENTIFIER(keys);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001056 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_keys);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001057}
1058
1059static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301060mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001061{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001062 _Py_IDENTIFIER(values);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001063 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_values);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001064}
1065
1066static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301067mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001068{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001069 _Py_IDENTIFIER(items);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001070 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_items);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001071}
1072
1073static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301074mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001075{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001076 _Py_IDENTIFIER(copy);
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001077 return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_copy);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001078}
1079
Victor Stinner0db176f2012-04-16 00:16:30 +02001080/* WARNING: mappingproxy methods must not give access
1081 to the underlying mapping */
1082
1083static PyMethodDef mappingproxy_methods[] = {
Zackery Spytz43d564c2019-08-13 23:51:06 -06001084 {"get", (PyCFunction)(void(*)(void))mappingproxy_get, METH_FASTCALL,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d."
Victor Stinner0db176f2012-04-16 00:16:30 +02001086 " d defaults to None.")},
1087 {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 PyDoc_STR("D.keys() -> list of D's keys")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001089 {"values", (PyCFunction)mappingproxy_values, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 PyDoc_STR("D.values() -> list of D's values")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001091 {"items", (PyCFunction)mappingproxy_items, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
Victor Stinner0db176f2012-04-16 00:16:30 +02001093 {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 PyDoc_STR("D.copy() -> a shallow copy of D")},
Guido van Rossum48b069a2020-04-07 09:50:06 -07001095 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS,
1096 PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001097 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001098};
1099
1100static void
Victor Stinner0db176f2012-04-16 00:16:30 +02001101mappingproxy_dealloc(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001102{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 _PyObject_GC_UNTRACK(pp);
Victor Stinner0db176f2012-04-16 00:16:30 +02001104 Py_DECREF(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 PyObject_GC_Del(pp);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001106}
1107
1108static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001109mappingproxy_getiter(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001110{
Victor Stinner0db176f2012-04-16 00:16:30 +02001111 return PyObject_GetIter(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001112}
1113
Neil Schemenauer26775122001-10-21 22:26:43 +00001114static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001115mappingproxy_str(mappingproxyobject *pp)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001116{
Victor Stinner0db176f2012-04-16 00:16:30 +02001117 return PyObject_Str(pp->mapping);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001118}
1119
Ezio Melottiac53ab62010-12-18 14:59:43 +00001120static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001121mappingproxy_repr(mappingproxyobject *pp)
Ezio Melottiac53ab62010-12-18 14:59:43 +00001122{
Victor Stinner0db176f2012-04-16 00:16:30 +02001123 return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping);
Ezio Melottiac53ab62010-12-18 14:59:43 +00001124}
1125
Guido van Rossum048eb752001-10-02 21:24:57 +00001126static int
Victor Stinner0db176f2012-04-16 00:16:30 +02001127mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
Guido van Rossum048eb752001-10-02 21:24:57 +00001128{
Victor Stinner0db176f2012-04-16 00:16:30 +02001129 mappingproxyobject *pp = (mappingproxyobject *)self;
1130 Py_VISIT(pp->mapping);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001132}
1133
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001134static PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001135mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op)
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001136{
Victor Stinner0db176f2012-04-16 00:16:30 +02001137 return PyObject_RichCompare(v->mapping, w, op);
1138}
1139
1140static int
1141mappingproxy_check_mapping(PyObject *mapping)
1142{
1143 if (!PyMapping_Check(mapping)
1144 || PyList_Check(mapping)
1145 || PyTuple_Check(mapping)) {
1146 PyErr_Format(PyExc_TypeError,
1147 "mappingproxy() argument must be a mapping, not %s",
1148 Py_TYPE(mapping)->tp_name);
1149 return -1;
1150 }
1151 return 0;
1152}
1153
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001154/*[clinic input]
1155@classmethod
1156mappingproxy.__new__ as mappingproxy_new
Victor Stinner0db176f2012-04-16 00:16:30 +02001157
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001158 mapping: object
1159
1160[clinic start generated code]*/
1161
1162static PyObject *
1163mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping)
1164/*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/
1165{
1166 mappingproxyobject *mappingproxy;
Victor Stinner0db176f2012-04-16 00:16:30 +02001167
1168 if (mappingproxy_check_mapping(mapping) == -1)
1169 return NULL;
1170
1171 mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
1172 if (mappingproxy == NULL)
1173 return NULL;
1174 Py_INCREF(mapping);
1175 mappingproxy->mapping = mapping;
1176 _PyObject_GC_TRACK(mappingproxy);
1177 return (PyObject *)mappingproxy;
Raymond Hettinger29a6d442002-08-31 15:51:04 +00001178}
1179
Tim Peters6d6c1a32001-08-02 04:15:00 +00001180PyObject *
Victor Stinner0db176f2012-04-16 00:16:30 +02001181PyDictProxy_New(PyObject *mapping)
Tim Peters6d6c1a32001-08-02 04:15:00 +00001182{
Victor Stinner0db176f2012-04-16 00:16:30 +02001183 mappingproxyobject *pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001184
Victor Stinner0db176f2012-04-16 00:16:30 +02001185 if (mappingproxy_check_mapping(mapping) == -1)
1186 return NULL;
1187
1188 pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 if (pp != NULL) {
Victor Stinner0db176f2012-04-16 00:16:30 +02001190 Py_INCREF(mapping);
1191 pp->mapping = mapping;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 _PyObject_GC_TRACK(pp);
1193 }
1194 return (PyObject *)pp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001195}
1196
1197
1198/* --- Wrapper object for "slot" methods --- */
1199
1200/* This has no reason to be in this file except that adding new files is a
1201 bit of a pain */
1202
1203typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 PyObject_HEAD
1205 PyWrapperDescrObject *descr;
1206 PyObject *self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001207} wrapperobject;
1208
Andy Lesterdffe4c02020-03-04 07:15:20 -06001209#define Wrapper_Check(v) Py_IS_TYPE(v, &_PyMethodWrapper_Type)
Mark Dickinson211c6252009-02-01 10:28:51 +00001210
Tim Peters6d6c1a32001-08-02 04:15:00 +00001211static void
1212wrapper_dealloc(wrapperobject *wp)
1213{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 PyObject_GC_UnTrack(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001215 Py_TRASHCAN_BEGIN(wp, wrapper_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 Py_XDECREF(wp->descr);
1217 Py_XDECREF(wp->self);
1218 PyObject_GC_Del(wp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02001219 Py_TRASHCAN_END
Tim Peters6d6c1a32001-08-02 04:15:00 +00001220}
1221
Mark Dickinson211c6252009-02-01 10:28:51 +00001222static PyObject *
1223wrapper_richcompare(PyObject *a, PyObject *b, int op)
Armin Rigoc6686b72005-11-07 08:38:00 +00001224{
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001225 wrapperobject *wa, *wb;
1226 int eq;
Mark Dickinson211c6252009-02-01 10:28:51 +00001227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +00001229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 /* both arguments should be wrapperobjects */
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001231 if ((op != Py_EQ && op != Py_NE)
1232 || !Wrapper_Check(a) || !Wrapper_Check(b))
1233 {
stratakise8b19652017-11-02 11:32:54 +01001234 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 }
Mark Dickinson211c6252009-02-01 10:28:51 +00001236
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001237 wa = (wrapperobject *)a;
1238 wb = (wrapperobject *)b;
1239 eq = (wa->descr == wb->descr && wa->self == wb->self);
1240 if (eq == (op == Py_EQ)) {
1241 Py_RETURN_TRUE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 }
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001243 else {
1244 Py_RETURN_FALSE;
1245 }
Armin Rigoc6686b72005-11-07 08:38:00 +00001246}
1247
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001248static Py_hash_t
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001249wrapper_hash(wrapperobject *wp)
1250{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001251 Py_hash_t x, y;
Serhiy Storchakaac20e0f2018-07-31 09:18:24 +03001252 x = _Py_HashPointer(wp->self);
1253 y = _Py_HashPointer(wp->descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 x = x ^ y;
1255 if (x == -1)
1256 x = -2;
1257 return x;
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001258}
1259
Armin Rigoc6686b72005-11-07 08:38:00 +00001260static PyObject *
1261wrapper_repr(wrapperobject *wp)
1262{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
1264 wp->descr->d_base->name,
Victor Stinner58ac7002020-02-07 03:04:21 +01001265 Py_TYPE(wp->self)->tp_name,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 wp->self);
Armin Rigoc6686b72005-11-07 08:38:00 +00001267}
1268
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001269static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301270wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001271{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02001272 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
1273 wp->self, PyDescr_NAME(wp->descr));
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001274}
1275
1276static PyMethodDef wrapper_methods[] = {
1277 {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
1278 {NULL, NULL}
1279};
1280
Armin Rigoc6686b72005-11-07 08:38:00 +00001281static PyMemberDef wrapper_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
1283 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001284};
1285
1286static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001287wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored))
Armin Rigoc6686b72005-11-07 08:38:00 +00001288{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
Armin Rigoc6686b72005-11-07 08:38:00 +00001290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 Py_INCREF(c);
1292 return c;
Armin Rigoc6686b72005-11-07 08:38:00 +00001293}
1294
1295static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001296wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001297{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 const char *s = wp->descr->d_base->name;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 return PyUnicode_FromString(s);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001301}
1302
1303static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001304wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored))
Tim Peters6d6c1a32001-08-02 04:15:00 +00001305{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001306 return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Larry Hastings5c661892014-01-24 06:17:25 -08001307}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001308
Larry Hastings5c661892014-01-24 06:17:25 -08001309static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001310wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
Larry Hastings5c661892014-01-24 06:17:25 -08001311{
Larry Hastings2623c8c2014-02-08 22:15:29 -08001312 return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001313}
1314
Antoine Pitrou9d574812011-12-12 13:47:25 +01001315static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001316wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored))
Antoine Pitrou9d574812011-12-12 13:47:25 +01001317{
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001318 return descr_get_qualname((PyDescrObject *)wp->descr, NULL);
Antoine Pitrou9d574812011-12-12 13:47:25 +01001319}
1320
Guido van Rossum32d34c82001-09-20 21:45:26 +00001321static PyGetSetDef wrapper_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 {"__objclass__", (getter)wrapper_objclass},
1323 {"__name__", (getter)wrapper_name},
Antoine Pitrou9d574812011-12-12 13:47:25 +01001324 {"__qualname__", (getter)wrapper_qualname},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 {"__doc__", (getter)wrapper_doc},
Larry Hastings5c661892014-01-24 06:17:25 -08001326 {"__text_signature__", (getter)wrapper_text_signature},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 {0}
Tim Peters6d6c1a32001-08-02 04:15:00 +00001328};
1329
1330static PyObject *
1331wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
1332{
Serhiy Storchaka5e02c782017-09-21 14:25:36 +03001333 return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001334}
1335
Guido van Rossum048eb752001-10-02 21:24:57 +00001336static int
1337wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 wrapperobject *wp = (wrapperobject *)self;
1340 Py_VISIT(wp->descr);
1341 Py_VISIT(wp->self);
1342 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001343}
1344
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001345PyTypeObject _PyMethodWrapper_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1347 "method-wrapper", /* tp_name */
1348 sizeof(wrapperobject), /* tp_basicsize */
1349 0, /* tp_itemsize */
1350 /* methods */
1351 (destructor)wrapper_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001352 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 0, /* tp_getattr */
1354 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001355 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 (reprfunc)wrapper_repr, /* tp_repr */
1357 0, /* tp_as_number */
1358 0, /* tp_as_sequence */
1359 0, /* tp_as_mapping */
1360 (hashfunc)wrapper_hash, /* tp_hash */
1361 (ternaryfunc)wrapper_call, /* tp_call */
1362 0, /* tp_str */
1363 PyObject_GenericGetAttr, /* tp_getattro */
1364 0, /* tp_setattro */
1365 0, /* tp_as_buffer */
1366 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1367 0, /* tp_doc */
1368 wrapper_traverse, /* tp_traverse */
1369 0, /* tp_clear */
1370 wrapper_richcompare, /* tp_richcompare */
1371 0, /* tp_weaklistoffset */
1372 0, /* tp_iter */
1373 0, /* tp_iternext */
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001374 wrapper_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 wrapper_members, /* tp_members */
1376 wrapper_getsets, /* tp_getset */
1377 0, /* tp_base */
1378 0, /* tp_dict */
1379 0, /* tp_descr_get */
1380 0, /* tp_descr_set */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001381};
1382
1383PyObject *
1384PyWrapper_New(PyObject *d, PyObject *self)
1385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 wrapperobject *wp;
1387 PyWrapperDescrObject *descr;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1390 descr = (PyWrapperDescrObject *)d;
Victor Stinner3249dec2011-05-01 23:19:15 +02001391 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
Victor Stinnerd9561312011-05-01 23:31:36 +02001392 (PyObject *)PyDescr_TYPE(descr)));
Tim Peters6d6c1a32001-08-02 04:15:00 +00001393
Benjamin Petersoneff61f62011-09-01 16:32:31 -04001394 wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 if (wp != NULL) {
1396 Py_INCREF(descr);
1397 wp->descr = descr;
1398 Py_INCREF(self);
1399 wp->self = self;
1400 _PyObject_GC_TRACK(wp);
1401 }
1402 return (PyObject *)wp;
Tim Peters6d6c1a32001-08-02 04:15:00 +00001403}
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001404
1405
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001406/* A built-in 'property' type */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001407
1408/*
Serhiy Storchakad741a882015-06-11 00:06:39 +03001409class property(object):
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
1412 if doc is None and fget is not None and hasattr(fget, "__doc__"):
Serhiy Storchakad741a882015-06-11 00:06:39 +03001413 doc = fget.__doc__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 self.__get = fget
1415 self.__set = fset
1416 self.__del = fdel
1417 self.__doc__ = doc
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 def __get__(self, inst, type=None):
1420 if inst is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001421 return self
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 if self.__get is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001423 raise AttributeError, "unreadable attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 return self.__get(inst)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 def __set__(self, inst, value):
1427 if self.__set is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001428 raise AttributeError, "can't set attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 return self.__set(inst, value)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 def __delete__(self, inst):
1432 if self.__del is None:
Serhiy Storchakad741a882015-06-11 00:06:39 +03001433 raise AttributeError, "can't delete attribute"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 return self.__del(inst)
Guido van Rossumba2485f2001-12-10 18:03:34 +00001435
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001436*/
1437
1438typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 PyObject_HEAD
1440 PyObject *prop_get;
1441 PyObject *prop_set;
1442 PyObject *prop_del;
1443 PyObject *prop_doc;
1444 int getter_doc;
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001445} propertyobject;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001446
Christian Heimes0449f632007-12-15 01:27:15 +00001447static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
Benjamin Peterson93964832010-06-28 03:07:10 +00001448 PyObject *);
Christian Heimes0449f632007-12-15 01:27:15 +00001449
Tim Peters66c1a522001-09-24 21:17:50 +00001450static PyMemberDef property_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
1452 {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
1453 {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
Raymond Hettingereac503a2015-05-13 01:09:59 -07001454 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 {0}
Tim Peters66c1a522001-09-24 21:17:50 +00001456};
1457
Christian Heimes0449f632007-12-15 01:27:15 +00001458
Guido van Rossum58da9312007-11-10 23:39:45 +00001459PyDoc_STRVAR(getter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 "Descriptor to change the getter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001461
Neal Norwitz32dde222008-04-15 06:43:13 +00001462static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001463property_getter(PyObject *self, PyObject *getter)
1464{
Benjamin Peterson93964832010-06-28 03:07:10 +00001465 return property_copy(self, getter, NULL, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001466}
1467
Christian Heimes0449f632007-12-15 01:27:15 +00001468
Guido van Rossum58da9312007-11-10 23:39:45 +00001469PyDoc_STRVAR(setter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 "Descriptor to change the setter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001471
Neal Norwitz32dde222008-04-15 06:43:13 +00001472static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001473property_setter(PyObject *self, PyObject *setter)
1474{
Benjamin Peterson93964832010-06-28 03:07:10 +00001475 return property_copy(self, NULL, setter, NULL);
Guido van Rossum58da9312007-11-10 23:39:45 +00001476}
1477
Christian Heimes0449f632007-12-15 01:27:15 +00001478
Guido van Rossum58da9312007-11-10 23:39:45 +00001479PyDoc_STRVAR(deleter_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 "Descriptor to change the deleter on a property.");
Guido van Rossum58da9312007-11-10 23:39:45 +00001481
Neal Norwitz32dde222008-04-15 06:43:13 +00001482static PyObject *
Guido van Rossum58da9312007-11-10 23:39:45 +00001483property_deleter(PyObject *self, PyObject *deleter)
1484{
Benjamin Peterson93964832010-06-28 03:07:10 +00001485 return property_copy(self, NULL, NULL, deleter);
Guido van Rossum58da9312007-11-10 23:39:45 +00001486}
1487
1488
Guido van Rossum58da9312007-11-10 23:39:45 +00001489static PyMethodDef property_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 {"getter", property_getter, METH_O, getter_doc},
1491 {"setter", property_setter, METH_O, setter_doc},
1492 {"deleter", property_deleter, METH_O, deleter_doc},
1493 {0}
Guido van Rossum58da9312007-11-10 23:39:45 +00001494};
1495
Tim Peters66c1a522001-09-24 21:17:50 +00001496
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001497static void
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001498property_dealloc(PyObject *self)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001499{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 propertyobject *gs = (propertyobject *)self;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 _PyObject_GC_UNTRACK(self);
1503 Py_XDECREF(gs->prop_get);
1504 Py_XDECREF(gs->prop_set);
1505 Py_XDECREF(gs->prop_del);
1506 Py_XDECREF(gs->prop_doc);
Victor Stinner58ac7002020-02-07 03:04:21 +01001507 Py_TYPE(self)->tp_free(self);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001508}
1509
1510static PyObject *
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001511property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001512{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 if (obj == NULL || obj == Py_None) {
1514 Py_INCREF(self);
1515 return self;
1516 }
Victor Stinnere972c132018-10-01 03:03:22 -07001517
1518 propertyobject *gs = (propertyobject *)self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 if (gs->prop_get == NULL) {
1520 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1521 return NULL;
1522 }
Victor Stinnere972c132018-10-01 03:03:22 -07001523
Petr Viktorinffd97532020-02-11 17:46:57 +01001524 return PyObject_CallOneArg(gs->prop_get, obj);
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001525}
1526
1527static int
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001528property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 propertyobject *gs = (propertyobject *)self;
1531 PyObject *func, *res;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 if (value == NULL)
1534 func = gs->prop_del;
1535 else
1536 func = gs->prop_set;
1537 if (func == NULL) {
1538 PyErr_SetString(PyExc_AttributeError,
1539 value == NULL ?
1540 "can't delete attribute" :
1541 "can't set attribute");
1542 return -1;
1543 }
1544 if (value == NULL)
Petr Viktorinffd97532020-02-11 17:46:57 +01001545 res = PyObject_CallOneArg(func, obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 else
Benjamin Peterson9b955de2010-12-07 04:04:02 +00001547 res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 if (res == NULL)
1549 return -1;
1550 Py_DECREF(res);
1551 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001552}
1553
Christian Heimes0449f632007-12-15 01:27:15 +00001554static PyObject *
Benjamin Peterson93964832010-06-28 03:07:10 +00001555property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
Christian Heimes0449f632007-12-15 01:27:15 +00001556{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 propertyobject *pold = (propertyobject *)old;
Benjamin Peterson93964832010-06-28 03:07:10 +00001558 PyObject *new, *type, *doc;
Christian Heimes0449f632007-12-15 01:27:15 +00001559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 type = PyObject_Type(old);
1561 if (type == NULL)
1562 return NULL;
Christian Heimes0449f632007-12-15 01:27:15 +00001563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001564 if (get == NULL || get == Py_None) {
1565 Py_XDECREF(get);
1566 get = pold->prop_get ? pold->prop_get : Py_None;
1567 }
1568 if (set == NULL || set == Py_None) {
1569 Py_XDECREF(set);
1570 set = pold->prop_set ? pold->prop_set : Py_None;
1571 }
1572 if (del == NULL || del == Py_None) {
1573 Py_XDECREF(del);
1574 del = pold->prop_del ? pold->prop_del : Py_None;
1575 }
Benjamin Peterson93964832010-06-28 03:07:10 +00001576 if (pold->getter_doc && get != Py_None) {
1577 /* make _init use __doc__ from getter */
1578 doc = Py_None;
1579 }
1580 else {
1581 doc = pold->prop_doc ? pold->prop_doc : Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 }
R. David Murrayb18500d2009-05-04 22:59:07 +00001583
Victor Stinner5abaa2b2016-12-09 16:22:32 +01001584 new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 Py_DECREF(type);
1586 if (new == NULL)
1587 return NULL;
1588 return new;
Christian Heimes0449f632007-12-15 01:27:15 +00001589}
1590
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001591/*[clinic input]
1592property.__init__ as property_init
1593
1594 fget: object(c_default="NULL") = None
1595 function to be used for getting an attribute value
1596 fset: object(c_default="NULL") = None
1597 function to be used for setting an attribute value
1598 fdel: object(c_default="NULL") = None
1599 function to be used for del'ing an attribute
1600 doc: object(c_default="NULL") = None
1601 docstring
1602
1603Property attribute.
1604
1605Typical use is to define a managed attribute x:
1606
1607class C(object):
1608 def getx(self): return self._x
1609 def setx(self, value): self._x = value
1610 def delx(self): del self._x
1611 x = property(getx, setx, delx, "I'm the 'x' property.")
1612
1613Decorators make defining new properties or modifying existing ones easy:
1614
1615class C(object):
1616 @property
1617 def x(self):
1618 "I am the 'x' property."
1619 return self._x
1620 @x.setter
1621 def x(self, value):
1622 self._x = value
1623 @x.deleter
1624 def x(self):
1625 del self._x
1626[clinic start generated code]*/
1627
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001628static int
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001629property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1630 PyObject *fdel, PyObject *doc)
1631/*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001632{
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001633 if (fget == Py_None)
1634 fget = NULL;
1635 if (fset == Py_None)
1636 fset = NULL;
1637 if (fdel == Py_None)
1638 fdel = NULL;
Tim Peters66c1a522001-09-24 21:17:50 +00001639
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001640 Py_XINCREF(fget);
1641 Py_XINCREF(fset);
1642 Py_XINCREF(fdel);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 Py_XINCREF(doc);
Christian Heimes0449f632007-12-15 01:27:15 +00001644
Oren Milmand019bc82018-02-13 12:28:33 +02001645 Py_XSETREF(self->prop_get, fget);
1646 Py_XSETREF(self->prop_set, fset);
1647 Py_XSETREF(self->prop_del, fdel);
1648 Py_XSETREF(self->prop_doc, doc);
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001649 self->getter_doc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 /* if no docstring given and the getter has one, use that one */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001652 if ((doc == NULL || doc == Py_None) && fget != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001653 _Py_IDENTIFIER(__doc__);
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001654 PyObject *get_doc;
1655 int rc = _PyObject_LookupAttrId(fget, &PyId___doc__, &get_doc);
1656 if (rc <= 0) {
1657 return rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 }
Andy Lesterdffe4c02020-03-04 07:15:20 -06001659 if (Py_IS_TYPE(self, &PyProperty_Type)) {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001660 Py_XSETREF(self->prop_doc, get_doc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001661 }
1662 else {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001663 /* If this is a property subclass, put __doc__
1664 in dict of the subclass instance instead,
1665 otherwise it gets shadowed by __doc__ in the
1666 class's dict. */
1667 int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc);
1668 Py_DECREF(get_doc);
1669 if (err < 0)
1670 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 }
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001672 self->getter_doc = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 }
1674
1675 return 0;
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001676}
1677
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001678static PyObject *
1679property_get___isabstractmethod__(propertyobject *prop, void *closure)
1680{
1681 int res = _PyObject_IsAbstract(prop->prop_get);
1682 if (res == -1) {
1683 return NULL;
1684 }
1685 else if (res) {
1686 Py_RETURN_TRUE;
1687 }
1688
1689 res = _PyObject_IsAbstract(prop->prop_set);
1690 if (res == -1) {
1691 return NULL;
1692 }
1693 else if (res) {
1694 Py_RETURN_TRUE;
1695 }
1696
1697 res = _PyObject_IsAbstract(prop->prop_del);
1698 if (res == -1) {
1699 return NULL;
1700 }
1701 else if (res) {
1702 Py_RETURN_TRUE;
1703 }
1704 Py_RETURN_FALSE;
1705}
1706
1707static PyGetSetDef property_getsetlist[] = {
1708 {"__isabstractmethod__",
1709 (getter)property_get___isabstractmethod__, NULL,
1710 NULL,
1711 NULL},
1712 {NULL} /* Sentinel */
1713};
1714
Guido van Rossum048eb752001-10-02 21:24:57 +00001715static int
1716property_traverse(PyObject *self, visitproc visit, void *arg)
1717{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 propertyobject *pp = (propertyobject *)self;
1719 Py_VISIT(pp->prop_get);
1720 Py_VISIT(pp->prop_set);
1721 Py_VISIT(pp->prop_del);
1722 Py_VISIT(pp->prop_doc);
1723 return 0;
Guido van Rossum048eb752001-10-02 21:24:57 +00001724}
1725
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001726static int
1727property_clear(PyObject *self)
1728{
1729 propertyobject *pp = (propertyobject *)self;
1730 Py_CLEAR(pp->prop_doc);
1731 return 0;
1732}
1733
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001734#include "clinic/descrobject.c.h"
1735
1736PyTypeObject PyDictProxy_Type = {
1737 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1738 "mappingproxy", /* tp_name */
1739 sizeof(mappingproxyobject), /* tp_basicsize */
1740 0, /* tp_itemsize */
1741 /* methods */
1742 (destructor)mappingproxy_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001743 0, /* tp_vectorcall_offset */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001744 0, /* tp_getattr */
1745 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001746 0, /* tp_as_async */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001747 (reprfunc)mappingproxy_repr, /* tp_repr */
Brandt Bucher4663f662020-03-07 11:03:09 -08001748 &mappingproxy_as_number, /* tp_as_number */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001749 &mappingproxy_as_sequence, /* tp_as_sequence */
1750 &mappingproxy_as_mapping, /* tp_as_mapping */
1751 0, /* tp_hash */
1752 0, /* tp_call */
1753 (reprfunc)mappingproxy_str, /* tp_str */
1754 PyObject_GenericGetAttr, /* tp_getattro */
1755 0, /* tp_setattro */
1756 0, /* tp_as_buffer */
1757 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1758 0, /* tp_doc */
1759 mappingproxy_traverse, /* tp_traverse */
1760 0, /* tp_clear */
1761 (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
1762 0, /* tp_weaklistoffset */
1763 (getiterfunc)mappingproxy_getiter, /* tp_iter */
1764 0, /* tp_iternext */
1765 mappingproxy_methods, /* tp_methods */
1766 0, /* tp_members */
1767 0, /* tp_getset */
1768 0, /* tp_base */
1769 0, /* tp_dict */
1770 0, /* tp_descr_get */
1771 0, /* tp_descr_set */
1772 0, /* tp_dictoffset */
1773 0, /* tp_init */
1774 0, /* tp_alloc */
1775 mappingproxy_new, /* tp_new */
1776};
1777
Guido van Rossum8bce4ac2001-09-06 21:56:42 +00001778PyTypeObject PyProperty_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1780 "property", /* tp_name */
1781 sizeof(propertyobject), /* tp_basicsize */
1782 0, /* tp_itemsize */
1783 /* methods */
1784 property_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001785 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 0, /* tp_getattr */
1787 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001788 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 0, /* tp_repr */
1790 0, /* tp_as_number */
1791 0, /* tp_as_sequence */
1792 0, /* tp_as_mapping */
1793 0, /* tp_hash */
1794 0, /* tp_call */
1795 0, /* tp_str */
1796 PyObject_GenericGetAttr, /* tp_getattro */
1797 0, /* tp_setattro */
1798 0, /* tp_as_buffer */
1799 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1800 Py_TPFLAGS_BASETYPE, /* tp_flags */
Serhiy Storchaka18b250f2017-03-19 08:51:07 +02001801 property_init__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 property_traverse, /* tp_traverse */
Raymond Hettingerd4be6912015-05-13 11:12:33 -07001803 (inquiry)property_clear, /* tp_clear */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001804 0, /* tp_richcompare */
1805 0, /* tp_weaklistoffset */
1806 0, /* tp_iter */
1807 0, /* tp_iternext */
1808 property_methods, /* tp_methods */
1809 property_members, /* tp_members */
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05001810 property_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 0, /* tp_base */
1812 0, /* tp_dict */
1813 property_descr_get, /* tp_descr_get */
1814 property_descr_set, /* tp_descr_set */
1815 0, /* tp_dictoffset */
1816 property_init, /* tp_init */
1817 PyType_GenericAlloc, /* tp_alloc */
1818 PyType_GenericNew, /* tp_new */
1819 PyObject_GC_Del, /* tp_free */
Guido van Rossum29a62dd2001-08-23 21:40:38 +00001820};