PageRenderTime 28ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/Objects/descrobject.c

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