_zope_interface_coptimizations.c 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669
  1. /*###########################################################################
  2. #
  3. # Copyright (c) 2003 Zope Foundation and Contributors.
  4. # All Rights Reserved.
  5. #
  6. # This software is subject to the provisions of the Zope Public License,
  7. # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
  8. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  9. # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  10. # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  11. # FOR A PARTICULAR PURPOSE.
  12. #
  13. ############################################################################*/
  14. #include "Python.h"
  15. #include "structmember.h"
  16. #ifdef __clang__
  17. #pragma clang diagnostic push
  18. #pragma clang diagnostic ignored "-Wunused-parameter"
  19. #pragma clang diagnostic ignored "-Wmissing-field-initializers"
  20. #endif
  21. #define TYPE(O) ((PyTypeObject*)(O))
  22. #define OBJECT(O) ((PyObject*)(O))
  23. #define CLASSIC(O) ((PyClassObject*)(O))
  24. #ifndef Py_TYPE
  25. #define Py_TYPE(o) ((o)->ob_type)
  26. #endif
  27. #define PyNative_FromString PyUnicode_FromString
  28. #define ASSURE_DICT(N) \
  29. if (N == NULL) { \
  30. N = PyDict_New(); \
  31. if (N == NULL) \
  32. return NULL; \
  33. }
  34. /*
  35. * Don't use heap-allocated types for Python < 3.11: the API needed
  36. * to find the dynamic module, 'PyType_GetModuleByDef', was added then.
  37. */
  38. #if PY_VERSION_HEX < 0x030b0000
  39. #define USE_STATIC_TYPES 1
  40. #define USE_HEAP_TYPES 0
  41. #else
  42. #define USE_STATIC_TYPES 0
  43. #define USE_HEAP_TYPES 1
  44. #endif
  45. #define BASETYPE_FLAGS \
  46. Py_TPFLAGS_DEFAULT | \
  47. Py_TPFLAGS_BASETYPE | \
  48. Py_TPFLAGS_HAVE_GC
  49. #if PY_VERSION_HEX >= 0x030c0000
  50. /* Add MANAGED_WEAKREF flag for Python >= 3.12, and don't define
  51. * the '.tp_weaklistoffset' slot.
  52. *
  53. * See: https://docs.python.org/3/c-api/typeobj.html
  54. * #c.PyTypeObject.tp_weaklistoffset
  55. */
  56. #define USE_EXPLICIT_WEAKREFLIST 0
  57. #define WEAKREFTYPE_FLAGS BASETYPE_FLAGS | Py_TPFLAGS_MANAGED_WEAKREF
  58. #else
  59. /* No MANAGED_WEAKREF flag for Python < 3.12, and therefore define
  60. * the '.tp_weaklistoffset' slot, and the member whose offset it holds.
  61. *
  62. * See: https://docs.python.org/3/c-api/typeobj.html
  63. * #c.PyTypeObject.tp_weaklistoffset
  64. */
  65. #define USE_EXPLICIT_WEAKREFLIST 1
  66. #define WEAKREFTYPE_FLAGS BASETYPE_FLAGS
  67. #endif
  68. /* Static strings, used to invoke PyObject_GetAttr (only in hot paths) */
  69. static PyObject *str__class__ = NULL;
  70. static PyObject *str__conform__ = NULL;
  71. static PyObject *str__dict__ = NULL;
  72. static PyObject *str__module__ = NULL;
  73. static PyObject *str__name__ = NULL;
  74. static PyObject *str__providedBy__ = NULL;
  75. static PyObject *str__provides__ = NULL;
  76. static PyObject *str__self__ = NULL;
  77. static PyObject *str_generation = NULL;
  78. static PyObject *str_registry = NULL;
  79. static PyObject *strro = NULL;
  80. /* Static strings, used to invoke PyObject_CallMethodObjArgs */
  81. static PyObject *str_call_conform = NULL;
  82. static PyObject *str_uncached_lookup = NULL;
  83. static PyObject *str_uncached_lookupAll = NULL;
  84. static PyObject *str_uncached_subscriptions = NULL;
  85. static PyObject *strchanged = NULL;
  86. static PyObject *str__adapt__ = NULL;
  87. /* Static strings, used to invoke PyObject_GetItem
  88. *
  89. * We cannot use PyDict_GetItemString, because the '__dict__' we get
  90. * from our types can be a 'types.mappingproxy', which causes a segfault.
  91. */
  92. static PyObject* str__implemented__;
  93. static int
  94. define_static_strings()
  95. {
  96. if (str__class__ != NULL) {
  97. return 0;
  98. }
  99. #define DEFINE_STATIC_STRING(S) \
  100. if (!(str##S = PyUnicode_FromString(#S))) \
  101. return -1
  102. DEFINE_STATIC_STRING(__class__);
  103. DEFINE_STATIC_STRING(__conform__);
  104. DEFINE_STATIC_STRING(__dict__);
  105. DEFINE_STATIC_STRING(__module__);
  106. DEFINE_STATIC_STRING(__name__);
  107. DEFINE_STATIC_STRING(__providedBy__);
  108. DEFINE_STATIC_STRING(__provides__);
  109. DEFINE_STATIC_STRING(__self__);
  110. DEFINE_STATIC_STRING(_generation);
  111. DEFINE_STATIC_STRING(_registry);
  112. DEFINE_STATIC_STRING(ro);
  113. DEFINE_STATIC_STRING(__implemented__);
  114. DEFINE_STATIC_STRING(_call_conform);
  115. DEFINE_STATIC_STRING(_uncached_lookup);
  116. DEFINE_STATIC_STRING(_uncached_lookupAll);
  117. DEFINE_STATIC_STRING(_uncached_subscriptions);
  118. DEFINE_STATIC_STRING(changed);
  119. DEFINE_STATIC_STRING(__adapt__);
  120. #undef DEFINE_STATIC_STRING
  121. return 0;
  122. }
  123. /* Public module-scope functions, forward-declared here for type methods. */
  124. static PyObject *implementedBy(PyObject* module, PyObject *cls);
  125. static PyObject *getObjectSpecification(PyObject *module, PyObject *ob);
  126. static PyObject *providedBy(PyObject *module, PyObject *ob);
  127. /*
  128. * Utility functions, forward-declared here for type methods.
  129. */
  130. static PyObject* _get_module(PyTypeObject *typeobj);
  131. static PyObject* _get_adapter_hooks(PyTypeObject *typeobj);
  132. static PyTypeObject* _get_specification_base_class(PyTypeObject *typeobj);
  133. static PyTypeObject* _get_interface_base_class(PyTypeObject *typeobj);
  134. #if USE_STATIC_TYPES
  135. /*
  136. * Global used by static IB__adapt
  137. */
  138. static PyObject* adapter_hooks = NULL;
  139. /*
  140. * Globals imported from 'zope.interface.declarations'
  141. */
  142. static int imported_declarations = 0;
  143. static PyObject* BuiltinImplementationSpecifications;
  144. static PyObject* empty;
  145. static PyObject* fallback;
  146. static PyTypeObject *Implements;
  147. /* Import zope.interface.declarations and store results in global statics.
  148. *
  149. * Static alternative to '_zic_state_load_declarations' below.
  150. */
  151. static int
  152. import_declarations(void)
  153. {
  154. PyObject *declarations, *i;
  155. declarations = PyImport_ImportModule("zope.interface.declarations");
  156. if (declarations == NULL) { return -1; }
  157. BuiltinImplementationSpecifications = PyObject_GetAttrString(
  158. declarations, "BuiltinImplementationSpecifications");
  159. if (BuiltinImplementationSpecifications == NULL) { return -1; }
  160. empty = PyObject_GetAttrString(declarations, "_empty");
  161. if (empty == NULL) { return -1; }
  162. fallback = PyObject_GetAttrString(declarations, "implementedByFallback");
  163. if (fallback == NULL) { return -1;}
  164. i = PyObject_GetAttrString(declarations, "Implements");
  165. if (i == NULL) { return -1; }
  166. if (! PyType_Check(i)) {
  167. PyErr_SetString(
  168. PyExc_TypeError,
  169. "zope.interface.declarations.Implements is not a type");
  170. return -1;
  171. }
  172. Implements = (PyTypeObject *)i;
  173. Py_DECREF(declarations);
  174. imported_declarations = 1;
  175. return 0;
  176. }
  177. #endif
  178. /*
  179. * SpecificationBase class
  180. */
  181. typedef struct
  182. {
  183. PyObject_HEAD
  184. /*
  185. In the past, these fields were stored in the __dict__
  186. and were technically allowed to contain any Python object, though
  187. other type checks would fail or fall back to generic code paths if
  188. they didn't have the expected type. We preserve that behaviour and don't
  189. make any assumptions about contents.
  190. */
  191. PyObject* _implied;
  192. #if USE_EXPLICIT_WEAKREFLIST
  193. PyObject* weakreflist;
  194. #endif
  195. /*
  196. The remainder aren't used in C code but must be stored here
  197. to prevent instance layout conflicts.
  198. */
  199. PyObject* _dependents;
  200. PyObject* _bases;
  201. PyObject* _v_attrs;
  202. PyObject* __iro__;
  203. PyObject* __sro__;
  204. } SB;
  205. /*
  206. We know what the fields are *supposed* to define, but
  207. they could have anything, so we need to traverse them.
  208. */
  209. static int
  210. SB_traverse(SB* self, visitproc visit, void* arg)
  211. {
  212. /* Visit our 'tp_type' only on Python >= 3.9, per
  213. * https://docs.python.org/3/howto/isolating-extensions.html
  214. * #tp-traverse-in-python-3-8-and-lower
  215. */
  216. #if USE_HEAP_TYPES && PY_VERSION_HEX > 0x03090000
  217. Py_VISIT(Py_TYPE(self));
  218. #endif
  219. Py_VISIT(self->_implied);
  220. Py_VISIT(self->_dependents);
  221. Py_VISIT(self->_bases);
  222. Py_VISIT(self->_v_attrs);
  223. Py_VISIT(self->__iro__);
  224. Py_VISIT(self->__sro__);
  225. return 0;
  226. }
  227. static int
  228. SB_clear(SB* self)
  229. {
  230. Py_CLEAR(self->_implied);
  231. Py_CLEAR(self->_dependents);
  232. Py_CLEAR(self->_bases);
  233. Py_CLEAR(self->_v_attrs);
  234. Py_CLEAR(self->__iro__);
  235. Py_CLEAR(self->__sro__);
  236. return 0;
  237. }
  238. static void
  239. SB_dealloc(SB* self)
  240. {
  241. PyObject_GC_UnTrack((PyObject*)self);
  242. PyObject_ClearWeakRefs(OBJECT(self));
  243. PyTypeObject* tp = Py_TYPE(self);
  244. SB_clear(self);
  245. tp->tp_free(OBJECT(self));
  246. #if USE_HEAP_TYPES
  247. Py_DECREF(tp);
  248. #endif
  249. }
  250. static char SB_extends__doc__[] =
  251. "Test whether a specification is or extends another";
  252. static PyObject*
  253. SB_extends(SB* self, PyObject* other)
  254. {
  255. PyObject* implied;
  256. implied = self->_implied;
  257. if (implied == NULL) {
  258. return NULL;
  259. }
  260. if (PyDict_GetItem(implied, other) != NULL)
  261. Py_RETURN_TRUE;
  262. Py_RETURN_FALSE;
  263. }
  264. static PyObject*
  265. SB__call__(SB* self, PyObject* args, PyObject* kw)
  266. {
  267. PyObject* spec;
  268. if (!PyArg_ParseTuple(args, "O", &spec))
  269. return NULL;
  270. return SB_extends(self, spec);
  271. }
  272. static char SB_providedBy__doc__[] =
  273. "Test whether an interface is implemented by the specification";
  274. static PyObject*
  275. SB_providedBy(PyObject* self, PyObject* ob)
  276. {
  277. PyObject *decl;
  278. PyObject *item;
  279. PyObject *module;
  280. PyTypeObject *specification_base_class;
  281. module = _get_module(Py_TYPE(self));
  282. specification_base_class = _get_specification_base_class(Py_TYPE(self));
  283. decl = providedBy(module, ob);
  284. if (decl == NULL)
  285. return NULL;
  286. if (PyObject_TypeCheck(decl, specification_base_class))
  287. item = SB_extends((SB*)decl, self);
  288. else
  289. /* decl is probably a security proxy. We have to go the long way
  290. around.
  291. */
  292. item = PyObject_CallFunctionObjArgs(decl, self, NULL);
  293. Py_DECREF(decl);
  294. return item;
  295. }
  296. static char SB_implementedBy__doc__[] =
  297. "Test whether the specification is implemented by a class or factory.\n"
  298. "Raise TypeError if argument is neither a class nor a callable.";
  299. static PyObject*
  300. SB_implementedBy(PyObject* self, PyObject* cls)
  301. {
  302. PyObject *decl;
  303. PyObject *item;
  304. PyObject *module;
  305. PyTypeObject *specification_base_class;
  306. module = _get_module(Py_TYPE(self));
  307. specification_base_class = _get_specification_base_class(Py_TYPE(self));
  308. decl = implementedBy(module, cls);
  309. if (decl == NULL)
  310. return NULL;
  311. if (PyObject_TypeCheck(decl, specification_base_class))
  312. item = SB_extends((SB*)decl, self);
  313. else
  314. item = PyObject_CallFunctionObjArgs(decl, self, NULL);
  315. Py_DECREF(decl);
  316. return item;
  317. }
  318. static struct PyMethodDef SB_methods[] = {
  319. { "providedBy",
  320. (PyCFunction)SB_providedBy,
  321. METH_O,
  322. SB_providedBy__doc__ },
  323. { "implementedBy",
  324. (PyCFunction)SB_implementedBy,
  325. METH_O,
  326. SB_implementedBy__doc__ },
  327. { "isOrExtends",
  328. (PyCFunction)SB_extends,
  329. METH_O,
  330. SB_extends__doc__ },
  331. { NULL, NULL } /* sentinel */
  332. };
  333. static PyMemberDef SB_members[] = {
  334. { "_implied", T_OBJECT_EX, offsetof(SB, _implied), 0, "" },
  335. { "_dependents", T_OBJECT_EX, offsetof(SB, _dependents), 0, "" },
  336. { "_bases", T_OBJECT_EX, offsetof(SB, _bases), 0, "" },
  337. { "_v_attrs", T_OBJECT_EX, offsetof(SB, _v_attrs), 0, "" },
  338. { "__iro__", T_OBJECT_EX, offsetof(SB, __iro__), 0, "" },
  339. { "__sro__", T_OBJECT_EX, offsetof(SB, __sro__), 0, "" },
  340. #if USE_EXPLICIT_WEAKREFLIST
  341. { "__weaklistoffset__", T_PYSSIZET, offsetof(SB, weakreflist), READONLY, "" },
  342. #endif
  343. { NULL },
  344. };
  345. static char SB__name__[] = "_zope_interface_coptimizations.SpecificationBase";
  346. static char SB__doc__[] = "Base type for Specification objects";
  347. #if USE_STATIC_TYPES
  348. /*
  349. * Static type: SpecificationBase
  350. */
  351. static PyTypeObject SB_type_def = {
  352. PyVarObject_HEAD_INIT(NULL, 0)
  353. .tp_name = SB__name__,
  354. .tp_doc = SB__doc__,
  355. .tp_basicsize = sizeof(SB),
  356. .tp_flags = WEAKREFTYPE_FLAGS,
  357. .tp_call = (ternaryfunc)SB__call__,
  358. .tp_traverse = (traverseproc)SB_traverse,
  359. .tp_clear = (inquiry)SB_clear,
  360. .tp_dealloc = (destructor)SB_dealloc,
  361. #if USE_EXPLICIT_WEAKREFLIST
  362. .tp_weaklistoffset = offsetof(SB, weakreflist),
  363. #endif
  364. .tp_methods = SB_methods,
  365. .tp_members = SB_members,
  366. };
  367. #else
  368. /*
  369. * Heap-based type: SpecificationBase
  370. */
  371. static PyType_Slot SB_type_slots[] = {
  372. {Py_tp_doc, SB__doc__},
  373. {Py_tp_call, SB__call__},
  374. {Py_tp_traverse, SB_traverse},
  375. {Py_tp_clear, SB_clear},
  376. {Py_tp_dealloc, SB_dealloc},
  377. {Py_tp_methods, SB_methods},
  378. {Py_tp_members, SB_members},
  379. {0, NULL}
  380. };
  381. static PyType_Spec SB_type_spec = {
  382. .name = SB__name__,
  383. .basicsize = sizeof(SB),
  384. .flags = WEAKREFTYPE_FLAGS,
  385. .slots = SB_type_slots
  386. };
  387. #endif
  388. /*
  389. * ObjectSpecificationDescriptor class
  390. */
  391. #if USE_HEAP_TYPES
  392. static int
  393. OSD_traverse(PyObject* self, visitproc visit, void* arg)
  394. {
  395. Py_VISIT(Py_TYPE(self));
  396. return 0;
  397. }
  398. static void
  399. OSD_dealloc(PyObject* self)
  400. {
  401. PyObject_GC_UnTrack(self);
  402. PyTypeObject *tp = Py_TYPE(self);
  403. tp->tp_free(OBJECT(self));
  404. Py_DECREF(tp);
  405. }
  406. #endif
  407. static PyObject*
  408. OSD_descr_get(PyObject* self, PyObject* inst, PyObject* cls)
  409. {
  410. PyObject* provides;
  411. PyObject *module;
  412. module = _get_module(Py_TYPE(self));
  413. if (inst == NULL) {
  414. return getObjectSpecification(module, cls);
  415. }
  416. provides = PyObject_GetAttr(inst, str__provides__);
  417. /* Return __provides__ if we got it, or return NULL and propagate
  418. * non-AttributeError. */
  419. if (provides != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError)) {
  420. return provides;
  421. }
  422. PyErr_Clear();
  423. return implementedBy(module, cls);
  424. }
  425. static char OSD__name__[] = (
  426. "_zope_interface_coptimizations.ObjectSpecificationDescriptor");
  427. static char OSD__doc__[] = "Object Specification Descriptor";
  428. #if USE_STATIC_TYPES
  429. /*
  430. * Static type: ObjectSpecificationDescriptor
  431. */
  432. static PyTypeObject OSD_type_def = {
  433. PyVarObject_HEAD_INIT(NULL, 0)
  434. .tp_name = OSD__name__,
  435. .tp_doc = OSD__doc__,
  436. /* No GC for the static version */
  437. .tp_flags = Py_TPFLAGS_DEFAULT |
  438. Py_TPFLAGS_BASETYPE,
  439. .tp_descr_get = (descrgetfunc)OSD_descr_get,
  440. /*.tp_traverse, = OSD_traverse}, not reqd for static */
  441. /*.tp_dealloc, = OSD_dealloc}, not reqd for static */
  442. };
  443. #else
  444. /*
  445. * Heap type: ObjectSpecificationDescriptor
  446. */
  447. static PyType_Slot OSD_type_slots[] = {
  448. {Py_tp_doc, OSD__doc__},
  449. {Py_tp_descr_get, OSD_descr_get},
  450. {Py_tp_traverse, OSD_traverse},
  451. {Py_tp_dealloc, OSD_dealloc},
  452. {0, NULL}
  453. };
  454. static PyType_Spec OSD_type_spec = {
  455. .name = OSD__name__,
  456. .basicsize = 0,
  457. .flags = BASETYPE_FLAGS,
  458. .slots = OSD_type_slots
  459. };
  460. #endif
  461. /*
  462. * ClassProvidesBase class
  463. */
  464. typedef struct
  465. {
  466. SB spec;
  467. /* These members are handled generically, as for SB members. */
  468. PyObject* _cls;
  469. PyObject* _implements;
  470. } CPB;
  471. static int
  472. CPB_traverse(CPB* self, visitproc visit, void* arg)
  473. {
  474. Py_VISIT(self->_cls);
  475. Py_VISIT(self->_implements);
  476. return SB_traverse((SB*)self, visit, arg);
  477. }
  478. static int
  479. CPB_clear(CPB* self)
  480. {
  481. Py_CLEAR(self->_cls);
  482. Py_CLEAR(self->_implements);
  483. return SB_clear((SB*)self);
  484. }
  485. static void
  486. CPB_dealloc(CPB* self)
  487. {
  488. PyObject_GC_UnTrack((PyObject*)self);
  489. CPB_clear(self);
  490. SB_dealloc((SB*)self); /* handles decrefing tp */
  491. }
  492. static PyObject*
  493. CPB_descr_get(CPB* self, PyObject* inst, PyObject* cls)
  494. {
  495. PyObject* implements;
  496. if (self->_cls == NULL)
  497. return NULL;
  498. if (cls == self->_cls) {
  499. if (inst == NULL) {
  500. Py_INCREF(self);
  501. return OBJECT(self);
  502. }
  503. implements = self->_implements;
  504. Py_XINCREF(implements);
  505. return implements;
  506. }
  507. PyErr_SetString(PyExc_AttributeError, "__provides__");
  508. return NULL;
  509. }
  510. static PyMemberDef CPB_members[] = {
  511. { "_cls", T_OBJECT_EX, offsetof(CPB, _cls), 0, "Defining class." },
  512. { "_implements",
  513. T_OBJECT_EX,
  514. offsetof(CPB, _implements),
  515. 0,
  516. "Result of implementedBy." },
  517. { NULL }
  518. };
  519. static char CPB__name__[] = "_zope_interface_coptimizations.ClassProvidesBase";
  520. static char CPB__doc__[] = "C Base class for ClassProvides";
  521. #if USE_STATIC_TYPES
  522. /*
  523. * Static type: ClassProvidesBase
  524. */
  525. static PyTypeObject CPB_type_def = {
  526. PyVarObject_HEAD_INIT(NULL, 0)
  527. .tp_name = CPB__name__,
  528. .tp_doc = CPB__doc__,
  529. .tp_base = &SB_type_def,
  530. .tp_basicsize = sizeof(CPB),
  531. .tp_flags = BASETYPE_FLAGS,
  532. .tp_descr_get = (descrgetfunc)CPB_descr_get,
  533. .tp_traverse = (traverseproc)CPB_traverse,
  534. .tp_clear = (inquiry)CPB_clear,
  535. .tp_dealloc = (destructor)CPB_dealloc,
  536. .tp_members = CPB_members,
  537. };
  538. #else
  539. /*
  540. * Heap type: ClassProvidesBase
  541. */
  542. static PyType_Slot CPB_type_slots[] = {
  543. {Py_tp_doc, CPB__doc__},
  544. {Py_tp_descr_get, CPB_descr_get},
  545. {Py_tp_traverse, CPB_traverse},
  546. {Py_tp_clear, CPB_clear},
  547. {Py_tp_dealloc, CPB_dealloc},
  548. {Py_tp_members, CPB_members},
  549. /* tp_base cannot be set as a slot -- pass to PyType_FromModuleAndSpec */
  550. {0, NULL}
  551. };
  552. static PyType_Spec CPB_type_spec = {
  553. .name = CPB__name__,
  554. .basicsize = sizeof(CPB),
  555. .flags = BASETYPE_FLAGS,
  556. .slots = CPB_type_slots
  557. };
  558. #endif
  559. /*
  560. * InterfaceBase class
  561. */
  562. typedef struct
  563. {
  564. SB spec;
  565. PyObject* __name__;
  566. PyObject* __module__;
  567. Py_hash_t _v_cached_hash;
  568. } IB;
  569. static int
  570. IB_traverse(IB* self, visitproc visit, void* arg)
  571. {
  572. Py_VISIT(self->__name__);
  573. Py_VISIT(self->__module__);
  574. return SB_traverse((SB*)self, visit, arg);
  575. }
  576. static int
  577. IB_clear(IB* self)
  578. {
  579. Py_CLEAR(self->__name__);
  580. Py_CLEAR(self->__module__);
  581. return SB_clear((SB*)self);
  582. }
  583. static void
  584. IB_dealloc(IB* self)
  585. {
  586. PyObject_GC_UnTrack((PyObject*)self);
  587. IB_clear(self);
  588. SB_dealloc((SB*)self); /* handles decrefing tp */
  589. }
  590. static int
  591. IB__init__(IB* self, PyObject* args, PyObject* kwargs)
  592. {
  593. static char* kwlist[] = { "__name__", "__module__", NULL };
  594. PyObject* module = NULL;
  595. PyObject* name = NULL;
  596. if (!PyArg_ParseTupleAndKeywords(
  597. args, kwargs, "|OO:InterfaceBase.__init__", kwlist, &name, &module)) {
  598. return -1;
  599. }
  600. IB_clear(self);
  601. self->__module__ = module ? module : Py_None;
  602. Py_INCREF(self->__module__);
  603. self->__name__ = name ? name : Py_None;
  604. Py_INCREF(self->__name__);
  605. return 0;
  606. }
  607. /*
  608. def __adapt__(self, obj):
  609. """Adapt an object to the receiver
  610. """
  611. if self.providedBy(obj):
  612. return obj
  613. for hook in adapter_hooks:
  614. adapter = hook(self, obj)
  615. if adapter is not None:
  616. return adapter
  617. */
  618. const char IB__adapt____doc__[] = "Adapt an object to the receiver";
  619. static PyObject*
  620. IB__adapt__(PyObject* self, PyObject* obj)
  621. {
  622. PyObject *decl;
  623. PyObject *args;
  624. PyObject *adapter;
  625. PyObject *module;
  626. PyObject *adapter_hooks;
  627. PyTypeObject *specification_base_class;
  628. int implements;
  629. int i;
  630. int l;
  631. module = _get_module(Py_TYPE(self));
  632. decl = providedBy(module, obj);
  633. if (decl == NULL)
  634. return NULL;
  635. specification_base_class = _get_specification_base_class(Py_TYPE(self));
  636. if (PyObject_TypeCheck(decl, specification_base_class)) {
  637. PyObject* implied;
  638. implied = ((SB*)decl)->_implied;
  639. if (implied == NULL) {
  640. Py_DECREF(decl);
  641. return NULL;
  642. }
  643. implements = PyDict_GetItem(implied, self) != NULL;
  644. Py_DECREF(decl);
  645. } else {
  646. /* decl is probably a security proxy. We have to go the long way
  647. around.
  648. */
  649. PyObject* r;
  650. r = PyObject_CallFunctionObjArgs(decl, self, NULL);
  651. Py_DECREF(decl);
  652. if (r == NULL)
  653. return NULL;
  654. implements = PyObject_IsTrue(r);
  655. Py_DECREF(r);
  656. }
  657. if (implements) {
  658. Py_INCREF(obj);
  659. return obj;
  660. }
  661. args = PyTuple_New(2);
  662. if (args == NULL) { return NULL; }
  663. Py_INCREF(self);
  664. PyTuple_SET_ITEM(args, 0, self);
  665. Py_INCREF(obj);
  666. PyTuple_SET_ITEM(args, 1, obj);
  667. adapter_hooks = _get_adapter_hooks(Py_TYPE(self));
  668. l = PyList_GET_SIZE(adapter_hooks);
  669. for (i = 0; i < l; i++) {
  670. adapter = PyObject_CallObject(PyList_GET_ITEM(adapter_hooks, i), args);
  671. if (adapter == NULL || adapter != Py_None) {
  672. Py_DECREF(args);
  673. return adapter;
  674. }
  675. Py_DECREF(adapter);
  676. }
  677. Py_DECREF(args);
  678. Py_INCREF(Py_None);
  679. return Py_None;
  680. }
  681. /*
  682. def __call__(self, obj, alternate=_marker):
  683. try:
  684. conform = obj.__conform__
  685. except AttributeError: # pylint:disable=bare-except
  686. conform = None
  687. if conform is not None:
  688. adapter = self._call_conform(conform)
  689. if adapter is not None:
  690. return adapter
  691. adapter = self.__adapt__(obj)
  692. if adapter is not None:
  693. return adapter
  694. if alternate is not _marker:
  695. return alternate
  696. raise TypeError("Could not adapt", obj, self)
  697. */
  698. static PyObject*
  699. IB__call__(PyObject* self, PyObject* args, PyObject* kwargs)
  700. {
  701. PyObject *conform, *obj, *alternate, *adapter;
  702. static char* kwlist[] = { "obj", "alternate", NULL };
  703. conform = obj = alternate = adapter = NULL;
  704. if (!PyArg_ParseTupleAndKeywords(
  705. args, kwargs, "O|O", kwlist, &obj, &alternate))
  706. return NULL;
  707. conform = PyObject_GetAttr(obj, str__conform__);
  708. if (conform == NULL) {
  709. if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
  710. /* Propagate non-AttributeErrors */
  711. return NULL;
  712. }
  713. PyErr_Clear();
  714. Py_INCREF(Py_None);
  715. conform = Py_None;
  716. }
  717. if (conform != Py_None) {
  718. adapter =
  719. PyObject_CallMethodObjArgs(self, str_call_conform, conform, NULL);
  720. Py_DECREF(conform);
  721. if (adapter == NULL || adapter != Py_None)
  722. return adapter;
  723. Py_DECREF(adapter);
  724. } else {
  725. Py_DECREF(conform);
  726. }
  727. /* We differ from the Python code here. For speed, instead of always calling
  728. self.__adapt__(), we check to see if the type has defined it. Checking in
  729. the dict for __adapt__ isn't sufficient because there's no cheap way to
  730. tell if it's the __adapt__ that InterfaceBase itself defines (our type
  731. will *never* be InterfaceBase, we're always subclassed by
  732. InterfaceClass). Instead, we cooperate with InterfaceClass in Python to
  733. set a flag in a new subclass when this is necessary. */
  734. if (PyDict_GetItemString(self->ob_type->tp_dict, "_CALL_CUSTOM_ADAPT")) {
  735. /* Doesn't matter what the value is. Simply being present is enough. */
  736. adapter = PyObject_CallMethodObjArgs(self, str__adapt__, obj, NULL);
  737. } else {
  738. adapter = IB__adapt__(self, obj);
  739. }
  740. if (adapter == NULL || adapter != Py_None) {
  741. return adapter;
  742. }
  743. Py_DECREF(adapter);
  744. if (alternate != NULL) {
  745. Py_INCREF(alternate);
  746. return alternate;
  747. }
  748. adapter = Py_BuildValue("sOO", "Could not adapt", obj, self);
  749. if (adapter != NULL) {
  750. PyErr_SetObject(PyExc_TypeError, adapter);
  751. Py_DECREF(adapter);
  752. }
  753. return NULL;
  754. }
  755. static Py_hash_t
  756. IB__hash__(IB* self)
  757. {
  758. PyObject* tuple;
  759. if (!self->__module__) {
  760. PyErr_SetString(PyExc_AttributeError, "__module__");
  761. return -1;
  762. }
  763. if (!self->__name__) {
  764. PyErr_SetString(PyExc_AttributeError, "__name__");
  765. return -1;
  766. }
  767. if (self->_v_cached_hash) {
  768. return self->_v_cached_hash;
  769. }
  770. tuple = PyTuple_Pack(2, self->__name__, self->__module__);
  771. if (!tuple) {
  772. return -1;
  773. }
  774. self->_v_cached_hash = PyObject_Hash(tuple);
  775. Py_CLEAR(tuple);
  776. return self->_v_cached_hash;
  777. }
  778. static PyObject*
  779. IB_richcompare(IB* self, PyObject* other, int op)
  780. {
  781. PyObject* othername;
  782. PyObject* othermod;
  783. PyObject* oresult;
  784. PyTypeObject* interface_base_class;
  785. IB* otherib;
  786. int result;
  787. otherib = NULL;
  788. oresult = othername = othermod = NULL;
  789. if (OBJECT(self) == other) {
  790. switch (op) {
  791. case Py_EQ:
  792. case Py_LE:
  793. case Py_GE:
  794. Py_RETURN_TRUE;
  795. break;
  796. case Py_NE:
  797. Py_RETURN_FALSE;
  798. }
  799. }
  800. if (other == Py_None) {
  801. switch (op) {
  802. case Py_LT:
  803. case Py_LE:
  804. case Py_NE:
  805. Py_RETURN_TRUE;
  806. default:
  807. Py_RETURN_FALSE;
  808. }
  809. }
  810. interface_base_class = _get_interface_base_class(Py_TYPE(self));
  811. if (interface_base_class == NULL) {
  812. oresult = Py_NotImplemented;
  813. goto cleanup;
  814. }
  815. if (PyObject_TypeCheck(other, interface_base_class)) {
  816. // This branch borrows references. No need to clean
  817. // up if otherib is not null.
  818. otherib = (IB*)other;
  819. othername = otherib->__name__;
  820. othermod = otherib->__module__;
  821. } else {
  822. othername = PyObject_GetAttr(other, str__name__);
  823. if (othername) {
  824. othermod = PyObject_GetAttr(other, str__module__);
  825. }
  826. if (!othername || !othermod) {
  827. if (PyErr_Occurred() &&
  828. PyErr_ExceptionMatches(PyExc_AttributeError)) {
  829. PyErr_Clear();
  830. oresult = Py_NotImplemented;
  831. }
  832. goto cleanup;
  833. }
  834. }
  835. #if 0
  836. // This is the simple, straightforward version of what Python does.
  837. PyObject* pt1 = PyTuple_Pack(2, self->__name__, self->__module__);
  838. PyObject* pt2 = PyTuple_Pack(2, othername, othermod);
  839. oresult = PyObject_RichCompare(pt1, pt2, op);
  840. #endif
  841. // tuple comparison is decided by the first non-equal element.
  842. result = PyObject_RichCompareBool(self->__name__, othername, Py_EQ);
  843. if (result == 0) {
  844. result = PyObject_RichCompareBool(self->__name__, othername, op);
  845. } else if (result == 1) {
  846. result = PyObject_RichCompareBool(self->__module__, othermod, op);
  847. }
  848. // If either comparison failed, we have an error set.
  849. // Leave oresult NULL so we raise it.
  850. if (result == -1) {
  851. goto cleanup;
  852. }
  853. oresult = result ? Py_True : Py_False;
  854. cleanup:
  855. Py_XINCREF(oresult);
  856. if (!otherib) {
  857. Py_XDECREF(othername);
  858. Py_XDECREF(othermod);
  859. }
  860. return oresult;
  861. }
  862. static PyMemberDef IB_members[] = {
  863. { "__name__", T_OBJECT_EX, offsetof(IB, __name__), 0, "" },
  864. // The redundancy between __module__ and __ibmodule__ is because
  865. // __module__ is often shadowed by subclasses.
  866. { "__module__", T_OBJECT_EX, offsetof(IB, __module__), READONLY, "" },
  867. { "__ibmodule__", T_OBJECT_EX, offsetof(IB, __module__), 0, "" },
  868. { NULL }
  869. };
  870. static struct PyMethodDef IB_methods[] = {
  871. { "__adapt__", (PyCFunction)IB__adapt__, METH_O, IB__adapt____doc__},
  872. { NULL, NULL } /* sentinel */
  873. };
  874. static char IB__name__[] ="_zope_interface_coptimizations.InterfaceBase";
  875. static char IB__doc__[] = (
  876. "Interface base type providing __call__ and __adapt__"
  877. );
  878. #if USE_STATIC_TYPES
  879. /*
  880. * Static type: InterfaceBase
  881. */
  882. static PyTypeObject IB_type_def = {
  883. PyVarObject_HEAD_INIT(NULL, 0)
  884. .tp_name = IB__name__,
  885. .tp_doc = IB__doc__,
  886. .tp_base = &SB_type_def,
  887. .tp_basicsize = sizeof(IB),
  888. .tp_flags = BASETYPE_FLAGS,
  889. .tp_init = (initproc)IB__init__,
  890. .tp_hash = (hashfunc)IB__hash__,
  891. .tp_richcompare = (richcmpfunc)IB_richcompare,
  892. .tp_call = (ternaryfunc)IB__call__,
  893. .tp_traverse = (traverseproc)IB_traverse,
  894. .tp_clear = (inquiry)IB_clear,
  895. .tp_dealloc = (destructor)IB_dealloc,
  896. .tp_methods = IB_methods,
  897. .tp_members = IB_members,
  898. };
  899. #else
  900. /*
  901. * Heap type: InterfaceBase
  902. */
  903. static PyType_Slot IB_type_slots[] = {
  904. {Py_tp_doc, IB__doc__},
  905. {Py_tp_init, IB__init__},
  906. {Py_tp_hash, IB__hash__},
  907. {Py_tp_richcompare, IB_richcompare},
  908. {Py_tp_call, IB__call__},
  909. {Py_tp_traverse, IB_traverse},
  910. {Py_tp_clear, IB_clear},
  911. {Py_tp_dealloc, IB_dealloc},
  912. {Py_tp_methods, IB_methods},
  913. {Py_tp_members, IB_members},
  914. /* tp_base cannot be set as a slot -- pass to PyType_FromModuleAndSpec */
  915. {0, NULL}
  916. };
  917. static PyType_Spec IB_type_spec = {
  918. .name = IB__name__,
  919. .basicsize = sizeof(IB),
  920. .flags = BASETYPE_FLAGS,
  921. .slots = IB_type_slots
  922. };
  923. #endif
  924. /*
  925. * LookupBase class
  926. */
  927. typedef struct
  928. {
  929. PyObject_HEAD
  930. PyObject* _cache;
  931. PyObject* _mcache;
  932. PyObject* _scache;
  933. } LB;
  934. static int
  935. LB_traverse(LB* self, visitproc visit, void* arg)
  936. {
  937. /* Visit our 'tp_type' only on Python >= 3.9, per
  938. * https://docs.python.org/3/howto/isolating-extensions.html
  939. * #tp-traverse-in-python-3-8-and-lower
  940. */
  941. #if USE_HEAP_TYPES && PY_VERSION_HEX > 0x03090000
  942. Py_VISIT(Py_TYPE(self));
  943. #endif
  944. Py_VISIT(self->_cache);
  945. Py_VISIT(self->_mcache);
  946. Py_VISIT(self->_scache);
  947. return 0;
  948. }
  949. static int
  950. LB_clear(LB* self)
  951. {
  952. Py_CLEAR(self->_cache);
  953. Py_CLEAR(self->_mcache);
  954. Py_CLEAR(self->_scache);
  955. return 0;
  956. }
  957. static void
  958. LB_dealloc(LB* self)
  959. {
  960. PyObject_GC_UnTrack((PyObject*)self);
  961. PyTypeObject* tp = Py_TYPE(self);
  962. LB_clear(self);
  963. tp->tp_free((PyObject*)self);
  964. #if USE_HEAP_TYPES
  965. Py_DECREF(tp);
  966. #endif
  967. }
  968. /*
  969. def changed(self, ignored=None):
  970. self._cache.clear()
  971. self._mcache.clear()
  972. self._scache.clear()
  973. */
  974. static PyObject*
  975. LB_changed(LB* self, PyObject* ignored)
  976. {
  977. LB_clear(self);
  978. Py_INCREF(Py_None);
  979. return Py_None;
  980. }
  981. /*
  982. def _getcache(self, provided, name):
  983. cache = self._cache.get(provided)
  984. if cache is None:
  985. cache = {}
  986. self._cache[provided] = cache
  987. if name:
  988. c = cache.get(name)
  989. if c is None:
  990. c = {}
  991. cache[name] = c
  992. cache = c
  993. return cache
  994. */
  995. static PyObject*
  996. _subcache(PyObject* cache, PyObject* key)
  997. {
  998. PyObject* subcache;
  999. subcache = PyDict_GetItem(cache, key);
  1000. if (subcache == NULL) {
  1001. int status;
  1002. subcache = PyDict_New();
  1003. if (subcache == NULL)
  1004. return NULL;
  1005. status = PyDict_SetItem(cache, key, subcache);
  1006. Py_DECREF(subcache);
  1007. if (status < 0)
  1008. return NULL;
  1009. }
  1010. return subcache;
  1011. }
  1012. static PyObject*
  1013. _getcache(LB* self, PyObject* provided, PyObject* name)
  1014. {
  1015. PyObject* cache;
  1016. ASSURE_DICT(self->_cache);
  1017. cache = _subcache(self->_cache, provided);
  1018. if (cache == NULL)
  1019. return NULL;
  1020. if (name != NULL && PyObject_IsTrue(name))
  1021. cache = _subcache(cache, name);
  1022. return cache;
  1023. }
  1024. /*
  1025. def lookup(self, required, provided, name=u'', default=None):
  1026. cache = self._getcache(provided, name)
  1027. if len(required) == 1:
  1028. result = cache.get(required[0], _not_in_mapping)
  1029. else:
  1030. result = cache.get(tuple(required), _not_in_mapping)
  1031. if result is _not_in_mapping:
  1032. result = self._uncached_lookup(required, provided, name)
  1033. if len(required) == 1:
  1034. cache[required[0]] = result
  1035. else:
  1036. cache[tuple(required)] = result
  1037. if result is None:
  1038. return default
  1039. return result
  1040. */
  1041. static PyObject*
  1042. _lookup(LB* self,
  1043. PyObject* required,
  1044. PyObject* provided,
  1045. PyObject* name,
  1046. PyObject* default_)
  1047. {
  1048. PyObject *result, *key, *cache;
  1049. result = key = cache = NULL;
  1050. if (name && !PyUnicode_Check(name)) {
  1051. PyErr_SetString(PyExc_ValueError, "name is not a string");
  1052. return NULL;
  1053. }
  1054. /* If `required` is a lazy sequence, it could have arbitrary side-effects,
  1055. such as clearing our caches. So we must not retrieve the cache until
  1056. after resolving it. */
  1057. required = PySequence_Tuple(required);
  1058. if (required == NULL)
  1059. return NULL;
  1060. cache = _getcache(self, provided, name);
  1061. if (cache == NULL)
  1062. return NULL;
  1063. if (PyTuple_GET_SIZE(required) == 1)
  1064. key = PyTuple_GET_ITEM(required, 0);
  1065. else
  1066. key = required;
  1067. result = PyDict_GetItem(cache, key);
  1068. if (result == NULL) {
  1069. int status;
  1070. result = PyObject_CallMethodObjArgs(
  1071. OBJECT(self), str_uncached_lookup, required, provided, name, NULL);
  1072. if (result == NULL) {
  1073. Py_DECREF(required);
  1074. return NULL;
  1075. }
  1076. status = PyDict_SetItem(cache, key, result);
  1077. Py_DECREF(required);
  1078. if (status < 0) {
  1079. Py_DECREF(result);
  1080. return NULL;
  1081. }
  1082. } else {
  1083. Py_INCREF(result);
  1084. Py_DECREF(required);
  1085. }
  1086. if (result == Py_None && default_ != NULL) {
  1087. Py_DECREF(Py_None);
  1088. Py_INCREF(default_);
  1089. return default_;
  1090. }
  1091. return result;
  1092. }
  1093. static PyObject*
  1094. LB_lookup(LB* self, PyObject* args, PyObject* kwds)
  1095. {
  1096. static char* kwlist[] = { "required", "provided", "name", "default", NULL };
  1097. PyObject *required, *provided, *name = NULL, *default_ = NULL;
  1098. if (!PyArg_ParseTupleAndKeywords(args,
  1099. kwds,
  1100. "OO|OO:LookupBase.lookup",
  1101. kwlist,
  1102. &required,
  1103. &provided,
  1104. &name,
  1105. &default_))
  1106. return NULL;
  1107. return _lookup(self, required, provided, name, default_);
  1108. }
  1109. /*
  1110. def lookup1(self, required, provided, name=u'', default=None):
  1111. cache = self._getcache(provided, name)
  1112. result = cache.get(required, _not_in_mapping)
  1113. if result is _not_in_mapping:
  1114. return self.lookup((required, ), provided, name, default)
  1115. if result is None:
  1116. return default
  1117. return result
  1118. */
  1119. static PyObject*
  1120. _lookup1(LB* self,
  1121. PyObject* required,
  1122. PyObject* provided,
  1123. PyObject* name,
  1124. PyObject* default_)
  1125. {
  1126. PyObject *result, *cache;
  1127. if (name && !PyUnicode_Check(name)) {
  1128. PyErr_SetString(PyExc_ValueError, "name is not a string");
  1129. return NULL;
  1130. }
  1131. cache = _getcache(self, provided, name);
  1132. if (cache == NULL)
  1133. return NULL;
  1134. result = PyDict_GetItem(cache, required);
  1135. if (result == NULL) {
  1136. PyObject* tup;
  1137. tup = PyTuple_New(1);
  1138. if (tup == NULL)
  1139. return NULL;
  1140. Py_INCREF(required);
  1141. PyTuple_SET_ITEM(tup, 0, required);
  1142. result = _lookup(self, tup, provided, name, default_);
  1143. Py_DECREF(tup);
  1144. } else {
  1145. if (result == Py_None && default_ != NULL) {
  1146. result = default_;
  1147. }
  1148. Py_INCREF(result);
  1149. }
  1150. return result;
  1151. }
  1152. static PyObject*
  1153. LB_lookup1(LB* self, PyObject* args, PyObject* kwds)
  1154. {
  1155. static char* kwlist[] = { "required", "provided", "name", "default", NULL };
  1156. PyObject *required, *provided, *name = NULL, *default_ = NULL;
  1157. if (!PyArg_ParseTupleAndKeywords(args,
  1158. kwds,
  1159. "OO|OO:LookupBase.lookup1",
  1160. kwlist,
  1161. &required,
  1162. &provided,
  1163. &name,
  1164. &default_))
  1165. return NULL;
  1166. return _lookup1(self, required, provided, name, default_);
  1167. }
  1168. /*
  1169. def adapter_hook(self, provided, object, name=u'', default=None):
  1170. required = providedBy(object)
  1171. cache = self._getcache(provided, name)
  1172. factory = cache.get(required, _not_in_mapping)
  1173. if factory is _not_in_mapping:
  1174. factory = self.lookup((required, ), provided, name)
  1175. if factory is not None:
  1176. if isinstance(object, super):
  1177. object = object.__self__
  1178. result = factory(object)
  1179. if result is not None:
  1180. return result
  1181. return default
  1182. */
  1183. static PyObject*
  1184. _adapter_hook(LB* self,
  1185. PyObject* provided,
  1186. PyObject* object,
  1187. PyObject* name,
  1188. PyObject* default_)
  1189. {
  1190. PyObject *required;
  1191. PyObject *factory;
  1192. PyObject *result;
  1193. PyObject *module;
  1194. module = _get_module(Py_TYPE(self));
  1195. if (name && !PyUnicode_Check(name)) {
  1196. PyErr_SetString(PyExc_ValueError, "name is not a string");
  1197. return NULL;
  1198. }
  1199. required = providedBy(module, object);
  1200. if (required == NULL)
  1201. return NULL;
  1202. factory = _lookup1(self, required, provided, name, Py_None);
  1203. Py_DECREF(required);
  1204. if (factory == NULL)
  1205. return NULL;
  1206. if (factory != Py_None) {
  1207. if (PyObject_TypeCheck(object, &PySuper_Type)) {
  1208. PyObject* self = PyObject_GetAttr(object, str__self__);
  1209. if (self == NULL) {
  1210. Py_DECREF(factory);
  1211. return NULL;
  1212. }
  1213. // Borrow the reference to self
  1214. Py_DECREF(self);
  1215. object = self;
  1216. }
  1217. result = PyObject_CallFunctionObjArgs(factory, object, NULL);
  1218. Py_DECREF(factory);
  1219. if (result == NULL || result != Py_None)
  1220. return result;
  1221. } else
  1222. result = factory; /* None */
  1223. if (default_ == NULL || default_ == result) /* No default specified, */
  1224. return result; /* Return None. result is owned None */
  1225. Py_DECREF(result);
  1226. Py_INCREF(default_);
  1227. return default_;
  1228. }
  1229. static PyObject*
  1230. LB_adapter_hook(LB* self, PyObject* args, PyObject* kwds)
  1231. {
  1232. static char* kwlist[] = { "provided", "object", "name", "default", NULL };
  1233. PyObject *object, *provided, *name = NULL, *default_ = NULL;
  1234. if (!PyArg_ParseTupleAndKeywords(args,
  1235. kwds,
  1236. "OO|OO:LookupBase.adapter_hook",
  1237. kwlist,
  1238. &provided,
  1239. &object,
  1240. &name,
  1241. &default_))
  1242. return NULL;
  1243. return _adapter_hook(self, provided, object, name, default_);
  1244. }
  1245. static PyObject*
  1246. LB_queryAdapter(LB* self, PyObject* args, PyObject* kwds)
  1247. {
  1248. static char* kwlist[] = { "object", "provided", "name", "default", NULL };
  1249. PyObject *object, *provided, *name = NULL, *default_ = NULL;
  1250. if (!PyArg_ParseTupleAndKeywords(args,
  1251. kwds,
  1252. "OO|OO:LookupBase.queryAdapter",
  1253. kwlist,
  1254. &object,
  1255. &provided,
  1256. &name,
  1257. &default_))
  1258. return NULL;
  1259. return _adapter_hook(self, provided, object, name, default_);
  1260. }
  1261. /*
  1262. def lookupAll(self, required, provided):
  1263. cache = self._mcache.get(provided)
  1264. if cache is None:
  1265. cache = {}
  1266. self._mcache[provided] = cache
  1267. required = tuple(required)
  1268. result = cache.get(required, _not_in_mapping)
  1269. if result is _not_in_mapping:
  1270. result = self._uncached_lookupAll(required, provided)
  1271. cache[required] = result
  1272. return result
  1273. */
  1274. static PyObject*
  1275. _lookupAll(LB* self, PyObject* required, PyObject* provided)
  1276. {
  1277. PyObject *cache, *result;
  1278. /* resolve before getting cache. See note in _lookup. */
  1279. required = PySequence_Tuple(required);
  1280. if (required == NULL)
  1281. return NULL;
  1282. ASSURE_DICT(self->_mcache);
  1283. cache = _subcache(self->_mcache, provided);
  1284. if (cache == NULL)
  1285. return NULL;
  1286. result = PyDict_GetItem(cache, required);
  1287. if (result == NULL) {
  1288. int status;
  1289. result = PyObject_CallMethodObjArgs(
  1290. OBJECT(self), str_uncached_lookupAll, required, provided, NULL);
  1291. if (result == NULL) {
  1292. Py_DECREF(required);
  1293. return NULL;
  1294. }
  1295. status = PyDict_SetItem(cache, required, result);
  1296. Py_DECREF(required);
  1297. if (status < 0) {
  1298. Py_DECREF(result);
  1299. return NULL;
  1300. }
  1301. } else {
  1302. Py_INCREF(result);
  1303. Py_DECREF(required);
  1304. }
  1305. return result;
  1306. }
  1307. static PyObject*
  1308. LB_lookupAll(LB* self, PyObject* args, PyObject* kwds)
  1309. {
  1310. static char* kwlist[] = { "required", "provided", NULL };
  1311. PyObject *required, *provided;
  1312. if (!PyArg_ParseTupleAndKeywords(
  1313. args, kwds, "OO:LookupBase.lookupAll", kwlist, &required, &provided))
  1314. return NULL;
  1315. return _lookupAll(self, required, provided);
  1316. }
  1317. /*
  1318. def subscriptions(self, required, provided):
  1319. cache = self._scache.get(provided)
  1320. if cache is None:
  1321. cache = {}
  1322. self._scache[provided] = cache
  1323. required = tuple(required)
  1324. result = cache.get(required, _not_in_mapping)
  1325. if result is _not_in_mapping:
  1326. result = self._uncached_subscriptions(required, provided)
  1327. cache[required] = result
  1328. return result
  1329. */
  1330. static PyObject*
  1331. _subscriptions(LB* self, PyObject* required, PyObject* provided)
  1332. {
  1333. PyObject *cache, *result;
  1334. /* resolve before getting cache. See note in _lookup. */
  1335. required = PySequence_Tuple(required);
  1336. if (required == NULL)
  1337. return NULL;
  1338. ASSURE_DICT(self->_scache);
  1339. cache = _subcache(self->_scache, provided);
  1340. if (cache == NULL)
  1341. return NULL;
  1342. result = PyDict_GetItem(cache, required);
  1343. if (result == NULL) {
  1344. int status;
  1345. result = PyObject_CallMethodObjArgs(
  1346. OBJECT(self), str_uncached_subscriptions, required, provided, NULL);
  1347. if (result == NULL) {
  1348. Py_DECREF(required);
  1349. return NULL;
  1350. }
  1351. status = PyDict_SetItem(cache, required, result);
  1352. Py_DECREF(required);
  1353. if (status < 0) {
  1354. Py_DECREF(result);
  1355. return NULL;
  1356. }
  1357. } else {
  1358. Py_INCREF(result);
  1359. Py_DECREF(required);
  1360. }
  1361. return result;
  1362. }
  1363. static PyObject*
  1364. LB_subscriptions(LB* self, PyObject* args, PyObject* kwds)
  1365. {
  1366. static char* kwlist[] = { "required", "provided", NULL };
  1367. PyObject *required, *provided;
  1368. if (!PyArg_ParseTupleAndKeywords(
  1369. args, kwds, "OO", kwlist, &required, &provided))
  1370. return NULL;
  1371. return _subscriptions(self, required, provided);
  1372. }
  1373. static struct PyMethodDef LB_methods[] = {
  1374. { "changed", (PyCFunction)LB_changed, METH_O, "" },
  1375. { "lookup", (PyCFunction)LB_lookup, METH_KEYWORDS | METH_VARARGS, "" },
  1376. { "lookup1",
  1377. (PyCFunction)LB_lookup1,
  1378. METH_KEYWORDS | METH_VARARGS,
  1379. "" },
  1380. { "queryAdapter",
  1381. (PyCFunction)LB_queryAdapter,
  1382. METH_KEYWORDS | METH_VARARGS,
  1383. "" },
  1384. { "adapter_hook",
  1385. (PyCFunction)LB_adapter_hook,
  1386. METH_KEYWORDS | METH_VARARGS,
  1387. "" },
  1388. { "lookupAll",
  1389. (PyCFunction)LB_lookupAll,
  1390. METH_KEYWORDS | METH_VARARGS,
  1391. "" },
  1392. { "subscriptions",
  1393. (PyCFunction)LB_subscriptions,
  1394. METH_KEYWORDS | METH_VARARGS,
  1395. "" },
  1396. { NULL, NULL } /* sentinel */
  1397. };
  1398. static char LB__name__[] = "_zope_interface_coptimizations.LookupBase";
  1399. static char LB__doc__[] = "Base class for adapter registries";
  1400. #if USE_STATIC_TYPES
  1401. /*
  1402. * Static type: LookupBase
  1403. */
  1404. static PyTypeObject LB_type_def = {
  1405. PyVarObject_HEAD_INIT(NULL, 0)
  1406. .tp_name = LB__name__,
  1407. .tp_doc = LB__doc__,
  1408. .tp_basicsize = sizeof(LB),
  1409. .tp_flags = BASETYPE_FLAGS,
  1410. .tp_traverse = (traverseproc)LB_traverse,
  1411. .tp_clear = (inquiry)LB_clear,
  1412. .tp_dealloc = (destructor)&LB_dealloc,
  1413. .tp_methods = LB_methods,
  1414. };
  1415. #else
  1416. /*
  1417. * Heap type: LookupBase
  1418. */
  1419. static PyType_Slot LB_type_slots[] = {
  1420. {Py_tp_doc, LB__doc__},
  1421. {Py_tp_traverse, LB_traverse},
  1422. {Py_tp_clear, LB_clear},
  1423. {Py_tp_dealloc, LB_dealloc},
  1424. {Py_tp_methods, LB_methods},
  1425. {0, NULL}
  1426. };
  1427. static PyType_Spec LB_type_spec = {
  1428. .name = LB__name__,
  1429. .basicsize = sizeof(LB),
  1430. .flags = BASETYPE_FLAGS,
  1431. .slots = LB_type_slots
  1432. };
  1433. #endif
  1434. typedef struct
  1435. {
  1436. LB lookup;
  1437. PyObject* _verify_ro;
  1438. PyObject* _verify_generations;
  1439. } VB;
  1440. static int
  1441. VB_traverse(VB* self, visitproc visit, void* arg)
  1442. {
  1443. Py_VISIT(self->_verify_ro);
  1444. Py_VISIT(self->_verify_generations);
  1445. return LB_traverse((LB*)self, visit, arg);
  1446. }
  1447. static int
  1448. VB_clear(VB* self)
  1449. {
  1450. Py_CLEAR(self->_verify_generations);
  1451. Py_CLEAR(self->_verify_ro);
  1452. return LB_clear((LB*)self);
  1453. }
  1454. static void
  1455. VB_dealloc(VB* self)
  1456. {
  1457. PyObject_GC_UnTrack((PyObject*)self);
  1458. PyTypeObject *tp = Py_TYPE(self);
  1459. VB_clear(self);
  1460. tp->tp_free((PyObject*)self);
  1461. #if USE_HEAP_TYPES
  1462. Py_DECREF(tp);
  1463. #endif
  1464. }
  1465. /*
  1466. def changed(self, originally_changed):
  1467. super(VerifyingBasePy, self).changed(originally_changed)
  1468. self._verify_ro = self._registry.ro[1:]
  1469. self._verify_generations = [r._generation for r in self._verify_ro]
  1470. */
  1471. static PyObject*
  1472. _generations_tuple(PyObject* ro)
  1473. {
  1474. int i, l;
  1475. PyObject* generations;
  1476. l = PyTuple_GET_SIZE(ro);
  1477. generations = PyTuple_New(l);
  1478. for (i = 0; i < l; i++) {
  1479. PyObject* generation;
  1480. generation = PyObject_GetAttr(PyTuple_GET_ITEM(ro, i), str_generation);
  1481. if (generation == NULL) {
  1482. Py_DECREF(generations);
  1483. return NULL;
  1484. }
  1485. PyTuple_SET_ITEM(generations, i, generation);
  1486. }
  1487. return generations;
  1488. }
  1489. static PyObject*
  1490. verify_changed(VB* self, PyObject* ignored)
  1491. {
  1492. PyObject *t, *ro;
  1493. VB_clear(self);
  1494. t = PyObject_GetAttr(OBJECT(self), str_registry);
  1495. if (t == NULL)
  1496. return NULL;
  1497. ro = PyObject_GetAttr(t, strro);
  1498. Py_DECREF(t);
  1499. if (ro == NULL)
  1500. return NULL;
  1501. t = PyObject_CallFunctionObjArgs(OBJECT(&PyTuple_Type), ro, NULL);
  1502. Py_DECREF(ro);
  1503. if (t == NULL)
  1504. return NULL;
  1505. ro = PyTuple_GetSlice(t, 1, PyTuple_GET_SIZE(t));
  1506. Py_DECREF(t);
  1507. if (ro == NULL)
  1508. return NULL;
  1509. self->_verify_generations = _generations_tuple(ro);
  1510. if (self->_verify_generations == NULL) {
  1511. Py_DECREF(ro);
  1512. return NULL;
  1513. }
  1514. self->_verify_ro = ro;
  1515. Py_INCREF(Py_None);
  1516. return Py_None;
  1517. }
  1518. /*
  1519. def _verify(self):
  1520. if ([r._generation for r in self._verify_ro]
  1521. != self._verify_generations):
  1522. self.changed(None)
  1523. */
  1524. static int
  1525. _verify(VB* self)
  1526. {
  1527. PyObject* changed_result;
  1528. if (self->_verify_ro != NULL && self->_verify_generations != NULL) {
  1529. PyObject* generations;
  1530. int changed;
  1531. generations = _generations_tuple(self->_verify_ro);
  1532. if (generations == NULL)
  1533. return -1;
  1534. changed = PyObject_RichCompareBool(
  1535. self->_verify_generations, generations, Py_NE);
  1536. Py_DECREF(generations);
  1537. if (changed == -1)
  1538. return -1;
  1539. if (changed == 0)
  1540. return 0;
  1541. }
  1542. changed_result =
  1543. PyObject_CallMethodObjArgs(OBJECT(self), strchanged, Py_None, NULL);
  1544. if (changed_result == NULL)
  1545. return -1;
  1546. Py_DECREF(changed_result);
  1547. return 0;
  1548. }
  1549. static PyObject*
  1550. VB_lookup(VB* self, PyObject* args, PyObject* kwds)
  1551. {
  1552. static char* kwlist[] = { "required", "provided", "name", "default", NULL };
  1553. PyObject *required, *provided, *name = NULL, *default_ = NULL;
  1554. if (!PyArg_ParseTupleAndKeywords(
  1555. args, kwds, "OO|OO", kwlist, &required, &provided, &name, &default_))
  1556. return NULL;
  1557. if (_verify(self) < 0)
  1558. return NULL;
  1559. return _lookup((LB*)self, required, provided, name, default_);
  1560. }
  1561. static PyObject*
  1562. VB_lookup1(VB* self, PyObject* args, PyObject* kwds)
  1563. {
  1564. static char* kwlist[] = { "required", "provided", "name", "default", NULL };
  1565. PyObject *required, *provided, *name = NULL, *default_ = NULL;
  1566. if (!PyArg_ParseTupleAndKeywords(
  1567. args, kwds, "OO|OO", kwlist, &required, &provided, &name, &default_))
  1568. return NULL;
  1569. if (_verify(self) < 0)
  1570. return NULL;
  1571. return _lookup1((LB*)self, required, provided, name, default_);
  1572. }
  1573. static PyObject*
  1574. VB_adapter_hook(VB* self, PyObject* args, PyObject* kwds)
  1575. {
  1576. static char* kwlist[] = { "provided", "object", "name", "default", NULL };
  1577. PyObject *object, *provided, *name = NULL, *default_ = NULL;
  1578. if (!PyArg_ParseTupleAndKeywords(
  1579. args, kwds, "OO|OO", kwlist, &provided, &object, &name, &default_))
  1580. return NULL;
  1581. if (_verify(self) < 0)
  1582. return NULL;
  1583. return _adapter_hook((LB*)self, provided, object, name, default_);
  1584. }
  1585. static PyObject*
  1586. VB_queryAdapter(VB* self, PyObject* args, PyObject* kwds)
  1587. {
  1588. static char* kwlist[] = { "object", "provided", "name", "default", NULL };
  1589. PyObject *object, *provided, *name = NULL, *default_ = NULL;
  1590. if (!PyArg_ParseTupleAndKeywords(
  1591. args, kwds, "OO|OO", kwlist, &object, &provided, &name, &default_))
  1592. return NULL;
  1593. if (_verify(self) < 0)
  1594. return NULL;
  1595. return _adapter_hook((LB*)self, provided, object, name, default_);
  1596. }
  1597. static PyObject*
  1598. VB_lookupAll(VB* self, PyObject* args, PyObject* kwds)
  1599. {
  1600. static char* kwlist[] = { "required", "provided", NULL };
  1601. PyObject *required, *provided;
  1602. if (!PyArg_ParseTupleAndKeywords(
  1603. args, kwds, "OO", kwlist, &required, &provided))
  1604. return NULL;
  1605. if (_verify(self) < 0)
  1606. return NULL;
  1607. return _lookupAll((LB*)self, required, provided);
  1608. }
  1609. static PyObject*
  1610. VB_subscriptions(VB* self, PyObject* args, PyObject* kwds)
  1611. {
  1612. static char* kwlist[] = { "required", "provided", NULL };
  1613. PyObject *required, *provided;
  1614. if (!PyArg_ParseTupleAndKeywords(
  1615. args, kwds, "OO", kwlist, &required, &provided))
  1616. return NULL;
  1617. if (_verify(self) < 0)
  1618. return NULL;
  1619. return _subscriptions((LB*)self, required, provided);
  1620. }
  1621. static struct PyMethodDef VB_methods[] = {
  1622. { "changed", (PyCFunction)verify_changed, METH_O, "" },
  1623. { "lookup",
  1624. (PyCFunction)VB_lookup,
  1625. METH_KEYWORDS | METH_VARARGS,
  1626. "" },
  1627. { "lookup1",
  1628. (PyCFunction)VB_lookup1,
  1629. METH_KEYWORDS | METH_VARARGS,
  1630. "" },
  1631. { "queryAdapter",
  1632. (PyCFunction)VB_queryAdapter,
  1633. METH_KEYWORDS | METH_VARARGS,
  1634. "" },
  1635. { "adapter_hook",
  1636. (PyCFunction)VB_adapter_hook,
  1637. METH_KEYWORDS | METH_VARARGS,
  1638. "" },
  1639. { "lookupAll",
  1640. (PyCFunction)VB_lookupAll,
  1641. METH_KEYWORDS | METH_VARARGS,
  1642. "" },
  1643. { "subscriptions",
  1644. (PyCFunction)VB_subscriptions,
  1645. METH_KEYWORDS | METH_VARARGS,
  1646. "" },
  1647. { NULL, NULL } /* sentinel */
  1648. };
  1649. static char VB__name__[] = "_zope_interface_coptimizations.VerifyingBase";
  1650. static char VB__doc__[] = "Base class for verifying adapter registries.";
  1651. #if USE_STATIC_TYPES
  1652. /*
  1653. * Static type: VerifyingBase
  1654. */
  1655. static PyTypeObject VB_type_def = {
  1656. PyVarObject_HEAD_INIT(NULL, 0)
  1657. .tp_name = VB__name__,
  1658. .tp_doc = VB__doc__,
  1659. .tp_base = &LB_type_def,
  1660. .tp_basicsize = sizeof(VB),
  1661. .tp_flags = BASETYPE_FLAGS,
  1662. .tp_traverse = (traverseproc)VB_traverse,
  1663. .tp_clear = (inquiry)VB_clear,
  1664. .tp_dealloc = (destructor)&VB_dealloc,
  1665. .tp_methods = VB_methods,
  1666. };
  1667. #else
  1668. /*
  1669. * Heap type: VerifyingBase
  1670. */
  1671. static PyType_Slot VB_type_slots[] = {
  1672. {Py_tp_doc, VB__doc__},
  1673. {Py_tp_traverse, VB_traverse},
  1674. {Py_tp_clear, VB_clear},
  1675. {Py_tp_dealloc, VB_dealloc},
  1676. {Py_tp_methods, VB_methods},
  1677. /* tp_base cannot be set as a slot -- pass to PyType_FromModuleAndSpec */
  1678. {0, NULL}
  1679. };
  1680. static PyType_Spec VB_type_spec = {
  1681. .name = VB__name__,
  1682. .basicsize = sizeof(VB),
  1683. .flags = BASETYPE_FLAGS,
  1684. .slots = VB_type_slots
  1685. };
  1686. #endif
  1687. /*
  1688. * Module state struct: holds all data formerly kept as static globals.
  1689. */
  1690. typedef struct
  1691. {
  1692. /* our globals (exposed to Python) */
  1693. PyTypeObject* specification_base_class;
  1694. PyTypeObject* object_specification_descriptor_class;
  1695. PyTypeObject* class_provides_base_class;
  1696. PyTypeObject* interface_base_class;
  1697. PyTypeObject* lookup_base_class;
  1698. PyTypeObject* verifying_base_class;
  1699. PyObject* adapter_hooks;
  1700. /* members imported from 'zope.interface.declarations'
  1701. */
  1702. PyObject* empty;
  1703. PyObject* fallback;
  1704. PyObject* builtin_impl_specs;
  1705. PyTypeObject* implements_class;
  1706. /* flag: have we imported the next set of members yet from
  1707. * 'zope.interface.declarations?
  1708. */
  1709. int decl_imported;
  1710. } _zic_module_state;
  1711. /*
  1712. * Macro to speed lookup of state members
  1713. */
  1714. #define _zic_state(o) ((_zic_module_state*)PyModule_GetState(o))
  1715. static _zic_module_state*
  1716. _zic_state_init(PyObject* module)
  1717. {
  1718. _zic_module_state* rec = _zic_state(module);
  1719. rec->specification_base_class = NULL;
  1720. rec->object_specification_descriptor_class = NULL;
  1721. rec->class_provides_base_class = NULL;
  1722. rec->interface_base_class = NULL;
  1723. rec->lookup_base_class = NULL;
  1724. rec->verifying_base_class = NULL;
  1725. rec->adapter_hooks = NULL;
  1726. rec->builtin_impl_specs = NULL;
  1727. rec->empty = NULL;
  1728. rec->fallback = NULL;
  1729. rec->implements_class = NULL;
  1730. rec->decl_imported = 0;
  1731. return rec;
  1732. }
  1733. static int
  1734. _zic_state_traverse(PyObject* module, visitproc visit, void* arg)
  1735. {
  1736. _zic_module_state* rec = _zic_state(module);
  1737. Py_VISIT(rec->specification_base_class);
  1738. Py_VISIT(rec->object_specification_descriptor_class);
  1739. Py_VISIT(rec->class_provides_base_class);
  1740. Py_VISIT(rec->interface_base_class);
  1741. Py_VISIT(rec->lookup_base_class);
  1742. Py_VISIT(rec->verifying_base_class);
  1743. Py_VISIT(rec->adapter_hooks);
  1744. Py_VISIT(rec->builtin_impl_specs);
  1745. Py_VISIT(rec->empty);
  1746. Py_VISIT(rec->fallback);
  1747. Py_VISIT(rec->implements_class);
  1748. return 0;
  1749. }
  1750. static int
  1751. _zic_state_clear(PyObject* module)
  1752. {
  1753. _zic_module_state* rec = _zic_state(module);
  1754. Py_CLEAR(rec->specification_base_class);
  1755. Py_CLEAR(rec->object_specification_descriptor_class);
  1756. Py_CLEAR(rec->class_provides_base_class);
  1757. Py_CLEAR(rec->interface_base_class);
  1758. Py_CLEAR(rec->lookup_base_class);
  1759. Py_CLEAR(rec->verifying_base_class);
  1760. Py_CLEAR(rec->adapter_hooks);
  1761. Py_CLEAR(rec->builtin_impl_specs);
  1762. Py_CLEAR(rec->empty);
  1763. Py_CLEAR(rec->fallback);
  1764. Py_CLEAR(rec->implements_class);
  1765. return 0;
  1766. }
  1767. #if USE_HEAP_TYPES
  1768. /* Import zope.interface.declarations and store results in module state.
  1769. *
  1770. * Dynamic alternative to 'import_declarations' above.
  1771. */
  1772. static _zic_module_state*
  1773. _zic_state_load_declarations(PyObject* module)
  1774. {
  1775. PyObject* declarations;
  1776. PyObject* builtin_impl_specs;
  1777. PyObject* empty;
  1778. PyObject* fallback;
  1779. PyObject* implements;
  1780. _zic_module_state* rec = _zic_state(module);
  1781. if (!rec->decl_imported) {
  1782. declarations = PyImport_ImportModule("zope.interface.declarations");
  1783. if (declarations == NULL) {
  1784. return NULL;
  1785. }
  1786. builtin_impl_specs = PyObject_GetAttrString(
  1787. declarations, "BuiltinImplementationSpecifications");
  1788. if (builtin_impl_specs == NULL) {
  1789. return NULL;
  1790. }
  1791. empty = PyObject_GetAttrString(declarations, "_empty");
  1792. if (empty == NULL) {
  1793. return NULL;
  1794. }
  1795. fallback =
  1796. PyObject_GetAttrString(declarations, "implementedByFallback");
  1797. if (fallback == NULL) {
  1798. return NULL;
  1799. }
  1800. implements = PyObject_GetAttrString(declarations, "Implements");
  1801. if (implements == NULL) {
  1802. return NULL;
  1803. }
  1804. if (!PyType_Check(implements)) {
  1805. PyErr_SetString(
  1806. PyExc_TypeError,
  1807. "zope.interface.declarations.Implements is not a type");
  1808. return NULL;
  1809. }
  1810. Py_DECREF(declarations);
  1811. rec->builtin_impl_specs = builtin_impl_specs;
  1812. rec->empty = empty;
  1813. rec->fallback = fallback;
  1814. rec->implements_class = (PyTypeObject*)implements;
  1815. rec->decl_imported = 1;
  1816. }
  1817. return rec;
  1818. }
  1819. #endif
  1820. /*
  1821. * Provide access to the current module given the type.
  1822. */
  1823. static struct PyModuleDef _zic_module_def;
  1824. static PyObject*
  1825. _get_module(PyTypeObject *typeobj)
  1826. {
  1827. #if USE_STATIC_TYPES
  1828. return (PyObject*)&_zic_module_def;
  1829. #else
  1830. if (PyType_Check(typeobj)) {
  1831. /* Only added in Python 3.11 */
  1832. return PyType_GetModuleByDef(typeobj, &_zic_module_def);
  1833. }
  1834. PyErr_SetString(PyExc_TypeError, "_get_module: called w/ non-type");
  1835. return NULL;
  1836. #endif
  1837. }
  1838. /*
  1839. * Fetch the adapter hooks for the current type's module.
  1840. */
  1841. static PyObject*
  1842. _get_adapter_hooks(PyTypeObject *typeobj)
  1843. {
  1844. #if USE_STATIC_TYPES
  1845. return adapter_hooks;
  1846. #else
  1847. PyObject* module;
  1848. _zic_module_state* rec;
  1849. module = _get_module(typeobj);
  1850. if (module == NULL) { return NULL; }
  1851. rec = _zic_state(module);
  1852. return rec->adapter_hooks;
  1853. #endif
  1854. }
  1855. /*
  1856. * Fetch the 'SpecificationBase' class for the current type's module.
  1857. */
  1858. static PyTypeObject*
  1859. _get_specification_base_class(PyTypeObject *typeobj)
  1860. {
  1861. #if USE_STATIC_TYPES
  1862. return &SB_type_def;
  1863. #else
  1864. PyObject* module;
  1865. _zic_module_state* rec;
  1866. module = _get_module(typeobj);
  1867. if (module == NULL) { return NULL; }
  1868. rec = _zic_state(module);
  1869. return rec->specification_base_class;
  1870. #endif
  1871. }
  1872. /*
  1873. * Fetch the 'InterfaceBase' class for the current type's module.
  1874. */
  1875. static PyTypeObject*
  1876. _get_interface_base_class(PyTypeObject *typeobj)
  1877. {
  1878. #if USE_STATIC_TYPES
  1879. return &IB_type_def;
  1880. #else
  1881. PyObject* module;
  1882. _zic_module_state* rec;
  1883. module = _get_module(typeobj);
  1884. if (module == NULL) { return NULL; }
  1885. rec = _zic_state(module);
  1886. return rec->interface_base_class;
  1887. #endif
  1888. }
  1889. static PyObject*
  1890. implementedByFallback(PyObject* module, PyObject* cls)
  1891. {
  1892. #if USE_STATIC_TYPES
  1893. if (imported_declarations == 0 && import_declarations() < 0) {
  1894. return NULL;
  1895. }
  1896. /* now use static 'fallback' */
  1897. #else
  1898. PyObject* fallback;
  1899. _zic_module_state* rec = _zic_state_load_declarations(module);
  1900. if (rec == NULL) { return NULL; }
  1901. fallback = rec->fallback;
  1902. #endif
  1903. return PyObject_CallFunctionObjArgs(fallback, cls, NULL);
  1904. }
  1905. static char implementedBy___doc__[] =
  1906. ("Interfaces implemented by a class or factory.\n"
  1907. "Raises TypeError if argument is neither a class nor a callable.");
  1908. static PyObject*
  1909. implementedBy(PyObject* module, PyObject* cls)
  1910. {
  1911. /* Fast retrieval of implements spec, if possible, to optimize
  1912. common case. Use fallback code if we get stuck.
  1913. */
  1914. PyObject *dict = NULL;
  1915. PyObject *spec;
  1916. PyTypeObject *implements_class;
  1917. PyObject *builtin_impl_specs;
  1918. #if USE_STATIC_TYPES
  1919. if (imported_declarations == 0 && import_declarations() < 0) {
  1920. return NULL;
  1921. }
  1922. implements_class = Implements;
  1923. builtin_impl_specs = BuiltinImplementationSpecifications;
  1924. #else
  1925. _zic_module_state* rec = _zic_state_load_declarations(module);
  1926. if (rec == NULL) { return NULL; }
  1927. implements_class = rec->implements_class;
  1928. builtin_impl_specs = rec->builtin_impl_specs;
  1929. #endif
  1930. if (PyObject_TypeCheck(cls, &PySuper_Type)) {
  1931. // Let merging be handled by Python.
  1932. return implementedByFallback(module, cls);
  1933. }
  1934. if (PyType_Check(cls)) {
  1935. dict = TYPE(cls)->tp_dict;
  1936. Py_XINCREF(dict);
  1937. }
  1938. if (dict == NULL)
  1939. dict = PyObject_GetAttr(cls, str__dict__);
  1940. if (dict == NULL) {
  1941. /* Probably a security proxied class, use more expensive fallback code
  1942. */
  1943. PyErr_Clear();
  1944. return implementedByFallback(module, cls);
  1945. }
  1946. spec = PyObject_GetItem(dict, str__implemented__);
  1947. Py_DECREF(dict);
  1948. if (spec) {
  1949. if (PyObject_TypeCheck(spec, implements_class))
  1950. return spec;
  1951. /* Old-style declaration, use more expensive fallback code */
  1952. Py_DECREF(spec);
  1953. return implementedByFallback(module, cls);
  1954. }
  1955. PyErr_Clear();
  1956. /* Maybe we have a builtin */
  1957. spec = PyDict_GetItem(builtin_impl_specs, cls);
  1958. if (spec != NULL) {
  1959. Py_INCREF(spec);
  1960. return spec;
  1961. }
  1962. /* We're stuck, use fallback */
  1963. return implementedByFallback(module, cls);
  1964. }
  1965. static char getObjectSpecification___doc__[] =
  1966. ("Get an object's interfaces (internal api)");
  1967. static PyObject*
  1968. getObjectSpecification(PyObject* module, PyObject* ob)
  1969. {
  1970. PyObject *cls;
  1971. PyObject *result;
  1972. PyTypeObject *specification_base_class;
  1973. PyObject *empty_;
  1974. #if USE_STATIC_TYPES
  1975. specification_base_class = &SB_type_def;
  1976. if (imported_declarations == 0 && import_declarations() < 0) {
  1977. return NULL;
  1978. }
  1979. empty_ = empty; /* global from import */
  1980. #else
  1981. _zic_module_state* rec = _zic_state_load_declarations(module);
  1982. if (rec == NULL) { return NULL; }
  1983. specification_base_class = rec->specification_base_class;
  1984. empty_ = rec->empty;
  1985. #endif
  1986. result = PyObject_GetAttr(ob, str__provides__);
  1987. if (!result) {
  1988. if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
  1989. /* Propagate non AttributeError exceptions. */
  1990. return NULL;
  1991. }
  1992. PyErr_Clear();
  1993. } else {
  1994. int is_instance = -1;
  1995. is_instance =
  1996. PyObject_IsInstance(result, OBJECT(specification_base_class));
  1997. if (is_instance < 0) {
  1998. /* Propagate all errors */
  1999. return NULL;
  2000. }
  2001. if (is_instance) {
  2002. return result;
  2003. }
  2004. }
  2005. /* We do a getattr here so as not to be defeated by proxies */
  2006. cls = PyObject_GetAttr(ob, str__class__);
  2007. if (cls == NULL) {
  2008. if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
  2009. /* Propagate non-AttributeErrors */
  2010. return NULL;
  2011. }
  2012. PyErr_Clear();
  2013. Py_INCREF(empty_);
  2014. return empty_;
  2015. }
  2016. result = implementedBy(module, cls);
  2017. Py_DECREF(cls);
  2018. return result;
  2019. }
  2020. static char providedBy___doc__[] = ("Get an object's interfaces");
  2021. static PyObject*
  2022. providedBy(PyObject* module, PyObject* ob)
  2023. {
  2024. PyObject *result = NULL;
  2025. PyObject *cls;
  2026. PyObject *cp;
  2027. PyTypeObject *specification_base_class;
  2028. int is_instance = -1;
  2029. is_instance = PyObject_IsInstance(ob, (PyObject*)&PySuper_Type);
  2030. if (is_instance < 0) {
  2031. if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
  2032. /* Propagate non-AttributeErrors */
  2033. return NULL;
  2034. }
  2035. PyErr_Clear();
  2036. }
  2037. if (is_instance) {
  2038. return implementedBy(module, ob);
  2039. }
  2040. result = PyObject_GetAttr(ob, str__providedBy__);
  2041. if (result == NULL) {
  2042. if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
  2043. return NULL;
  2044. }
  2045. PyErr_Clear();
  2046. return getObjectSpecification(module, ob);
  2047. }
  2048. /* We want to make sure we have a spec. We can't do a type check
  2049. because we may have a proxy, so we'll just try to get the
  2050. only attribute.
  2051. */
  2052. #if USE_STATIC_TYPES
  2053. specification_base_class = &SB_type_def;
  2054. #else
  2055. _zic_module_state* rec = _zic_state(module);
  2056. specification_base_class = rec->specification_base_class;
  2057. #endif
  2058. if (PyObject_TypeCheck(result, specification_base_class) ||
  2059. PyObject_HasAttrString(result, "extends"))
  2060. return result;
  2061. /*
  2062. The object's class doesn't understand descriptors.
  2063. Sigh. We need to get an object descriptor, but we have to be
  2064. careful. We want to use the instance's __provides__,l if
  2065. there is one, but only if it didn't come from the class.
  2066. */
  2067. Py_DECREF(result);
  2068. cls = PyObject_GetAttr(ob, str__class__);
  2069. if (cls == NULL)
  2070. return NULL;
  2071. result = PyObject_GetAttr(ob, str__provides__);
  2072. if (result == NULL) {
  2073. /* No __provides__, so just fall back to implementedBy */
  2074. PyErr_Clear();
  2075. result = implementedBy(module, cls);
  2076. Py_DECREF(cls);
  2077. return result;
  2078. }
  2079. cp = PyObject_GetAttr(cls, str__provides__);
  2080. if (cp == NULL) {
  2081. /* The the class has no provides, assume we're done: */
  2082. PyErr_Clear();
  2083. Py_DECREF(cls);
  2084. return result;
  2085. }
  2086. if (cp == result) {
  2087. /*
  2088. Oops, we got the provides from the class. This means
  2089. the object doesn't have it's own. We should use implementedBy
  2090. */
  2091. Py_DECREF(result);
  2092. result = implementedBy(module, cls);
  2093. }
  2094. Py_DECREF(cls);
  2095. Py_DECREF(cp);
  2096. return result;
  2097. }
  2098. static struct PyMethodDef _zic_module_methods[] = {
  2099. { "implementedBy",
  2100. (PyCFunction)implementedBy,
  2101. METH_O,
  2102. implementedBy___doc__ },
  2103. { "getObjectSpecification",
  2104. (PyCFunction)getObjectSpecification,
  2105. METH_O,
  2106. getObjectSpecification___doc__ },
  2107. { "providedBy", (PyCFunction)providedBy, METH_O, providedBy___doc__ },
  2108. { NULL, (PyCFunction)NULL, 0, NULL } /* sentinel */
  2109. };
  2110. /* Handler for the 'execute' phase of multi-phase initialization
  2111. *
  2112. * See: https://docs.python.org/3/c-api/module.html#multi-phase-initialization
  2113. * and: https://peps.python.org/pep-0489/#module-execution-phase
  2114. */
  2115. static int
  2116. _zic_module_exec(PyObject* module)
  2117. {
  2118. _zic_module_state* rec = _zic_state_init(module);
  2119. rec->adapter_hooks = PyList_New(0);
  2120. if (rec->adapter_hooks == NULL)
  2121. return -1;
  2122. Py_INCREF(rec->adapter_hooks);
  2123. #if USE_STATIC_TYPES
  2124. /* Initialize static global */
  2125. adapter_hooks = rec->adapter_hooks;
  2126. /* Initialize types: */
  2127. SB_type_def.tp_new = PyBaseObject_Type.tp_new;
  2128. if (PyType_Ready(&SB_type_def) < 0) { return -1; }
  2129. Py_INCREF(&SB_type_def);
  2130. rec->specification_base_class = &SB_type_def;
  2131. OSD_type_def.tp_new = PyBaseObject_Type.tp_new;
  2132. if (PyType_Ready(&OSD_type_def) < 0) { return -1; }
  2133. Py_INCREF(&OSD_type_def);
  2134. rec->object_specification_descriptor_class = &OSD_type_def;
  2135. CPB_type_def.tp_new = PyBaseObject_Type.tp_new;
  2136. if (PyType_Ready(&CPB_type_def) < 0) { return -1; }
  2137. Py_INCREF(&CPB_type_def);
  2138. rec->class_provides_base_class = &CPB_type_def;
  2139. IB_type_def.tp_new = PyBaseObject_Type.tp_new;
  2140. if (PyType_Ready(&IB_type_def) < 0) { return -1; }
  2141. Py_INCREF(&IB_type_def);
  2142. rec->interface_base_class = &IB_type_def;
  2143. LB_type_def.tp_new = PyBaseObject_Type.tp_new;
  2144. if (PyType_Ready(&LB_type_def) < 0) { return -1; }
  2145. Py_INCREF(&LB_type_def);
  2146. rec->lookup_base_class = &LB_type_def;
  2147. VB_type_def.tp_new = PyBaseObject_Type.tp_new;
  2148. if (PyType_Ready(&VB_type_def) < 0) { return -1; }
  2149. Py_INCREF(&VB_type_def);
  2150. rec->verifying_base_class = &VB_type_def;
  2151. #else
  2152. PyObject *sb_class;
  2153. PyObject *osd_class;
  2154. PyObject *cpb_class;
  2155. PyObject *ib_class;
  2156. PyObject *lb_class;
  2157. PyObject *vb_class;
  2158. /* Initialize types:
  2159. */
  2160. sb_class = PyType_FromModuleAndSpec(module, &SB_type_spec, NULL);
  2161. if (sb_class == NULL) { return -1; }
  2162. Py_INCREF(sb_class);
  2163. rec->specification_base_class = TYPE(sb_class);
  2164. osd_class = PyType_FromModuleAndSpec(module, &OSD_type_spec, NULL);
  2165. if (osd_class == NULL) { return -1; }
  2166. Py_INCREF(osd_class);
  2167. rec->object_specification_descriptor_class = TYPE(osd_class);
  2168. cpb_class = PyType_FromModuleAndSpec(module, &CPB_type_spec, sb_class);
  2169. if (cpb_class == NULL) { return -1; }
  2170. Py_INCREF(cpb_class);
  2171. rec->class_provides_base_class = TYPE(cpb_class);
  2172. ib_class = PyType_FromModuleAndSpec(module, &IB_type_spec, sb_class);
  2173. if (ib_class == NULL) { return -1; }
  2174. Py_INCREF(ib_class);
  2175. rec->interface_base_class = TYPE(ib_class);
  2176. lb_class = PyType_FromModuleAndSpec(module, &LB_type_spec, NULL);
  2177. if (lb_class == NULL) { return -1; }
  2178. Py_INCREF(lb_class);
  2179. rec->lookup_base_class = TYPE(lb_class);
  2180. vb_class = PyType_FromModuleAndSpec(module, &VB_type_spec, lb_class);
  2181. if (vb_class == NULL) { return -1; }
  2182. Py_INCREF(vb_class);
  2183. rec->verifying_base_class = TYPE(vb_class);
  2184. #endif
  2185. /* Add types to our dict FBO python; also the adapter hooks */
  2186. if (PyModule_AddObject(module,
  2187. "SpecificationBase", OBJECT(rec->specification_base_class)) < 0)
  2188. return -1;
  2189. if (PyModule_AddObject(module,
  2190. "ObjectSpecificationDescriptor",
  2191. OBJECT(rec->object_specification_descriptor_class)) <
  2192. 0)
  2193. return -1;
  2194. if (PyModule_AddObject(module,
  2195. "ClassProvidesBase", OBJECT(rec->class_provides_base_class)) < 0)
  2196. return -1;
  2197. if (PyModule_AddObject(module,
  2198. "InterfaceBase", OBJECT(rec->interface_base_class)) < 0)
  2199. return -1;
  2200. if (PyModule_AddObject(module,
  2201. "LookupBase", OBJECT(rec->lookup_base_class)) < 0)
  2202. return -1;
  2203. if (PyModule_AddObject(module,
  2204. "VerifyingBase", OBJECT(rec->verifying_base_class)) < 0)
  2205. return -1;
  2206. if (PyModule_AddObject(module, "adapter_hooks", rec->adapter_hooks) < 0)
  2207. return -1;
  2208. return 0;
  2209. }
  2210. /* Slot definitions for multi-phase initialization
  2211. *
  2212. * See: https://docs.python.org/3/c-api/module.html#multi-phase-initialization
  2213. * and: https://peps.python.org/pep-0489
  2214. */
  2215. static PyModuleDef_Slot _zic_module_slots[] = {
  2216. {Py_mod_exec, _zic_module_exec},
  2217. {0, NULL}
  2218. };
  2219. static char _zic_module__doc__[] = "C optimizations for zope.interface\n\n";
  2220. static struct PyModuleDef _zic_module_def = {
  2221. PyModuleDef_HEAD_INIT,
  2222. .m_name = "_zope_interface_coptimizations",
  2223. .m_doc = _zic_module__doc__,
  2224. .m_size = sizeof(_zic_module_state),
  2225. .m_methods = _zic_module_methods,
  2226. .m_slots=_zic_module_slots,
  2227. .m_traverse = _zic_state_traverse,
  2228. .m_clear = _zic_state_clear,
  2229. };
  2230. static PyObject*
  2231. init(void)
  2232. {
  2233. if (define_static_strings() < 0) { return NULL; }
  2234. return PyModuleDef_Init(&_zic_module_def);
  2235. }
  2236. PyMODINIT_FUNC
  2237. PyInit__zope_interface_coptimizations(void)
  2238. {
  2239. return init();
  2240. }
  2241. #ifdef __clang__
  2242. #pragma clang diagnostic pop
  2243. #endif