_zope_interface_coptimizations.c 70 KB

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