_zope_interface_coptimizations.c 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081
  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 PyVarObject_HEAD_INIT
  25. #define PyVarObject_HEAD_INIT(a, b) PyObject_HEAD_INIT(a) b,
  26. #endif
  27. #ifndef Py_TYPE
  28. #define Py_TYPE(o) ((o)->ob_type)
  29. #endif
  30. #define PyNative_FromString PyUnicode_FromString
  31. static PyObject *str__dict__, *str__implemented__, *strextends;
  32. static PyObject *BuiltinImplementationSpecifications, *str__provides__;
  33. static PyObject *str__class__, *str__providedBy__;
  34. static PyObject *empty, *fallback;
  35. static PyObject *str__conform__, *str_call_conform, *adapter_hooks;
  36. static PyObject *str_uncached_lookup, *str_uncached_lookupAll;
  37. static PyObject *str_uncached_subscriptions;
  38. static PyObject *str_registry, *strro, *str_generation, *strchanged;
  39. static PyObject *str__self__;
  40. static PyObject *str__module__;
  41. static PyObject *str__name__;
  42. static PyObject *str__adapt__;
  43. static PyObject *str_CALL_CUSTOM_ADAPT;
  44. static PyTypeObject *Implements;
  45. static int imported_declarations = 0;
  46. static int
  47. import_declarations(void)
  48. {
  49. PyObject *declarations, *i;
  50. declarations = PyImport_ImportModule("zope.interface.declarations");
  51. if (declarations == NULL)
  52. return -1;
  53. BuiltinImplementationSpecifications = PyObject_GetAttrString(
  54. declarations, "BuiltinImplementationSpecifications");
  55. if (BuiltinImplementationSpecifications == NULL)
  56. return -1;
  57. empty = PyObject_GetAttrString(declarations, "_empty");
  58. if (empty == NULL)
  59. return -1;
  60. fallback = PyObject_GetAttrString(declarations, "implementedByFallback");
  61. if (fallback == NULL)
  62. return -1;
  63. i = PyObject_GetAttrString(declarations, "Implements");
  64. if (i == NULL)
  65. return -1;
  66. if (! PyType_Check(i))
  67. {
  68. PyErr_SetString(PyExc_TypeError,
  69. "zope.interface.declarations.Implements is not a type");
  70. return -1;
  71. }
  72. Implements = (PyTypeObject *)i;
  73. Py_DECREF(declarations);
  74. imported_declarations = 1;
  75. return 0;
  76. }
  77. static PyTypeObject SpecificationBaseType; /* Forward */
  78. static PyObject *
  79. implementedByFallback(PyObject *cls)
  80. {
  81. if (imported_declarations == 0 && import_declarations() < 0)
  82. return NULL;
  83. return PyObject_CallFunctionObjArgs(fallback, cls, NULL);
  84. }
  85. static PyObject *
  86. implementedBy(PyObject *ignored, PyObject *cls)
  87. {
  88. /* Fast retrieval of implements spec, if possible, to optimize
  89. common case. Use fallback code if we get stuck.
  90. */
  91. PyObject *dict = NULL, *spec;
  92. if (PyObject_TypeCheck(cls, &PySuper_Type))
  93. {
  94. // Let merging be handled by Python.
  95. return implementedByFallback(cls);
  96. }
  97. if (PyType_Check(cls))
  98. {
  99. dict = TYPE(cls)->tp_dict;
  100. Py_XINCREF(dict);
  101. }
  102. if (dict == NULL)
  103. dict = PyObject_GetAttr(cls, str__dict__);
  104. if (dict == NULL)
  105. {
  106. /* Probably a security proxied class, use more expensive fallback code */
  107. PyErr_Clear();
  108. return implementedByFallback(cls);
  109. }
  110. spec = PyObject_GetItem(dict, str__implemented__);
  111. Py_DECREF(dict);
  112. if (spec)
  113. {
  114. if (imported_declarations == 0 && import_declarations() < 0)
  115. return NULL;
  116. if (PyObject_TypeCheck(spec, Implements))
  117. return spec;
  118. /* Old-style declaration, use more expensive fallback code */
  119. Py_DECREF(spec);
  120. return implementedByFallback(cls);
  121. }
  122. PyErr_Clear();
  123. /* Maybe we have a builtin */
  124. if (imported_declarations == 0 && import_declarations() < 0)
  125. return NULL;
  126. spec = PyDict_GetItem(BuiltinImplementationSpecifications, cls);
  127. if (spec != NULL)
  128. {
  129. Py_INCREF(spec);
  130. return spec;
  131. }
  132. /* We're stuck, use fallback */
  133. return implementedByFallback(cls);
  134. }
  135. static PyObject *
  136. getObjectSpecification(PyObject *ignored, PyObject *ob)
  137. {
  138. PyObject *cls, *result;
  139. result = PyObject_GetAttr(ob, str__provides__);
  140. if (!result)
  141. {
  142. if (!PyErr_ExceptionMatches(PyExc_AttributeError))
  143. {
  144. /* Propagate non AttributeError exceptions. */
  145. return NULL;
  146. }
  147. PyErr_Clear();
  148. }
  149. else
  150. {
  151. int is_instance = -1;
  152. is_instance = PyObject_IsInstance(result, (PyObject*)&SpecificationBaseType);
  153. if (is_instance < 0)
  154. {
  155. /* Propagate all errors */
  156. return NULL;
  157. }
  158. if (is_instance)
  159. {
  160. return result;
  161. }
  162. }
  163. /* We do a getattr here so as not to be defeated by proxies */
  164. cls = PyObject_GetAttr(ob, str__class__);
  165. if (cls == NULL)
  166. {
  167. if (!PyErr_ExceptionMatches(PyExc_AttributeError))
  168. {
  169. /* Propagate non-AttributeErrors */
  170. return NULL;
  171. }
  172. PyErr_Clear();
  173. if (imported_declarations == 0 && import_declarations() < 0)
  174. return NULL;
  175. Py_INCREF(empty);
  176. return empty;
  177. }
  178. result = implementedBy(NULL, cls);
  179. Py_DECREF(cls);
  180. return result;
  181. }
  182. static PyObject *
  183. providedBy(PyObject *ignored, PyObject *ob)
  184. {
  185. PyObject *result, *cls, *cp;
  186. int is_instance = -1;
  187. result = NULL;
  188. is_instance = PyObject_IsInstance(ob, (PyObject*)&PySuper_Type);
  189. if (is_instance < 0)
  190. {
  191. if (!PyErr_ExceptionMatches(PyExc_AttributeError))
  192. {
  193. /* Propagate non-AttributeErrors */
  194. return NULL;
  195. }
  196. PyErr_Clear();
  197. }
  198. if (is_instance)
  199. {
  200. return implementedBy(NULL, ob);
  201. }
  202. result = PyObject_GetAttr(ob, str__providedBy__);
  203. if (result == NULL)
  204. {
  205. if (!PyErr_ExceptionMatches(PyExc_AttributeError))
  206. {
  207. return NULL;
  208. }
  209. PyErr_Clear();
  210. return getObjectSpecification(NULL, ob);
  211. }
  212. /* We want to make sure we have a spec. We can't do a type check
  213. because we may have a proxy, so we'll just try to get the
  214. only attribute.
  215. */
  216. if (PyObject_TypeCheck(result, &SpecificationBaseType)
  217. ||
  218. PyObject_HasAttr(result, strextends)
  219. )
  220. return result;
  221. /*
  222. The object's class doesn't understand descriptors.
  223. Sigh. We need to get an object descriptor, but we have to be
  224. careful. We want to use the instance's __provides__,l if
  225. there is one, but only if it didn't come from the class.
  226. */
  227. Py_DECREF(result);
  228. cls = PyObject_GetAttr(ob, str__class__);
  229. if (cls == NULL)
  230. return NULL;
  231. result = PyObject_GetAttr(ob, str__provides__);
  232. if (result == NULL)
  233. {
  234. /* No __provides__, so just fall back to implementedBy */
  235. PyErr_Clear();
  236. result = implementedBy(NULL, cls);
  237. Py_DECREF(cls);
  238. return result;
  239. }
  240. cp = PyObject_GetAttr(cls, str__provides__);
  241. if (cp == NULL)
  242. {
  243. /* The the class has no provides, assume we're done: */
  244. PyErr_Clear();
  245. Py_DECREF(cls);
  246. return result;
  247. }
  248. if (cp == result)
  249. {
  250. /*
  251. Oops, we got the provides from the class. This means
  252. the object doesn't have it's own. We should use implementedBy
  253. */
  254. Py_DECREF(result);
  255. result = implementedBy(NULL, cls);
  256. }
  257. Py_DECREF(cls);
  258. Py_DECREF(cp);
  259. return result;
  260. }
  261. typedef struct {
  262. PyObject_HEAD
  263. PyObject* weakreflist;
  264. /*
  265. In the past, these fields were stored in the __dict__
  266. and were technically allowed to contain any Python object, though
  267. other type checks would fail or fall back to generic code paths if
  268. they didn't have the expected type. We preserve that behaviour and don't
  269. make any assumptions about contents.
  270. */
  271. PyObject* _implied;
  272. /*
  273. The remainder aren't used in C code but must be stored here
  274. to prevent instance layout conflicts.
  275. */
  276. PyObject* _dependents;
  277. PyObject* _bases;
  278. PyObject* _v_attrs;
  279. PyObject* __iro__;
  280. PyObject* __sro__;
  281. } Spec;
  282. /*
  283. We know what the fields are *supposed* to define, but
  284. they could have anything, so we need to traverse them.
  285. */
  286. static int
  287. Spec_traverse(Spec* self, visitproc visit, void* arg)
  288. {
  289. Py_VISIT(self->_implied);
  290. Py_VISIT(self->_dependents);
  291. Py_VISIT(self->_bases);
  292. Py_VISIT(self->_v_attrs);
  293. Py_VISIT(self->__iro__);
  294. Py_VISIT(self->__sro__);
  295. return 0;
  296. }
  297. static int
  298. Spec_clear(Spec* self)
  299. {
  300. Py_CLEAR(self->_implied);
  301. Py_CLEAR(self->_dependents);
  302. Py_CLEAR(self->_bases);
  303. Py_CLEAR(self->_v_attrs);
  304. Py_CLEAR(self->__iro__);
  305. Py_CLEAR(self->__sro__);
  306. return 0;
  307. }
  308. static void
  309. Spec_dealloc(Spec* self)
  310. {
  311. /* PyType_GenericAlloc that you get when you don't
  312. specify a tp_alloc always tracks the object. */
  313. PyObject_GC_UnTrack((PyObject *)self);
  314. if (self->weakreflist != NULL) {
  315. PyObject_ClearWeakRefs(OBJECT(self));
  316. }
  317. Spec_clear(self);
  318. Py_TYPE(self)->tp_free(OBJECT(self));
  319. }
  320. static PyObject *
  321. Spec_extends(Spec *self, PyObject *other)
  322. {
  323. PyObject *implied;
  324. implied = self->_implied;
  325. if (implied == NULL) {
  326. return NULL;
  327. }
  328. if (PyDict_GetItem(implied, other) != NULL)
  329. Py_RETURN_TRUE;
  330. Py_RETURN_FALSE;
  331. }
  332. static char Spec_extends__doc__[] =
  333. "Test whether a specification is or extends another"
  334. ;
  335. static char Spec_providedBy__doc__[] =
  336. "Test whether an interface is implemented by the specification"
  337. ;
  338. static PyObject *
  339. Spec_call(Spec *self, PyObject *args, PyObject *kw)
  340. {
  341. PyObject *spec;
  342. if (! PyArg_ParseTuple(args, "O", &spec))
  343. return NULL;
  344. return Spec_extends(self, spec);
  345. }
  346. static PyObject *
  347. Spec_providedBy(PyObject *self, PyObject *ob)
  348. {
  349. PyObject *decl, *item;
  350. decl = providedBy(NULL, ob);
  351. if (decl == NULL)
  352. return NULL;
  353. if (PyObject_TypeCheck(decl, &SpecificationBaseType))
  354. item = Spec_extends((Spec*)decl, self);
  355. else
  356. /* decl is probably a security proxy. We have to go the long way
  357. around.
  358. */
  359. item = PyObject_CallFunctionObjArgs(decl, self, NULL);
  360. Py_DECREF(decl);
  361. return item;
  362. }
  363. static char Spec_implementedBy__doc__[] =
  364. "Test whether the specification is implemented by a class or factory.\n"
  365. "Raise TypeError if argument is neither a class nor a callable."
  366. ;
  367. static PyObject *
  368. Spec_implementedBy(PyObject *self, PyObject *cls)
  369. {
  370. PyObject *decl, *item;
  371. decl = implementedBy(NULL, cls);
  372. if (decl == NULL)
  373. return NULL;
  374. if (PyObject_TypeCheck(decl, &SpecificationBaseType))
  375. item = Spec_extends((Spec*)decl, self);
  376. else
  377. item = PyObject_CallFunctionObjArgs(decl, self, NULL);
  378. Py_DECREF(decl);
  379. return item;
  380. }
  381. static struct PyMethodDef Spec_methods[] = {
  382. {"providedBy",
  383. (PyCFunction)Spec_providedBy, METH_O,
  384. Spec_providedBy__doc__},
  385. {"implementedBy",
  386. (PyCFunction)Spec_implementedBy, METH_O,
  387. Spec_implementedBy__doc__},
  388. {"isOrExtends", (PyCFunction)Spec_extends, METH_O,
  389. Spec_extends__doc__},
  390. {NULL, NULL} /* sentinel */
  391. };
  392. static PyMemberDef Spec_members[] = {
  393. {"_implied", T_OBJECT_EX, offsetof(Spec, _implied), 0, ""},
  394. {"_dependents", T_OBJECT_EX, offsetof(Spec, _dependents), 0, ""},
  395. {"_bases", T_OBJECT_EX, offsetof(Spec, _bases), 0, ""},
  396. {"_v_attrs", T_OBJECT_EX, offsetof(Spec, _v_attrs), 0, ""},
  397. {"__iro__", T_OBJECT_EX, offsetof(Spec, __iro__), 0, ""},
  398. {"__sro__", T_OBJECT_EX, offsetof(Spec, __sro__), 0, ""},
  399. {NULL},
  400. };
  401. static PyTypeObject SpecificationBaseType = {
  402. PyVarObject_HEAD_INIT(NULL, 0)
  403. /* tp_name */ "_interface_coptimizations."
  404. "SpecificationBase",
  405. /* tp_basicsize */ sizeof(Spec),
  406. /* tp_itemsize */ 0,
  407. /* tp_dealloc */ (destructor)Spec_dealloc,
  408. /* tp_print */ (printfunc)0,
  409. /* tp_getattr */ (getattrfunc)0,
  410. /* tp_setattr */ (setattrfunc)0,
  411. /* tp_compare */ 0,
  412. /* tp_repr */ (reprfunc)0,
  413. /* tp_as_number */ 0,
  414. /* tp_as_sequence */ 0,
  415. /* tp_as_mapping */ 0,
  416. /* tp_hash */ (hashfunc)0,
  417. /* tp_call */ (ternaryfunc)Spec_call,
  418. /* tp_str */ (reprfunc)0,
  419. /* tp_getattro */ (getattrofunc)0,
  420. /* tp_setattro */ (setattrofunc)0,
  421. /* tp_as_buffer */ 0,
  422. /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
  423. "Base type for Specification objects",
  424. /* tp_traverse */ (traverseproc)Spec_traverse,
  425. /* tp_clear */ (inquiry)Spec_clear,
  426. /* tp_richcompare */ (richcmpfunc)0,
  427. /* tp_weaklistoffset */ offsetof(Spec, weakreflist),
  428. /* tp_iter */ (getiterfunc)0,
  429. /* tp_iternext */ (iternextfunc)0,
  430. /* tp_methods */ Spec_methods,
  431. /* tp_members */ Spec_members,
  432. };
  433. static PyObject *
  434. OSD_descr_get(PyObject *self, PyObject *inst, PyObject *cls)
  435. {
  436. PyObject *provides;
  437. if (inst == NULL)
  438. return getObjectSpecification(NULL, cls);
  439. provides = PyObject_GetAttr(inst, str__provides__);
  440. /* Return __provides__ if we got it, or return NULL and propagate non-AttributeError. */
  441. if (provides != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError))
  442. return provides;
  443. PyErr_Clear();
  444. return implementedBy(NULL, cls);
  445. }
  446. static PyTypeObject OSDType = {
  447. PyVarObject_HEAD_INIT(NULL, 0)
  448. /* tp_name */ "_interface_coptimizations."
  449. "ObjectSpecificationDescriptor",
  450. /* tp_basicsize */ 0,
  451. /* tp_itemsize */ 0,
  452. /* tp_dealloc */ (destructor)0,
  453. /* tp_print */ (printfunc)0,
  454. /* tp_getattr */ (getattrfunc)0,
  455. /* tp_setattr */ (setattrfunc)0,
  456. /* tp_compare */ 0,
  457. /* tp_repr */ (reprfunc)0,
  458. /* tp_as_number */ 0,
  459. /* tp_as_sequence */ 0,
  460. /* tp_as_mapping */ 0,
  461. /* tp_hash */ (hashfunc)0,
  462. /* tp_call */ (ternaryfunc)0,
  463. /* tp_str */ (reprfunc)0,
  464. /* tp_getattro */ (getattrofunc)0,
  465. /* tp_setattro */ (setattrofunc)0,
  466. /* tp_as_buffer */ 0,
  467. /* tp_flags */ Py_TPFLAGS_DEFAULT
  468. | Py_TPFLAGS_BASETYPE ,
  469. "Object Specification Descriptor",
  470. /* tp_traverse */ (traverseproc)0,
  471. /* tp_clear */ (inquiry)0,
  472. /* tp_richcompare */ (richcmpfunc)0,
  473. /* tp_weaklistoffset */ (long)0,
  474. /* tp_iter */ (getiterfunc)0,
  475. /* tp_iternext */ (iternextfunc)0,
  476. /* tp_methods */ 0,
  477. /* tp_members */ 0,
  478. /* tp_getset */ 0,
  479. /* tp_base */ 0,
  480. /* tp_dict */ 0, /* internal use */
  481. /* tp_descr_get */ (descrgetfunc)OSD_descr_get,
  482. };
  483. typedef struct {
  484. Spec spec;
  485. /* These members are handled generically, as for Spec members. */
  486. PyObject* _cls;
  487. PyObject* _implements;
  488. } CPB;
  489. static PyObject *
  490. CPB_descr_get(CPB *self, PyObject *inst, PyObject *cls)
  491. {
  492. PyObject *implements;
  493. if (self->_cls == NULL)
  494. return NULL;
  495. if (cls == self->_cls)
  496. {
  497. if (inst == NULL)
  498. {
  499. Py_INCREF(self);
  500. return OBJECT(self);
  501. }
  502. implements = self->_implements;
  503. Py_XINCREF(implements);
  504. return implements;
  505. }
  506. PyErr_SetObject(PyExc_AttributeError, str__provides__);
  507. return NULL;
  508. }
  509. static int
  510. CPB_traverse(CPB* self, visitproc visit, void* arg)
  511. {
  512. Py_VISIT(self->_cls);
  513. Py_VISIT(self->_implements);
  514. return Spec_traverse((Spec*)self, visit, arg);
  515. }
  516. static int
  517. CPB_clear(CPB* self)
  518. {
  519. Py_CLEAR(self->_cls);
  520. Py_CLEAR(self->_implements);
  521. Spec_clear((Spec*)self);
  522. return 0;
  523. }
  524. static void
  525. CPB_dealloc(CPB* self)
  526. {
  527. PyObject_GC_UnTrack((PyObject *)self);
  528. CPB_clear(self);
  529. Spec_dealloc((Spec*)self);
  530. }
  531. static PyMemberDef CPB_members[] = {
  532. {"_cls", T_OBJECT_EX, offsetof(CPB, _cls), 0, "Defining class."},
  533. {"_implements", T_OBJECT_EX, offsetof(CPB, _implements), 0, "Result of implementedBy."},
  534. {NULL}
  535. };
  536. static PyTypeObject CPBType = {
  537. PyVarObject_HEAD_INIT(NULL, 0)
  538. /* tp_name */ "_interface_coptimizations."
  539. "ClassProvidesBase",
  540. /* tp_basicsize */ sizeof(CPB),
  541. /* tp_itemsize */ 0,
  542. /* tp_dealloc */ (destructor)CPB_dealloc,
  543. /* tp_print */ (printfunc)0,
  544. /* tp_getattr */ (getattrfunc)0,
  545. /* tp_setattr */ (setattrfunc)0,
  546. /* tp_compare */ 0,
  547. /* tp_repr */ (reprfunc)0,
  548. /* tp_as_number */ 0,
  549. /* tp_as_sequence */ 0,
  550. /* tp_as_mapping */ 0,
  551. /* tp_hash */ (hashfunc)0,
  552. /* tp_call */ (ternaryfunc)0,
  553. /* tp_str */ (reprfunc)0,
  554. /* tp_getattro */ (getattrofunc)0,
  555. /* tp_setattro */ (setattrofunc)0,
  556. /* tp_as_buffer */ 0,
  557. /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
  558. "C Base class for ClassProvides",
  559. /* tp_traverse */ (traverseproc)CPB_traverse,
  560. /* tp_clear */ (inquiry)CPB_clear,
  561. /* tp_richcompare */ (richcmpfunc)0,
  562. /* tp_weaklistoffset */ (long)0,
  563. /* tp_iter */ (getiterfunc)0,
  564. /* tp_iternext */ (iternextfunc)0,
  565. /* tp_methods */ 0,
  566. /* tp_members */ CPB_members,
  567. /* tp_getset */ 0,
  568. /* tp_base */ &SpecificationBaseType,
  569. /* tp_dict */ 0, /* internal use */
  570. /* tp_descr_get */ (descrgetfunc)CPB_descr_get,
  571. /* tp_descr_set */ 0,
  572. /* tp_dictoffset */ 0,
  573. /* tp_init */ 0,
  574. /* tp_alloc */ 0,
  575. /* tp_new */ 0,
  576. };
  577. /* ==================================================================== */
  578. /* ========== Begin: __call__ and __adapt__ =========================== */
  579. /*
  580. def __adapt__(self, obj):
  581. """Adapt an object to the receiver
  582. """
  583. if self.providedBy(obj):
  584. return obj
  585. for hook in adapter_hooks:
  586. adapter = hook(self, obj)
  587. if adapter is not None:
  588. return adapter
  589. */
  590. static PyObject *
  591. __adapt__(PyObject *self, PyObject *obj)
  592. {
  593. PyObject *decl, *args, *adapter;
  594. int implements, i, l;
  595. decl = providedBy(NULL, obj);
  596. if (decl == NULL)
  597. return NULL;
  598. if (PyObject_TypeCheck(decl, &SpecificationBaseType))
  599. {
  600. PyObject *implied;
  601. implied = ((Spec*)decl)->_implied;
  602. if (implied == NULL)
  603. {
  604. Py_DECREF(decl);
  605. return NULL;
  606. }
  607. implements = PyDict_GetItem(implied, self) != NULL;
  608. Py_DECREF(decl);
  609. }
  610. else
  611. {
  612. /* decl is probably a security proxy. We have to go the long way
  613. around.
  614. */
  615. PyObject *r;
  616. r = PyObject_CallFunctionObjArgs(decl, self, NULL);
  617. Py_DECREF(decl);
  618. if (r == NULL)
  619. return NULL;
  620. implements = PyObject_IsTrue(r);
  621. Py_DECREF(r);
  622. }
  623. if (implements)
  624. {
  625. Py_INCREF(obj);
  626. return obj;
  627. }
  628. l = PyList_GET_SIZE(adapter_hooks);
  629. args = PyTuple_New(2);
  630. if (args == NULL)
  631. return NULL;
  632. Py_INCREF(self);
  633. PyTuple_SET_ITEM(args, 0, self);
  634. Py_INCREF(obj);
  635. PyTuple_SET_ITEM(args, 1, obj);
  636. for (i = 0; i < l; i++)
  637. {
  638. adapter = PyObject_CallObject(PyList_GET_ITEM(adapter_hooks, i), args);
  639. if (adapter == NULL || adapter != Py_None)
  640. {
  641. Py_DECREF(args);
  642. return adapter;
  643. }
  644. Py_DECREF(adapter);
  645. }
  646. Py_DECREF(args);
  647. Py_INCREF(Py_None);
  648. return Py_None;
  649. }
  650. typedef struct {
  651. Spec spec;
  652. PyObject* __name__;
  653. PyObject* __module__;
  654. Py_hash_t _v_cached_hash;
  655. } IB;
  656. static struct PyMethodDef ib_methods[] = {
  657. {"__adapt__", (PyCFunction)__adapt__, METH_O,
  658. "Adapt an object to the receiver"},
  659. {NULL, NULL} /* sentinel */
  660. };
  661. /*
  662. def __call__(self, obj, alternate=_marker):
  663. try:
  664. conform = obj.__conform__
  665. except AttributeError: # pylint:disable=bare-except
  666. conform = None
  667. if conform is not None:
  668. adapter = self._call_conform(conform)
  669. if adapter is not None:
  670. return adapter
  671. adapter = self.__adapt__(obj)
  672. if adapter is not None:
  673. return adapter
  674. if alternate is not _marker:
  675. return alternate
  676. raise TypeError("Could not adapt", obj, self)
  677. */
  678. static PyObject *
  679. IB_call(PyObject *self, PyObject *args, PyObject *kwargs)
  680. {
  681. PyObject *conform, *obj, *alternate, *adapter;
  682. static char *kwlist[] = {"obj", "alternate", NULL};
  683. conform = obj = alternate = adapter = NULL;
  684. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist,
  685. &obj, &alternate))
  686. return NULL;
  687. conform = PyObject_GetAttr(obj, str__conform__);
  688. if (conform == NULL)
  689. {
  690. if (!PyErr_ExceptionMatches(PyExc_AttributeError))
  691. {
  692. /* Propagate non-AttributeErrors */
  693. return NULL;
  694. }
  695. PyErr_Clear();
  696. Py_INCREF(Py_None);
  697. conform = Py_None;
  698. }
  699. if (conform != Py_None)
  700. {
  701. adapter = PyObject_CallMethodObjArgs(self, str_call_conform,
  702. conform, NULL);
  703. Py_DECREF(conform);
  704. if (adapter == NULL || adapter != Py_None)
  705. return adapter;
  706. Py_DECREF(adapter);
  707. }
  708. else
  709. {
  710. Py_DECREF(conform);
  711. }
  712. /* We differ from the Python code here. For speed, instead of always calling
  713. self.__adapt__(), we check to see if the type has defined it. Checking in
  714. the dict for __adapt__ isn't sufficient because there's no cheap way to
  715. tell if it's the __adapt__ that InterfaceBase itself defines (our type
  716. will *never* be InterfaceBase, we're always subclassed by
  717. InterfaceClass). Instead, we cooperate with InterfaceClass in Python to
  718. set a flag in a new subclass when this is necessary. */
  719. if (PyDict_GetItem(self->ob_type->tp_dict, str_CALL_CUSTOM_ADAPT))
  720. {
  721. /* Doesn't matter what the value is. Simply being present is enough. */
  722. adapter = PyObject_CallMethodObjArgs(self, str__adapt__, obj, NULL);
  723. }
  724. else
  725. {
  726. adapter = __adapt__(self, obj);
  727. }
  728. if (adapter == NULL || adapter != Py_None)
  729. {
  730. return adapter;
  731. }
  732. Py_DECREF(adapter);
  733. if (alternate != NULL)
  734. {
  735. Py_INCREF(alternate);
  736. return alternate;
  737. }
  738. adapter = Py_BuildValue("sOO", "Could not adapt", obj, self);
  739. if (adapter != NULL)
  740. {
  741. PyErr_SetObject(PyExc_TypeError, adapter);
  742. Py_DECREF(adapter);
  743. }
  744. return NULL;
  745. }
  746. static int
  747. IB_traverse(IB* self, visitproc visit, void* arg)
  748. {
  749. Py_VISIT(self->__name__);
  750. Py_VISIT(self->__module__);
  751. return Spec_traverse((Spec*)self, visit, arg);
  752. }
  753. static int
  754. IB_clear(IB* self)
  755. {
  756. Py_CLEAR(self->__name__);
  757. Py_CLEAR(self->__module__);
  758. return Spec_clear((Spec*)self);
  759. }
  760. static void
  761. IB_dealloc(IB* self)
  762. {
  763. PyObject_GC_UnTrack((PyObject *)self);
  764. IB_clear(self);
  765. Spec_dealloc((Spec*)self);
  766. }
  767. static PyMemberDef IB_members[] = {
  768. {"__name__", T_OBJECT_EX, offsetof(IB, __name__), 0, ""},
  769. // The redundancy between __module__ and __ibmodule__ is because
  770. // __module__ is often shadowed by subclasses.
  771. {"__module__", T_OBJECT_EX, offsetof(IB, __module__), READONLY, ""},
  772. {"__ibmodule__", T_OBJECT_EX, offsetof(IB, __module__), 0, ""},
  773. {NULL}
  774. };
  775. static Py_hash_t
  776. IB_hash(IB* self)
  777. {
  778. PyObject* tuple;
  779. if (!self->__module__) {
  780. PyErr_SetString(PyExc_AttributeError, "__module__");
  781. return -1;
  782. }
  783. if (!self->__name__) {
  784. PyErr_SetString(PyExc_AttributeError, "__name__");
  785. return -1;
  786. }
  787. if (self->_v_cached_hash) {
  788. return self->_v_cached_hash;
  789. }
  790. tuple = PyTuple_Pack(2, self->__name__, self->__module__);
  791. if (!tuple) {
  792. return -1;
  793. }
  794. self->_v_cached_hash = PyObject_Hash(tuple);
  795. Py_CLEAR(tuple);
  796. return self->_v_cached_hash;
  797. }
  798. static PyTypeObject InterfaceBaseType;
  799. static PyObject*
  800. IB_richcompare(IB* self, PyObject* other, int op)
  801. {
  802. PyObject* othername;
  803. PyObject* othermod;
  804. PyObject* oresult;
  805. IB* otherib;
  806. int result;
  807. otherib = NULL;
  808. oresult = othername = othermod = NULL;
  809. if (OBJECT(self) == other) {
  810. switch(op) {
  811. case Py_EQ:
  812. case Py_LE:
  813. case Py_GE:
  814. Py_RETURN_TRUE;
  815. break;
  816. case Py_NE:
  817. Py_RETURN_FALSE;
  818. }
  819. }
  820. if (other == Py_None) {
  821. switch(op) {
  822. case Py_LT:
  823. case Py_LE:
  824. case Py_NE:
  825. Py_RETURN_TRUE;
  826. default:
  827. Py_RETURN_FALSE;
  828. }
  829. }
  830. if (PyObject_TypeCheck(other, &InterfaceBaseType)) {
  831. // This branch borrows references. No need to clean
  832. // up if otherib is not null.
  833. otherib = (IB*)other;
  834. othername = otherib->__name__;
  835. othermod = otherib->__module__;
  836. }
  837. else {
  838. othername = PyObject_GetAttrString(other, "__name__");
  839. if (othername) {
  840. othermod = PyObject_GetAttrString(other, "__module__");
  841. }
  842. if (!othername || !othermod) {
  843. if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_AttributeError)) {
  844. PyErr_Clear();
  845. oresult = Py_NotImplemented;
  846. }
  847. goto cleanup;
  848. }
  849. }
  850. #if 0
  851. // This is the simple, straightforward version of what Python does.
  852. PyObject* pt1 = PyTuple_Pack(2, self->__name__, self->__module__);
  853. PyObject* pt2 = PyTuple_Pack(2, othername, othermod);
  854. oresult = PyObject_RichCompare(pt1, pt2, op);
  855. #endif
  856. // tuple comparison is decided by the first non-equal element.
  857. result = PyObject_RichCompareBool(self->__name__, othername, Py_EQ);
  858. if (result == 0) {
  859. result = PyObject_RichCompareBool(self->__name__, othername, op);
  860. }
  861. else if (result == 1) {
  862. result = PyObject_RichCompareBool(self->__module__, othermod, op);
  863. }
  864. // If either comparison failed, we have an error set.
  865. // Leave oresult NULL so we raise it.
  866. if (result == -1) {
  867. goto cleanup;
  868. }
  869. oresult = result ? Py_True : Py_False;
  870. cleanup:
  871. Py_XINCREF(oresult);
  872. if (!otherib) {
  873. Py_XDECREF(othername);
  874. Py_XDECREF(othermod);
  875. }
  876. return oresult;
  877. }
  878. static int
  879. IB_init(IB* self, PyObject* args, PyObject* kwargs)
  880. {
  881. static char *kwlist[] = {"__name__", "__module__", NULL};
  882. PyObject* module = NULL;
  883. PyObject* name = NULL;
  884. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO:InterfaceBase.__init__", kwlist,
  885. &name, &module)) {
  886. return -1;
  887. }
  888. IB_clear(self);
  889. self->__module__ = module ? module : Py_None;
  890. Py_INCREF(self->__module__);
  891. self->__name__ = name ? name : Py_None;
  892. Py_INCREF(self->__name__);
  893. return 0;
  894. }
  895. static PyTypeObject InterfaceBaseType = {
  896. PyVarObject_HEAD_INIT(NULL, 0)
  897. /* tp_name */ "_zope_interface_coptimizations."
  898. "InterfaceBase",
  899. /* tp_basicsize */ sizeof(IB),
  900. /* tp_itemsize */ 0,
  901. /* tp_dealloc */ (destructor)IB_dealloc,
  902. /* tp_print */ (printfunc)0,
  903. /* tp_getattr */ (getattrfunc)0,
  904. /* tp_setattr */ (setattrfunc)0,
  905. /* tp_compare */ 0,
  906. /* tp_repr */ (reprfunc)0,
  907. /* tp_as_number */ 0,
  908. /* tp_as_sequence */ 0,
  909. /* tp_as_mapping */ 0,
  910. /* tp_hash */ (hashfunc)IB_hash,
  911. /* tp_call */ (ternaryfunc)IB_call,
  912. /* tp_str */ (reprfunc)0,
  913. /* tp_getattro */ (getattrofunc)0,
  914. /* tp_setattro */ (setattrofunc)0,
  915. /* tp_as_buffer */ 0,
  916. /* tp_flags */ Py_TPFLAGS_DEFAULT
  917. | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
  918. /* tp_doc */ "Interface base type providing __call__ and __adapt__",
  919. /* tp_traverse */ (traverseproc)IB_traverse,
  920. /* tp_clear */ (inquiry)IB_clear,
  921. /* tp_richcompare */ (richcmpfunc)IB_richcompare,
  922. /* tp_weaklistoffset */ (long)0,
  923. /* tp_iter */ (getiterfunc)0,
  924. /* tp_iternext */ (iternextfunc)0,
  925. /* tp_methods */ ib_methods,
  926. /* tp_members */ IB_members,
  927. /* tp_getset */ 0,
  928. /* tp_base */ &SpecificationBaseType,
  929. /* tp_dict */ 0,
  930. /* tp_descr_get */ 0,
  931. /* tp_descr_set */ 0,
  932. /* tp_dictoffset */ 0,
  933. /* tp_init */ (initproc)IB_init,
  934. };
  935. /* =================== End: __call__ and __adapt__ ==================== */
  936. /* ==================================================================== */
  937. /* ==================================================================== */
  938. /* ========================== Begin: Lookup Bases ===================== */
  939. typedef struct {
  940. PyObject_HEAD
  941. PyObject *_cache;
  942. PyObject *_mcache;
  943. PyObject *_scache;
  944. } lookup;
  945. typedef struct {
  946. PyObject_HEAD
  947. PyObject *_cache;
  948. PyObject *_mcache;
  949. PyObject *_scache;
  950. PyObject *_verify_ro;
  951. PyObject *_verify_generations;
  952. } verify;
  953. static int
  954. lookup_traverse(lookup *self, visitproc visit, void *arg)
  955. {
  956. int vret;
  957. if (self->_cache) {
  958. vret = visit(self->_cache, arg);
  959. if (vret != 0)
  960. return vret;
  961. }
  962. if (self->_mcache) {
  963. vret = visit(self->_mcache, arg);
  964. if (vret != 0)
  965. return vret;
  966. }
  967. if (self->_scache) {
  968. vret = visit(self->_scache, arg);
  969. if (vret != 0)
  970. return vret;
  971. }
  972. return 0;
  973. }
  974. static int
  975. lookup_clear(lookup *self)
  976. {
  977. Py_CLEAR(self->_cache);
  978. Py_CLEAR(self->_mcache);
  979. Py_CLEAR(self->_scache);
  980. return 0;
  981. }
  982. static void
  983. lookup_dealloc(lookup *self)
  984. {
  985. PyObject_GC_UnTrack((PyObject *)self);
  986. lookup_clear(self);
  987. Py_TYPE(self)->tp_free((PyObject*)self);
  988. }
  989. /*
  990. def changed(self, ignored=None):
  991. self._cache.clear()
  992. self._mcache.clear()
  993. self._scache.clear()
  994. */
  995. static PyObject *
  996. lookup_changed(lookup *self, PyObject *ignored)
  997. {
  998. lookup_clear(self);
  999. Py_INCREF(Py_None);
  1000. return Py_None;
  1001. }
  1002. #define ASSURE_DICT(N) if (N == NULL) { N = PyDict_New(); \
  1003. if (N == NULL) return NULL; \
  1004. }
  1005. /*
  1006. def _getcache(self, provided, name):
  1007. cache = self._cache.get(provided)
  1008. if cache is None:
  1009. cache = {}
  1010. self._cache[provided] = cache
  1011. if name:
  1012. c = cache.get(name)
  1013. if c is None:
  1014. c = {}
  1015. cache[name] = c
  1016. cache = c
  1017. return cache
  1018. */
  1019. static PyObject *
  1020. _subcache(PyObject *cache, PyObject *key)
  1021. {
  1022. PyObject *subcache;
  1023. subcache = PyDict_GetItem(cache, key);
  1024. if (subcache == NULL)
  1025. {
  1026. int status;
  1027. subcache = PyDict_New();
  1028. if (subcache == NULL)
  1029. return NULL;
  1030. status = PyDict_SetItem(cache, key, subcache);
  1031. Py_DECREF(subcache);
  1032. if (status < 0)
  1033. return NULL;
  1034. }
  1035. return subcache;
  1036. }
  1037. static PyObject *
  1038. _getcache(lookup *self, PyObject *provided, PyObject *name)
  1039. {
  1040. PyObject *cache;
  1041. ASSURE_DICT(self->_cache);
  1042. cache = _subcache(self->_cache, provided);
  1043. if (cache == NULL)
  1044. return NULL;
  1045. if (name != NULL && PyObject_IsTrue(name))
  1046. cache = _subcache(cache, name);
  1047. return cache;
  1048. }
  1049. /*
  1050. def lookup(self, required, provided, name=u'', default=None):
  1051. cache = self._getcache(provided, name)
  1052. if len(required) == 1:
  1053. result = cache.get(required[0], _not_in_mapping)
  1054. else:
  1055. result = cache.get(tuple(required), _not_in_mapping)
  1056. if result is _not_in_mapping:
  1057. result = self._uncached_lookup(required, provided, name)
  1058. if len(required) == 1:
  1059. cache[required[0]] = result
  1060. else:
  1061. cache[tuple(required)] = result
  1062. if result is None:
  1063. return default
  1064. return result
  1065. */
  1066. static PyObject *
  1067. _lookup(lookup *self,
  1068. PyObject *required, PyObject *provided, PyObject *name,
  1069. PyObject *default_)
  1070. {
  1071. PyObject *result, *key, *cache;
  1072. result = key = cache = NULL;
  1073. if ( name && !PyUnicode_Check(name) )
  1074. {
  1075. PyErr_SetString(PyExc_ValueError,
  1076. "name is not a string or unicode");
  1077. return NULL;
  1078. }
  1079. /* If `required` is a lazy sequence, it could have arbitrary side-effects,
  1080. such as clearing our caches. So we must not retrieve the cache until
  1081. after resolving it. */
  1082. required = PySequence_Tuple(required);
  1083. if (required == NULL)
  1084. return NULL;
  1085. cache = _getcache(self, provided, name);
  1086. if (cache == NULL)
  1087. return NULL;
  1088. if (PyTuple_GET_SIZE(required) == 1)
  1089. key = PyTuple_GET_ITEM(required, 0);
  1090. else
  1091. key = required;
  1092. result = PyDict_GetItem(cache, key);
  1093. if (result == NULL)
  1094. {
  1095. int status;
  1096. result = PyObject_CallMethodObjArgs(OBJECT(self), str_uncached_lookup,
  1097. required, provided, name, NULL);
  1098. if (result == NULL)
  1099. {
  1100. Py_DECREF(required);
  1101. return NULL;
  1102. }
  1103. status = PyDict_SetItem(cache, key, result);
  1104. Py_DECREF(required);
  1105. if (status < 0)
  1106. {
  1107. Py_DECREF(result);
  1108. return NULL;
  1109. }
  1110. }
  1111. else
  1112. {
  1113. Py_INCREF(result);
  1114. Py_DECREF(required);
  1115. }
  1116. if (result == Py_None && default_ != NULL)
  1117. {
  1118. Py_DECREF(Py_None);
  1119. Py_INCREF(default_);
  1120. return default_;
  1121. }
  1122. return result;
  1123. }
  1124. static PyObject *
  1125. lookup_lookup(lookup *self, PyObject *args, PyObject *kwds)
  1126. {
  1127. static char *kwlist[] = {"required", "provided", "name", "default", NULL};
  1128. PyObject *required, *provided, *name=NULL, *default_=NULL;
  1129. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:LookupBase.lookup", kwlist,
  1130. &required, &provided, &name, &default_))
  1131. return NULL;
  1132. return _lookup(self, required, provided, name, default_);
  1133. }
  1134. /*
  1135. def lookup1(self, required, provided, name=u'', default=None):
  1136. cache = self._getcache(provided, name)
  1137. result = cache.get(required, _not_in_mapping)
  1138. if result is _not_in_mapping:
  1139. return self.lookup((required, ), provided, name, default)
  1140. if result is None:
  1141. return default
  1142. return result
  1143. */
  1144. static PyObject *
  1145. _lookup1(lookup *self,
  1146. PyObject *required, PyObject *provided, PyObject *name,
  1147. PyObject *default_)
  1148. {
  1149. PyObject *result, *cache;
  1150. if ( name && !PyUnicode_Check(name) )
  1151. {
  1152. PyErr_SetString(PyExc_ValueError,
  1153. "name is not a string or unicode");
  1154. return NULL;
  1155. }
  1156. cache = _getcache(self, provided, name);
  1157. if (cache == NULL)
  1158. return NULL;
  1159. result = PyDict_GetItem(cache, required);
  1160. if (result == NULL)
  1161. {
  1162. PyObject *tup;
  1163. tup = PyTuple_New(1);
  1164. if (tup == NULL)
  1165. return NULL;
  1166. Py_INCREF(required);
  1167. PyTuple_SET_ITEM(tup, 0, required);
  1168. result = _lookup(self, tup, provided, name, default_);
  1169. Py_DECREF(tup);
  1170. }
  1171. else
  1172. {
  1173. if (result == Py_None && default_ != NULL)
  1174. {
  1175. result = default_;
  1176. }
  1177. Py_INCREF(result);
  1178. }
  1179. return result;
  1180. }
  1181. static PyObject *
  1182. lookup_lookup1(lookup *self, PyObject *args, PyObject *kwds)
  1183. {
  1184. static char *kwlist[] = {"required", "provided", "name", "default", NULL};
  1185. PyObject *required, *provided, *name=NULL, *default_=NULL;
  1186. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:LookupBase.lookup1", kwlist,
  1187. &required, &provided, &name, &default_))
  1188. return NULL;
  1189. return _lookup1(self, required, provided, name, default_);
  1190. }
  1191. /*
  1192. def adapter_hook(self, provided, object, name=u'', default=None):
  1193. required = providedBy(object)
  1194. cache = self._getcache(provided, name)
  1195. factory = cache.get(required, _not_in_mapping)
  1196. if factory is _not_in_mapping:
  1197. factory = self.lookup((required, ), provided, name)
  1198. if factory is not None:
  1199. if isinstance(object, super):
  1200. object = object.__self__
  1201. result = factory(object)
  1202. if result is not None:
  1203. return result
  1204. return default
  1205. */
  1206. static PyObject *
  1207. _adapter_hook(lookup *self,
  1208. PyObject *provided, PyObject *object, PyObject *name,
  1209. PyObject *default_)
  1210. {
  1211. PyObject *required, *factory, *result;
  1212. if ( name && !PyUnicode_Check(name) )
  1213. {
  1214. PyErr_SetString(PyExc_ValueError,
  1215. "name is not a string or unicode");
  1216. return NULL;
  1217. }
  1218. required = providedBy(NULL, object);
  1219. if (required == NULL)
  1220. return NULL;
  1221. factory = _lookup1(self, required, provided, name, Py_None);
  1222. Py_DECREF(required);
  1223. if (factory == NULL)
  1224. return NULL;
  1225. if (factory != Py_None)
  1226. {
  1227. if (PyObject_TypeCheck(object, &PySuper_Type)) {
  1228. PyObject* self = PyObject_GetAttr(object, str__self__);
  1229. if (self == NULL)
  1230. {
  1231. Py_DECREF(factory);
  1232. return NULL;
  1233. }
  1234. // Borrow the reference to self
  1235. Py_DECREF(self);
  1236. object = self;
  1237. }
  1238. result = PyObject_CallFunctionObjArgs(factory, object, NULL);
  1239. Py_DECREF(factory);
  1240. if (result == NULL || result != Py_None)
  1241. return result;
  1242. }
  1243. else
  1244. result = factory; /* None */
  1245. if (default_ == NULL || default_ == result) /* No default specified, */
  1246. return result; /* Return None. result is owned None */
  1247. Py_DECREF(result);
  1248. Py_INCREF(default_);
  1249. return default_;
  1250. }
  1251. static PyObject *
  1252. lookup_adapter_hook(lookup *self, PyObject *args, PyObject *kwds)
  1253. {
  1254. static char *kwlist[] = {"provided", "object", "name", "default", NULL};
  1255. PyObject *object, *provided, *name=NULL, *default_=NULL;
  1256. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:LookupBase.adapter_hook", kwlist,
  1257. &provided, &object, &name, &default_))
  1258. return NULL;
  1259. return _adapter_hook(self, provided, object, name, default_);
  1260. }
  1261. static PyObject *
  1262. lookup_queryAdapter(lookup *self, PyObject *args, PyObject *kwds)
  1263. {
  1264. static char *kwlist[] = {"object", "provided", "name", "default", NULL};
  1265. PyObject *object, *provided, *name=NULL, *default_=NULL;
  1266. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:LookupBase.queryAdapter", kwlist,
  1267. &object, &provided, &name, &default_))
  1268. return NULL;
  1269. return _adapter_hook(self, provided, object, name, default_);
  1270. }
  1271. /*
  1272. def lookupAll(self, required, provided):
  1273. cache = self._mcache.get(provided)
  1274. if cache is None:
  1275. cache = {}
  1276. self._mcache[provided] = cache
  1277. required = tuple(required)
  1278. result = cache.get(required, _not_in_mapping)
  1279. if result is _not_in_mapping:
  1280. result = self._uncached_lookupAll(required, provided)
  1281. cache[required] = result
  1282. return result
  1283. */
  1284. static PyObject *
  1285. _lookupAll(lookup *self, PyObject *required, PyObject *provided)
  1286. {
  1287. PyObject *cache, *result;
  1288. /* resolve before getting cache. See note in _lookup. */
  1289. required = PySequence_Tuple(required);
  1290. if (required == NULL)
  1291. return NULL;
  1292. ASSURE_DICT(self->_mcache);
  1293. cache = _subcache(self->_mcache, provided);
  1294. if (cache == NULL)
  1295. return NULL;
  1296. result = PyDict_GetItem(cache, required);
  1297. if (result == NULL)
  1298. {
  1299. int status;
  1300. result = PyObject_CallMethodObjArgs(OBJECT(self), str_uncached_lookupAll,
  1301. required, provided, NULL);
  1302. if (result == NULL)
  1303. {
  1304. Py_DECREF(required);
  1305. return NULL;
  1306. }
  1307. status = PyDict_SetItem(cache, required, result);
  1308. Py_DECREF(required);
  1309. if (status < 0)
  1310. {
  1311. Py_DECREF(result);
  1312. return NULL;
  1313. }
  1314. }
  1315. else
  1316. {
  1317. Py_INCREF(result);
  1318. Py_DECREF(required);
  1319. }
  1320. return result;
  1321. }
  1322. static PyObject *
  1323. lookup_lookupAll(lookup *self, PyObject *args, PyObject *kwds)
  1324. {
  1325. static char *kwlist[] = {"required", "provided", NULL};
  1326. PyObject *required, *provided;
  1327. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO:LookupBase.lookupAll", kwlist,
  1328. &required, &provided))
  1329. return NULL;
  1330. return _lookupAll(self, required, provided);
  1331. }
  1332. /*
  1333. def subscriptions(self, required, provided):
  1334. cache = self._scache.get(provided)
  1335. if cache is None:
  1336. cache = {}
  1337. self._scache[provided] = cache
  1338. required = tuple(required)
  1339. result = cache.get(required, _not_in_mapping)
  1340. if result is _not_in_mapping:
  1341. result = self._uncached_subscriptions(required, provided)
  1342. cache[required] = result
  1343. return result
  1344. */
  1345. static PyObject *
  1346. _subscriptions(lookup *self, PyObject *required, PyObject *provided)
  1347. {
  1348. PyObject *cache, *result;
  1349. /* resolve before getting cache. See note in _lookup. */
  1350. required = PySequence_Tuple(required);
  1351. if (required == NULL)
  1352. return NULL;
  1353. ASSURE_DICT(self->_scache);
  1354. cache = _subcache(self->_scache, provided);
  1355. if (cache == NULL)
  1356. return NULL;
  1357. result = PyDict_GetItem(cache, required);
  1358. if (result == NULL)
  1359. {
  1360. int status;
  1361. result = PyObject_CallMethodObjArgs(
  1362. OBJECT(self), str_uncached_subscriptions,
  1363. required, provided, NULL);
  1364. if (result == NULL)
  1365. {
  1366. Py_DECREF(required);
  1367. return NULL;
  1368. }
  1369. status = PyDict_SetItem(cache, required, result);
  1370. Py_DECREF(required);
  1371. if (status < 0)
  1372. {
  1373. Py_DECREF(result);
  1374. return NULL;
  1375. }
  1376. }
  1377. else
  1378. {
  1379. Py_INCREF(result);
  1380. Py_DECREF(required);
  1381. }
  1382. return result;
  1383. }
  1384. static PyObject *
  1385. lookup_subscriptions(lookup *self, PyObject *args, PyObject *kwds)
  1386. {
  1387. static char *kwlist[] = {"required", "provided", NULL};
  1388. PyObject *required, *provided;
  1389. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist,
  1390. &required, &provided))
  1391. return NULL;
  1392. return _subscriptions(self, required, provided);
  1393. }
  1394. static struct PyMethodDef lookup_methods[] = {
  1395. {"changed", (PyCFunction)lookup_changed, METH_O, ""},
  1396. {"lookup", (PyCFunction)lookup_lookup, METH_KEYWORDS | METH_VARARGS, ""},
  1397. {"lookup1", (PyCFunction)lookup_lookup1, METH_KEYWORDS | METH_VARARGS, ""},
  1398. {"queryAdapter", (PyCFunction)lookup_queryAdapter, METH_KEYWORDS | METH_VARARGS, ""},
  1399. {"adapter_hook", (PyCFunction)lookup_adapter_hook, METH_KEYWORDS | METH_VARARGS, ""},
  1400. {"lookupAll", (PyCFunction)lookup_lookupAll, METH_KEYWORDS | METH_VARARGS, ""},
  1401. {"subscriptions", (PyCFunction)lookup_subscriptions, METH_KEYWORDS | METH_VARARGS, ""},
  1402. {NULL, NULL} /* sentinel */
  1403. };
  1404. static PyTypeObject LookupBase = {
  1405. PyVarObject_HEAD_INIT(NULL, 0)
  1406. /* tp_name */ "_zope_interface_coptimizations."
  1407. "LookupBase",
  1408. /* tp_basicsize */ sizeof(lookup),
  1409. /* tp_itemsize */ 0,
  1410. /* tp_dealloc */ (destructor)&lookup_dealloc,
  1411. /* tp_print */ (printfunc)0,
  1412. /* tp_getattr */ (getattrfunc)0,
  1413. /* tp_setattr */ (setattrfunc)0,
  1414. /* tp_compare */ 0,
  1415. /* tp_repr */ (reprfunc)0,
  1416. /* tp_as_number */ 0,
  1417. /* tp_as_sequence */ 0,
  1418. /* tp_as_mapping */ 0,
  1419. /* tp_hash */ (hashfunc)0,
  1420. /* tp_call */ (ternaryfunc)0,
  1421. /* tp_str */ (reprfunc)0,
  1422. /* tp_getattro */ (getattrofunc)0,
  1423. /* tp_setattro */ (setattrofunc)0,
  1424. /* tp_as_buffer */ 0,
  1425. /* tp_flags */ Py_TPFLAGS_DEFAULT
  1426. | Py_TPFLAGS_BASETYPE
  1427. | Py_TPFLAGS_HAVE_GC,
  1428. /* tp_doc */ "",
  1429. /* tp_traverse */ (traverseproc)lookup_traverse,
  1430. /* tp_clear */ (inquiry)lookup_clear,
  1431. /* tp_richcompare */ (richcmpfunc)0,
  1432. /* tp_weaklistoffset */ (long)0,
  1433. /* tp_iter */ (getiterfunc)0,
  1434. /* tp_iternext */ (iternextfunc)0,
  1435. /* tp_methods */ lookup_methods,
  1436. };
  1437. static int
  1438. verifying_traverse(verify *self, visitproc visit, void *arg)
  1439. {
  1440. int vret;
  1441. vret = lookup_traverse((lookup *)self, visit, arg);
  1442. if (vret != 0)
  1443. return vret;
  1444. if (self->_verify_ro) {
  1445. vret = visit(self->_verify_ro, arg);
  1446. if (vret != 0)
  1447. return vret;
  1448. }
  1449. if (self->_verify_generations) {
  1450. vret = visit(self->_verify_generations, arg);
  1451. if (vret != 0)
  1452. return vret;
  1453. }
  1454. return 0;
  1455. }
  1456. static int
  1457. verifying_clear(verify *self)
  1458. {
  1459. lookup_clear((lookup *)self);
  1460. Py_CLEAR(self->_verify_generations);
  1461. Py_CLEAR(self->_verify_ro);
  1462. return 0;
  1463. }
  1464. static void
  1465. verifying_dealloc(verify *self)
  1466. {
  1467. PyObject_GC_UnTrack((PyObject *)self);
  1468. verifying_clear(self);
  1469. Py_TYPE(self)->tp_free((PyObject*)self);
  1470. }
  1471. /*
  1472. def changed(self, originally_changed):
  1473. super(VerifyingBasePy, self).changed(originally_changed)
  1474. self._verify_ro = self._registry.ro[1:]
  1475. self._verify_generations = [r._generation for r in self._verify_ro]
  1476. */
  1477. static PyObject *
  1478. _generations_tuple(PyObject *ro)
  1479. {
  1480. int i, l;
  1481. PyObject *generations;
  1482. l = PyTuple_GET_SIZE(ro);
  1483. generations = PyTuple_New(l);
  1484. for (i=0; i < l; i++)
  1485. {
  1486. PyObject *generation;
  1487. generation = PyObject_GetAttr(PyTuple_GET_ITEM(ro, i), str_generation);
  1488. if (generation == NULL)
  1489. {
  1490. Py_DECREF(generations);
  1491. return NULL;
  1492. }
  1493. PyTuple_SET_ITEM(generations, i, generation);
  1494. }
  1495. return generations;
  1496. }
  1497. static PyObject *
  1498. verifying_changed(verify *self, PyObject *ignored)
  1499. {
  1500. PyObject *t, *ro;
  1501. verifying_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. {
  1520. Py_DECREF(ro);
  1521. return NULL;
  1522. }
  1523. self->_verify_ro = ro;
  1524. Py_INCREF(Py_None);
  1525. return Py_None;
  1526. }
  1527. /*
  1528. def _verify(self):
  1529. if ([r._generation for r in self._verify_ro]
  1530. != self._verify_generations):
  1531. self.changed(None)
  1532. */
  1533. static int
  1534. _verify(verify *self)
  1535. {
  1536. PyObject *changed_result;
  1537. if (self->_verify_ro != NULL && self->_verify_generations != NULL)
  1538. {
  1539. PyObject *generations;
  1540. int changed;
  1541. generations = _generations_tuple(self->_verify_ro);
  1542. if (generations == NULL)
  1543. return -1;
  1544. changed = PyObject_RichCompareBool(self->_verify_generations,
  1545. generations, Py_NE);
  1546. Py_DECREF(generations);
  1547. if (changed == -1)
  1548. return -1;
  1549. if (changed == 0)
  1550. return 0;
  1551. }
  1552. changed_result = PyObject_CallMethodObjArgs(OBJECT(self), strchanged,
  1553. Py_None, NULL);
  1554. if (changed_result == NULL)
  1555. return -1;
  1556. Py_DECREF(changed_result);
  1557. return 0;
  1558. }
  1559. static PyObject *
  1560. verifying_lookup(verify *self, PyObject *args, PyObject *kwds)
  1561. {
  1562. static char *kwlist[] = {"required", "provided", "name", "default", NULL};
  1563. PyObject *required, *provided, *name=NULL, *default_=NULL;
  1564. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
  1565. &required, &provided, &name, &default_))
  1566. return NULL;
  1567. if (_verify(self) < 0)
  1568. return NULL;
  1569. return _lookup((lookup *)self, required, provided, name, default_);
  1570. }
  1571. static PyObject *
  1572. verifying_lookup1(verify *self, PyObject *args, PyObject *kwds)
  1573. {
  1574. static char *kwlist[] = {"required", "provided", "name", "default", NULL};
  1575. PyObject *required, *provided, *name=NULL, *default_=NULL;
  1576. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
  1577. &required, &provided, &name, &default_))
  1578. return NULL;
  1579. if (_verify(self) < 0)
  1580. return NULL;
  1581. return _lookup1((lookup *)self, required, provided, name, default_);
  1582. }
  1583. static PyObject *
  1584. verifying_adapter_hook(verify *self, PyObject *args, PyObject *kwds)
  1585. {
  1586. static char *kwlist[] = {"provided", "object", "name", "default", NULL};
  1587. PyObject *object, *provided, *name=NULL, *default_=NULL;
  1588. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
  1589. &provided, &object, &name, &default_))
  1590. return NULL;
  1591. if (_verify(self) < 0)
  1592. return NULL;
  1593. return _adapter_hook((lookup *)self, provided, object, name, default_);
  1594. }
  1595. static PyObject *
  1596. verifying_queryAdapter(verify *self, PyObject *args, PyObject *kwds)
  1597. {
  1598. static char *kwlist[] = {"object", "provided", "name", "default", NULL};
  1599. PyObject *object, *provided, *name=NULL, *default_=NULL;
  1600. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist,
  1601. &object, &provided, &name, &default_))
  1602. return NULL;
  1603. if (_verify(self) < 0)
  1604. return NULL;
  1605. return _adapter_hook((lookup *)self, provided, object, name, default_);
  1606. }
  1607. static PyObject *
  1608. verifying_lookupAll(verify *self, PyObject *args, PyObject *kwds)
  1609. {
  1610. static char *kwlist[] = {"required", "provided", NULL};
  1611. PyObject *required, *provided;
  1612. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist,
  1613. &required, &provided))
  1614. return NULL;
  1615. if (_verify(self) < 0)
  1616. return NULL;
  1617. return _lookupAll((lookup *)self, required, provided);
  1618. }
  1619. static PyObject *
  1620. verifying_subscriptions(verify *self, PyObject *args, PyObject *kwds)
  1621. {
  1622. static char *kwlist[] = {"required", "provided", NULL};
  1623. PyObject *required, *provided;
  1624. if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist,
  1625. &required, &provided))
  1626. return NULL;
  1627. if (_verify(self) < 0)
  1628. return NULL;
  1629. return _subscriptions((lookup *)self, required, provided);
  1630. }
  1631. static struct PyMethodDef verifying_methods[] = {
  1632. {"changed", (PyCFunction)verifying_changed, METH_O, ""},
  1633. {"lookup", (PyCFunction)verifying_lookup, METH_KEYWORDS | METH_VARARGS, ""},
  1634. {"lookup1", (PyCFunction)verifying_lookup1, METH_KEYWORDS | METH_VARARGS, ""},
  1635. {"queryAdapter", (PyCFunction)verifying_queryAdapter, METH_KEYWORDS | METH_VARARGS, ""},
  1636. {"adapter_hook", (PyCFunction)verifying_adapter_hook, METH_KEYWORDS | METH_VARARGS, ""},
  1637. {"lookupAll", (PyCFunction)verifying_lookupAll, METH_KEYWORDS | METH_VARARGS, ""},
  1638. {"subscriptions", (PyCFunction)verifying_subscriptions, METH_KEYWORDS | METH_VARARGS, ""},
  1639. {NULL, NULL} /* sentinel */
  1640. };
  1641. static PyTypeObject VerifyingBase = {
  1642. PyVarObject_HEAD_INIT(NULL, 0)
  1643. /* tp_name */ "_zope_interface_coptimizations."
  1644. "VerifyingBase",
  1645. /* tp_basicsize */ sizeof(verify),
  1646. /* tp_itemsize */ 0,
  1647. /* tp_dealloc */ (destructor)&verifying_dealloc,
  1648. /* tp_print */ (printfunc)0,
  1649. /* tp_getattr */ (getattrfunc)0,
  1650. /* tp_setattr */ (setattrfunc)0,
  1651. /* tp_compare */ 0,
  1652. /* tp_repr */ (reprfunc)0,
  1653. /* tp_as_number */ 0,
  1654. /* tp_as_sequence */ 0,
  1655. /* tp_as_mapping */ 0,
  1656. /* tp_hash */ (hashfunc)0,
  1657. /* tp_call */ (ternaryfunc)0,
  1658. /* tp_str */ (reprfunc)0,
  1659. /* tp_getattro */ (getattrofunc)0,
  1660. /* tp_setattro */ (setattrofunc)0,
  1661. /* tp_as_buffer */ 0,
  1662. /* tp_flags */ Py_TPFLAGS_DEFAULT
  1663. | Py_TPFLAGS_BASETYPE
  1664. | Py_TPFLAGS_HAVE_GC,
  1665. /* tp_doc */ "",
  1666. /* tp_traverse */ (traverseproc)verifying_traverse,
  1667. /* tp_clear */ (inquiry)verifying_clear,
  1668. /* tp_richcompare */ (richcmpfunc)0,
  1669. /* tp_weaklistoffset */ (long)0,
  1670. /* tp_iter */ (getiterfunc)0,
  1671. /* tp_iternext */ (iternextfunc)0,
  1672. /* tp_methods */ verifying_methods,
  1673. /* tp_members */ 0,
  1674. /* tp_getset */ 0,
  1675. /* tp_base */ &LookupBase,
  1676. };
  1677. /* ========================== End: Lookup Bases ======================= */
  1678. /* ==================================================================== */
  1679. static struct PyMethodDef m_methods[] = {
  1680. {"implementedBy", (PyCFunction)implementedBy, METH_O,
  1681. "Interfaces implemented by a class or factory.\n"
  1682. "Raises TypeError if argument is neither a class nor a callable."},
  1683. {"getObjectSpecification", (PyCFunction)getObjectSpecification, METH_O,
  1684. "Get an object's interfaces (internal api)"},
  1685. {"providedBy", (PyCFunction)providedBy, METH_O,
  1686. "Get an object's interfaces"},
  1687. {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
  1688. };
  1689. static char module_doc[] = "C optimizations for zope.interface\n\n";
  1690. static struct PyModuleDef _zic_module = {
  1691. PyModuleDef_HEAD_INIT,
  1692. "_zope_interface_coptimizations",
  1693. module_doc,
  1694. -1,
  1695. m_methods,
  1696. NULL,
  1697. NULL,
  1698. NULL,
  1699. NULL
  1700. };
  1701. static PyObject *
  1702. init(void)
  1703. {
  1704. PyObject *m;
  1705. #define DEFINE_STRING(S) \
  1706. if(! (str ## S = PyUnicode_FromString(# S))) return NULL
  1707. DEFINE_STRING(__dict__);
  1708. DEFINE_STRING(__implemented__);
  1709. DEFINE_STRING(__provides__);
  1710. DEFINE_STRING(__class__);
  1711. DEFINE_STRING(__providedBy__);
  1712. DEFINE_STRING(extends);
  1713. DEFINE_STRING(__conform__);
  1714. DEFINE_STRING(_call_conform);
  1715. DEFINE_STRING(_uncached_lookup);
  1716. DEFINE_STRING(_uncached_lookupAll);
  1717. DEFINE_STRING(_uncached_subscriptions);
  1718. DEFINE_STRING(_registry);
  1719. DEFINE_STRING(_generation);
  1720. DEFINE_STRING(ro);
  1721. DEFINE_STRING(changed);
  1722. DEFINE_STRING(__self__);
  1723. DEFINE_STRING(__name__);
  1724. DEFINE_STRING(__module__);
  1725. DEFINE_STRING(__adapt__);
  1726. DEFINE_STRING(_CALL_CUSTOM_ADAPT);
  1727. #undef DEFINE_STRING
  1728. adapter_hooks = PyList_New(0);
  1729. if (adapter_hooks == NULL)
  1730. return NULL;
  1731. /* Initialize types: */
  1732. SpecificationBaseType.tp_new = PyBaseObject_Type.tp_new;
  1733. if (PyType_Ready(&SpecificationBaseType) < 0)
  1734. return NULL;
  1735. OSDType.tp_new = PyBaseObject_Type.tp_new;
  1736. if (PyType_Ready(&OSDType) < 0)
  1737. return NULL;
  1738. CPBType.tp_new = PyBaseObject_Type.tp_new;
  1739. if (PyType_Ready(&CPBType) < 0)
  1740. return NULL;
  1741. InterfaceBaseType.tp_new = PyBaseObject_Type.tp_new;
  1742. if (PyType_Ready(&InterfaceBaseType) < 0)
  1743. return NULL;
  1744. LookupBase.tp_new = PyBaseObject_Type.tp_new;
  1745. if (PyType_Ready(&LookupBase) < 0)
  1746. return NULL;
  1747. VerifyingBase.tp_new = PyBaseObject_Type.tp_new;
  1748. if (PyType_Ready(&VerifyingBase) < 0)
  1749. return NULL;
  1750. m = PyModule_Create(&_zic_module);
  1751. if (m == NULL)
  1752. return NULL;
  1753. /* Add types: */
  1754. if (PyModule_AddObject(m, "SpecificationBase", OBJECT(&SpecificationBaseType)) < 0)
  1755. return NULL;
  1756. if (PyModule_AddObject(m, "ObjectSpecificationDescriptor",
  1757. (PyObject *)&OSDType) < 0)
  1758. return NULL;
  1759. if (PyModule_AddObject(m, "ClassProvidesBase", OBJECT(&CPBType)) < 0)
  1760. return NULL;
  1761. if (PyModule_AddObject(m, "InterfaceBase", OBJECT(&InterfaceBaseType)) < 0)
  1762. return NULL;
  1763. if (PyModule_AddObject(m, "LookupBase", OBJECT(&LookupBase)) < 0)
  1764. return NULL;
  1765. if (PyModule_AddObject(m, "VerifyingBase", OBJECT(&VerifyingBase)) < 0)
  1766. return NULL;
  1767. if (PyModule_AddObject(m, "adapter_hooks", adapter_hooks) < 0)
  1768. return NULL;
  1769. return m;
  1770. }
  1771. PyMODINIT_FUNC
  1772. PyInit__zope_interface_coptimizations(void)
  1773. {
  1774. return init();
  1775. }
  1776. #ifdef __clang__
  1777. #pragma clang diagnostic pop
  1778. #endif