descrobject.c 65 KB

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