Line data Source code
1 : /* Descriptors -- a new, flexible way to describe attributes */
2 :
3 : #include "Python.h"
4 : #include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate()
5 : #include "pycore_object.h" // _PyObject_GC_UNTRACK()
6 : #include "pycore_pystate.h" // _PyThreadState_GET()
7 : #include "pycore_tuple.h" // _PyTuple_ITEMS()
8 : #include "structmember.h" // PyMemberDef
9 : #include "pycore_descrobject.h"
10 :
11 : /*[clinic input]
12 : class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type"
13 : class property "propertyobject *" "&PyProperty_Type"
14 : [clinic start generated code]*/
15 : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=556352653fd4c02e]*/
16 :
17 : // see pycore_object.h
18 : #if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
19 : #include <emscripten.h>
20 : EM_JS(PyObject*, descr_set_trampoline_call, (setter set, PyObject *obj, PyObject *value, void *closure), {
21 : return wasmTable.get(set)(obj, value, closure);
22 : });
23 :
24 : EM_JS(PyObject*, descr_get_trampoline_call, (getter get, PyObject *obj, void *closure), {
25 : return wasmTable.get(get)(obj, closure);
26 : });
27 : #else
28 : #define descr_set_trampoline_call(set, obj, value, closure) \
29 : (set)((obj), (value), (closure))
30 :
31 : #define descr_get_trampoline_call(get, obj, closure) \
32 : (get)((obj), (closure))
33 :
34 : #endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE
35 :
36 : static void
37 7442590 : descr_dealloc(PyDescrObject *descr)
38 : {
39 7442590 : _PyObject_GC_UNTRACK(descr);
40 7442590 : Py_XDECREF(descr->d_type);
41 7442590 : Py_XDECREF(descr->d_name);
42 7442590 : Py_XDECREF(descr->d_qualname);
43 7442590 : PyObject_GC_Del(descr);
44 7442590 : }
45 :
46 : static PyObject *
47 212 : descr_name(PyDescrObject *descr)
48 : {
49 212 : if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
50 212 : return descr->d_name;
51 0 : return NULL;
52 : }
53 :
54 : static PyObject *
55 95 : descr_repr(PyDescrObject *descr, const char *format)
56 : {
57 95 : PyObject *name = NULL;
58 95 : if (descr->d_name != NULL && PyUnicode_Check(descr->d_name))
59 95 : name = descr->d_name;
60 :
61 95 : return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name);
62 : }
63 :
64 : static PyObject *
65 90 : method_repr(PyMethodDescrObject *descr)
66 : {
67 90 : return descr_repr((PyDescrObject *)descr,
68 : "<method '%V' of '%s' objects>");
69 : }
70 :
71 : static PyObject *
72 1 : member_repr(PyMemberDescrObject *descr)
73 : {
74 1 : return descr_repr((PyDescrObject *)descr,
75 : "<member '%V' of '%s' objects>");
76 : }
77 :
78 : static PyObject *
79 4 : getset_repr(PyGetSetDescrObject *descr)
80 : {
81 4 : return descr_repr((PyDescrObject *)descr,
82 : "<attribute '%V' of '%s' objects>");
83 : }
84 :
85 : static PyObject *
86 0 : wrapperdescr_repr(PyWrapperDescrObject *descr)
87 : {
88 0 : return descr_repr((PyDescrObject *)descr,
89 : "<slot wrapper '%V' of '%s' objects>");
90 : }
91 :
92 : static int
93 136035000 : descr_check(PyDescrObject *descr, PyObject *obj)
94 : {
95 136035000 : if (!PyObject_TypeCheck(obj, descr->d_type)) {
96 168 : PyErr_Format(PyExc_TypeError,
97 : "descriptor '%V' for '%.100s' objects "
98 : "doesn't apply to a '%.100s' object",
99 : descr_name((PyDescrObject *)descr), "?",
100 168 : descr->d_type->tp_name,
101 168 : Py_TYPE(obj)->tp_name);
102 168 : return -1;
103 : }
104 136034000 : return 0;
105 : }
106 :
107 : static PyObject *
108 3387670 : classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
109 : {
110 : /* Ensure a valid type. Class methods ignore obj. */
111 3387670 : if (type == NULL) {
112 2 : if (obj != NULL)
113 2 : type = (PyObject *)Py_TYPE(obj);
114 : else {
115 : /* Wot - no type?! */
116 0 : PyErr_Format(PyExc_TypeError,
117 : "descriptor '%V' for type '%.100s' "
118 : "needs either an object or a type",
119 : descr_name((PyDescrObject *)descr), "?",
120 0 : PyDescr_TYPE(descr)->tp_name);
121 0 : return NULL;
122 : }
123 : }
124 3387670 : if (!PyType_Check(type)) {
125 2 : PyErr_Format(PyExc_TypeError,
126 : "descriptor '%V' for type '%.100s' "
127 : "needs a type, not a '%.100s' as arg 2",
128 : descr_name((PyDescrObject *)descr), "?",
129 2 : PyDescr_TYPE(descr)->tp_name,
130 2 : Py_TYPE(type)->tp_name);
131 2 : return NULL;
132 : }
133 3387670 : if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) {
134 4 : PyErr_Format(PyExc_TypeError,
135 : "descriptor '%V' requires a subtype of '%.100s' "
136 : "but received '%.100s'",
137 : descr_name((PyDescrObject *)descr), "?",
138 4 : PyDescr_TYPE(descr)->tp_name,
139 : ((PyTypeObject *)type)->tp_name);
140 4 : return NULL;
141 : }
142 3387670 : PyTypeObject *cls = NULL;
143 3387670 : if (descr->d_method->ml_flags & METH_METHOD) {
144 0 : cls = descr->d_common.d_type;
145 : }
146 3387670 : return PyCMethod_New(descr->d_method, type, NULL, cls);
147 : }
148 :
149 : static PyObject *
150 25805700 : method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
151 : {
152 25805700 : if (obj == NULL) {
153 484275 : return Py_NewRef(descr);
154 : }
155 25321400 : if (descr_check((PyDescrObject *)descr, obj) < 0) {
156 3 : return NULL;
157 : }
158 25321400 : if (descr->d_method->ml_flags & METH_METHOD) {
159 3140900 : if (PyType_Check(type)) {
160 3140900 : return PyCMethod_New(descr->d_method, obj, NULL, descr->d_common.d_type);
161 : } else {
162 0 : PyErr_Format(PyExc_TypeError,
163 : "descriptor '%V' needs a type, not '%s', as arg 2",
164 : descr_name((PyDescrObject *)descr),
165 0 : Py_TYPE(type)->tp_name);
166 0 : return NULL;
167 : }
168 : } else {
169 22180500 : return PyCFunction_NewEx(descr->d_method, obj, NULL);
170 : }
171 : }
172 :
173 : static PyObject *
174 12158800 : member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
175 : {
176 12158800 : if (obj == NULL) {
177 5425 : return Py_NewRef(descr);
178 : }
179 12153400 : if (descr_check((PyDescrObject *)descr, obj) < 0) {
180 55 : return NULL;
181 : }
182 :
183 12153300 : if (descr->d_member->flags & PY_AUDIT_READ) {
184 283431 : if (PySys_Audit("object.__getattr__", "Os",
185 283431 : obj ? obj : Py_None, descr->d_member->name) < 0) {
186 0 : return NULL;
187 : }
188 : }
189 :
190 12153300 : return PyMember_GetOne((char *)obj, descr->d_member);
191 : }
192 :
193 : static PyObject *
194 42326100 : getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
195 : {
196 42326100 : if (obj == NULL) {
197 13069 : return Py_NewRef(descr);
198 : }
199 42313000 : if (descr_check((PyDescrObject *)descr, obj) < 0) {
200 0 : return NULL;
201 : }
202 42313000 : if (descr->d_getset->get != NULL)
203 42313000 : return descr_get_trampoline_call(
204 : descr->d_getset->get, obj, descr->d_getset->closure);
205 0 : PyErr_Format(PyExc_AttributeError,
206 : "attribute '%V' of '%.100s' objects is not readable",
207 : descr_name((PyDescrObject *)descr), "?",
208 0 : PyDescr_TYPE(descr)->tp_name);
209 0 : return NULL;
210 : }
211 :
212 : static PyObject *
213 8226460 : wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
214 : {
215 8226460 : if (obj == NULL) {
216 198423 : return Py_NewRef(descr);
217 : }
218 8028040 : if (descr_check((PyDescrObject *)descr, obj) < 0) {
219 0 : return NULL;
220 : }
221 8028040 : return PyWrapper_New((PyObject *)descr, obj);
222 : }
223 :
224 : static int
225 4596510 : descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value)
226 : {
227 4596510 : assert(obj != NULL);
228 4596510 : if (!PyObject_TypeCheck(obj, descr->d_type)) {
229 2 : PyErr_Format(PyExc_TypeError,
230 : "descriptor '%V' for '%.100s' objects "
231 : "doesn't apply to a '%.100s' object",
232 : descr_name(descr), "?",
233 2 : descr->d_type->tp_name,
234 2 : Py_TYPE(obj)->tp_name);
235 2 : return -1;
236 : }
237 4596510 : return 0;
238 : }
239 :
240 : static int
241 3815840 : member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
242 : {
243 3815840 : if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) {
244 1 : return -1;
245 : }
246 3815840 : return PyMember_SetOne((char *)obj, descr->d_member, value);
247 : }
248 :
249 : static int
250 780669 : getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
251 : {
252 780669 : if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) {
253 1 : return -1;
254 : }
255 780668 : if (descr->d_getset->set != NULL) {
256 780639 : return descr_set_trampoline_call(
257 : descr->d_getset->set, obj, value,
258 : descr->d_getset->closure);
259 : }
260 29 : PyErr_Format(PyExc_AttributeError,
261 : "attribute '%V' of '%.100s' objects is not writable",
262 : descr_name((PyDescrObject *)descr), "?",
263 29 : PyDescr_TYPE(descr)->tp_name);
264 29 : return -1;
265 : }
266 :
267 :
268 : /* Vectorcall functions for each of the PyMethodDescr calling conventions.
269 : *
270 : * First, common helpers
271 : */
272 : static inline int
273 48218800 : method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
274 : {
275 48218800 : assert(!PyErr_Occurred());
276 48218800 : if (nargs < 1) {
277 11 : PyObject *funcstr = _PyObject_FunctionStr(func);
278 11 : if (funcstr != NULL) {
279 11 : PyErr_Format(PyExc_TypeError,
280 : "unbound method %U needs an argument", funcstr);
281 11 : Py_DECREF(funcstr);
282 : }
283 11 : return -1;
284 : }
285 48218800 : PyObject *self = args[0];
286 48218800 : if (descr_check((PyDescrObject *)func, self) < 0) {
287 110 : return -1;
288 : }
289 48218700 : if (kwnames && PyTuple_GET_SIZE(kwnames)) {
290 6 : PyObject *funcstr = _PyObject_FunctionStr(func);
291 6 : if (funcstr != NULL) {
292 6 : PyErr_Format(PyExc_TypeError,
293 : "%U takes no keyword arguments", funcstr);
294 6 : Py_DECREF(funcstr);
295 : }
296 6 : return -1;
297 : }
298 48218700 : return 0;
299 : }
300 :
301 : typedef void (*funcptr)(void);
302 :
303 : static inline funcptr
304 48218700 : method_enter_call(PyThreadState *tstate, PyObject *func)
305 : {
306 48218700 : if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
307 9 : return NULL;
308 : }
309 48218700 : return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth;
310 : }
311 :
312 : /* Now the actual vectorcall functions */
313 : static PyObject *
314 15836200 : method_vectorcall_VARARGS(
315 : PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
316 : {
317 15836200 : PyThreadState *tstate = _PyThreadState_GET();
318 15836200 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
319 15836200 : if (method_check_args(func, args, nargs, kwnames)) {
320 1 : return NULL;
321 : }
322 15836200 : PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
323 15836200 : if (argstuple == NULL) {
324 0 : return NULL;
325 : }
326 15836200 : PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
327 15836200 : if (meth == NULL) {
328 1 : Py_DECREF(argstuple);
329 1 : return NULL;
330 : }
331 15836200 : PyObject *result = _PyCFunction_TrampolineCall(
332 : meth, args[0], argstuple);
333 15836200 : Py_DECREF(argstuple);
334 15836200 : _Py_LeaveRecursiveCallTstate(tstate);
335 15836200 : return result;
336 : }
337 :
338 : static PyObject *
339 6469060 : method_vectorcall_VARARGS_KEYWORDS(
340 : PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
341 : {
342 6469060 : PyThreadState *tstate = _PyThreadState_GET();
343 6469060 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
344 6469060 : if (method_check_args(func, args, nargs, NULL)) {
345 6 : return NULL;
346 : }
347 6469060 : PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1);
348 6469060 : if (argstuple == NULL) {
349 0 : return NULL;
350 : }
351 6469060 : PyObject *result = NULL;
352 : /* Create a temporary dict for keyword arguments */
353 6469060 : PyObject *kwdict = NULL;
354 6469060 : if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) > 0) {
355 36071 : kwdict = _PyStack_AsDict(args + nargs, kwnames);
356 36071 : if (kwdict == NULL) {
357 0 : goto exit;
358 : }
359 : }
360 : PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords)
361 6469060 : method_enter_call(tstate, func);
362 6469060 : if (meth == NULL) {
363 1 : goto exit;
364 : }
365 6469060 : result = _PyCFunctionWithKeywords_TrampolineCall(
366 : meth, args[0], argstuple, kwdict);
367 6469050 : _Py_LeaveRecursiveCallTstate(tstate);
368 6469050 : exit:
369 6469050 : Py_DECREF(argstuple);
370 6469050 : Py_XDECREF(kwdict);
371 6469050 : return result;
372 : }
373 :
374 : static PyObject *
375 11259400 : method_vectorcall_FASTCALL_KEYWORDS_METHOD(
376 : PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
377 : {
378 11259400 : PyThreadState *tstate = _PyThreadState_GET();
379 11259400 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
380 11259400 : if (method_check_args(func, args, nargs, NULL)) {
381 0 : return NULL;
382 : }
383 11259400 : PyCMethod meth = (PyCMethod) method_enter_call(tstate, func);
384 11259400 : if (meth == NULL) {
385 0 : return NULL;
386 : }
387 11259400 : PyObject *result = meth(args[0],
388 : ((PyMethodDescrObject *)func)->d_common.d_type,
389 11259400 : args+1, nargs-1, kwnames);
390 11259400 : _Py_LeaveRecursiveCall();
391 11259400 : return result;
392 : }
393 :
394 : static PyObject *
395 2275880 : method_vectorcall_FASTCALL(
396 : PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
397 : {
398 2275880 : PyThreadState *tstate = _PyThreadState_GET();
399 2275880 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
400 2275880 : if (method_check_args(func, args, nargs, kwnames)) {
401 24 : return NULL;
402 : }
403 : _PyCFunctionFast meth = (_PyCFunctionFast)
404 2275860 : method_enter_call(tstate, func);
405 2275860 : if (meth == NULL) {
406 1 : return NULL;
407 : }
408 2275860 : PyObject *result = meth(args[0], args+1, nargs-1);
409 2275860 : _Py_LeaveRecursiveCallTstate(tstate);
410 2275860 : return result;
411 : }
412 :
413 : static PyObject *
414 852525 : method_vectorcall_FASTCALL_KEYWORDS(
415 : PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
416 : {
417 852525 : PyThreadState *tstate = _PyThreadState_GET();
418 852525 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
419 852525 : if (method_check_args(func, args, nargs, NULL)) {
420 51 : return NULL;
421 : }
422 : _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
423 852474 : method_enter_call(tstate, func);
424 852474 : if (meth == NULL) {
425 0 : return NULL;
426 : }
427 852474 : PyObject *result = meth(args[0], args+1, nargs-1, kwnames);
428 852474 : _Py_LeaveRecursiveCallTstate(tstate);
429 852474 : return result;
430 : }
431 :
432 : static PyObject *
433 8637910 : method_vectorcall_NOARGS(
434 : PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
435 : {
436 8637910 : PyThreadState *tstate = _PyThreadState_GET();
437 8637910 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
438 8637910 : if (method_check_args(func, args, nargs, kwnames)) {
439 21 : return NULL;
440 : }
441 8637890 : if (nargs != 1) {
442 3 : PyObject *funcstr = _PyObject_FunctionStr(func);
443 3 : if (funcstr != NULL) {
444 3 : PyErr_Format(PyExc_TypeError,
445 : "%U takes no arguments (%zd given)", funcstr, nargs-1);
446 3 : Py_DECREF(funcstr);
447 : }
448 3 : return NULL;
449 : }
450 8637890 : PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
451 8637890 : if (meth == NULL) {
452 2 : return NULL;
453 : }
454 8637890 : PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], NULL);
455 8637840 : _Py_LeaveRecursiveCallTstate(tstate);
456 8637840 : return result;
457 : }
458 :
459 : static PyObject *
460 2887800 : method_vectorcall_O(
461 : PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
462 : {
463 2887800 : PyThreadState *tstate = _PyThreadState_GET();
464 2887800 : Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
465 2887800 : if (method_check_args(func, args, nargs, kwnames)) {
466 24 : return NULL;
467 : }
468 2887780 : if (nargs != 2) {
469 2 : PyObject *funcstr = _PyObject_FunctionStr(func);
470 2 : if (funcstr != NULL) {
471 2 : PyErr_Format(PyExc_TypeError,
472 : "%U takes exactly one argument (%zd given)",
473 : funcstr, nargs-1);
474 2 : Py_DECREF(funcstr);
475 : }
476 2 : return NULL;
477 : }
478 2887780 : PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
479 2887780 : if (meth == NULL) {
480 4 : return NULL;
481 : }
482 2887780 : PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], args[1]);
483 2887770 : _Py_LeaveRecursiveCallTstate(tstate);
484 2887770 : return result;
485 : }
486 :
487 :
488 : /* Instances of classmethod_descriptor are unlikely to be called directly.
489 : For one, the analogous class "classmethod" (for Python classes) is not
490 : callable. Second, users are not likely to access a classmethod_descriptor
491 : directly, since it means pulling it from the class __dict__.
492 :
493 : This is just an excuse to say that this doesn't need to be optimized:
494 : we implement this simply by calling __get__ and then calling the result.
495 : */
496 : static PyObject *
497 5 : classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
498 : PyObject *kwds)
499 : {
500 5 : Py_ssize_t argc = PyTuple_GET_SIZE(args);
501 5 : if (argc < 1) {
502 1 : PyErr_Format(PyExc_TypeError,
503 : "descriptor '%V' of '%.100s' "
504 : "object needs an argument",
505 : descr_name((PyDescrObject *)descr), "?",
506 1 : PyDescr_TYPE(descr)->tp_name);
507 1 : return NULL;
508 : }
509 4 : PyObject *self = PyTuple_GET_ITEM(args, 0);
510 4 : PyObject *bound = classmethod_get(descr, NULL, self);
511 4 : if (bound == NULL) {
512 2 : return NULL;
513 : }
514 2 : PyObject *res = PyObject_VectorcallDict(bound, _PyTuple_ITEMS(args)+1,
515 2 : argc-1, kwds);
516 2 : Py_DECREF(bound);
517 2 : return res;
518 : }
519 :
520 : Py_LOCAL_INLINE(PyObject *)
521 12599100 : wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self,
522 : PyObject *args, PyObject *kwds)
523 : {
524 12599100 : wrapperfunc wrapper = descr->d_base->wrapper;
525 :
526 12599100 : if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
527 5047910 : wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper;
528 5047910 : return (*wk)(self, args, descr->d_wrapped, kwds);
529 : }
530 :
531 7551180 : if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) {
532 0 : PyErr_Format(PyExc_TypeError,
533 : "wrapper %s() takes no keyword arguments",
534 0 : descr->d_base->name);
535 0 : return NULL;
536 : }
537 7551180 : return (*wrapper)(self, args, descr->d_wrapped);
538 : }
539 :
540 : static PyObject *
541 3568990 : wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
542 : {
543 : Py_ssize_t argc;
544 : PyObject *self, *result;
545 :
546 : /* Make sure that the first argument is acceptable as 'self' */
547 3568990 : assert(PyTuple_Check(args));
548 3568990 : argc = PyTuple_GET_SIZE(args);
549 3568990 : if (argc < 1) {
550 3 : PyErr_Format(PyExc_TypeError,
551 : "descriptor '%V' of '%.100s' "
552 : "object needs an argument",
553 : descr_name((PyDescrObject *)descr), "?",
554 3 : PyDescr_TYPE(descr)->tp_name);
555 3 : return NULL;
556 : }
557 3568980 : self = PyTuple_GET_ITEM(args, 0);
558 3568980 : if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
559 3568980 : (PyObject *)PyDescr_TYPE(descr))) {
560 3 : PyErr_Format(PyExc_TypeError,
561 : "descriptor '%V' "
562 : "requires a '%.100s' object "
563 : "but received a '%.100s'",
564 : descr_name((PyDescrObject *)descr), "?",
565 3 : PyDescr_TYPE(descr)->tp_name,
566 3 : Py_TYPE(self)->tp_name);
567 3 : return NULL;
568 : }
569 :
570 3568980 : args = PyTuple_GetSlice(args, 1, argc);
571 3568980 : if (args == NULL) {
572 0 : return NULL;
573 : }
574 3568980 : result = wrapperdescr_raw_call(descr, self, args, kwds);
575 3568980 : Py_DECREF(args);
576 3568980 : return result;
577 : }
578 :
579 :
580 : static PyObject *
581 2473 : method_get_doc(PyMethodDescrObject *descr, void *closure)
582 : {
583 2473 : return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
584 : }
585 :
586 : static PyObject *
587 314 : method_get_text_signature(PyMethodDescrObject *descr, void *closure)
588 : {
589 314 : return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
590 : }
591 :
592 : static PyObject *
593 205 : calculate_qualname(PyDescrObject *descr)
594 : {
595 : PyObject *type_qualname, *res;
596 :
597 205 : if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) {
598 0 : PyErr_SetString(PyExc_TypeError,
599 : "<descriptor>.__name__ is not a unicode object");
600 0 : return NULL;
601 : }
602 :
603 205 : type_qualname = PyObject_GetAttr(
604 205 : (PyObject *)descr->d_type, &_Py_ID(__qualname__));
605 205 : if (type_qualname == NULL)
606 0 : return NULL;
607 :
608 205 : if (!PyUnicode_Check(type_qualname)) {
609 0 : PyErr_SetString(PyExc_TypeError, "<descriptor>.__objclass__."
610 : "__qualname__ is not a unicode object");
611 0 : Py_XDECREF(type_qualname);
612 0 : return NULL;
613 : }
614 :
615 205 : res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name);
616 205 : Py_DECREF(type_qualname);
617 205 : return res;
618 : }
619 :
620 : static PyObject *
621 1067 : descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
622 : {
623 1067 : if (descr->d_qualname == NULL)
624 205 : descr->d_qualname = calculate_qualname(descr);
625 1067 : Py_XINCREF(descr->d_qualname);
626 1067 : return descr->d_qualname;
627 : }
628 :
629 : static PyObject *
630 180 : descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
631 : {
632 180 : return Py_BuildValue("N(OO)", _PyEval_GetBuiltin(&_Py_ID(getattr)),
633 : PyDescr_TYPE(descr), PyDescr_NAME(descr));
634 : }
635 :
636 : static PyMethodDef descr_methods[] = {
637 : {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL},
638 : {NULL, NULL}
639 : };
640 :
641 : static PyMemberDef descr_members[] = {
642 : {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
643 : {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
644 : {0}
645 : };
646 :
647 : static PyGetSetDef method_getset[] = {
648 : {"__doc__", (getter)method_get_doc},
649 : {"__qualname__", (getter)descr_get_qualname},
650 : {"__text_signature__", (getter)method_get_text_signature},
651 : {0}
652 : };
653 :
654 : static PyObject *
655 25 : member_get_doc(PyMemberDescrObject *descr, void *closure)
656 : {
657 25 : if (descr->d_member->doc == NULL) {
658 18 : Py_RETURN_NONE;
659 : }
660 7 : return PyUnicode_FromString(descr->d_member->doc);
661 : }
662 :
663 : static PyGetSetDef member_getset[] = {
664 : {"__doc__", (getter)member_get_doc},
665 : {"__qualname__", (getter)descr_get_qualname},
666 : {0}
667 : };
668 :
669 : static PyObject *
670 121 : getset_get_doc(PyGetSetDescrObject *descr, void *closure)
671 : {
672 121 : if (descr->d_getset->doc == NULL) {
673 21 : Py_RETURN_NONE;
674 : }
675 100 : return PyUnicode_FromString(descr->d_getset->doc);
676 : }
677 :
678 : static PyGetSetDef getset_getset[] = {
679 : {"__doc__", (getter)getset_get_doc},
680 : {"__qualname__", (getter)descr_get_qualname},
681 : {0}
682 : };
683 :
684 : static PyObject *
685 3072 : wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
686 : {
687 3072 : return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc);
688 : }
689 :
690 : static PyObject *
691 836 : wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
692 : {
693 836 : return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
694 : }
695 :
696 : static PyGetSetDef wrapperdescr_getset[] = {
697 : {"__doc__", (getter)wrapperdescr_get_doc},
698 : {"__qualname__", (getter)descr_get_qualname},
699 : {"__text_signature__", (getter)wrapperdescr_get_text_signature},
700 : {0}
701 : };
702 :
703 : static int
704 190273000 : descr_traverse(PyObject *self, visitproc visit, void *arg)
705 : {
706 190273000 : PyDescrObject *descr = (PyDescrObject *)self;
707 190273000 : Py_VISIT(descr->d_type);
708 190273000 : return 0;
709 : }
710 :
711 : PyTypeObject PyMethodDescr_Type = {
712 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
713 : "method_descriptor",
714 : sizeof(PyMethodDescrObject),
715 : 0,
716 : (destructor)descr_dealloc, /* tp_dealloc */
717 : offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */
718 : 0, /* tp_getattr */
719 : 0, /* tp_setattr */
720 : 0, /* tp_as_async */
721 : (reprfunc)method_repr, /* tp_repr */
722 : 0, /* tp_as_number */
723 : 0, /* tp_as_sequence */
724 : 0, /* tp_as_mapping */
725 : 0, /* tp_hash */
726 : PyVectorcall_Call, /* tp_call */
727 : 0, /* tp_str */
728 : PyObject_GenericGetAttr, /* tp_getattro */
729 : 0, /* tp_setattro */
730 : 0, /* tp_as_buffer */
731 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
732 : Py_TPFLAGS_HAVE_VECTORCALL |
733 : Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
734 : 0, /* tp_doc */
735 : descr_traverse, /* tp_traverse */
736 : 0, /* tp_clear */
737 : 0, /* tp_richcompare */
738 : 0, /* tp_weaklistoffset */
739 : 0, /* tp_iter */
740 : 0, /* tp_iternext */
741 : descr_methods, /* tp_methods */
742 : descr_members, /* tp_members */
743 : method_getset, /* tp_getset */
744 : 0, /* tp_base */
745 : 0, /* tp_dict */
746 : (descrgetfunc)method_get, /* tp_descr_get */
747 : 0, /* tp_descr_set */
748 : };
749 :
750 : /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
751 : PyTypeObject PyClassMethodDescr_Type = {
752 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
753 : "classmethod_descriptor",
754 : sizeof(PyMethodDescrObject),
755 : 0,
756 : (destructor)descr_dealloc, /* tp_dealloc */
757 : 0, /* tp_vectorcall_offset */
758 : 0, /* tp_getattr */
759 : 0, /* tp_setattr */
760 : 0, /* tp_as_async */
761 : (reprfunc)method_repr, /* tp_repr */
762 : 0, /* tp_as_number */
763 : 0, /* tp_as_sequence */
764 : 0, /* tp_as_mapping */
765 : 0, /* tp_hash */
766 : (ternaryfunc)classmethoddescr_call, /* tp_call */
767 : 0, /* tp_str */
768 : PyObject_GenericGetAttr, /* tp_getattro */
769 : 0, /* tp_setattro */
770 : 0, /* tp_as_buffer */
771 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
772 : 0, /* tp_doc */
773 : descr_traverse, /* tp_traverse */
774 : 0, /* tp_clear */
775 : 0, /* tp_richcompare */
776 : 0, /* tp_weaklistoffset */
777 : 0, /* tp_iter */
778 : 0, /* tp_iternext */
779 : descr_methods, /* tp_methods */
780 : descr_members, /* tp_members */
781 : method_getset, /* tp_getset */
782 : 0, /* tp_base */
783 : 0, /* tp_dict */
784 : (descrgetfunc)classmethod_get, /* tp_descr_get */
785 : 0, /* tp_descr_set */
786 : };
787 :
788 : PyTypeObject PyMemberDescr_Type = {
789 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
790 : "member_descriptor",
791 : sizeof(PyMemberDescrObject),
792 : 0,
793 : (destructor)descr_dealloc, /* tp_dealloc */
794 : 0, /* tp_vectorcall_offset */
795 : 0, /* tp_getattr */
796 : 0, /* tp_setattr */
797 : 0, /* tp_as_async */
798 : (reprfunc)member_repr, /* tp_repr */
799 : 0, /* tp_as_number */
800 : 0, /* tp_as_sequence */
801 : 0, /* tp_as_mapping */
802 : 0, /* tp_hash */
803 : 0, /* tp_call */
804 : 0, /* tp_str */
805 : PyObject_GenericGetAttr, /* tp_getattro */
806 : 0, /* tp_setattro */
807 : 0, /* tp_as_buffer */
808 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
809 : 0, /* tp_doc */
810 : descr_traverse, /* tp_traverse */
811 : 0, /* tp_clear */
812 : 0, /* tp_richcompare */
813 : 0, /* tp_weaklistoffset */
814 : 0, /* tp_iter */
815 : 0, /* tp_iternext */
816 : descr_methods, /* tp_methods */
817 : descr_members, /* tp_members */
818 : member_getset, /* tp_getset */
819 : 0, /* tp_base */
820 : 0, /* tp_dict */
821 : (descrgetfunc)member_get, /* tp_descr_get */
822 : (descrsetfunc)member_set, /* tp_descr_set */
823 : };
824 :
825 : PyTypeObject PyGetSetDescr_Type = {
826 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
827 : "getset_descriptor",
828 : sizeof(PyGetSetDescrObject),
829 : 0,
830 : (destructor)descr_dealloc, /* tp_dealloc */
831 : 0, /* tp_vectorcall_offset */
832 : 0, /* tp_getattr */
833 : 0, /* tp_setattr */
834 : 0, /* tp_as_async */
835 : (reprfunc)getset_repr, /* tp_repr */
836 : 0, /* tp_as_number */
837 : 0, /* tp_as_sequence */
838 : 0, /* tp_as_mapping */
839 : 0, /* tp_hash */
840 : 0, /* tp_call */
841 : 0, /* tp_str */
842 : PyObject_GenericGetAttr, /* tp_getattro */
843 : 0, /* tp_setattro */
844 : 0, /* tp_as_buffer */
845 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
846 : 0, /* tp_doc */
847 : descr_traverse, /* tp_traverse */
848 : 0, /* tp_clear */
849 : 0, /* tp_richcompare */
850 : 0, /* tp_weaklistoffset */
851 : 0, /* tp_iter */
852 : 0, /* tp_iternext */
853 : 0, /* tp_methods */
854 : descr_members, /* tp_members */
855 : getset_getset, /* tp_getset */
856 : 0, /* tp_base */
857 : 0, /* tp_dict */
858 : (descrgetfunc)getset_get, /* tp_descr_get */
859 : (descrsetfunc)getset_set, /* tp_descr_set */
860 : };
861 :
862 : PyTypeObject PyWrapperDescr_Type = {
863 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
864 : "wrapper_descriptor",
865 : sizeof(PyWrapperDescrObject),
866 : 0,
867 : (destructor)descr_dealloc, /* tp_dealloc */
868 : 0, /* tp_vectorcall_offset */
869 : 0, /* tp_getattr */
870 : 0, /* tp_setattr */
871 : 0, /* tp_as_async */
872 : (reprfunc)wrapperdescr_repr, /* tp_repr */
873 : 0, /* tp_as_number */
874 : 0, /* tp_as_sequence */
875 : 0, /* tp_as_mapping */
876 : 0, /* tp_hash */
877 : (ternaryfunc)wrapperdescr_call, /* tp_call */
878 : 0, /* tp_str */
879 : PyObject_GenericGetAttr, /* tp_getattro */
880 : 0, /* tp_setattro */
881 : 0, /* tp_as_buffer */
882 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
883 : Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */
884 : 0, /* tp_doc */
885 : descr_traverse, /* tp_traverse */
886 : 0, /* tp_clear */
887 : 0, /* tp_richcompare */
888 : 0, /* tp_weaklistoffset */
889 : 0, /* tp_iter */
890 : 0, /* tp_iternext */
891 : descr_methods, /* tp_methods */
892 : descr_members, /* tp_members */
893 : wrapperdescr_getset, /* tp_getset */
894 : 0, /* tp_base */
895 : 0, /* tp_dict */
896 : (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
897 : 0, /* tp_descr_set */
898 : };
899 :
900 : static PyDescrObject *
901 8241170 : descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
902 : {
903 : PyDescrObject *descr;
904 :
905 8241170 : descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
906 8241170 : if (descr != NULL) {
907 8241170 : Py_XINCREF(type);
908 8241170 : descr->d_type = type;
909 8241170 : descr->d_name = PyUnicode_InternFromString(name);
910 8241170 : if (descr->d_name == NULL) {
911 0 : Py_DECREF(descr);
912 0 : descr = NULL;
913 : }
914 : else {
915 8241170 : descr->d_qualname = NULL;
916 : }
917 : }
918 8241170 : return descr;
919 : }
920 :
921 : PyObject *
922 2273040 : PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
923 : {
924 : /* Figure out correct vectorcall function to use */
925 : vectorcallfunc vectorcall;
926 2273040 : switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS |
927 : METH_O | METH_KEYWORDS | METH_METHOD))
928 : {
929 215740 : case METH_VARARGS:
930 215740 : vectorcall = method_vectorcall_VARARGS;
931 215740 : break;
932 31135 : case METH_VARARGS | METH_KEYWORDS:
933 31135 : vectorcall = method_vectorcall_VARARGS_KEYWORDS;
934 31135 : break;
935 248803 : case METH_FASTCALL:
936 248803 : vectorcall = method_vectorcall_FASTCALL;
937 248803 : break;
938 127087 : case METH_FASTCALL | METH_KEYWORDS:
939 127087 : vectorcall = method_vectorcall_FASTCALL_KEYWORDS;
940 127087 : break;
941 1180650 : case METH_NOARGS:
942 1180650 : vectorcall = method_vectorcall_NOARGS;
943 1180650 : break;
944 417044 : case METH_O:
945 417044 : vectorcall = method_vectorcall_O;
946 417044 : break;
947 52577 : case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
948 52577 : vectorcall = method_vectorcall_FASTCALL_KEYWORDS_METHOD;
949 52577 : break;
950 0 : default:
951 0 : PyErr_Format(PyExc_SystemError,
952 : "%s() method: bad call flags", method->ml_name);
953 0 : return NULL;
954 : }
955 :
956 : PyMethodDescrObject *descr;
957 :
958 2273040 : descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
959 : type, method->ml_name);
960 2273040 : if (descr != NULL) {
961 2273040 : descr->d_method = method;
962 2273040 : descr->vectorcall = vectorcall;
963 : }
964 2273040 : return (PyObject *)descr;
965 : }
966 :
967 : PyObject *
968 97156 : PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
969 : {
970 : PyMethodDescrObject *descr;
971 :
972 97156 : descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
973 : type, method->ml_name);
974 97156 : if (descr != NULL)
975 97156 : descr->d_method = method;
976 97156 : return (PyObject *)descr;
977 : }
978 :
979 : PyObject *
980 1031600 : PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
981 : {
982 : PyMemberDescrObject *descr;
983 :
984 1031600 : descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
985 : type, member->name);
986 1031600 : if (descr != NULL)
987 1031600 : descr->d_member = member;
988 1031600 : return (PyObject *)descr;
989 : }
990 :
991 : PyObject *
992 1409630 : PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
993 : {
994 : PyGetSetDescrObject *descr;
995 :
996 1409630 : descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
997 : type, getset->name);
998 1409630 : if (descr != NULL)
999 1409630 : descr->d_getset = getset;
1000 1409630 : return (PyObject *)descr;
1001 : }
1002 :
1003 : PyObject *
1004 3429750 : PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
1005 : {
1006 : PyWrapperDescrObject *descr;
1007 :
1008 3429750 : descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
1009 : type, base->name);
1010 3429750 : if (descr != NULL) {
1011 3429750 : descr->d_base = base;
1012 3429750 : descr->d_wrapped = wrapped;
1013 : }
1014 3429750 : return (PyObject *)descr;
1015 : }
1016 :
1017 : int
1018 90303300 : PyDescr_IsData(PyObject *ob)
1019 : {
1020 90303300 : return Py_TYPE(ob)->tp_descr_set != NULL;
1021 : }
1022 :
1023 : /* --- mappingproxy: read-only proxy for mappings --- */
1024 :
1025 : /* This has no reason to be in this file except that adding new files is a
1026 : bit of a pain */
1027 :
1028 : typedef struct {
1029 : PyObject_HEAD
1030 : PyObject *mapping;
1031 : } mappingproxyobject;
1032 :
1033 : static Py_ssize_t
1034 6873 : mappingproxy_len(mappingproxyobject *pp)
1035 : {
1036 6873 : return PyObject_Size(pp->mapping);
1037 : }
1038 :
1039 : static PyObject *
1040 2111180 : mappingproxy_getitem(mappingproxyobject *pp, PyObject *key)
1041 : {
1042 2111180 : return PyObject_GetItem(pp->mapping, key);
1043 : }
1044 :
1045 : static PyMappingMethods mappingproxy_as_mapping = {
1046 : (lenfunc)mappingproxy_len, /* mp_length */
1047 : (binaryfunc)mappingproxy_getitem, /* mp_subscript */
1048 : 0, /* mp_ass_subscript */
1049 : };
1050 :
1051 : static PyObject *
1052 4 : mappingproxy_or(PyObject *left, PyObject *right)
1053 : {
1054 4 : if (PyObject_TypeCheck(left, &PyDictProxy_Type)) {
1055 2 : left = ((mappingproxyobject*)left)->mapping;
1056 : }
1057 4 : if (PyObject_TypeCheck(right, &PyDictProxy_Type)) {
1058 2 : right = ((mappingproxyobject*)right)->mapping;
1059 : }
1060 4 : return PyNumber_Or(left, right);
1061 : }
1062 :
1063 : static PyObject *
1064 1 : mappingproxy_ior(PyObject *self, PyObject *Py_UNUSED(other))
1065 : {
1066 1 : return PyErr_Format(PyExc_TypeError,
1067 1 : "'|=' is not supported by %s; use '|' instead", Py_TYPE(self)->tp_name);
1068 : }
1069 :
1070 : static PyNumberMethods mappingproxy_as_number = {
1071 : .nb_or = mappingproxy_or,
1072 : .nb_inplace_or = mappingproxy_ior,
1073 : };
1074 :
1075 : static int
1076 341782 : mappingproxy_contains(mappingproxyobject *pp, PyObject *key)
1077 : {
1078 341782 : if (PyDict_CheckExact(pp->mapping))
1079 341773 : return PyDict_Contains(pp->mapping, key);
1080 : else
1081 9 : return PySequence_Contains(pp->mapping, key);
1082 : }
1083 :
1084 : static PySequenceMethods mappingproxy_as_sequence = {
1085 : 0, /* sq_length */
1086 : 0, /* sq_concat */
1087 : 0, /* sq_repeat */
1088 : 0, /* sq_item */
1089 : 0, /* sq_slice */
1090 : 0, /* sq_ass_item */
1091 : 0, /* sq_ass_slice */
1092 : (objobjproc)mappingproxy_contains, /* sq_contains */
1093 : 0, /* sq_inplace_concat */
1094 : 0, /* sq_inplace_repeat */
1095 : };
1096 :
1097 : static PyObject *
1098 658903 : mappingproxy_get(mappingproxyobject *pp, PyObject *const *args, Py_ssize_t nargs)
1099 : {
1100 : /* newargs: mapping, key, default=None */
1101 : PyObject *newargs[3];
1102 658903 : newargs[0] = pp->mapping;
1103 658903 : newargs[2] = Py_None;
1104 :
1105 658903 : if (!_PyArg_UnpackStack(args, nargs, "get", 1, 2,
1106 : &newargs[1], &newargs[2]))
1107 : {
1108 0 : return NULL;
1109 : }
1110 658903 : return _PyObject_VectorcallMethod(&_Py_ID(get), newargs,
1111 : 3 | PY_VECTORCALL_ARGUMENTS_OFFSET,
1112 : NULL);
1113 : }
1114 :
1115 : static PyObject *
1116 96885 : mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
1117 : {
1118 96885 : return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(keys));
1119 : }
1120 :
1121 : static PyObject *
1122 15054 : mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
1123 : {
1124 15054 : return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(values));
1125 : }
1126 :
1127 : static PyObject *
1128 200002 : mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
1129 : {
1130 200002 : return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(items));
1131 : }
1132 :
1133 : static PyObject *
1134 18 : mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
1135 : {
1136 18 : return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(copy));
1137 : }
1138 :
1139 : static PyObject *
1140 1 : mappingproxy_reversed(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
1141 : {
1142 1 : return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(__reversed__));
1143 : }
1144 :
1145 : /* WARNING: mappingproxy methods must not give access
1146 : to the underlying mapping */
1147 :
1148 : static PyMethodDef mappingproxy_methods[] = {
1149 : {"get", _PyCFunction_CAST(mappingproxy_get), METH_FASTCALL,
1150 : PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d."
1151 : " d defaults to None.")},
1152 : {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS,
1153 : PyDoc_STR("D.keys() -> a set-like object providing a view on D's keys")},
1154 : {"values", (PyCFunction)mappingproxy_values, METH_NOARGS,
1155 : PyDoc_STR("D.values() -> an object providing a view on D's values")},
1156 : {"items", (PyCFunction)mappingproxy_items, METH_NOARGS,
1157 : PyDoc_STR("D.items() -> a set-like object providing a view on D's items")},
1158 : {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS,
1159 : PyDoc_STR("D.copy() -> a shallow copy of D")},
1160 : {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS,
1161 : PyDoc_STR("See PEP 585")},
1162 : {"__reversed__", (PyCFunction)mappingproxy_reversed, METH_NOARGS,
1163 : PyDoc_STR("D.__reversed__() -> reverse iterator")},
1164 : {0}
1165 : };
1166 :
1167 : static void
1168 1462780 : mappingproxy_dealloc(mappingproxyobject *pp)
1169 : {
1170 1462780 : _PyObject_GC_UNTRACK(pp);
1171 1462780 : Py_DECREF(pp->mapping);
1172 1462780 : PyObject_GC_Del(pp);
1173 1462780 : }
1174 :
1175 : static PyObject *
1176 9103 : mappingproxy_getiter(mappingproxyobject *pp)
1177 : {
1178 9103 : return PyObject_GetIter(pp->mapping);
1179 : }
1180 :
1181 : static Py_hash_t
1182 2 : mappingproxy_hash(mappingproxyobject *pp)
1183 : {
1184 2 : return PyObject_Hash(pp->mapping);
1185 : }
1186 :
1187 : static PyObject *
1188 0 : mappingproxy_str(mappingproxyobject *pp)
1189 : {
1190 0 : return PyObject_Str(pp->mapping);
1191 : }
1192 :
1193 : static PyObject *
1194 9 : mappingproxy_repr(mappingproxyobject *pp)
1195 : {
1196 9 : return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping);
1197 : }
1198 :
1199 : static int
1200 77687 : mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
1201 : {
1202 77687 : mappingproxyobject *pp = (mappingproxyobject *)self;
1203 77687 : Py_VISIT(pp->mapping);
1204 77687 : return 0;
1205 : }
1206 :
1207 : static PyObject *
1208 133 : mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op)
1209 : {
1210 133 : return PyObject_RichCompare(v->mapping, w, op);
1211 : }
1212 :
1213 : static int
1214 1462790 : mappingproxy_check_mapping(PyObject *mapping)
1215 : {
1216 1462790 : if (!PyMapping_Check(mapping)
1217 1462780 : || PyList_Check(mapping)
1218 1462780 : || PyTuple_Check(mapping)) {
1219 4 : PyErr_Format(PyExc_TypeError,
1220 : "mappingproxy() argument must be a mapping, not %s",
1221 4 : Py_TYPE(mapping)->tp_name);
1222 4 : return -1;
1223 : }
1224 1462780 : return 0;
1225 : }
1226 :
1227 : /*[clinic input]
1228 : @classmethod
1229 : mappingproxy.__new__ as mappingproxy_new
1230 :
1231 : mapping: object
1232 :
1233 : [clinic start generated code]*/
1234 :
1235 : static PyObject *
1236 27844 : mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping)
1237 : /*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/
1238 : {
1239 : mappingproxyobject *mappingproxy;
1240 :
1241 27844 : if (mappingproxy_check_mapping(mapping) == -1)
1242 4 : return NULL;
1243 :
1244 27840 : mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
1245 27840 : if (mappingproxy == NULL)
1246 0 : return NULL;
1247 27840 : Py_INCREF(mapping);
1248 27840 : mappingproxy->mapping = mapping;
1249 27840 : _PyObject_GC_TRACK(mappingproxy);
1250 27840 : return (PyObject *)mappingproxy;
1251 : }
1252 :
1253 : PyObject *
1254 1434940 : PyDictProxy_New(PyObject *mapping)
1255 : {
1256 : mappingproxyobject *pp;
1257 :
1258 1434940 : if (mappingproxy_check_mapping(mapping) == -1)
1259 0 : return NULL;
1260 :
1261 1434940 : pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type);
1262 1434940 : if (pp != NULL) {
1263 1434940 : Py_INCREF(mapping);
1264 1434940 : pp->mapping = mapping;
1265 1434940 : _PyObject_GC_TRACK(pp);
1266 : }
1267 1434940 : return (PyObject *)pp;
1268 : }
1269 :
1270 :
1271 : /* --- Wrapper object for "slot" methods --- */
1272 :
1273 : /* This has no reason to be in this file except that adding new files is a
1274 : bit of a pain */
1275 :
1276 : typedef struct {
1277 : PyObject_HEAD
1278 : PyWrapperDescrObject *descr;
1279 : PyObject *self;
1280 : } wrapperobject;
1281 :
1282 : #define Wrapper_Check(v) Py_IS_TYPE(v, &_PyMethodWrapper_Type)
1283 :
1284 : static void
1285 8048440 : wrapper_dealloc(wrapperobject *wp)
1286 : {
1287 8048440 : PyObject_GC_UnTrack(wp);
1288 8048440 : Py_TRASHCAN_BEGIN(wp, wrapper_dealloc)
1289 8028040 : Py_XDECREF(wp->descr);
1290 8028040 : Py_XDECREF(wp->self);
1291 8028040 : PyObject_GC_Del(wp);
1292 8028040 : Py_TRASHCAN_END
1293 8048440 : }
1294 :
1295 : static PyObject *
1296 14 : wrapper_richcompare(PyObject *a, PyObject *b, int op)
1297 : {
1298 : wrapperobject *wa, *wb;
1299 : int eq;
1300 :
1301 14 : assert(a != NULL && b != NULL);
1302 :
1303 : /* both arguments should be wrapperobjects */
1304 14 : if ((op != Py_EQ && op != Py_NE)
1305 6 : || !Wrapper_Check(a) || !Wrapper_Check(b))
1306 : {
1307 8 : Py_RETURN_NOTIMPLEMENTED;
1308 : }
1309 :
1310 6 : wa = (wrapperobject *)a;
1311 6 : wb = (wrapperobject *)b;
1312 6 : eq = (wa->descr == wb->descr && wa->self == wb->self);
1313 6 : if (eq == (op == Py_EQ)) {
1314 3 : Py_RETURN_TRUE;
1315 : }
1316 : else {
1317 3 : Py_RETURN_FALSE;
1318 : }
1319 : }
1320 :
1321 : static Py_hash_t
1322 1 : wrapper_hash(wrapperobject *wp)
1323 : {
1324 : Py_hash_t x, y;
1325 1 : x = _Py_HashPointer(wp->self);
1326 1 : y = _Py_HashPointer(wp->descr);
1327 1 : x = x ^ y;
1328 1 : if (x == -1)
1329 0 : x = -2;
1330 1 : return x;
1331 : }
1332 :
1333 : static PyObject *
1334 34 : wrapper_repr(wrapperobject *wp)
1335 : {
1336 102 : return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
1337 34 : wp->descr->d_base->name,
1338 34 : Py_TYPE(wp->self)->tp_name,
1339 : wp->self);
1340 : }
1341 :
1342 : static PyObject *
1343 36 : wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
1344 : {
1345 36 : return Py_BuildValue("N(OO)", _PyEval_GetBuiltin(&_Py_ID(getattr)),
1346 36 : wp->self, PyDescr_NAME(wp->descr));
1347 : }
1348 :
1349 : static PyMethodDef wrapper_methods[] = {
1350 : {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL},
1351 : {NULL, NULL}
1352 : };
1353 :
1354 : static PyMemberDef wrapper_members[] = {
1355 : {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
1356 : {0}
1357 : };
1358 :
1359 : static PyObject *
1360 1 : wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored))
1361 : {
1362 1 : PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
1363 :
1364 1 : Py_INCREF(c);
1365 1 : return c;
1366 : }
1367 :
1368 : static PyObject *
1369 138378 : wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored))
1370 : {
1371 138378 : const char *s = wp->descr->d_base->name;
1372 :
1373 138378 : return PyUnicode_FromString(s);
1374 : }
1375 :
1376 : static PyObject *
1377 164 : wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored))
1378 : {
1379 164 : return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
1380 : }
1381 :
1382 : static PyObject *
1383 531 : wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
1384 : {
1385 531 : return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
1386 : }
1387 :
1388 : static PyObject *
1389 0 : wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored))
1390 : {
1391 0 : return descr_get_qualname((PyDescrObject *)wp->descr, NULL);
1392 : }
1393 :
1394 : static PyGetSetDef wrapper_getsets[] = {
1395 : {"__objclass__", (getter)wrapper_objclass},
1396 : {"__name__", (getter)wrapper_name},
1397 : {"__qualname__", (getter)wrapper_qualname},
1398 : {"__doc__", (getter)wrapper_doc},
1399 : {"__text_signature__", (getter)wrapper_text_signature},
1400 : {0}
1401 : };
1402 :
1403 : static PyObject *
1404 9030110 : wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
1405 : {
1406 9030110 : return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds);
1407 : }
1408 :
1409 : static int
1410 11345700 : wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1411 : {
1412 11345700 : wrapperobject *wp = (wrapperobject *)self;
1413 11345700 : Py_VISIT(wp->descr);
1414 11345700 : Py_VISIT(wp->self);
1415 11345700 : return 0;
1416 : }
1417 :
1418 : PyTypeObject _PyMethodWrapper_Type = {
1419 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
1420 : "method-wrapper", /* tp_name */
1421 : sizeof(wrapperobject), /* tp_basicsize */
1422 : 0, /* tp_itemsize */
1423 : /* methods */
1424 : (destructor)wrapper_dealloc, /* tp_dealloc */
1425 : 0, /* tp_vectorcall_offset */
1426 : 0, /* tp_getattr */
1427 : 0, /* tp_setattr */
1428 : 0, /* tp_as_async */
1429 : (reprfunc)wrapper_repr, /* tp_repr */
1430 : 0, /* tp_as_number */
1431 : 0, /* tp_as_sequence */
1432 : 0, /* tp_as_mapping */
1433 : (hashfunc)wrapper_hash, /* tp_hash */
1434 : (ternaryfunc)wrapper_call, /* tp_call */
1435 : 0, /* tp_str */
1436 : PyObject_GenericGetAttr, /* tp_getattro */
1437 : 0, /* tp_setattro */
1438 : 0, /* tp_as_buffer */
1439 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1440 : 0, /* tp_doc */
1441 : wrapper_traverse, /* tp_traverse */
1442 : 0, /* tp_clear */
1443 : wrapper_richcompare, /* tp_richcompare */
1444 : 0, /* tp_weaklistoffset */
1445 : 0, /* tp_iter */
1446 : 0, /* tp_iternext */
1447 : wrapper_methods, /* tp_methods */
1448 : wrapper_members, /* tp_members */
1449 : wrapper_getsets, /* tp_getset */
1450 : 0, /* tp_base */
1451 : 0, /* tp_dict */
1452 : 0, /* tp_descr_get */
1453 : 0, /* tp_descr_set */
1454 : };
1455 :
1456 : PyObject *
1457 8028040 : PyWrapper_New(PyObject *d, PyObject *self)
1458 : {
1459 : wrapperobject *wp;
1460 : PyWrapperDescrObject *descr;
1461 :
1462 8028040 : assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1463 8028040 : descr = (PyWrapperDescrObject *)d;
1464 8028040 : assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
1465 : (PyObject *)PyDescr_TYPE(descr)));
1466 :
1467 8028040 : wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type);
1468 8028040 : if (wp != NULL) {
1469 8028040 : Py_INCREF(descr);
1470 8028040 : wp->descr = descr;
1471 8028040 : Py_INCREF(self);
1472 8028040 : wp->self = self;
1473 8028040 : _PyObject_GC_TRACK(wp);
1474 : }
1475 8028040 : return (PyObject *)wp;
1476 : }
1477 :
1478 :
1479 : /* A built-in 'property' type */
1480 :
1481 : /*
1482 : class property(object):
1483 :
1484 : def __init__(self, fget=None, fset=None, fdel=None, doc=None):
1485 : if doc is None and fget is not None and hasattr(fget, "__doc__"):
1486 : doc = fget.__doc__
1487 : self.__get = fget
1488 : self.__set = fset
1489 : self.__del = fdel
1490 : self.__doc__ = doc
1491 :
1492 : def __get__(self, inst, type=None):
1493 : if inst is None:
1494 : return self
1495 : if self.__get is None:
1496 : raise AttributeError, "property has no getter"
1497 : return self.__get(inst)
1498 :
1499 : def __set__(self, inst, value):
1500 : if self.__set is None:
1501 : raise AttributeError, "property has no setter"
1502 : return self.__set(inst, value)
1503 :
1504 : def __delete__(self, inst):
1505 : if self.__del is None:
1506 : raise AttributeError, "property has no deleter"
1507 : return self.__del(inst)
1508 :
1509 : */
1510 :
1511 : static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
1512 : PyObject *);
1513 :
1514 : static PyMemberDef property_members[] = {
1515 : {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
1516 : {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
1517 : {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
1518 : {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0},
1519 : {0}
1520 : };
1521 :
1522 :
1523 : PyDoc_STRVAR(getter_doc,
1524 : "Descriptor to obtain a copy of the property with a different getter.");
1525 :
1526 : static PyObject *
1527 16 : property_getter(PyObject *self, PyObject *getter)
1528 : {
1529 16 : return property_copy(self, getter, NULL, NULL);
1530 : }
1531 :
1532 :
1533 : PyDoc_STRVAR(setter_doc,
1534 : "Descriptor to obtain a copy of the property with a different setter.");
1535 :
1536 : static PyObject *
1537 25011 : property_setter(PyObject *self, PyObject *setter)
1538 : {
1539 25011 : return property_copy(self, NULL, setter, NULL);
1540 : }
1541 :
1542 :
1543 : PyDoc_STRVAR(deleter_doc,
1544 : "Descriptor to obtain a copy of the property with a different deleter.");
1545 :
1546 : static PyObject *
1547 77 : property_deleter(PyObject *self, PyObject *deleter)
1548 : {
1549 77 : return property_copy(self, NULL, NULL, deleter);
1550 : }
1551 :
1552 :
1553 : PyDoc_STRVAR(set_name_doc,
1554 : "Method to set name of a property.");
1555 :
1556 : static PyObject *
1557 162493 : property_set_name(PyObject *self, PyObject *args) {
1558 162493 : if (PyTuple_GET_SIZE(args) != 2) {
1559 3 : PyErr_Format(
1560 : PyExc_TypeError,
1561 : "__set_name__() takes 2 positional arguments but %d were given",
1562 : PyTuple_GET_SIZE(args));
1563 3 : return NULL;
1564 : }
1565 :
1566 162490 : propertyobject *prop = (propertyobject *)self;
1567 162490 : PyObject *name = PyTuple_GET_ITEM(args, 1);
1568 :
1569 162490 : Py_XINCREF(name);
1570 162490 : Py_XSETREF(prop->prop_name, name);
1571 :
1572 162490 : Py_RETURN_NONE;
1573 : }
1574 :
1575 : static PyMethodDef property_methods[] = {
1576 : {"getter", property_getter, METH_O, getter_doc},
1577 : {"setter", property_setter, METH_O, setter_doc},
1578 : {"deleter", property_deleter, METH_O, deleter_doc},
1579 : {"__set_name__", property_set_name, METH_VARARGS, set_name_doc},
1580 : {0}
1581 : };
1582 :
1583 :
1584 : static void
1585 179244 : property_dealloc(PyObject *self)
1586 : {
1587 179244 : propertyobject *gs = (propertyobject *)self;
1588 :
1589 179244 : _PyObject_GC_UNTRACK(self);
1590 179244 : Py_XDECREF(gs->prop_get);
1591 179244 : Py_XDECREF(gs->prop_set);
1592 179244 : Py_XDECREF(gs->prop_del);
1593 179244 : Py_XDECREF(gs->prop_doc);
1594 179244 : Py_XDECREF(gs->prop_name);
1595 179244 : Py_TYPE(self)->tp_free(self);
1596 179244 : }
1597 :
1598 : static PyObject *
1599 659036 : property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1600 : {
1601 659036 : if (obj == NULL || obj == Py_None) {
1602 2232 : Py_INCREF(self);
1603 2232 : return self;
1604 : }
1605 :
1606 656804 : propertyobject *gs = (propertyobject *)self;
1607 656804 : if (gs->prop_get == NULL) {
1608 2 : PyObject *qualname = PyType_GetQualName(Py_TYPE(obj));
1609 2 : if (gs->prop_name != NULL && qualname != NULL) {
1610 1 : PyErr_Format(PyExc_AttributeError,
1611 : "property %R of %R object has no getter",
1612 : gs->prop_name,
1613 : qualname);
1614 : }
1615 1 : else if (qualname != NULL) {
1616 1 : PyErr_Format(PyExc_AttributeError,
1617 : "property of %R object has no getter",
1618 : qualname);
1619 : } else {
1620 0 : PyErr_SetString(PyExc_AttributeError,
1621 : "property has no getter");
1622 : }
1623 2 : Py_XDECREF(qualname);
1624 2 : return NULL;
1625 : }
1626 :
1627 656802 : return PyObject_CallOneArg(gs->prop_get, obj);
1628 : }
1629 :
1630 : static int
1631 76487 : property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
1632 : {
1633 76487 : propertyobject *gs = (propertyobject *)self;
1634 : PyObject *func, *res;
1635 :
1636 76487 : if (value == NULL) {
1637 17 : func = gs->prop_del;
1638 : }
1639 : else {
1640 76470 : func = gs->prop_set;
1641 : }
1642 :
1643 76487 : if (func == NULL) {
1644 104 : PyObject *qualname = NULL;
1645 104 : if (obj != NULL) {
1646 104 : qualname = PyType_GetQualName(Py_TYPE(obj));
1647 : }
1648 104 : if (gs->prop_name != NULL && qualname != NULL) {
1649 102 : PyErr_Format(PyExc_AttributeError,
1650 : value == NULL ?
1651 : "property %R of %R object has no deleter" :
1652 : "property %R of %R object has no setter",
1653 : gs->prop_name,
1654 : qualname);
1655 : }
1656 2 : else if (qualname != NULL) {
1657 2 : PyErr_Format(PyExc_AttributeError,
1658 : value == NULL ?
1659 : "property of %R object has no deleter" :
1660 : "property of %R object has no setter",
1661 : qualname);
1662 : }
1663 : else {
1664 0 : PyErr_SetString(PyExc_AttributeError,
1665 : value == NULL ?
1666 : "property has no deleter" :
1667 : "property has no setter");
1668 : }
1669 104 : Py_XDECREF(qualname);
1670 104 : return -1;
1671 : }
1672 :
1673 76383 : if (value == NULL) {
1674 15 : res = PyObject_CallOneArg(func, obj);
1675 : }
1676 : else {
1677 : EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
1678 76368 : PyObject *args[] = { obj, value };
1679 76368 : res = PyObject_Vectorcall(func, args, 2, NULL);
1680 : }
1681 :
1682 76383 : if (res == NULL) {
1683 29 : return -1;
1684 : }
1685 :
1686 76354 : Py_DECREF(res);
1687 76354 : return 0;
1688 : }
1689 :
1690 : static PyObject *
1691 25104 : property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
1692 : {
1693 25104 : propertyobject *pold = (propertyobject *)old;
1694 : PyObject *new, *type, *doc;
1695 :
1696 25104 : type = PyObject_Type(old);
1697 25104 : if (type == NULL)
1698 0 : return NULL;
1699 :
1700 25104 : if (get == NULL || get == Py_None) {
1701 25088 : Py_XDECREF(get);
1702 25088 : get = pold->prop_get ? pold->prop_get : Py_None;
1703 : }
1704 25104 : if (set == NULL || set == Py_None) {
1705 93 : Py_XDECREF(set);
1706 93 : set = pold->prop_set ? pold->prop_set : Py_None;
1707 : }
1708 25104 : if (del == NULL || del == Py_None) {
1709 25027 : Py_XDECREF(del);
1710 25027 : del = pold->prop_del ? pold->prop_del : Py_None;
1711 : }
1712 25104 : if (pold->getter_doc && get != Py_None) {
1713 : /* make _init use __doc__ from getter */
1714 9364 : doc = Py_None;
1715 : }
1716 : else {
1717 15740 : doc = pold->prop_doc ? pold->prop_doc : Py_None;
1718 : }
1719 :
1720 25104 : new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
1721 25104 : Py_DECREF(type);
1722 25104 : if (new == NULL)
1723 0 : return NULL;
1724 :
1725 25104 : Py_XINCREF(pold->prop_name);
1726 25104 : Py_XSETREF(((propertyobject *) new)->prop_name, pold->prop_name);
1727 25104 : return new;
1728 : }
1729 :
1730 : /*[clinic input]
1731 : property.__init__ as property_init
1732 :
1733 : fget: object(c_default="NULL") = None
1734 : function to be used for getting an attribute value
1735 : fset: object(c_default="NULL") = None
1736 : function to be used for setting an attribute value
1737 : fdel: object(c_default="NULL") = None
1738 : function to be used for del'ing an attribute
1739 : doc: object(c_default="NULL") = None
1740 : docstring
1741 :
1742 : Property attribute.
1743 :
1744 : Typical use is to define a managed attribute x:
1745 :
1746 : class C(object):
1747 : def getx(self): return self._x
1748 : def setx(self, value): self._x = value
1749 : def delx(self): del self._x
1750 : x = property(getx, setx, delx, "I'm the 'x' property.")
1751 :
1752 : Decorators make defining new properties or modifying existing ones easy:
1753 :
1754 : class C(object):
1755 : @property
1756 : def x(self):
1757 : "I am the 'x' property."
1758 : return self._x
1759 : @x.setter
1760 : def x(self, value):
1761 : self._x = value
1762 : @x.deleter
1763 : def x(self):
1764 : del self._x
1765 : [clinic start generated code]*/
1766 :
1767 : static int
1768 182166 : property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1769 : PyObject *fdel, PyObject *doc)
1770 : /*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
1771 : {
1772 182166 : if (fget == Py_None)
1773 1 : fget = NULL;
1774 182166 : if (fset == Py_None)
1775 36 : fset = NULL;
1776 182166 : if (fdel == Py_None)
1777 25041 : fdel = NULL;
1778 :
1779 182166 : Py_XINCREF(fget);
1780 182166 : Py_XINCREF(fset);
1781 182166 : Py_XINCREF(fdel);
1782 :
1783 182166 : Py_XSETREF(self->prop_get, fget);
1784 182166 : Py_XSETREF(self->prop_set, fset);
1785 182166 : Py_XSETREF(self->prop_del, fdel);
1786 182166 : Py_XSETREF(self->prop_doc, NULL);
1787 182166 : Py_XSETREF(self->prop_name, NULL);
1788 :
1789 182166 : self->getter_doc = 0;
1790 182166 : PyObject *prop_doc = NULL;
1791 :
1792 182166 : if (doc != NULL && doc != Py_None) {
1793 1380 : prop_doc = doc;
1794 1380 : Py_XINCREF(prop_doc);
1795 : }
1796 : /* if no docstring given and the getter has one, use that one */
1797 180786 : else if (fget != NULL) {
1798 180780 : int rc = _PyObject_LookupAttr(fget, &_Py_ID(__doc__), &prop_doc);
1799 180780 : if (rc <= 0) {
1800 0 : return rc;
1801 : }
1802 180780 : if (prop_doc == Py_None) {
1803 115911 : prop_doc = NULL;
1804 115911 : Py_DECREF(Py_None);
1805 : }
1806 180780 : if (prop_doc != NULL){
1807 64869 : self->getter_doc = 1;
1808 : }
1809 : }
1810 :
1811 : /* At this point `prop_doc` is either NULL or
1812 : a non-None object with incremented ref counter */
1813 :
1814 182166 : if (Py_IS_TYPE(self, &PyProperty_Type)) {
1815 182087 : Py_XSETREF(self->prop_doc, prop_doc);
1816 : } else {
1817 : /* If this is a property subclass, put __doc__
1818 : in dict of the subclass instance instead,
1819 : otherwise it gets shadowed by __doc__ in the
1820 : class's dict. */
1821 :
1822 79 : if (prop_doc == NULL) {
1823 11 : prop_doc = Py_None;
1824 11 : Py_INCREF(prop_doc);
1825 : }
1826 79 : int err = PyObject_SetAttr(
1827 : (PyObject *)self, &_Py_ID(__doc__), prop_doc);
1828 79 : Py_XDECREF(prop_doc);
1829 79 : if (err < 0)
1830 1 : return -1;
1831 : }
1832 :
1833 182165 : return 0;
1834 : }
1835 :
1836 : static PyObject *
1837 15808 : property_get___isabstractmethod__(propertyobject *prop, void *closure)
1838 : {
1839 15808 : int res = _PyObject_IsAbstract(prop->prop_get);
1840 15808 : if (res == -1) {
1841 1 : return NULL;
1842 : }
1843 15807 : else if (res) {
1844 293 : Py_RETURN_TRUE;
1845 : }
1846 :
1847 15514 : res = _PyObject_IsAbstract(prop->prop_set);
1848 15514 : if (res == -1) {
1849 0 : return NULL;
1850 : }
1851 15514 : else if (res) {
1852 4 : Py_RETURN_TRUE;
1853 : }
1854 :
1855 15510 : res = _PyObject_IsAbstract(prop->prop_del);
1856 15510 : if (res == -1) {
1857 0 : return NULL;
1858 : }
1859 15510 : else if (res) {
1860 0 : Py_RETURN_TRUE;
1861 : }
1862 15510 : Py_RETURN_FALSE;
1863 : }
1864 :
1865 : static PyGetSetDef property_getsetlist[] = {
1866 : {"__isabstractmethod__",
1867 : (getter)property_get___isabstractmethod__, NULL,
1868 : NULL,
1869 : NULL},
1870 : {NULL} /* Sentinel */
1871 : };
1872 :
1873 : static int
1874 4463200 : property_traverse(PyObject *self, visitproc visit, void *arg)
1875 : {
1876 4463200 : propertyobject *pp = (propertyobject *)self;
1877 4463200 : Py_VISIT(pp->prop_get);
1878 4463200 : Py_VISIT(pp->prop_set);
1879 4463200 : Py_VISIT(pp->prop_del);
1880 4463200 : Py_VISIT(pp->prop_doc);
1881 4463200 : Py_VISIT(pp->prop_name);
1882 4463200 : return 0;
1883 : }
1884 :
1885 : static int
1886 2651 : property_clear(PyObject *self)
1887 : {
1888 2651 : propertyobject *pp = (propertyobject *)self;
1889 2651 : Py_CLEAR(pp->prop_doc);
1890 2651 : return 0;
1891 : }
1892 :
1893 : #include "clinic/descrobject.c.h"
1894 :
1895 : PyTypeObject PyDictProxy_Type = {
1896 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
1897 : "mappingproxy", /* tp_name */
1898 : sizeof(mappingproxyobject), /* tp_basicsize */
1899 : 0, /* tp_itemsize */
1900 : /* methods */
1901 : (destructor)mappingproxy_dealloc, /* tp_dealloc */
1902 : 0, /* tp_vectorcall_offset */
1903 : 0, /* tp_getattr */
1904 : 0, /* tp_setattr */
1905 : 0, /* tp_as_async */
1906 : (reprfunc)mappingproxy_repr, /* tp_repr */
1907 : &mappingproxy_as_number, /* tp_as_number */
1908 : &mappingproxy_as_sequence, /* tp_as_sequence */
1909 : &mappingproxy_as_mapping, /* tp_as_mapping */
1910 : (hashfunc)mappingproxy_hash, /* tp_hash */
1911 : 0, /* tp_call */
1912 : (reprfunc)mappingproxy_str, /* tp_str */
1913 : PyObject_GenericGetAttr, /* tp_getattro */
1914 : 0, /* tp_setattro */
1915 : 0, /* tp_as_buffer */
1916 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1917 : Py_TPFLAGS_MAPPING, /* tp_flags */
1918 : 0, /* tp_doc */
1919 : mappingproxy_traverse, /* tp_traverse */
1920 : 0, /* tp_clear */
1921 : (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
1922 : 0, /* tp_weaklistoffset */
1923 : (getiterfunc)mappingproxy_getiter, /* tp_iter */
1924 : 0, /* tp_iternext */
1925 : mappingproxy_methods, /* tp_methods */
1926 : 0, /* tp_members */
1927 : 0, /* tp_getset */
1928 : 0, /* tp_base */
1929 : 0, /* tp_dict */
1930 : 0, /* tp_descr_get */
1931 : 0, /* tp_descr_set */
1932 : 0, /* tp_dictoffset */
1933 : 0, /* tp_init */
1934 : 0, /* tp_alloc */
1935 : mappingproxy_new, /* tp_new */
1936 : };
1937 :
1938 : PyTypeObject PyProperty_Type = {
1939 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
1940 : "property", /* tp_name */
1941 : sizeof(propertyobject), /* tp_basicsize */
1942 : 0, /* tp_itemsize */
1943 : /* methods */
1944 : property_dealloc, /* tp_dealloc */
1945 : 0, /* tp_vectorcall_offset */
1946 : 0, /* tp_getattr */
1947 : 0, /* tp_setattr */
1948 : 0, /* tp_as_async */
1949 : 0, /* tp_repr */
1950 : 0, /* tp_as_number */
1951 : 0, /* tp_as_sequence */
1952 : 0, /* tp_as_mapping */
1953 : 0, /* tp_hash */
1954 : 0, /* tp_call */
1955 : 0, /* tp_str */
1956 : PyObject_GenericGetAttr, /* tp_getattro */
1957 : 0, /* tp_setattro */
1958 : 0, /* tp_as_buffer */
1959 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1960 : Py_TPFLAGS_BASETYPE, /* tp_flags */
1961 : property_init__doc__, /* tp_doc */
1962 : property_traverse, /* tp_traverse */
1963 : (inquiry)property_clear, /* tp_clear */
1964 : 0, /* tp_richcompare */
1965 : 0, /* tp_weaklistoffset */
1966 : 0, /* tp_iter */
1967 : 0, /* tp_iternext */
1968 : property_methods, /* tp_methods */
1969 : property_members, /* tp_members */
1970 : property_getsetlist, /* tp_getset */
1971 : 0, /* tp_base */
1972 : 0, /* tp_dict */
1973 : property_descr_get, /* tp_descr_get */
1974 : property_descr_set, /* tp_descr_set */
1975 : 0, /* tp_dictoffset */
1976 : property_init, /* tp_init */
1977 : PyType_GenericAlloc, /* tp_alloc */
1978 : PyType_GenericNew, /* tp_new */
1979 : PyObject_GC_Del, /* tp_free */
1980 : };
|