1 /* Descriptors -- a new, flexible way to describe attributes */ 2 3 #include "Python.h" 4 #include "internal/pystate.h" 5 #include "structmember.h" /* Why is this not included in Python.h? */ 6 7 /*[clinic input] 8 class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type" 9 class property "propertyobject *" "&PyProperty_Type" 10 [clinic start generated code]*/ 11 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=556352653fd4c02e]*/ 12 13 static void 14 descr_dealloc(PyDescrObject *descr) 15 { 16 _PyObject_GC_UNTRACK(descr); 17 Py_XDECREF(descr->d_type); 18 Py_XDECREF(descr->d_name); 19 Py_XDECREF(descr->d_qualname); 20 PyObject_GC_Del(descr); 21 } 22 23 static PyObject * 24 descr_name(PyDescrObject *descr) 25 { 26 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name)) 27 return descr->d_name; 28 return NULL; 29 } 30 31 static PyObject * 32 descr_repr(PyDescrObject *descr, const char *format) 33 { 34 PyObject *name = NULL; 35 if (descr->d_name != NULL && PyUnicode_Check(descr->d_name)) 36 name = descr->d_name; 37 38 return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name); 39 } 40 41 static PyObject * 42 method_repr(PyMethodDescrObject *descr) 43 { 44 return descr_repr((PyDescrObject *)descr, 45 "<method '%V' of '%s' objects>"); 46 } 47 48 static PyObject * 49 member_repr(PyMemberDescrObject *descr) 50 { 51 return descr_repr((PyDescrObject *)descr, 52 "<member '%V' of '%s' objects>"); 53 } 54 55 static PyObject * 56 getset_repr(PyGetSetDescrObject *descr) 57 { 58 return descr_repr((PyDescrObject *)descr, 59 "<attribute '%V' of '%s' objects>"); 60 } 61 62 static PyObject * 63 wrapperdescr_repr(PyWrapperDescrObject *descr) 64 { 65 return descr_repr((PyDescrObject *)descr, 66 "<slot wrapper '%V' of '%s' objects>"); 67 } 68 69 static int 70 descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres) 71 { 72 if (obj == NULL) { 73 Py_INCREF(descr); 74 *pres = (PyObject *)descr; 75 return 1; 76 } 77 if (!PyObject_TypeCheck(obj, descr->d_type)) { 78 PyErr_Format(PyExc_TypeError, 79 "descriptor '%V' for '%s' objects " 80 "doesn't apply to '%s' object", 81 descr_name((PyDescrObject *)descr), "?", 82 descr->d_type->tp_name, 83 obj->ob_type->tp_name); 84 *pres = NULL; 85 return 1; 86 } 87 return 0; 88 } 89 90 static PyObject * 91 classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) 92 { 93 /* Ensure a valid type. Class methods ignore obj. */ 94 if (type == NULL) { 95 if (obj != NULL) 96 type = (PyObject *)obj->ob_type; 97 else { 98 /* Wot - no type?! */ 99 PyErr_Format(PyExc_TypeError, 100 "descriptor '%V' for type '%s' " 101 "needs either an object or a type", 102 descr_name((PyDescrObject *)descr), "?", 103 PyDescr_TYPE(descr)->tp_name); 104 return NULL; 105 } 106 } 107 if (!PyType_Check(type)) { 108 PyErr_Format(PyExc_TypeError, 109 "descriptor '%V' for type '%s' " 110 "needs a type, not a '%s' as arg 2", 111 descr_name((PyDescrObject *)descr), "?", 112 PyDescr_TYPE(descr)->tp_name, 113 type->ob_type->tp_name); 114 return NULL; 115 } 116 if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) { 117 PyErr_Format(PyExc_TypeError, 118 "descriptor '%V' for type '%s' " 119 "doesn't apply to type '%s'", 120 descr_name((PyDescrObject *)descr), "?", 121 PyDescr_TYPE(descr)->tp_name, 122 ((PyTypeObject *)type)->tp_name); 123 return NULL; 124 } 125 return PyCFunction_NewEx(descr->d_method, type, NULL); 126 } 127 128 static PyObject * 129 method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) 130 { 131 PyObject *res; 132 133 if (descr_check((PyDescrObject *)descr, obj, &res)) 134 return res; 135 return PyCFunction_NewEx(descr->d_method, obj, NULL); 136 } 137 138 static PyObject * 139 member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) 140 { 141 PyObject *res; 142 143 if (descr_check((PyDescrObject *)descr, obj, &res)) 144 return res; 145 return PyMember_GetOne((char *)obj, descr->d_member); 146 } 147 148 static PyObject * 149 getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) 150 { 151 PyObject *res; 152 153 if (descr_check((PyDescrObject *)descr, obj, &res)) 154 return res; 155 if (descr->d_getset->get != NULL) 156 return descr->d_getset->get(obj, descr->d_getset->closure); 157 PyErr_Format(PyExc_AttributeError, 158 "attribute '%V' of '%.100s' objects is not readable", 159 descr_name((PyDescrObject *)descr), "?", 160 PyDescr_TYPE(descr)->tp_name); 161 return NULL; 162 } 163 164 static PyObject * 165 wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type) 166 { 167 PyObject *res; 168 169 if (descr_check((PyDescrObject *)descr, obj, &res)) 170 return res; 171 return PyWrapper_New((PyObject *)descr, obj); 172 } 173 174 static int 175 descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, 176 int *pres) 177 { 178 assert(obj != NULL); 179 if (!PyObject_TypeCheck(obj, descr->d_type)) { 180 PyErr_Format(PyExc_TypeError, 181 "descriptor '%V' for '%.100s' objects " 182 "doesn't apply to '%.100s' object", 183 descr_name(descr), "?", 184 descr->d_type->tp_name, 185 obj->ob_type->tp_name); 186 *pres = -1; 187 return 1; 188 } 189 return 0; 190 } 191 192 static int 193 member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value) 194 { 195 int res; 196 197 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) 198 return res; 199 return PyMember_SetOne((char *)obj, descr->d_member, value); 200 } 201 202 static int 203 getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) 204 { 205 int res; 206 207 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) 208 return res; 209 if (descr->d_getset->set != NULL) 210 return descr->d_getset->set(obj, value, 211 descr->d_getset->closure); 212 PyErr_Format(PyExc_AttributeError, 213 "attribute '%V' of '%.100s' objects is not writable", 214 descr_name((PyDescrObject *)descr), "?", 215 PyDescr_TYPE(descr)->tp_name); 216 return -1; 217 } 218 219 static PyObject * 220 methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs) 221 { 222 Py_ssize_t nargs; 223 PyObject *self, *result; 224 225 /* Make sure that the first argument is acceptable as 'self' */ 226 assert(PyTuple_Check(args)); 227 nargs = PyTuple_GET_SIZE(args); 228 if (nargs < 1) { 229 PyErr_Format(PyExc_TypeError, 230 "descriptor '%V' of '%.100s' " 231 "object needs an argument", 232 descr_name((PyDescrObject *)descr), "?", 233 PyDescr_TYPE(descr)->tp_name); 234 return NULL; 235 } 236 self = PyTuple_GET_ITEM(args, 0); 237 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 238 (PyObject *)PyDescr_TYPE(descr))) { 239 PyErr_Format(PyExc_TypeError, 240 "descriptor '%V' " 241 "requires a '%.100s' object " 242 "but received a '%.100s'", 243 descr_name((PyDescrObject *)descr), "?", 244 PyDescr_TYPE(descr)->tp_name, 245 self->ob_type->tp_name); 246 return NULL; 247 } 248 249 result = _PyMethodDef_RawFastCallDict(descr->d_method, self, 250 &PyTuple_GET_ITEM(args, 1), nargs - 1, 251 kwargs); 252 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL); 253 return result; 254 } 255 256 // same to methoddescr_call(), but use FASTCALL convention. 257 PyObject * 258 _PyMethodDescr_FastCallKeywords(PyObject *descrobj, 259 PyObject *const *args, Py_ssize_t nargs, 260 PyObject *kwnames) 261 { 262 assert(Py_TYPE(descrobj) == &PyMethodDescr_Type); 263 PyMethodDescrObject *descr = (PyMethodDescrObject *)descrobj; 264 PyObject *self, *result; 265 266 /* Make sure that the first argument is acceptable as 'self' */ 267 if (nargs < 1) { 268 PyErr_Format(PyExc_TypeError, 269 "descriptor '%V' of '%.100s' " 270 "object needs an argument", 271 descr_name((PyDescrObject *)descr), "?", 272 PyDescr_TYPE(descr)->tp_name); 273 return NULL; 274 } 275 self = args[0]; 276 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 277 (PyObject *)PyDescr_TYPE(descr))) { 278 PyErr_Format(PyExc_TypeError, 279 "descriptor '%V' " 280 "requires a '%.100s' object " 281 "but received a '%.100s'", 282 descr_name((PyDescrObject *)descr), "?", 283 PyDescr_TYPE(descr)->tp_name, 284 self->ob_type->tp_name); 285 return NULL; 286 } 287 288 result = _PyMethodDef_RawFastCallKeywords(descr->d_method, self, 289 args+1, nargs-1, kwnames); 290 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL); 291 return result; 292 } 293 294 static PyObject * 295 classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, 296 PyObject *kwds) 297 { 298 Py_ssize_t argc; 299 PyObject *self, *result; 300 301 /* Make sure that the first argument is acceptable as 'self' */ 302 assert(PyTuple_Check(args)); 303 argc = PyTuple_GET_SIZE(args); 304 if (argc < 1) { 305 PyErr_Format(PyExc_TypeError, 306 "descriptor '%V' of '%.100s' " 307 "object needs an argument", 308 descr_name((PyDescrObject *)descr), "?", 309 PyDescr_TYPE(descr)->tp_name); 310 return NULL; 311 } 312 self = PyTuple_GET_ITEM(args, 0); 313 if (!PyType_Check(self)) { 314 PyErr_Format(PyExc_TypeError, 315 "descriptor '%V' requires a type " 316 "but received a '%.100s'", 317 descr_name((PyDescrObject *)descr), "?", 318 PyDescr_TYPE(descr)->tp_name, 319 self->ob_type->tp_name); 320 return NULL; 321 } 322 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) { 323 PyErr_Format(PyExc_TypeError, 324 "descriptor '%V' " 325 "requires a subtype of '%.100s' " 326 "but received '%.100s", 327 descr_name((PyDescrObject *)descr), "?", 328 PyDescr_TYPE(descr)->tp_name, 329 self->ob_type->tp_name); 330 return NULL; 331 } 332 333 result = _PyMethodDef_RawFastCallDict(descr->d_method, self, 334 &PyTuple_GET_ITEM(args, 1), argc - 1, 335 kwds); 336 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL); 337 return result; 338 } 339 340 Py_LOCAL_INLINE(PyObject *) 341 wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self, 342 PyObject *args, PyObject *kwds) 343 { 344 wrapperfunc wrapper = descr->d_base->wrapper; 345 346 if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) { 347 wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper; 348 return (*wk)(self, args, descr->d_wrapped, kwds); 349 } 350 351 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) { 352 PyErr_Format(PyExc_TypeError, 353 "wrapper %s() takes no keyword arguments", 354 descr->d_base->name); 355 return NULL; 356 } 357 return (*wrapper)(self, args, descr->d_wrapped); 358 } 359 360 static PyObject * 361 wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) 362 { 363 Py_ssize_t argc; 364 PyObject *self, *result; 365 366 /* Make sure that the first argument is acceptable as 'self' */ 367 assert(PyTuple_Check(args)); 368 argc = PyTuple_GET_SIZE(args); 369 if (argc < 1) { 370 PyErr_Format(PyExc_TypeError, 371 "descriptor '%V' of '%.100s' " 372 "object needs an argument", 373 descr_name((PyDescrObject *)descr), "?", 374 PyDescr_TYPE(descr)->tp_name); 375 return NULL; 376 } 377 self = PyTuple_GET_ITEM(args, 0); 378 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 379 (PyObject *)PyDescr_TYPE(descr))) { 380 PyErr_Format(PyExc_TypeError, 381 "descriptor '%V' " 382 "requires a '%.100s' object " 383 "but received a '%.100s'", 384 descr_name((PyDescrObject *)descr), "?", 385 PyDescr_TYPE(descr)->tp_name, 386 self->ob_type->tp_name); 387 return NULL; 388 } 389 390 args = PyTuple_GetSlice(args, 1, argc); 391 if (args == NULL) { 392 return NULL; 393 } 394 result = wrapperdescr_raw_call(descr, self, args, kwds); 395 Py_DECREF(args); 396 return result; 397 } 398 399 400 static PyObject * 401 method_get_doc(PyMethodDescrObject *descr, void *closure) 402 { 403 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc); 404 } 405 406 static PyObject * 407 method_get_text_signature(PyMethodDescrObject *descr, void *closure) 408 { 409 return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc); 410 } 411 412 static PyObject * 413 calculate_qualname(PyDescrObject *descr) 414 { 415 PyObject *type_qualname, *res; 416 _Py_IDENTIFIER(__qualname__); 417 418 if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) { 419 PyErr_SetString(PyExc_TypeError, 420 "<descriptor>.__name__ is not a unicode object"); 421 return NULL; 422 } 423 424 type_qualname = _PyObject_GetAttrId((PyObject *)descr->d_type, 425 &PyId___qualname__); 426 if (type_qualname == NULL) 427 return NULL; 428 429 if (!PyUnicode_Check(type_qualname)) { 430 PyErr_SetString(PyExc_TypeError, "<descriptor>.__objclass__." 431 "__qualname__ is not a unicode object"); 432 Py_XDECREF(type_qualname); 433 return NULL; 434 } 435 436 res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name); 437 Py_DECREF(type_qualname); 438 return res; 439 } 440 441 static PyObject * 442 descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored)) 443 { 444 if (descr->d_qualname == NULL) 445 descr->d_qualname = calculate_qualname(descr); 446 Py_XINCREF(descr->d_qualname); 447 return descr->d_qualname; 448 } 449 450 static PyObject * 451 descr_reduce(PyDescrObject *descr) 452 { 453 _Py_IDENTIFIER(getattr); 454 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr), 455 PyDescr_TYPE(descr), PyDescr_NAME(descr)); 456 } 457 458 static PyMethodDef descr_methods[] = { 459 {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL}, 460 {NULL, NULL} 461 }; 462 463 static PyMemberDef descr_members[] = { 464 {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY}, 465 {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY}, 466 {0} 467 }; 468 469 static PyGetSetDef method_getset[] = { 470 {"__doc__", (getter)method_get_doc}, 471 {"__qualname__", (getter)descr_get_qualname}, 472 {"__text_signature__", (getter)method_get_text_signature}, 473 {0} 474 }; 475 476 static PyObject * 477 member_get_doc(PyMemberDescrObject *descr, void *closure) 478 { 479 if (descr->d_member->doc == NULL) { 480 Py_RETURN_NONE; 481 } 482 return PyUnicode_FromString(descr->d_member->doc); 483 } 484 485 static PyGetSetDef member_getset[] = { 486 {"__doc__", (getter)member_get_doc}, 487 {"__qualname__", (getter)descr_get_qualname}, 488 {0} 489 }; 490 491 static PyObject * 492 getset_get_doc(PyGetSetDescrObject *descr, void *closure) 493 { 494 if (descr->d_getset->doc == NULL) { 495 Py_RETURN_NONE; 496 } 497 return PyUnicode_FromString(descr->d_getset->doc); 498 } 499 500 static PyGetSetDef getset_getset[] = { 501 {"__doc__", (getter)getset_get_doc}, 502 {"__qualname__", (getter)descr_get_qualname}, 503 {0} 504 }; 505 506 static PyObject * 507 wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure) 508 { 509 return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc); 510 } 511 512 static PyObject * 513 wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure) 514 { 515 return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc); 516 } 517 518 static PyGetSetDef wrapperdescr_getset[] = { 519 {"__doc__", (getter)wrapperdescr_get_doc}, 520 {"__qualname__", (getter)descr_get_qualname}, 521 {"__text_signature__", (getter)wrapperdescr_get_text_signature}, 522 {0} 523 }; 524 525 static int 526 descr_traverse(PyObject *self, visitproc visit, void *arg) 527 { 528 PyDescrObject *descr = (PyDescrObject *)self; 529 Py_VISIT(descr->d_type); 530 return 0; 531 } 532 533 PyTypeObject PyMethodDescr_Type = { 534 PyVarObject_HEAD_INIT(&PyType_Type, 0) 535 "method_descriptor", 536 sizeof(PyMethodDescrObject), 537 0, 538 (destructor)descr_dealloc, /* tp_dealloc */ 539 0, /* tp_print */ 540 0, /* tp_getattr */ 541 0, /* tp_setattr */ 542 0, /* tp_reserved */ 543 (reprfunc)method_repr, /* tp_repr */ 544 0, /* tp_as_number */ 545 0, /* tp_as_sequence */ 546 0, /* tp_as_mapping */ 547 0, /* tp_hash */ 548 (ternaryfunc)methoddescr_call, /* tp_call */ 549 0, /* tp_str */ 550 PyObject_GenericGetAttr, /* tp_getattro */ 551 0, /* tp_setattro */ 552 0, /* tp_as_buffer */ 553 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 554 0, /* tp_doc */ 555 descr_traverse, /* tp_traverse */ 556 0, /* tp_clear */ 557 0, /* tp_richcompare */ 558 0, /* tp_weaklistoffset */ 559 0, /* tp_iter */ 560 0, /* tp_iternext */ 561 descr_methods, /* tp_methods */ 562 descr_members, /* tp_members */ 563 method_getset, /* tp_getset */ 564 0, /* tp_base */ 565 0, /* tp_dict */ 566 (descrgetfunc)method_get, /* tp_descr_get */ 567 0, /* tp_descr_set */ 568 }; 569 570 /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */ 571 PyTypeObject PyClassMethodDescr_Type = { 572 PyVarObject_HEAD_INIT(&PyType_Type, 0) 573 "classmethod_descriptor", 574 sizeof(PyMethodDescrObject), 575 0, 576 (destructor)descr_dealloc, /* tp_dealloc */ 577 0, /* tp_print */ 578 0, /* tp_getattr */ 579 0, /* tp_setattr */ 580 0, /* tp_reserved */ 581 (reprfunc)method_repr, /* tp_repr */ 582 0, /* tp_as_number */ 583 0, /* tp_as_sequence */ 584 0, /* tp_as_mapping */ 585 0, /* tp_hash */ 586 (ternaryfunc)classmethoddescr_call, /* tp_call */ 587 0, /* tp_str */ 588 PyObject_GenericGetAttr, /* tp_getattro */ 589 0, /* tp_setattro */ 590 0, /* tp_as_buffer */ 591 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 592 0, /* tp_doc */ 593 descr_traverse, /* tp_traverse */ 594 0, /* tp_clear */ 595 0, /* tp_richcompare */ 596 0, /* tp_weaklistoffset */ 597 0, /* tp_iter */ 598 0, /* tp_iternext */ 599 descr_methods, /* tp_methods */ 600 descr_members, /* tp_members */ 601 method_getset, /* tp_getset */ 602 0, /* tp_base */ 603 0, /* tp_dict */ 604 (descrgetfunc)classmethod_get, /* tp_descr_get */ 605 0, /* tp_descr_set */ 606 }; 607 608 PyTypeObject PyMemberDescr_Type = { 609 PyVarObject_HEAD_INIT(&PyType_Type, 0) 610 "member_descriptor", 611 sizeof(PyMemberDescrObject), 612 0, 613 (destructor)descr_dealloc, /* tp_dealloc */ 614 0, /* tp_print */ 615 0, /* tp_getattr */ 616 0, /* tp_setattr */ 617 0, /* tp_reserved */ 618 (reprfunc)member_repr, /* tp_repr */ 619 0, /* tp_as_number */ 620 0, /* tp_as_sequence */ 621 0, /* tp_as_mapping */ 622 0, /* tp_hash */ 623 0, /* tp_call */ 624 0, /* tp_str */ 625 PyObject_GenericGetAttr, /* tp_getattro */ 626 0, /* tp_setattro */ 627 0, /* tp_as_buffer */ 628 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 629 0, /* tp_doc */ 630 descr_traverse, /* tp_traverse */ 631 0, /* tp_clear */ 632 0, /* tp_richcompare */ 633 0, /* tp_weaklistoffset */ 634 0, /* tp_iter */ 635 0, /* tp_iternext */ 636 descr_methods, /* tp_methods */ 637 descr_members, /* tp_members */ 638 member_getset, /* tp_getset */ 639 0, /* tp_base */ 640 0, /* tp_dict */ 641 (descrgetfunc)member_get, /* tp_descr_get */ 642 (descrsetfunc)member_set, /* tp_descr_set */ 643 }; 644 645 PyTypeObject PyGetSetDescr_Type = { 646 PyVarObject_HEAD_INIT(&PyType_Type, 0) 647 "getset_descriptor", 648 sizeof(PyGetSetDescrObject), 649 0, 650 (destructor)descr_dealloc, /* tp_dealloc */ 651 0, /* tp_print */ 652 0, /* tp_getattr */ 653 0, /* tp_setattr */ 654 0, /* tp_reserved */ 655 (reprfunc)getset_repr, /* tp_repr */ 656 0, /* tp_as_number */ 657 0, /* tp_as_sequence */ 658 0, /* tp_as_mapping */ 659 0, /* tp_hash */ 660 0, /* tp_call */ 661 0, /* tp_str */ 662 PyObject_GenericGetAttr, /* tp_getattro */ 663 0, /* tp_setattro */ 664 0, /* tp_as_buffer */ 665 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 666 0, /* tp_doc */ 667 descr_traverse, /* tp_traverse */ 668 0, /* tp_clear */ 669 0, /* tp_richcompare */ 670 0, /* tp_weaklistoffset */ 671 0, /* tp_iter */ 672 0, /* tp_iternext */ 673 0, /* tp_methods */ 674 descr_members, /* tp_members */ 675 getset_getset, /* tp_getset */ 676 0, /* tp_base */ 677 0, /* tp_dict */ 678 (descrgetfunc)getset_get, /* tp_descr_get */ 679 (descrsetfunc)getset_set, /* tp_descr_set */ 680 }; 681 682 PyTypeObject PyWrapperDescr_Type = { 683 PyVarObject_HEAD_INIT(&PyType_Type, 0) 684 "wrapper_descriptor", 685 sizeof(PyWrapperDescrObject), 686 0, 687 (destructor)descr_dealloc, /* tp_dealloc */ 688 0, /* tp_print */ 689 0, /* tp_getattr */ 690 0, /* tp_setattr */ 691 0, /* tp_reserved */ 692 (reprfunc)wrapperdescr_repr, /* tp_repr */ 693 0, /* tp_as_number */ 694 0, /* tp_as_sequence */ 695 0, /* tp_as_mapping */ 696 0, /* tp_hash */ 697 (ternaryfunc)wrapperdescr_call, /* tp_call */ 698 0, /* tp_str */ 699 PyObject_GenericGetAttr, /* tp_getattro */ 700 0, /* tp_setattro */ 701 0, /* tp_as_buffer */ 702 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 703 0, /* tp_doc */ 704 descr_traverse, /* tp_traverse */ 705 0, /* tp_clear */ 706 0, /* tp_richcompare */ 707 0, /* tp_weaklistoffset */ 708 0, /* tp_iter */ 709 0, /* tp_iternext */ 710 descr_methods, /* tp_methods */ 711 descr_members, /* tp_members */ 712 wrapperdescr_getset, /* tp_getset */ 713 0, /* tp_base */ 714 0, /* tp_dict */ 715 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */ 716 0, /* tp_descr_set */ 717 }; 718 719 static PyDescrObject * 720 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) 721 { 722 PyDescrObject *descr; 723 724 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); 725 if (descr != NULL) { 726 Py_XINCREF(type); 727 descr->d_type = type; 728 descr->d_name = PyUnicode_InternFromString(name); 729 if (descr->d_name == NULL) { 730 Py_DECREF(descr); 731 descr = NULL; 732 } 733 else { 734 descr->d_qualname = NULL; 735 } 736 } 737 return descr; 738 } 739 740 PyObject * 741 PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) 742 { 743 PyMethodDescrObject *descr; 744 745 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type, 746 type, method->ml_name); 747 if (descr != NULL) 748 descr->d_method = method; 749 return (PyObject *)descr; 750 } 751 752 PyObject * 753 PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method) 754 { 755 PyMethodDescrObject *descr; 756 757 descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type, 758 type, method->ml_name); 759 if (descr != NULL) 760 descr->d_method = method; 761 return (PyObject *)descr; 762 } 763 764 PyObject * 765 PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member) 766 { 767 PyMemberDescrObject *descr; 768 769 descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type, 770 type, member->name); 771 if (descr != NULL) 772 descr->d_member = member; 773 return (PyObject *)descr; 774 } 775 776 PyObject * 777 PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset) 778 { 779 PyGetSetDescrObject *descr; 780 781 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type, 782 type, getset->name); 783 if (descr != NULL) 784 descr->d_getset = getset; 785 return (PyObject *)descr; 786 } 787 788 PyObject * 789 PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped) 790 { 791 PyWrapperDescrObject *descr; 792 793 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type, 794 type, base->name); 795 if (descr != NULL) { 796 descr->d_base = base; 797 descr->d_wrapped = wrapped; 798 } 799 return (PyObject *)descr; 800 } 801 802 803 /* --- mappingproxy: read-only proxy for mappings --- */ 804 805 /* This has no reason to be in this file except that adding new files is a 806 bit of a pain */ 807 808 typedef struct { 809 PyObject_HEAD 810 PyObject *mapping; 811 } mappingproxyobject; 812 813 static Py_ssize_t 814 mappingproxy_len(mappingproxyobject *pp) 815 { 816 return PyObject_Size(pp->mapping); 817 } 818 819 static PyObject * 820 mappingproxy_getitem(mappingproxyobject *pp, PyObject *key) 821 { 822 return PyObject_GetItem(pp->mapping, key); 823 } 824 825 static PyMappingMethods mappingproxy_as_mapping = { 826 (lenfunc)mappingproxy_len, /* mp_length */ 827 (binaryfunc)mappingproxy_getitem, /* mp_subscript */ 828 0, /* mp_ass_subscript */ 829 }; 830 831 static int 832 mappingproxy_contains(mappingproxyobject *pp, PyObject *key) 833 { 834 if (PyDict_CheckExact(pp->mapping)) 835 return PyDict_Contains(pp->mapping, key); 836 else 837 return PySequence_Contains(pp->mapping, key); 838 } 839 840 static PySequenceMethods mappingproxy_as_sequence = { 841 0, /* sq_length */ 842 0, /* sq_concat */ 843 0, /* sq_repeat */ 844 0, /* sq_item */ 845 0, /* sq_slice */ 846 0, /* sq_ass_item */ 847 0, /* sq_ass_slice */ 848 (objobjproc)mappingproxy_contains, /* sq_contains */ 849 0, /* sq_inplace_concat */ 850 0, /* sq_inplace_repeat */ 851 }; 852 853 static PyObject * 854 mappingproxy_get(mappingproxyobject *pp, PyObject *args) 855 { 856 PyObject *key, *def = Py_None; 857 _Py_IDENTIFIER(get); 858 859 if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) 860 return NULL; 861 return _PyObject_CallMethodIdObjArgs(pp->mapping, &PyId_get, 862 key, def, NULL); 863 } 864 865 static PyObject * 866 mappingproxy_keys(mappingproxyobject *pp) 867 { 868 _Py_IDENTIFIER(keys); 869 return _PyObject_CallMethodId(pp->mapping, &PyId_keys, NULL); 870 } 871 872 static PyObject * 873 mappingproxy_values(mappingproxyobject *pp) 874 { 875 _Py_IDENTIFIER(values); 876 return _PyObject_CallMethodId(pp->mapping, &PyId_values, NULL); 877 } 878 879 static PyObject * 880 mappingproxy_items(mappingproxyobject *pp) 881 { 882 _Py_IDENTIFIER(items); 883 return _PyObject_CallMethodId(pp->mapping, &PyId_items, NULL); 884 } 885 886 static PyObject * 887 mappingproxy_copy(mappingproxyobject *pp) 888 { 889 _Py_IDENTIFIER(copy); 890 return _PyObject_CallMethodId(pp->mapping, &PyId_copy, NULL); 891 } 892 893 /* WARNING: mappingproxy methods must not give access 894 to the underlying mapping */ 895 896 static PyMethodDef mappingproxy_methods[] = { 897 {"get", (PyCFunction)mappingproxy_get, METH_VARARGS, 898 PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d." 899 " d defaults to None.")}, 900 {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS, 901 PyDoc_STR("D.keys() -> list of D's keys")}, 902 {"values", (PyCFunction)mappingproxy_values, METH_NOARGS, 903 PyDoc_STR("D.values() -> list of D's values")}, 904 {"items", (PyCFunction)mappingproxy_items, METH_NOARGS, 905 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")}, 906 {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS, 907 PyDoc_STR("D.copy() -> a shallow copy of D")}, 908 {0} 909 }; 910 911 static void 912 mappingproxy_dealloc(mappingproxyobject *pp) 913 { 914 _PyObject_GC_UNTRACK(pp); 915 Py_DECREF(pp->mapping); 916 PyObject_GC_Del(pp); 917 } 918 919 static PyObject * 920 mappingproxy_getiter(mappingproxyobject *pp) 921 { 922 return PyObject_GetIter(pp->mapping); 923 } 924 925 static PyObject * 926 mappingproxy_str(mappingproxyobject *pp) 927 { 928 return PyObject_Str(pp->mapping); 929 } 930 931 static PyObject * 932 mappingproxy_repr(mappingproxyobject *pp) 933 { 934 return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping); 935 } 936 937 static int 938 mappingproxy_traverse(PyObject *self, visitproc visit, void *arg) 939 { 940 mappingproxyobject *pp = (mappingproxyobject *)self; 941 Py_VISIT(pp->mapping); 942 return 0; 943 } 944 945 static PyObject * 946 mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op) 947 { 948 return PyObject_RichCompare(v->mapping, w, op); 949 } 950 951 static int 952 mappingproxy_check_mapping(PyObject *mapping) 953 { 954 if (!PyMapping_Check(mapping) 955 || PyList_Check(mapping) 956 || PyTuple_Check(mapping)) { 957 PyErr_Format(PyExc_TypeError, 958 "mappingproxy() argument must be a mapping, not %s", 959 Py_TYPE(mapping)->tp_name); 960 return -1; 961 } 962 return 0; 963 } 964 965 /*[clinic input] 966 @classmethod 967 mappingproxy.__new__ as mappingproxy_new 968 969 mapping: object 970 971 [clinic start generated code]*/ 972 973 static PyObject * 974 mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping) 975 /*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/ 976 { 977 mappingproxyobject *mappingproxy; 978 979 if (mappingproxy_check_mapping(mapping) == -1) 980 return NULL; 981 982 mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type); 983 if (mappingproxy == NULL) 984 return NULL; 985 Py_INCREF(mapping); 986 mappingproxy->mapping = mapping; 987 _PyObject_GC_TRACK(mappingproxy); 988 return (PyObject *)mappingproxy; 989 } 990 991 PyObject * 992 PyDictProxy_New(PyObject *mapping) 993 { 994 mappingproxyobject *pp; 995 996 if (mappingproxy_check_mapping(mapping) == -1) 997 return NULL; 998 999 pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type); 1000 if (pp != NULL) { 1001 Py_INCREF(mapping); 1002 pp->mapping = mapping; 1003 _PyObject_GC_TRACK(pp); 1004 } 1005 return (PyObject *)pp; 1006 } 1007 1008 1009 /* --- Wrapper object for "slot" methods --- */ 1010 1011 /* This has no reason to be in this file except that adding new files is a 1012 bit of a pain */ 1013 1014 typedef struct { 1015 PyObject_HEAD 1016 PyWrapperDescrObject *descr; 1017 PyObject *self; 1018 } wrapperobject; 1019 1020 #define Wrapper_Check(v) (Py_TYPE(v) == &_PyMethodWrapper_Type) 1021 1022 static void 1023 wrapper_dealloc(wrapperobject *wp) 1024 { 1025 PyObject_GC_UnTrack(wp); 1026 Py_TRASHCAN_SAFE_BEGIN(wp) 1027 Py_XDECREF(wp->descr); 1028 Py_XDECREF(wp->self); 1029 PyObject_GC_Del(wp); 1030 Py_TRASHCAN_SAFE_END(wp) 1031 } 1032 1033 static PyObject * 1034 wrapper_richcompare(PyObject *a, PyObject *b, int op) 1035 { 1036 PyWrapperDescrObject *a_descr, *b_descr; 1037 1038 assert(a != NULL && b != NULL); 1039 1040 /* both arguments should be wrapperobjects */ 1041 if (!Wrapper_Check(a) || !Wrapper_Check(b)) { 1042 Py_RETURN_NOTIMPLEMENTED; 1043 } 1044 1045 /* compare by descriptor address; if the descriptors are the same, 1046 compare by the objects they're bound to */ 1047 a_descr = ((wrapperobject *)a)->descr; 1048 b_descr = ((wrapperobject *)b)->descr; 1049 if (a_descr == b_descr) { 1050 a = ((wrapperobject *)a)->self; 1051 b = ((wrapperobject *)b)->self; 1052 return PyObject_RichCompare(a, b, op); 1053 } 1054 1055 Py_RETURN_RICHCOMPARE(a_descr, b_descr, op); 1056 } 1057 1058 static Py_hash_t 1059 wrapper_hash(wrapperobject *wp) 1060 { 1061 Py_hash_t x, y; 1062 x = _Py_HashPointer(wp->descr); 1063 if (x == -1) 1064 return -1; 1065 y = PyObject_Hash(wp->self); 1066 if (y == -1) 1067 return -1; 1068 x = x ^ y; 1069 if (x == -1) 1070 x = -2; 1071 return x; 1072 } 1073 1074 static PyObject * 1075 wrapper_repr(wrapperobject *wp) 1076 { 1077 return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>", 1078 wp->descr->d_base->name, 1079 wp->self->ob_type->tp_name, 1080 wp->self); 1081 } 1082 1083 static PyObject * 1084 wrapper_reduce(wrapperobject *wp) 1085 { 1086 _Py_IDENTIFIER(getattr); 1087 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr), 1088 wp->self, PyDescr_NAME(wp->descr)); 1089 } 1090 1091 static PyMethodDef wrapper_methods[] = { 1092 {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL}, 1093 {NULL, NULL} 1094 }; 1095 1096 static PyMemberDef wrapper_members[] = { 1097 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY}, 1098 {0} 1099 }; 1100 1101 static PyObject * 1102 wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored)) 1103 { 1104 PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr); 1105 1106 Py_INCREF(c); 1107 return c; 1108 } 1109 1110 static PyObject * 1111 wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored)) 1112 { 1113 const char *s = wp->descr->d_base->name; 1114 1115 return PyUnicode_FromString(s); 1116 } 1117 1118 static PyObject * 1119 wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored)) 1120 { 1121 return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc); 1122 } 1123 1124 static PyObject * 1125 wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored)) 1126 { 1127 return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc); 1128 } 1129 1130 static PyObject * 1131 wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored)) 1132 { 1133 return descr_get_qualname((PyDescrObject *)wp->descr, NULL); 1134 } 1135 1136 static PyGetSetDef wrapper_getsets[] = { 1137 {"__objclass__", (getter)wrapper_objclass}, 1138 {"__name__", (getter)wrapper_name}, 1139 {"__qualname__", (getter)wrapper_qualname}, 1140 {"__doc__", (getter)wrapper_doc}, 1141 {"__text_signature__", (getter)wrapper_text_signature}, 1142 {0} 1143 }; 1144 1145 static PyObject * 1146 wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds) 1147 { 1148 return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds); 1149 } 1150 1151 static int 1152 wrapper_traverse(PyObject *self, visitproc visit, void *arg) 1153 { 1154 wrapperobject *wp = (wrapperobject *)self; 1155 Py_VISIT(wp->descr); 1156 Py_VISIT(wp->self); 1157 return 0; 1158 } 1159 1160 PyTypeObject _PyMethodWrapper_Type = { 1161 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1162 "method-wrapper", /* tp_name */ 1163 sizeof(wrapperobject), /* tp_basicsize */ 1164 0, /* tp_itemsize */ 1165 /* methods */ 1166 (destructor)wrapper_dealloc, /* tp_dealloc */ 1167 0, /* tp_print */ 1168 0, /* tp_getattr */ 1169 0, /* tp_setattr */ 1170 0, /* tp_reserved */ 1171 (reprfunc)wrapper_repr, /* tp_repr */ 1172 0, /* tp_as_number */ 1173 0, /* tp_as_sequence */ 1174 0, /* tp_as_mapping */ 1175 (hashfunc)wrapper_hash, /* tp_hash */ 1176 (ternaryfunc)wrapper_call, /* tp_call */ 1177 0, /* tp_str */ 1178 PyObject_GenericGetAttr, /* tp_getattro */ 1179 0, /* tp_setattro */ 1180 0, /* tp_as_buffer */ 1181 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 1182 0, /* tp_doc */ 1183 wrapper_traverse, /* tp_traverse */ 1184 0, /* tp_clear */ 1185 wrapper_richcompare, /* tp_richcompare */ 1186 0, /* tp_weaklistoffset */ 1187 0, /* tp_iter */ 1188 0, /* tp_iternext */ 1189 wrapper_methods, /* tp_methods */ 1190 wrapper_members, /* tp_members */ 1191 wrapper_getsets, /* tp_getset */ 1192 0, /* tp_base */ 1193 0, /* tp_dict */ 1194 0, /* tp_descr_get */ 1195 0, /* tp_descr_set */ 1196 }; 1197 1198 PyObject * 1199 PyWrapper_New(PyObject *d, PyObject *self) 1200 { 1201 wrapperobject *wp; 1202 PyWrapperDescrObject *descr; 1203 1204 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); 1205 descr = (PyWrapperDescrObject *)d; 1206 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 1207 (PyObject *)PyDescr_TYPE(descr))); 1208 1209 wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type); 1210 if (wp != NULL) { 1211 Py_INCREF(descr); 1212 wp->descr = descr; 1213 Py_INCREF(self); 1214 wp->self = self; 1215 _PyObject_GC_TRACK(wp); 1216 } 1217 return (PyObject *)wp; 1218 } 1219 1220 1221 /* A built-in 'property' type */ 1222 1223 /* 1224 class property(object): 1225 1226 def __init__(self, fget=None, fset=None, fdel=None, doc=None): 1227 if doc is None and fget is not None and hasattr(fget, "__doc__"): 1228 doc = fget.__doc__ 1229 self.__get = fget 1230 self.__set = fset 1231 self.__del = fdel 1232 self.__doc__ = doc 1233 1234 def __get__(self, inst, type=None): 1235 if inst is None: 1236 return self 1237 if self.__get is None: 1238 raise AttributeError, "unreadable attribute" 1239 return self.__get(inst) 1240 1241 def __set__(self, inst, value): 1242 if self.__set is None: 1243 raise AttributeError, "can't set attribute" 1244 return self.__set(inst, value) 1245 1246 def __delete__(self, inst): 1247 if self.__del is None: 1248 raise AttributeError, "can't delete attribute" 1249 return self.__del(inst) 1250 1251 */ 1252 1253 typedef struct { 1254 PyObject_HEAD 1255 PyObject *prop_get; 1256 PyObject *prop_set; 1257 PyObject *prop_del; 1258 PyObject *prop_doc; 1259 int getter_doc; 1260 } propertyobject; 1261 1262 static PyObject * property_copy(PyObject *, PyObject *, PyObject *, 1263 PyObject *); 1264 1265 static PyMemberDef property_members[] = { 1266 {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY}, 1267 {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY}, 1268 {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY}, 1269 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0}, 1270 {0} 1271 }; 1272 1273 1274 PyDoc_STRVAR(getter_doc, 1275 "Descriptor to change the getter on a property."); 1276 1277 static PyObject * 1278 property_getter(PyObject *self, PyObject *getter) 1279 { 1280 return property_copy(self, getter, NULL, NULL); 1281 } 1282 1283 1284 PyDoc_STRVAR(setter_doc, 1285 "Descriptor to change the setter on a property."); 1286 1287 static PyObject * 1288 property_setter(PyObject *self, PyObject *setter) 1289 { 1290 return property_copy(self, NULL, setter, NULL); 1291 } 1292 1293 1294 PyDoc_STRVAR(deleter_doc, 1295 "Descriptor to change the deleter on a property."); 1296 1297 static PyObject * 1298 property_deleter(PyObject *self, PyObject *deleter) 1299 { 1300 return property_copy(self, NULL, NULL, deleter); 1301 } 1302 1303 1304 static PyMethodDef property_methods[] = { 1305 {"getter", property_getter, METH_O, getter_doc}, 1306 {"setter", property_setter, METH_O, setter_doc}, 1307 {"deleter", property_deleter, METH_O, deleter_doc}, 1308 {0} 1309 }; 1310 1311 1312 static void 1313 property_dealloc(PyObject *self) 1314 { 1315 propertyobject *gs = (propertyobject *)self; 1316 1317 _PyObject_GC_UNTRACK(self); 1318 Py_XDECREF(gs->prop_get); 1319 Py_XDECREF(gs->prop_set); 1320 Py_XDECREF(gs->prop_del); 1321 Py_XDECREF(gs->prop_doc); 1322 self->ob_type->tp_free(self); 1323 } 1324 1325 static PyObject * 1326 property_descr_get(PyObject *self, PyObject *obj, PyObject *type) 1327 { 1328 static PyObject * volatile cached_args = NULL; 1329 PyObject *args; 1330 PyObject *ret; 1331 propertyobject *gs = (propertyobject *)self; 1332 1333 if (obj == NULL || obj == Py_None) { 1334 Py_INCREF(self); 1335 return self; 1336 } 1337 if (gs->prop_get == NULL) { 1338 PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); 1339 return NULL; 1340 } 1341 args = cached_args; 1342 cached_args = NULL; 1343 if (!args) { 1344 args = PyTuple_New(1); 1345 if (!args) 1346 return NULL; 1347 _PyObject_GC_UNTRACK(args); 1348 } 1349 Py_INCREF(obj); 1350 PyTuple_SET_ITEM(args, 0, obj); 1351 ret = PyObject_Call(gs->prop_get, args, NULL); 1352 if (cached_args == NULL && Py_REFCNT(args) == 1) { 1353 assert(PyTuple_GET_SIZE(args) == 1); 1354 assert(PyTuple_GET_ITEM(args, 0) == obj); 1355 cached_args = args; 1356 Py_DECREF(obj); 1357 } 1358 else { 1359 assert(Py_REFCNT(args) >= 1); 1360 _PyObject_GC_TRACK(args); 1361 Py_DECREF(args); 1362 } 1363 return ret; 1364 } 1365 1366 static int 1367 property_descr_set(PyObject *self, PyObject *obj, PyObject *value) 1368 { 1369 propertyobject *gs = (propertyobject *)self; 1370 PyObject *func, *res; 1371 1372 if (value == NULL) 1373 func = gs->prop_del; 1374 else 1375 func = gs->prop_set; 1376 if (func == NULL) { 1377 PyErr_SetString(PyExc_AttributeError, 1378 value == NULL ? 1379 "can't delete attribute" : 1380 "can't set attribute"); 1381 return -1; 1382 } 1383 if (value == NULL) 1384 res = PyObject_CallFunctionObjArgs(func, obj, NULL); 1385 else 1386 res = PyObject_CallFunctionObjArgs(func, obj, value, NULL); 1387 if (res == NULL) 1388 return -1; 1389 Py_DECREF(res); 1390 return 0; 1391 } 1392 1393 static PyObject * 1394 property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) 1395 { 1396 propertyobject *pold = (propertyobject *)old; 1397 PyObject *new, *type, *doc; 1398 1399 type = PyObject_Type(old); 1400 if (type == NULL) 1401 return NULL; 1402 1403 if (get == NULL || get == Py_None) { 1404 Py_XDECREF(get); 1405 get = pold->prop_get ? pold->prop_get : Py_None; 1406 } 1407 if (set == NULL || set == Py_None) { 1408 Py_XDECREF(set); 1409 set = pold->prop_set ? pold->prop_set : Py_None; 1410 } 1411 if (del == NULL || del == Py_None) { 1412 Py_XDECREF(del); 1413 del = pold->prop_del ? pold->prop_del : Py_None; 1414 } 1415 if (pold->getter_doc && get != Py_None) { 1416 /* make _init use __doc__ from getter */ 1417 doc = Py_None; 1418 } 1419 else { 1420 doc = pold->prop_doc ? pold->prop_doc : Py_None; 1421 } 1422 1423 new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL); 1424 Py_DECREF(type); 1425 if (new == NULL) 1426 return NULL; 1427 return new; 1428 } 1429 1430 /*[clinic input] 1431 property.__init__ as property_init 1432 1433 fget: object(c_default="NULL") = None 1434 function to be used for getting an attribute value 1435 fset: object(c_default="NULL") = None 1436 function to be used for setting an attribute value 1437 fdel: object(c_default="NULL") = None 1438 function to be used for del'ing an attribute 1439 doc: object(c_default="NULL") = None 1440 docstring 1441 1442 Property attribute. 1443 1444 Typical use is to define a managed attribute x: 1445 1446 class C(object): 1447 def getx(self): return self._x 1448 def setx(self, value): self._x = value 1449 def delx(self): del self._x 1450 x = property(getx, setx, delx, "I'm the 'x' property.") 1451 1452 Decorators make defining new properties or modifying existing ones easy: 1453 1454 class C(object): 1455 @property 1456 def x(self): 1457 "I am the 'x' property." 1458 return self._x 1459 @x.setter 1460 def x(self, value): 1461 self._x = value 1462 @x.deleter 1463 def x(self): 1464 del self._x 1465 [clinic start generated code]*/ 1466 1467 static int 1468 property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset, 1469 PyObject *fdel, PyObject *doc) 1470 /*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/ 1471 { 1472 if (fget == Py_None) 1473 fget = NULL; 1474 if (fset == Py_None) 1475 fset = NULL; 1476 if (fdel == Py_None) 1477 fdel = NULL; 1478 1479 Py_XINCREF(fget); 1480 Py_XINCREF(fset); 1481 Py_XINCREF(fdel); 1482 Py_XINCREF(doc); 1483 1484 Py_XSETREF(self->prop_get, fget); 1485 Py_XSETREF(self->prop_set, fset); 1486 Py_XSETREF(self->prop_del, fdel); 1487 Py_XSETREF(self->prop_doc, doc); 1488 self->getter_doc = 0; 1489 1490 /* if no docstring given and the getter has one, use that one */ 1491 if ((doc == NULL || doc == Py_None) && fget != NULL) { 1492 _Py_IDENTIFIER(__doc__); 1493 PyObject *get_doc = _PyObject_GetAttrId(fget, &PyId___doc__); 1494 if (get_doc) { 1495 if (Py_TYPE(self) == &PyProperty_Type) { 1496 Py_XSETREF(self->prop_doc, get_doc); 1497 } 1498 else { 1499 /* If this is a property subclass, put __doc__ 1500 in dict of the subclass instance instead, 1501 otherwise it gets shadowed by __doc__ in the 1502 class's dict. */ 1503 int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc); 1504 Py_DECREF(get_doc); 1505 if (err < 0) 1506 return -1; 1507 } 1508 self->getter_doc = 1; 1509 } 1510 else if (PyErr_ExceptionMatches(PyExc_Exception)) { 1511 PyErr_Clear(); 1512 } 1513 else { 1514 return -1; 1515 } 1516 } 1517 1518 return 0; 1519 } 1520 1521 static PyObject * 1522 property_get___isabstractmethod__(propertyobject *prop, void *closure) 1523 { 1524 int res = _PyObject_IsAbstract(prop->prop_get); 1525 if (res == -1) { 1526 return NULL; 1527 } 1528 else if (res) { 1529 Py_RETURN_TRUE; 1530 } 1531 1532 res = _PyObject_IsAbstract(prop->prop_set); 1533 if (res == -1) { 1534 return NULL; 1535 } 1536 else if (res) { 1537 Py_RETURN_TRUE; 1538 } 1539 1540 res = _PyObject_IsAbstract(prop->prop_del); 1541 if (res == -1) { 1542 return NULL; 1543 } 1544 else if (res) { 1545 Py_RETURN_TRUE; 1546 } 1547 Py_RETURN_FALSE; 1548 } 1549 1550 static PyGetSetDef property_getsetlist[] = { 1551 {"__isabstractmethod__", 1552 (getter)property_get___isabstractmethod__, NULL, 1553 NULL, 1554 NULL}, 1555 {NULL} /* Sentinel */ 1556 }; 1557 1558 static int 1559 property_traverse(PyObject *self, visitproc visit, void *arg) 1560 { 1561 propertyobject *pp = (propertyobject *)self; 1562 Py_VISIT(pp->prop_get); 1563 Py_VISIT(pp->prop_set); 1564 Py_VISIT(pp->prop_del); 1565 Py_VISIT(pp->prop_doc); 1566 return 0; 1567 } 1568 1569 static int 1570 property_clear(PyObject *self) 1571 { 1572 propertyobject *pp = (propertyobject *)self; 1573 Py_CLEAR(pp->prop_doc); 1574 return 0; 1575 } 1576 1577 #include "clinic/descrobject.c.h" 1578 1579 PyTypeObject PyDictProxy_Type = { 1580 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1581 "mappingproxy", /* tp_name */ 1582 sizeof(mappingproxyobject), /* tp_basicsize */ 1583 0, /* tp_itemsize */ 1584 /* methods */ 1585 (destructor)mappingproxy_dealloc, /* tp_dealloc */ 1586 0, /* tp_print */ 1587 0, /* tp_getattr */ 1588 0, /* tp_setattr */ 1589 0, /* tp_reserved */ 1590 (reprfunc)mappingproxy_repr, /* tp_repr */ 1591 0, /* tp_as_number */ 1592 &mappingproxy_as_sequence, /* tp_as_sequence */ 1593 &mappingproxy_as_mapping, /* tp_as_mapping */ 1594 0, /* tp_hash */ 1595 0, /* tp_call */ 1596 (reprfunc)mappingproxy_str, /* tp_str */ 1597 PyObject_GenericGetAttr, /* tp_getattro */ 1598 0, /* tp_setattro */ 1599 0, /* tp_as_buffer */ 1600 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 1601 0, /* tp_doc */ 1602 mappingproxy_traverse, /* tp_traverse */ 1603 0, /* tp_clear */ 1604 (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */ 1605 0, /* tp_weaklistoffset */ 1606 (getiterfunc)mappingproxy_getiter, /* tp_iter */ 1607 0, /* tp_iternext */ 1608 mappingproxy_methods, /* tp_methods */ 1609 0, /* tp_members */ 1610 0, /* tp_getset */ 1611 0, /* tp_base */ 1612 0, /* tp_dict */ 1613 0, /* tp_descr_get */ 1614 0, /* tp_descr_set */ 1615 0, /* tp_dictoffset */ 1616 0, /* tp_init */ 1617 0, /* tp_alloc */ 1618 mappingproxy_new, /* tp_new */ 1619 }; 1620 1621 PyTypeObject PyProperty_Type = { 1622 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1623 "property", /* tp_name */ 1624 sizeof(propertyobject), /* tp_basicsize */ 1625 0, /* tp_itemsize */ 1626 /* methods */ 1627 property_dealloc, /* tp_dealloc */ 1628 0, /* tp_print */ 1629 0, /* tp_getattr */ 1630 0, /* tp_setattr */ 1631 0, /* tp_reserved */ 1632 0, /* tp_repr */ 1633 0, /* tp_as_number */ 1634 0, /* tp_as_sequence */ 1635 0, /* tp_as_mapping */ 1636 0, /* tp_hash */ 1637 0, /* tp_call */ 1638 0, /* tp_str */ 1639 PyObject_GenericGetAttr, /* tp_getattro */ 1640 0, /* tp_setattro */ 1641 0, /* tp_as_buffer */ 1642 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 1643 Py_TPFLAGS_BASETYPE, /* tp_flags */ 1644 property_init__doc__, /* tp_doc */ 1645 property_traverse, /* tp_traverse */ 1646 (inquiry)property_clear, /* tp_clear */ 1647 0, /* tp_richcompare */ 1648 0, /* tp_weaklistoffset */ 1649 0, /* tp_iter */ 1650 0, /* tp_iternext */ 1651 property_methods, /* tp_methods */ 1652 property_members, /* tp_members */ 1653 property_getsetlist, /* tp_getset */ 1654 0, /* tp_base */ 1655 0, /* tp_dict */ 1656 property_descr_get, /* tp_descr_get */ 1657 property_descr_set, /* tp_descr_set */ 1658 0, /* tp_dictoffset */ 1659 property_init, /* tp_init */ 1660 PyType_GenericAlloc, /* tp_alloc */ 1661 PyType_GenericNew, /* tp_new */ 1662 PyObject_GC_Del, /* tp_free */ 1663 }; 1664