descrobject.c 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000
  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. Py_XDECREF(get);
  1509. get = pold->prop_get ? pold->prop_get : Py_None;
  1510. }
  1511. if (set == NULL || set == Py_None) {
  1512. Py_XDECREF(set);
  1513. set = pold->prop_set ? pold->prop_set : Py_None;
  1514. }
  1515. if (del == NULL || del == Py_None) {
  1516. Py_XDECREF(del);
  1517. del = pold->prop_del ? pold->prop_del : Py_None;
  1518. }
  1519. if (pold->getter_doc && get != Py_None) {
  1520. /* make _init use __doc__ from getter */
  1521. doc = Py_None;
  1522. }
  1523. else {
  1524. doc = pold->prop_doc ? pold->prop_doc : Py_None;
  1525. }
  1526. new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL);
  1527. Py_DECREF(type);
  1528. if (new == NULL)
  1529. return NULL;
  1530. if (PyObject_TypeCheck((new), &PyProperty_Type)) {
  1531. Py_XSETREF(((propertyobject *) new)->prop_name, Py_XNewRef(pold->prop_name));
  1532. }
  1533. return new;
  1534. }
  1535. /*[clinic input]
  1536. property.__init__ as property_init
  1537. fget: object(c_default="NULL") = None
  1538. function to be used for getting an attribute value
  1539. fset: object(c_default="NULL") = None
  1540. function to be used for setting an attribute value
  1541. fdel: object(c_default="NULL") = None
  1542. function to be used for del'ing an attribute
  1543. doc: object(c_default="NULL") = None
  1544. docstring
  1545. Property attribute.
  1546. Typical use is to define a managed attribute x:
  1547. class C(object):
  1548. def getx(self): return self._x
  1549. def setx(self, value): self._x = value
  1550. def delx(self): del self._x
  1551. x = property(getx, setx, delx, "I'm the 'x' property.")
  1552. Decorators make defining new properties or modifying existing ones easy:
  1553. class C(object):
  1554. @property
  1555. def x(self):
  1556. "I am the 'x' property."
  1557. return self._x
  1558. @x.setter
  1559. def x(self, value):
  1560. self._x = value
  1561. @x.deleter
  1562. def x(self):
  1563. del self._x
  1564. [clinic start generated code]*/
  1565. static int
  1566. property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
  1567. PyObject *fdel, PyObject *doc)
  1568. /*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/
  1569. {
  1570. if (fget == Py_None)
  1571. fget = NULL;
  1572. if (fset == Py_None)
  1573. fset = NULL;
  1574. if (fdel == Py_None)
  1575. fdel = NULL;
  1576. Py_XSETREF(self->prop_get, Py_XNewRef(fget));
  1577. Py_XSETREF(self->prop_set, Py_XNewRef(fset));
  1578. Py_XSETREF(self->prop_del, Py_XNewRef(fdel));
  1579. Py_XSETREF(self->prop_doc, NULL);
  1580. Py_XSETREF(self->prop_name, NULL);
  1581. self->getter_doc = 0;
  1582. PyObject *prop_doc = NULL;
  1583. if (doc != NULL && doc != Py_None) {
  1584. prop_doc = Py_XNewRef(doc);
  1585. }
  1586. /* if no docstring given and the getter has one, use that one */
  1587. else if (fget != NULL) {
  1588. int rc = _PyObject_LookupAttr(fget, &_Py_ID(__doc__), &prop_doc);
  1589. if (rc <= 0) {
  1590. return rc;
  1591. }
  1592. if (!Py_IS_TYPE(self, &PyProperty_Type) &&
  1593. prop_doc != NULL && prop_doc != Py_None) {
  1594. // This oddity preserves the long existing behavior of surfacing
  1595. // an AttributeError when using a dict-less (__slots__) property
  1596. // subclass as a decorator on a getter method with a docstring.
  1597. // See PropertySubclassTest.test_slots_docstring_copy_exception.
  1598. int err = PyObject_SetAttr(
  1599. (PyObject *)self, &_Py_ID(__doc__), prop_doc);
  1600. if (err < 0) {
  1601. Py_DECREF(prop_doc); // release our new reference.
  1602. return -1;
  1603. }
  1604. }
  1605. if (prop_doc == Py_None) {
  1606. prop_doc = NULL;
  1607. Py_DECREF(Py_None);
  1608. }
  1609. if (prop_doc != NULL){
  1610. self->getter_doc = 1;
  1611. }
  1612. }
  1613. /* At this point `prop_doc` is either NULL or
  1614. a non-None object with incremented ref counter */
  1615. if (Py_IS_TYPE(self, &PyProperty_Type)) {
  1616. Py_XSETREF(self->prop_doc, prop_doc);
  1617. } else {
  1618. /* If this is a property subclass, put __doc__ in the dict
  1619. or designated slot of the subclass instance instead, otherwise
  1620. it gets shadowed by __doc__ in the class's dict. */
  1621. if (prop_doc == NULL) {
  1622. prop_doc = Py_NewRef(Py_None);
  1623. }
  1624. int err = PyObject_SetAttr(
  1625. (PyObject *)self, &_Py_ID(__doc__), prop_doc);
  1626. Py_DECREF(prop_doc);
  1627. if (err < 0) {
  1628. assert(PyErr_Occurred());
  1629. if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
  1630. PyErr_Clear();
  1631. // https://github.com/python/cpython/issues/98963#issuecomment-1574413319
  1632. // Python silently dropped this doc assignment through 3.11.
  1633. // We preserve that behavior for backwards compatibility.
  1634. //
  1635. // If we ever want to deprecate this behavior, only raise a
  1636. // warning or error when proc_doc is not None so that
  1637. // property without a specific doc= still works.
  1638. return 0;
  1639. } else {
  1640. return -1;
  1641. }
  1642. }
  1643. }
  1644. return 0;
  1645. }
  1646. static PyObject *
  1647. property_get___isabstractmethod__(propertyobject *prop, void *closure)
  1648. {
  1649. int res = _PyObject_IsAbstract(prop->prop_get);
  1650. if (res == -1) {
  1651. return NULL;
  1652. }
  1653. else if (res) {
  1654. Py_RETURN_TRUE;
  1655. }
  1656. res = _PyObject_IsAbstract(prop->prop_set);
  1657. if (res == -1) {
  1658. return NULL;
  1659. }
  1660. else if (res) {
  1661. Py_RETURN_TRUE;
  1662. }
  1663. res = _PyObject_IsAbstract(prop->prop_del);
  1664. if (res == -1) {
  1665. return NULL;
  1666. }
  1667. else if (res) {
  1668. Py_RETURN_TRUE;
  1669. }
  1670. Py_RETURN_FALSE;
  1671. }
  1672. static PyGetSetDef property_getsetlist[] = {
  1673. {"__isabstractmethod__",
  1674. (getter)property_get___isabstractmethod__, NULL,
  1675. NULL,
  1676. NULL},
  1677. {NULL} /* Sentinel */
  1678. };
  1679. static int
  1680. property_traverse(PyObject *self, visitproc visit, void *arg)
  1681. {
  1682. propertyobject *pp = (propertyobject *)self;
  1683. Py_VISIT(pp->prop_get);
  1684. Py_VISIT(pp->prop_set);
  1685. Py_VISIT(pp->prop_del);
  1686. Py_VISIT(pp->prop_doc);
  1687. Py_VISIT(pp->prop_name);
  1688. return 0;
  1689. }
  1690. static int
  1691. property_clear(PyObject *self)
  1692. {
  1693. propertyobject *pp = (propertyobject *)self;
  1694. Py_CLEAR(pp->prop_doc);
  1695. return 0;
  1696. }
  1697. #include "clinic/descrobject.c.h"
  1698. PyTypeObject PyDictProxy_Type = {
  1699. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  1700. "mappingproxy", /* tp_name */
  1701. sizeof(mappingproxyobject), /* tp_basicsize */
  1702. 0, /* tp_itemsize */
  1703. /* methods */
  1704. (destructor)mappingproxy_dealloc, /* tp_dealloc */
  1705. 0, /* tp_vectorcall_offset */
  1706. 0, /* tp_getattr */
  1707. 0, /* tp_setattr */
  1708. 0, /* tp_as_async */
  1709. (reprfunc)mappingproxy_repr, /* tp_repr */
  1710. &mappingproxy_as_number, /* tp_as_number */
  1711. &mappingproxy_as_sequence, /* tp_as_sequence */
  1712. &mappingproxy_as_mapping, /* tp_as_mapping */
  1713. (hashfunc)mappingproxy_hash, /* tp_hash */
  1714. 0, /* tp_call */
  1715. (reprfunc)mappingproxy_str, /* tp_str */
  1716. PyObject_GenericGetAttr, /* tp_getattro */
  1717. 0, /* tp_setattro */
  1718. 0, /* tp_as_buffer */
  1719. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
  1720. Py_TPFLAGS_MAPPING, /* tp_flags */
  1721. 0, /* tp_doc */
  1722. mappingproxy_traverse, /* tp_traverse */
  1723. 0, /* tp_clear */
  1724. (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */
  1725. 0, /* tp_weaklistoffset */
  1726. (getiterfunc)mappingproxy_getiter, /* tp_iter */
  1727. 0, /* tp_iternext */
  1728. mappingproxy_methods, /* tp_methods */
  1729. 0, /* tp_members */
  1730. 0, /* tp_getset */
  1731. 0, /* tp_base */
  1732. 0, /* tp_dict */
  1733. 0, /* tp_descr_get */
  1734. 0, /* tp_descr_set */
  1735. 0, /* tp_dictoffset */
  1736. 0, /* tp_init */
  1737. 0, /* tp_alloc */
  1738. mappingproxy_new, /* tp_new */
  1739. };
  1740. PyTypeObject PyProperty_Type = {
  1741. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  1742. "property", /* tp_name */
  1743. sizeof(propertyobject), /* tp_basicsize */
  1744. 0, /* tp_itemsize */
  1745. /* methods */
  1746. property_dealloc, /* tp_dealloc */
  1747. 0, /* tp_vectorcall_offset */
  1748. 0, /* tp_getattr */
  1749. 0, /* tp_setattr */
  1750. 0, /* tp_as_async */
  1751. 0, /* tp_repr */
  1752. 0, /* tp_as_number */
  1753. 0, /* tp_as_sequence */
  1754. 0, /* tp_as_mapping */
  1755. 0, /* tp_hash */
  1756. 0, /* tp_call */
  1757. 0, /* tp_str */
  1758. PyObject_GenericGetAttr, /* tp_getattro */
  1759. 0, /* tp_setattro */
  1760. 0, /* tp_as_buffer */
  1761. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
  1762. Py_TPFLAGS_BASETYPE, /* tp_flags */
  1763. property_init__doc__, /* tp_doc */
  1764. property_traverse, /* tp_traverse */
  1765. (inquiry)property_clear, /* tp_clear */
  1766. 0, /* tp_richcompare */
  1767. 0, /* tp_weaklistoffset */
  1768. 0, /* tp_iter */
  1769. 0, /* tp_iternext */
  1770. property_methods, /* tp_methods */
  1771. property_members, /* tp_members */
  1772. property_getsetlist, /* tp_getset */
  1773. 0, /* tp_base */
  1774. 0, /* tp_dict */
  1775. property_descr_get, /* tp_descr_get */
  1776. property_descr_set, /* tp_descr_set */
  1777. 0, /* tp_dictoffset */
  1778. property_init, /* tp_init */
  1779. PyType_GenericAlloc, /* tp_alloc */
  1780. PyType_GenericNew, /* tp_new */
  1781. PyObject_GC_Del, /* tp_free */
  1782. };