_zope_interface_coptimizations.c 57 KB

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