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