_zope_interface_coptimizations.c
1727 lines
| 44.9 KiB
| text/x-c
|
CLexer
Gregory Szorc
|
r37193 | /*########################################################################### | ||
# | ||||
# Copyright (c) 2003 Zope Foundation and Contributors. | ||||
# All Rights Reserved. | ||||
# | ||||
# This software is subject to the provisions of the Zope Public License, | ||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | ||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | ||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | ||||
# FOR A PARTICULAR PURPOSE. | ||||
# | ||||
############################################################################*/ | ||||
#include "Python.h" | ||||
#include "structmember.h" | ||||
#define TYPE(O) ((PyTypeObject*)(O)) | ||||
#define OBJECT(O) ((PyObject*)(O)) | ||||
#define CLASSIC(O) ((PyClassObject*)(O)) | ||||
#ifndef PyVarObject_HEAD_INIT | ||||
#define PyVarObject_HEAD_INIT(a, b) PyObject_HEAD_INIT(a) b, | ||||
#endif | ||||
#ifndef Py_TYPE | ||||
#define Py_TYPE(o) ((o)->ob_type) | ||||
#endif | ||||
#if PY_MAJOR_VERSION >= 3 | ||||
#define PY3K | ||||
#endif | ||||
static PyObject *str__dict__, *str__implemented__, *strextends; | ||||
static PyObject *BuiltinImplementationSpecifications, *str__provides__; | ||||
static PyObject *str__class__, *str__providedBy__; | ||||
static PyObject *empty, *fallback, *str_implied, *str_cls, *str_implements; | ||||
static PyObject *str__conform__, *str_call_conform, *adapter_hooks; | ||||
static PyObject *str_uncached_lookup, *str_uncached_lookupAll; | ||||
static PyObject *str_uncached_subscriptions; | ||||
static PyObject *str_registry, *strro, *str_generation, *strchanged; | ||||
static PyTypeObject *Implements; | ||||
static int imported_declarations = 0; | ||||
static int | ||||
import_declarations(void) | ||||
{ | ||||
PyObject *declarations, *i; | ||||
Gregory Szorc
|
r37195 | declarations = PyImport_ImportModule( | ||
"mercurial.thirdparty.zope.interface.declarations"); | ||||
Gregory Szorc
|
r37193 | if (declarations == NULL) | ||
return -1; | ||||
BuiltinImplementationSpecifications = PyObject_GetAttrString( | ||||
declarations, "BuiltinImplementationSpecifications"); | ||||
if (BuiltinImplementationSpecifications == NULL) | ||||
return -1; | ||||
empty = PyObject_GetAttrString(declarations, "_empty"); | ||||
if (empty == NULL) | ||||
return -1; | ||||
fallback = PyObject_GetAttrString(declarations, "implementedByFallback"); | ||||
if (fallback == NULL) | ||||
return -1; | ||||
i = PyObject_GetAttrString(declarations, "Implements"); | ||||
if (i == NULL) | ||||
return -1; | ||||
if (! PyType_Check(i)) | ||||
{ | ||||
PyErr_SetString(PyExc_TypeError, | ||||
"zope.interface.declarations.Implements is not a type"); | ||||
return -1; | ||||
} | ||||
Implements = (PyTypeObject *)i; | ||||
Py_DECREF(declarations); | ||||
imported_declarations = 1; | ||||
return 0; | ||||
} | ||||
static PyTypeObject SpecType; /* Forward */ | ||||
static PyObject * | ||||
implementedByFallback(PyObject *cls) | ||||
{ | ||||
if (imported_declarations == 0 && import_declarations() < 0) | ||||
return NULL; | ||||
return PyObject_CallFunctionObjArgs(fallback, cls, NULL); | ||||
} | ||||
static PyObject * | ||||
implementedBy(PyObject *ignored, PyObject *cls) | ||||
{ | ||||
/* Fast retrieval of implements spec, if possible, to optimize | ||||
common case. Use fallback code if we get stuck. | ||||
*/ | ||||
PyObject *dict = NULL, *spec; | ||||
if (PyType_Check(cls)) | ||||
{ | ||||
dict = TYPE(cls)->tp_dict; | ||||
Py_XINCREF(dict); | ||||
} | ||||
if (dict == NULL) | ||||
dict = PyObject_GetAttr(cls, str__dict__); | ||||
if (dict == NULL) | ||||
{ | ||||
/* Probably a security proxied class, use more expensive fallback code */ | ||||
PyErr_Clear(); | ||||
return implementedByFallback(cls); | ||||
} | ||||
spec = PyObject_GetItem(dict, str__implemented__); | ||||
Py_DECREF(dict); | ||||
if (spec) | ||||
{ | ||||
if (imported_declarations == 0 && import_declarations() < 0) | ||||
return NULL; | ||||
if (PyObject_TypeCheck(spec, Implements)) | ||||
return spec; | ||||
/* Old-style declaration, use more expensive fallback code */ | ||||
Py_DECREF(spec); | ||||
return implementedByFallback(cls); | ||||
} | ||||
PyErr_Clear(); | ||||
/* Maybe we have a builtin */ | ||||
if (imported_declarations == 0 && import_declarations() < 0) | ||||
return NULL; | ||||
spec = PyDict_GetItem(BuiltinImplementationSpecifications, cls); | ||||
if (spec != NULL) | ||||
{ | ||||
Py_INCREF(spec); | ||||
return spec; | ||||
} | ||||
/* We're stuck, use fallback */ | ||||
return implementedByFallback(cls); | ||||
} | ||||
static PyObject * | ||||
getObjectSpecification(PyObject *ignored, PyObject *ob) | ||||
{ | ||||
PyObject *cls, *result; | ||||
result = PyObject_GetAttr(ob, str__provides__); | ||||
if (result != NULL && PyObject_TypeCheck(result, &SpecType)) | ||||
return result; | ||||
PyErr_Clear(); | ||||
/* We do a getattr here so as not to be defeated by proxies */ | ||||
cls = PyObject_GetAttr(ob, str__class__); | ||||
if (cls == NULL) | ||||
{ | ||||
PyErr_Clear(); | ||||
if (imported_declarations == 0 && import_declarations() < 0) | ||||
return NULL; | ||||
Py_INCREF(empty); | ||||
return empty; | ||||
} | ||||
result = implementedBy(NULL, cls); | ||||
Py_DECREF(cls); | ||||
return result; | ||||
} | ||||
static PyObject * | ||||
providedBy(PyObject *ignored, PyObject *ob) | ||||
{ | ||||
PyObject *result, *cls, *cp; | ||||
result = PyObject_GetAttr(ob, str__providedBy__); | ||||
if (result == NULL) | ||||
{ | ||||
PyErr_Clear(); | ||||
return getObjectSpecification(NULL, ob); | ||||
} | ||||
/* We want to make sure we have a spec. We can't do a type check | ||||
because we may have a proxy, so we'll just try to get the | ||||
only attribute. | ||||
*/ | ||||
if (PyObject_TypeCheck(result, &SpecType) | ||||
|| | ||||
PyObject_HasAttr(result, strextends) | ||||
) | ||||
return result; | ||||
/* | ||||
The object's class doesn't understand descriptors. | ||||
Sigh. We need to get an object descriptor, but we have to be | ||||
careful. We want to use the instance's __provides__,l if | ||||
there is one, but only if it didn't come from the class. | ||||
*/ | ||||
Py_DECREF(result); | ||||
cls = PyObject_GetAttr(ob, str__class__); | ||||
if (cls == NULL) | ||||
return NULL; | ||||
result = PyObject_GetAttr(ob, str__provides__); | ||||
if (result == NULL) | ||||
{ | ||||
/* No __provides__, so just fall back to implementedBy */ | ||||
PyErr_Clear(); | ||||
result = implementedBy(NULL, cls); | ||||
Py_DECREF(cls); | ||||
return result; | ||||
} | ||||
cp = PyObject_GetAttr(cls, str__provides__); | ||||
if (cp == NULL) | ||||
{ | ||||
/* The the class has no provides, assume we're done: */ | ||||
PyErr_Clear(); | ||||
Py_DECREF(cls); | ||||
return result; | ||||
} | ||||
if (cp == result) | ||||
{ | ||||
/* | ||||
Oops, we got the provides from the class. This means | ||||
the object doesn't have it's own. We should use implementedBy | ||||
*/ | ||||
Py_DECREF(result); | ||||
result = implementedBy(NULL, cls); | ||||
} | ||||
Py_DECREF(cls); | ||||
Py_DECREF(cp); | ||||
return result; | ||||
} | ||||
/* | ||||
Get an attribute from an inst dict. Return a borrowed reference. | ||||
This has a number of advantages: | ||||
- It avoids layers of Python api | ||||
- It doesn't waste time looking for descriptors | ||||
- It fails wo raising an exception, although that shouldn't really | ||||
matter. | ||||
*/ | ||||
static PyObject * | ||||
inst_attr(PyObject *self, PyObject *name) | ||||
{ | ||||
PyObject **dictp, *v; | ||||
dictp = _PyObject_GetDictPtr(self); | ||||
if (dictp && *dictp && (v = PyDict_GetItem(*dictp, name))) | ||||
return v; | ||||
PyErr_SetObject(PyExc_AttributeError, name); | ||||
return NULL; | ||||
} | ||||
static PyObject * | ||||
Spec_extends(PyObject *self, PyObject *other) | ||||
{ | ||||
PyObject *implied; | ||||
implied = inst_attr(self, str_implied); | ||||
if (implied == NULL) | ||||
return NULL; | ||||
#ifdef Py_True | ||||
if (PyDict_GetItem(implied, other) != NULL) | ||||
{ | ||||
Py_INCREF(Py_True); | ||||
return Py_True; | ||||
} | ||||
Py_INCREF(Py_False); | ||||
return Py_False; | ||||
#else | ||||
return PyInt_FromLong(PyDict_GetItem(implied, other) != NULL); | ||||
#endif | ||||
} | ||||
static char Spec_extends__doc__[] = | ||||
"Test whether a specification is or extends another" | ||||
; | ||||
static char Spec_providedBy__doc__[] = | ||||
"Test whether an interface is implemented by the specification" | ||||
; | ||||
static PyObject * | ||||
Spec_call(PyObject *self, PyObject *args, PyObject *kw) | ||||
{ | ||||
PyObject *spec; | ||||
if (! PyArg_ParseTuple(args, "O", &spec)) | ||||
return NULL; | ||||
return Spec_extends(self, spec); | ||||
} | ||||
static PyObject * | ||||
Spec_providedBy(PyObject *self, PyObject *ob) | ||||
{ | ||||
PyObject *decl, *item; | ||||
decl = providedBy(NULL, ob); | ||||
if (decl == NULL) | ||||
return NULL; | ||||
if (PyObject_TypeCheck(decl, &SpecType)) | ||||
item = Spec_extends(decl, self); | ||||
else | ||||
/* decl is probably a security proxy. We have to go the long way | ||||
around. | ||||
*/ | ||||
item = PyObject_CallFunctionObjArgs(decl, self, NULL); | ||||
Py_DECREF(decl); | ||||
return item; | ||||
} | ||||
static char Spec_implementedBy__doc__[] = | ||||
"Test whether the specification is implemented by a class or factory.\n" | ||||
"Raise TypeError if argument is neither a class nor a callable." | ||||
; | ||||
static PyObject * | ||||
Spec_implementedBy(PyObject *self, PyObject *cls) | ||||
{ | ||||
PyObject *decl, *item; | ||||
decl = implementedBy(NULL, cls); | ||||
if (decl == NULL) | ||||
return NULL; | ||||
if (PyObject_TypeCheck(decl, &SpecType)) | ||||
item = Spec_extends(decl, self); | ||||
else | ||||
item = PyObject_CallFunctionObjArgs(decl, self, NULL); | ||||
Py_DECREF(decl); | ||||
return item; | ||||
} | ||||
static struct PyMethodDef Spec_methods[] = { | ||||
{"providedBy", | ||||
(PyCFunction)Spec_providedBy, METH_O, | ||||
Spec_providedBy__doc__}, | ||||
{"implementedBy", | ||||
(PyCFunction)Spec_implementedBy, METH_O, | ||||
Spec_implementedBy__doc__}, | ||||
{"isOrExtends", (PyCFunction)Spec_extends, METH_O, | ||||
Spec_extends__doc__}, | ||||
{NULL, NULL} /* sentinel */ | ||||
}; | ||||
static PyTypeObject SpecType = { | ||||
PyVarObject_HEAD_INIT(NULL, 0) | ||||
/* tp_name */ "_interface_coptimizations." | ||||
"SpecificationBase", | ||||
/* tp_basicsize */ 0, | ||||
/* tp_itemsize */ 0, | ||||
/* tp_dealloc */ (destructor)0, | ||||
/* tp_print */ (printfunc)0, | ||||
/* tp_getattr */ (getattrfunc)0, | ||||
/* tp_setattr */ (setattrfunc)0, | ||||
/* tp_compare */ 0, | ||||
/* tp_repr */ (reprfunc)0, | ||||
/* tp_as_number */ 0, | ||||
/* tp_as_sequence */ 0, | ||||
/* tp_as_mapping */ 0, | ||||
/* tp_hash */ (hashfunc)0, | ||||
/* tp_call */ (ternaryfunc)Spec_call, | ||||
/* tp_str */ (reprfunc)0, | ||||
/* tp_getattro */ (getattrofunc)0, | ||||
/* tp_setattro */ (setattrofunc)0, | ||||
/* tp_as_buffer */ 0, | ||||
/* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, | ||||
"Base type for Specification objects", | ||||
/* tp_traverse */ (traverseproc)0, | ||||
/* tp_clear */ (inquiry)0, | ||||
/* tp_richcompare */ (richcmpfunc)0, | ||||
/* tp_weaklistoffset */ (long)0, | ||||
/* tp_iter */ (getiterfunc)0, | ||||
/* tp_iternext */ (iternextfunc)0, | ||||
/* tp_methods */ Spec_methods, | ||||
}; | ||||
static PyObject * | ||||
OSD_descr_get(PyObject *self, PyObject *inst, PyObject *cls) | ||||
{ | ||||
PyObject *provides; | ||||
if (inst == NULL) | ||||
return getObjectSpecification(NULL, cls); | ||||
provides = PyObject_GetAttr(inst, str__provides__); | ||||
if (provides != NULL) | ||||
return provides; | ||||
PyErr_Clear(); | ||||
return implementedBy(NULL, cls); | ||||
} | ||||
static PyTypeObject OSDType = { | ||||
PyVarObject_HEAD_INIT(NULL, 0) | ||||
/* tp_name */ "_interface_coptimizations." | ||||
"ObjectSpecificationDescriptor", | ||||
/* tp_basicsize */ 0, | ||||
/* tp_itemsize */ 0, | ||||
/* tp_dealloc */ (destructor)0, | ||||
/* tp_print */ (printfunc)0, | ||||
/* tp_getattr */ (getattrfunc)0, | ||||
/* tp_setattr */ (setattrfunc)0, | ||||
/* tp_compare */ 0, | ||||
/* tp_repr */ (reprfunc)0, | ||||
/* tp_as_number */ 0, | ||||
/* tp_as_sequence */ 0, | ||||
/* tp_as_mapping */ 0, | ||||
/* tp_hash */ (hashfunc)0, | ||||
/* tp_call */ (ternaryfunc)0, | ||||
/* tp_str */ (reprfunc)0, | ||||
/* tp_getattro */ (getattrofunc)0, | ||||
/* tp_setattro */ (setattrofunc)0, | ||||
/* tp_as_buffer */ 0, | ||||
/* tp_flags */ Py_TPFLAGS_DEFAULT | ||||
| Py_TPFLAGS_BASETYPE , | ||||
"Object Specification Descriptor", | ||||
/* tp_traverse */ (traverseproc)0, | ||||
/* tp_clear */ (inquiry)0, | ||||
/* tp_richcompare */ (richcmpfunc)0, | ||||
/* tp_weaklistoffset */ (long)0, | ||||
/* tp_iter */ (getiterfunc)0, | ||||
/* tp_iternext */ (iternextfunc)0, | ||||
/* tp_methods */ 0, | ||||
/* tp_members */ 0, | ||||
/* tp_getset */ 0, | ||||
/* tp_base */ 0, | ||||
/* tp_dict */ 0, /* internal use */ | ||||
/* tp_descr_get */ (descrgetfunc)OSD_descr_get, | ||||
}; | ||||
static PyObject * | ||||
CPB_descr_get(PyObject *self, PyObject *inst, PyObject *cls) | ||||
{ | ||||
PyObject *mycls, *implements; | ||||
mycls = inst_attr(self, str_cls); | ||||
if (mycls == NULL) | ||||
return NULL; | ||||
if (cls == mycls) | ||||
{ | ||||
if (inst == NULL) | ||||
{ | ||||
Py_INCREF(self); | ||||
return OBJECT(self); | ||||
} | ||||
implements = inst_attr(self, str_implements); | ||||
Py_XINCREF(implements); | ||||
return implements; | ||||
} | ||||
PyErr_SetObject(PyExc_AttributeError, str__provides__); | ||||
return NULL; | ||||
} | ||||
static PyTypeObject CPBType = { | ||||
PyVarObject_HEAD_INIT(NULL, 0) | ||||
/* tp_name */ "_interface_coptimizations." | ||||
"ClassProvidesBase", | ||||
/* tp_basicsize */ 0, | ||||
/* tp_itemsize */ 0, | ||||
/* tp_dealloc */ (destructor)0, | ||||
/* tp_print */ (printfunc)0, | ||||
/* tp_getattr */ (getattrfunc)0, | ||||
/* tp_setattr */ (setattrfunc)0, | ||||
/* tp_compare */ 0, | ||||
/* tp_repr */ (reprfunc)0, | ||||
/* tp_as_number */ 0, | ||||
/* tp_as_sequence */ 0, | ||||
/* tp_as_mapping */ 0, | ||||
/* tp_hash */ (hashfunc)0, | ||||
/* tp_call */ (ternaryfunc)0, | ||||
/* tp_str */ (reprfunc)0, | ||||
/* tp_getattro */ (getattrofunc)0, | ||||
/* tp_setattro */ (setattrofunc)0, | ||||
/* tp_as_buffer */ 0, | ||||
/* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, | ||||
"C Base class for ClassProvides", | ||||
/* tp_traverse */ (traverseproc)0, | ||||
/* tp_clear */ (inquiry)0, | ||||
/* tp_richcompare */ (richcmpfunc)0, | ||||
/* tp_weaklistoffset */ (long)0, | ||||
/* tp_iter */ (getiterfunc)0, | ||||
/* tp_iternext */ (iternextfunc)0, | ||||
/* tp_methods */ 0, | ||||
/* tp_members */ 0, | ||||
/* tp_getset */ 0, | ||||
/* tp_base */ &SpecType, | ||||
/* tp_dict */ 0, /* internal use */ | ||||
/* tp_descr_get */ (descrgetfunc)CPB_descr_get, | ||||
}; | ||||
/* ==================================================================== */ | ||||
/* ========== Begin: __call__ and __adapt__ =========================== */ | ||||
/* | ||||
def __adapt__(self, obj): | ||||
"""Adapt an object to the reciever | ||||
""" | ||||
if self.providedBy(obj): | ||||
return obj | ||||
for hook in adapter_hooks: | ||||
adapter = hook(self, obj) | ||||
if adapter is not None: | ||||
return adapter | ||||
*/ | ||||
static PyObject * | ||||
__adapt__(PyObject *self, PyObject *obj) | ||||
{ | ||||
PyObject *decl, *args, *adapter; | ||||
int implements, i, l; | ||||
decl = providedBy(NULL, obj); | ||||
if (decl == NULL) | ||||
return NULL; | ||||
if (PyObject_TypeCheck(decl, &SpecType)) | ||||
{ | ||||
PyObject *implied; | ||||
implied = inst_attr(decl, str_implied); | ||||
if (implied == NULL) | ||||
{ | ||||
Py_DECREF(decl); | ||||
return NULL; | ||||
} | ||||
implements = PyDict_GetItem(implied, self) != NULL; | ||||
Py_DECREF(decl); | ||||
} | ||||
else | ||||
{ | ||||
/* decl is probably a security proxy. We have to go the long way | ||||
around. | ||||
*/ | ||||
PyObject *r; | ||||
r = PyObject_CallFunctionObjArgs(decl, self, NULL); | ||||
Py_DECREF(decl); | ||||
if (r == NULL) | ||||
return NULL; | ||||
implements = PyObject_IsTrue(r); | ||||
Py_DECREF(r); | ||||
} | ||||
if (implements) | ||||
{ | ||||
Py_INCREF(obj); | ||||
return obj; | ||||
} | ||||
l = PyList_GET_SIZE(adapter_hooks); | ||||
args = PyTuple_New(2); | ||||
if (args == NULL) | ||||
return NULL; | ||||
Py_INCREF(self); | ||||
PyTuple_SET_ITEM(args, 0, self); | ||||
Py_INCREF(obj); | ||||
PyTuple_SET_ITEM(args, 1, obj); | ||||
for (i = 0; i < l; i++) | ||||
{ | ||||
adapter = PyObject_CallObject(PyList_GET_ITEM(adapter_hooks, i), args); | ||||
if (adapter == NULL || adapter != Py_None) | ||||
{ | ||||
Py_DECREF(args); | ||||
return adapter; | ||||
} | ||||
Py_DECREF(adapter); | ||||
} | ||||
Py_DECREF(args); | ||||
Py_INCREF(Py_None); | ||||
return Py_None; | ||||
} | ||||
static struct PyMethodDef ib_methods[] = { | ||||
{"__adapt__", (PyCFunction)__adapt__, METH_O, | ||||
"Adapt an object to the reciever"}, | ||||
{NULL, NULL} /* sentinel */ | ||||
}; | ||||
/* | ||||
def __call__(self, obj, alternate=_marker): | ||||
conform = getattr(obj, '__conform__', None) | ||||
if conform is not None: | ||||
adapter = self._call_conform(conform) | ||||
if adapter is not None: | ||||
return adapter | ||||
adapter = self.__adapt__(obj) | ||||
if adapter is not None: | ||||
return adapter | ||||
elif alternate is not _marker: | ||||
return alternate | ||||
else: | ||||
raise TypeError("Could not adapt", obj, self) | ||||
*/ | ||||
static PyObject * | ||||
ib_call(PyObject *self, PyObject *args, PyObject *kwargs) | ||||
{ | ||||
PyObject *conform, *obj, *alternate=NULL, *adapter; | ||||
static char *kwlist[] = {"obj", "alternate", NULL}; | ||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, | ||||
&obj, &alternate)) | ||||
return NULL; | ||||
conform = PyObject_GetAttr(obj, str__conform__); | ||||
if (conform != NULL) | ||||
{ | ||||
adapter = PyObject_CallMethodObjArgs(self, str_call_conform, | ||||
conform, NULL); | ||||
Py_DECREF(conform); | ||||
if (adapter == NULL || adapter != Py_None) | ||||
return adapter; | ||||
Py_DECREF(adapter); | ||||
} | ||||
else | ||||
PyErr_Clear(); | ||||
adapter = __adapt__(self, obj); | ||||
if (adapter == NULL || adapter != Py_None) | ||||
return adapter; | ||||
Py_DECREF(adapter); | ||||
if (alternate != NULL) | ||||
{ | ||||
Py_INCREF(alternate); | ||||
return alternate; | ||||
} | ||||
adapter = Py_BuildValue("sOO", "Could not adapt", obj, self); | ||||
if (adapter != NULL) | ||||
{ | ||||
PyErr_SetObject(PyExc_TypeError, adapter); | ||||
Py_DECREF(adapter); | ||||
} | ||||
return NULL; | ||||
} | ||||
static PyTypeObject InterfaceBase = { | ||||
PyVarObject_HEAD_INIT(NULL, 0) | ||||
/* tp_name */ "_zope_interface_coptimizations." | ||||
"InterfaceBase", | ||||
/* tp_basicsize */ 0, | ||||
/* tp_itemsize */ 0, | ||||
/* tp_dealloc */ (destructor)0, | ||||
/* tp_print */ (printfunc)0, | ||||
/* tp_getattr */ (getattrfunc)0, | ||||
/* tp_setattr */ (setattrfunc)0, | ||||
/* tp_compare */ 0, | ||||
/* tp_repr */ (reprfunc)0, | ||||
/* tp_as_number */ 0, | ||||
/* tp_as_sequence */ 0, | ||||
/* tp_as_mapping */ 0, | ||||
/* tp_hash */ (hashfunc)0, | ||||
/* tp_call */ (ternaryfunc)ib_call, | ||||
/* tp_str */ (reprfunc)0, | ||||
/* tp_getattro */ (getattrofunc)0, | ||||
/* tp_setattro */ (setattrofunc)0, | ||||
/* tp_as_buffer */ 0, | ||||
/* tp_flags */ Py_TPFLAGS_DEFAULT | ||||
| Py_TPFLAGS_BASETYPE , | ||||
/* tp_doc */ "Interface base type providing __call__ and __adapt__", | ||||
/* tp_traverse */ (traverseproc)0, | ||||
/* tp_clear */ (inquiry)0, | ||||
/* tp_richcompare */ (richcmpfunc)0, | ||||
/* tp_weaklistoffset */ (long)0, | ||||
/* tp_iter */ (getiterfunc)0, | ||||
/* tp_iternext */ (iternextfunc)0, | ||||
/* tp_methods */ ib_methods, | ||||
}; | ||||
/* =================== End: __call__ and __adapt__ ==================== */ | ||||
/* ==================================================================== */ | ||||
/* ==================================================================== */ | ||||
/* ========================== Begin: Lookup Bases ===================== */ | ||||
typedef struct { | ||||
PyObject_HEAD | ||||
PyObject *_cache; | ||||
PyObject *_mcache; | ||||
PyObject *_scache; | ||||
} lookup; | ||||
typedef struct { | ||||
PyObject_HEAD | ||||
PyObject *_cache; | ||||
PyObject *_mcache; | ||||
PyObject *_scache; | ||||
PyObject *_verify_ro; | ||||
PyObject *_verify_generations; | ||||
} verify; | ||||
static int | ||||
lookup_traverse(lookup *self, visitproc visit, void *arg) | ||||
{ | ||||
int vret; | ||||
if (self->_cache) { | ||||
vret = visit(self->_cache, arg); | ||||
if (vret != 0) | ||||
return vret; | ||||
} | ||||
if (self->_mcache) { | ||||
vret = visit(self->_mcache, arg); | ||||
if (vret != 0) | ||||
return vret; | ||||
} | ||||
if (self->_scache) { | ||||
vret = visit(self->_scache, arg); | ||||
if (vret != 0) | ||||
return vret; | ||||
} | ||||
return 0; | ||||
} | ||||
static int | ||||
lookup_clear(lookup *self) | ||||
{ | ||||
Py_CLEAR(self->_cache); | ||||
Py_CLEAR(self->_mcache); | ||||
Py_CLEAR(self->_scache); | ||||
return 0; | ||||
} | ||||
static void | ||||
lookup_dealloc(lookup *self) | ||||
{ | ||||
PyObject_GC_UnTrack((PyObject *)self); | ||||
lookup_clear(self); | ||||
Py_TYPE(self)->tp_free((PyObject*)self); | ||||
} | ||||
/* | ||||
def changed(self, ignored=None): | ||||
self._cache.clear() | ||||
self._mcache.clear() | ||||
self._scache.clear() | ||||
*/ | ||||
static PyObject * | ||||
lookup_changed(lookup *self, PyObject *ignored) | ||||
{ | ||||
lookup_clear(self); | ||||
Py_INCREF(Py_None); | ||||
return Py_None; | ||||
} | ||||
#define ASSURE_DICT(N) if (N == NULL) { N = PyDict_New(); \ | ||||
if (N == NULL) return NULL; \ | ||||
} | ||||
/* | ||||
def _getcache(self, provided, name): | ||||
cache = self._cache.get(provided) | ||||
if cache is None: | ||||
cache = {} | ||||
self._cache[provided] = cache | ||||
if name: | ||||
c = cache.get(name) | ||||
if c is None: | ||||
c = {} | ||||
cache[name] = c | ||||
cache = c | ||||
return cache | ||||
*/ | ||||
static PyObject * | ||||
_subcache(PyObject *cache, PyObject *key) | ||||
{ | ||||
PyObject *subcache; | ||||
subcache = PyDict_GetItem(cache, key); | ||||
if (subcache == NULL) | ||||
{ | ||||
int status; | ||||
subcache = PyDict_New(); | ||||
if (subcache == NULL) | ||||
return NULL; | ||||
status = PyDict_SetItem(cache, key, subcache); | ||||
Py_DECREF(subcache); | ||||
if (status < 0) | ||||
return NULL; | ||||
} | ||||
return subcache; | ||||
} | ||||
static PyObject * | ||||
_getcache(lookup *self, PyObject *provided, PyObject *name) | ||||
{ | ||||
PyObject *cache; | ||||
ASSURE_DICT(self->_cache); | ||||
cache = _subcache(self->_cache, provided); | ||||
if (cache == NULL) | ||||
return NULL; | ||||
if (name != NULL && PyObject_IsTrue(name)) | ||||
cache = _subcache(cache, name); | ||||
return cache; | ||||
} | ||||
/* | ||||
def lookup(self, required, provided, name=u'', default=None): | ||||
cache = self._getcache(provided, name) | ||||
if len(required) == 1: | ||||
result = cache.get(required[0], _not_in_mapping) | ||||
else: | ||||
result = cache.get(tuple(required), _not_in_mapping) | ||||
if result is _not_in_mapping: | ||||
result = self._uncached_lookup(required, provided, name) | ||||
if len(required) == 1: | ||||
cache[required[0]] = result | ||||
else: | ||||
cache[tuple(required)] = result | ||||
if result is None: | ||||
return default | ||||
return result | ||||
*/ | ||||
static PyObject * | ||||
tuplefy(PyObject *v) | ||||
{ | ||||
if (! PyTuple_Check(v)) | ||||
{ | ||||
v = PyObject_CallFunctionObjArgs(OBJECT(&PyTuple_Type), v, NULL); | ||||
if (v == NULL) | ||||
return NULL; | ||||
} | ||||
else | ||||
Py_INCREF(v); | ||||
return v; | ||||
} | ||||
static PyObject * | ||||
_lookup(lookup *self, | ||||
PyObject *required, PyObject *provided, PyObject *name, | ||||
PyObject *default_) | ||||
{ | ||||
PyObject *result, *key, *cache; | ||||
#ifdef PY3K | ||||
if ( name && !PyUnicode_Check(name) ) | ||||
#else | ||||
if ( name && !PyString_Check(name) && !PyUnicode_Check(name) ) | ||||
#endif | ||||
{ | ||||
PyErr_SetString(PyExc_ValueError, | ||||
"name is not a string or unicode"); | ||||
return NULL; | ||||
} | ||||
cache = _getcache(self, provided, name); | ||||
if (cache == NULL) | ||||
return NULL; | ||||
required = tuplefy(required); | ||||
if (required == NULL) | ||||
return NULL; | ||||
if (PyTuple_GET_SIZE(required) == 1) | ||||
key = PyTuple_GET_ITEM(required, 0); | ||||
else | ||||
key = required; | ||||
result = PyDict_GetItem(cache, key); | ||||
if (result == NULL) | ||||
{ | ||||
int status; | ||||
result = PyObject_CallMethodObjArgs(OBJECT(self), str_uncached_lookup, | ||||
required, provided, name, NULL); | ||||
if (result == NULL) | ||||
{ | ||||
Py_DECREF(required); | ||||
return NULL; | ||||
} | ||||
status = PyDict_SetItem(cache, key, result); | ||||
Py_DECREF(required); | ||||
if (status < 0) | ||||
{ | ||||
Py_DECREF(result); | ||||
return NULL; | ||||
} | ||||
} | ||||
else | ||||
{ | ||||
Py_INCREF(result); | ||||
Py_DECREF(required); | ||||
} | ||||
if (result == Py_None && default_ != NULL) | ||||
{ | ||||
Py_DECREF(Py_None); | ||||
Py_INCREF(default_); | ||||
return default_; | ||||
} | ||||
return result; | ||||
} | ||||
static PyObject * | ||||
lookup_lookup(lookup *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"required", "provided", "name", "default", NULL}; | ||||
PyObject *required, *provided, *name=NULL, *default_=NULL; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, | ||||
&required, &provided, &name, &default_)) | ||||
return NULL; | ||||
return _lookup(self, required, provided, name, default_); | ||||
} | ||||
/* | ||||
def lookup1(self, required, provided, name=u'', default=None): | ||||
cache = self._getcache(provided, name) | ||||
result = cache.get(required, _not_in_mapping) | ||||
if result is _not_in_mapping: | ||||
return self.lookup((required, ), provided, name, default) | ||||
if result is None: | ||||
return default | ||||
return result | ||||
*/ | ||||
static PyObject * | ||||
_lookup1(lookup *self, | ||||
PyObject *required, PyObject *provided, PyObject *name, | ||||
PyObject *default_) | ||||
{ | ||||
PyObject *result, *cache; | ||||
#ifdef PY3K | ||||
if ( name && !PyUnicode_Check(name) ) | ||||
#else | ||||
if ( name && !PyString_Check(name) && !PyUnicode_Check(name) ) | ||||
#endif | ||||
{ | ||||
PyErr_SetString(PyExc_ValueError, | ||||
"name is not a string or unicode"); | ||||
return NULL; | ||||
} | ||||
cache = _getcache(self, provided, name); | ||||
if (cache == NULL) | ||||
return NULL; | ||||
result = PyDict_GetItem(cache, required); | ||||
if (result == NULL) | ||||
{ | ||||
PyObject *tup; | ||||
tup = PyTuple_New(1); | ||||
if (tup == NULL) | ||||
return NULL; | ||||
Py_INCREF(required); | ||||
PyTuple_SET_ITEM(tup, 0, required); | ||||
result = _lookup(self, tup, provided, name, default_); | ||||
Py_DECREF(tup); | ||||
} | ||||
else | ||||
{ | ||||
if (result == Py_None && default_ != NULL) | ||||
{ | ||||
result = default_; | ||||
} | ||||
Py_INCREF(result); | ||||
} | ||||
return result; | ||||
} | ||||
static PyObject * | ||||
lookup_lookup1(lookup *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"required", "provided", "name", "default", NULL}; | ||||
PyObject *required, *provided, *name=NULL, *default_=NULL; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, | ||||
&required, &provided, &name, &default_)) | ||||
return NULL; | ||||
return _lookup1(self, required, provided, name, default_); | ||||
} | ||||
/* | ||||
def adapter_hook(self, provided, object, name=u'', default=None): | ||||
required = providedBy(object) | ||||
cache = self._getcache(provided, name) | ||||
factory = cache.get(required, _not_in_mapping) | ||||
if factory is _not_in_mapping: | ||||
factory = self.lookup((required, ), provided, name) | ||||
if factory is not None: | ||||
result = factory(object) | ||||
if result is not None: | ||||
return result | ||||
return default | ||||
*/ | ||||
static PyObject * | ||||
_adapter_hook(lookup *self, | ||||
PyObject *provided, PyObject *object, PyObject *name, | ||||
PyObject *default_) | ||||
{ | ||||
PyObject *required, *factory, *result; | ||||
#ifdef PY3K | ||||
if ( name && !PyUnicode_Check(name) ) | ||||
#else | ||||
if ( name && !PyString_Check(name) && !PyUnicode_Check(name) ) | ||||
#endif | ||||
{ | ||||
PyErr_SetString(PyExc_ValueError, | ||||
"name is not a string or unicode"); | ||||
return NULL; | ||||
} | ||||
required = providedBy(NULL, object); | ||||
if (required == NULL) | ||||
return NULL; | ||||
factory = _lookup1(self, required, provided, name, Py_None); | ||||
Py_DECREF(required); | ||||
if (factory == NULL) | ||||
return NULL; | ||||
if (factory != Py_None) | ||||
{ | ||||
result = PyObject_CallFunctionObjArgs(factory, object, NULL); | ||||
Py_DECREF(factory); | ||||
if (result == NULL || result != Py_None) | ||||
return result; | ||||
} | ||||
else | ||||
result = factory; /* None */ | ||||
if (default_ == NULL || default_ == result) /* No default specified, */ | ||||
return result; /* Return None. result is owned None */ | ||||
Py_DECREF(result); | ||||
Py_INCREF(default_); | ||||
return default_; | ||||
} | ||||
static PyObject * | ||||
lookup_adapter_hook(lookup *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"provided", "object", "name", "default", NULL}; | ||||
PyObject *object, *provided, *name=NULL, *default_=NULL; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, | ||||
&provided, &object, &name, &default_)) | ||||
return NULL; | ||||
return _adapter_hook(self, provided, object, name, default_); | ||||
} | ||||
static PyObject * | ||||
lookup_queryAdapter(lookup *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"object", "provided", "name", "default", NULL}; | ||||
PyObject *object, *provided, *name=NULL, *default_=NULL; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, | ||||
&object, &provided, &name, &default_)) | ||||
return NULL; | ||||
return _adapter_hook(self, provided, object, name, default_); | ||||
} | ||||
/* | ||||
def lookupAll(self, required, provided): | ||||
cache = self._mcache.get(provided) | ||||
if cache is None: | ||||
cache = {} | ||||
self._mcache[provided] = cache | ||||
required = tuple(required) | ||||
result = cache.get(required, _not_in_mapping) | ||||
if result is _not_in_mapping: | ||||
result = self._uncached_lookupAll(required, provided) | ||||
cache[required] = result | ||||
return result | ||||
*/ | ||||
static PyObject * | ||||
_lookupAll(lookup *self, PyObject *required, PyObject *provided) | ||||
{ | ||||
PyObject *cache, *result; | ||||
ASSURE_DICT(self->_mcache); | ||||
cache = _subcache(self->_mcache, provided); | ||||
if (cache == NULL) | ||||
return NULL; | ||||
required = tuplefy(required); | ||||
if (required == NULL) | ||||
return NULL; | ||||
result = PyDict_GetItem(cache, required); | ||||
if (result == NULL) | ||||
{ | ||||
int status; | ||||
result = PyObject_CallMethodObjArgs(OBJECT(self), str_uncached_lookupAll, | ||||
required, provided, NULL); | ||||
if (result == NULL) | ||||
{ | ||||
Py_DECREF(required); | ||||
return NULL; | ||||
} | ||||
status = PyDict_SetItem(cache, required, result); | ||||
Py_DECREF(required); | ||||
if (status < 0) | ||||
{ | ||||
Py_DECREF(result); | ||||
return NULL; | ||||
} | ||||
} | ||||
else | ||||
{ | ||||
Py_INCREF(result); | ||||
Py_DECREF(required); | ||||
} | ||||
return result; | ||||
} | ||||
static PyObject * | ||||
lookup_lookupAll(lookup *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"required", "provided", NULL}; | ||||
PyObject *required, *provided; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, | ||||
&required, &provided)) | ||||
return NULL; | ||||
return _lookupAll(self, required, provided); | ||||
} | ||||
/* | ||||
def subscriptions(self, required, provided): | ||||
cache = self._scache.get(provided) | ||||
if cache is None: | ||||
cache = {} | ||||
self._scache[provided] = cache | ||||
required = tuple(required) | ||||
result = cache.get(required, _not_in_mapping) | ||||
if result is _not_in_mapping: | ||||
result = self._uncached_subscriptions(required, provided) | ||||
cache[required] = result | ||||
return result | ||||
*/ | ||||
static PyObject * | ||||
_subscriptions(lookup *self, PyObject *required, PyObject *provided) | ||||
{ | ||||
PyObject *cache, *result; | ||||
ASSURE_DICT(self->_scache); | ||||
cache = _subcache(self->_scache, provided); | ||||
if (cache == NULL) | ||||
return NULL; | ||||
required = tuplefy(required); | ||||
if (required == NULL) | ||||
return NULL; | ||||
result = PyDict_GetItem(cache, required); | ||||
if (result == NULL) | ||||
{ | ||||
int status; | ||||
result = PyObject_CallMethodObjArgs( | ||||
OBJECT(self), str_uncached_subscriptions, | ||||
required, provided, NULL); | ||||
if (result == NULL) | ||||
{ | ||||
Py_DECREF(required); | ||||
return NULL; | ||||
} | ||||
status = PyDict_SetItem(cache, required, result); | ||||
Py_DECREF(required); | ||||
if (status < 0) | ||||
{ | ||||
Py_DECREF(result); | ||||
return NULL; | ||||
} | ||||
} | ||||
else | ||||
{ | ||||
Py_INCREF(result); | ||||
Py_DECREF(required); | ||||
} | ||||
return result; | ||||
} | ||||
static PyObject * | ||||
lookup_subscriptions(lookup *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"required", "provided", NULL}; | ||||
PyObject *required, *provided; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, | ||||
&required, &provided)) | ||||
return NULL; | ||||
return _subscriptions(self, required, provided); | ||||
} | ||||
static struct PyMethodDef lookup_methods[] = { | ||||
{"changed", (PyCFunction)lookup_changed, METH_O, ""}, | ||||
{"lookup", (PyCFunction)lookup_lookup, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{"lookup1", (PyCFunction)lookup_lookup1, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{"queryAdapter", (PyCFunction)lookup_queryAdapter, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{"adapter_hook", (PyCFunction)lookup_adapter_hook, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{"lookupAll", (PyCFunction)lookup_lookupAll, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{"subscriptions", (PyCFunction)lookup_subscriptions, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{NULL, NULL} /* sentinel */ | ||||
}; | ||||
static PyTypeObject LookupBase = { | ||||
PyVarObject_HEAD_INIT(NULL, 0) | ||||
/* tp_name */ "_zope_interface_coptimizations." | ||||
"LookupBase", | ||||
/* tp_basicsize */ sizeof(lookup), | ||||
/* tp_itemsize */ 0, | ||||
/* tp_dealloc */ (destructor)&lookup_dealloc, | ||||
/* tp_print */ (printfunc)0, | ||||
/* tp_getattr */ (getattrfunc)0, | ||||
/* tp_setattr */ (setattrfunc)0, | ||||
/* tp_compare */ 0, | ||||
/* tp_repr */ (reprfunc)0, | ||||
/* tp_as_number */ 0, | ||||
/* tp_as_sequence */ 0, | ||||
/* tp_as_mapping */ 0, | ||||
/* tp_hash */ (hashfunc)0, | ||||
/* tp_call */ (ternaryfunc)0, | ||||
/* tp_str */ (reprfunc)0, | ||||
/* tp_getattro */ (getattrofunc)0, | ||||
/* tp_setattro */ (setattrofunc)0, | ||||
/* tp_as_buffer */ 0, | ||||
/* tp_flags */ Py_TPFLAGS_DEFAULT | ||||
| Py_TPFLAGS_BASETYPE | ||||
| Py_TPFLAGS_HAVE_GC, | ||||
/* tp_doc */ "", | ||||
/* tp_traverse */ (traverseproc)lookup_traverse, | ||||
/* tp_clear */ (inquiry)lookup_clear, | ||||
/* tp_richcompare */ (richcmpfunc)0, | ||||
/* tp_weaklistoffset */ (long)0, | ||||
/* tp_iter */ (getiterfunc)0, | ||||
/* tp_iternext */ (iternextfunc)0, | ||||
/* tp_methods */ lookup_methods, | ||||
}; | ||||
static int | ||||
verifying_traverse(verify *self, visitproc visit, void *arg) | ||||
{ | ||||
int vret; | ||||
vret = lookup_traverse((lookup *)self, visit, arg); | ||||
if (vret != 0) | ||||
return vret; | ||||
if (self->_verify_ro) { | ||||
vret = visit(self->_verify_ro, arg); | ||||
if (vret != 0) | ||||
return vret; | ||||
} | ||||
if (self->_verify_generations) { | ||||
vret = visit(self->_verify_generations, arg); | ||||
if (vret != 0) | ||||
return vret; | ||||
} | ||||
return 0; | ||||
} | ||||
static int | ||||
verifying_clear(verify *self) | ||||
{ | ||||
lookup_clear((lookup *)self); | ||||
Py_CLEAR(self->_verify_generations); | ||||
Py_CLEAR(self->_verify_ro); | ||||
return 0; | ||||
} | ||||
static void | ||||
verifying_dealloc(verify *self) | ||||
{ | ||||
Gregory Szorc
|
r37195 | PyObject_GC_UnTrack((PyObject *)self); | ||
Gregory Szorc
|
r37193 | verifying_clear(self); | ||
Py_TYPE(self)->tp_free((PyObject*)self); | ||||
} | ||||
/* | ||||
def changed(self, originally_changed): | ||||
super(VerifyingBasePy, self).changed(originally_changed) | ||||
self._verify_ro = self._registry.ro[1:] | ||||
self._verify_generations = [r._generation for r in self._verify_ro] | ||||
*/ | ||||
static PyObject * | ||||
_generations_tuple(PyObject *ro) | ||||
{ | ||||
int i, l; | ||||
PyObject *generations; | ||||
l = PyTuple_GET_SIZE(ro); | ||||
generations = PyTuple_New(l); | ||||
for (i=0; i < l; i++) | ||||
{ | ||||
PyObject *generation; | ||||
generation = PyObject_GetAttr(PyTuple_GET_ITEM(ro, i), str_generation); | ||||
if (generation == NULL) | ||||
{ | ||||
Py_DECREF(generations); | ||||
return NULL; | ||||
} | ||||
PyTuple_SET_ITEM(generations, i, generation); | ||||
} | ||||
return generations; | ||||
} | ||||
static PyObject * | ||||
verifying_changed(verify *self, PyObject *ignored) | ||||
{ | ||||
PyObject *t, *ro; | ||||
verifying_clear(self); | ||||
t = PyObject_GetAttr(OBJECT(self), str_registry); | ||||
if (t == NULL) | ||||
return NULL; | ||||
ro = PyObject_GetAttr(t, strro); | ||||
Py_DECREF(t); | ||||
if (ro == NULL) | ||||
return NULL; | ||||
t = PyObject_CallFunctionObjArgs(OBJECT(&PyTuple_Type), ro, NULL); | ||||
Py_DECREF(ro); | ||||
if (t == NULL) | ||||
return NULL; | ||||
ro = PyTuple_GetSlice(t, 1, PyTuple_GET_SIZE(t)); | ||||
Py_DECREF(t); | ||||
if (ro == NULL) | ||||
return NULL; | ||||
self->_verify_generations = _generations_tuple(ro); | ||||
if (self->_verify_generations == NULL) | ||||
{ | ||||
Py_DECREF(ro); | ||||
return NULL; | ||||
} | ||||
self->_verify_ro = ro; | ||||
Py_INCREF(Py_None); | ||||
return Py_None; | ||||
} | ||||
/* | ||||
def _verify(self): | ||||
if ([r._generation for r in self._verify_ro] | ||||
!= self._verify_generations): | ||||
self.changed(None) | ||||
*/ | ||||
static int | ||||
_verify(verify *self) | ||||
{ | ||||
PyObject *changed_result; | ||||
if (self->_verify_ro != NULL && self->_verify_generations != NULL) | ||||
{ | ||||
PyObject *generations; | ||||
int changed; | ||||
generations = _generations_tuple(self->_verify_ro); | ||||
if (generations == NULL) | ||||
return -1; | ||||
changed = PyObject_RichCompareBool(self->_verify_generations, | ||||
generations, Py_NE); | ||||
Py_DECREF(generations); | ||||
if (changed == -1) | ||||
return -1; | ||||
if (changed == 0) | ||||
return 0; | ||||
} | ||||
changed_result = PyObject_CallMethodObjArgs(OBJECT(self), strchanged, | ||||
Py_None, NULL); | ||||
if (changed_result == NULL) | ||||
return -1; | ||||
Py_DECREF(changed_result); | ||||
return 0; | ||||
} | ||||
static PyObject * | ||||
verifying_lookup(verify *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"required", "provided", "name", "default", NULL}; | ||||
PyObject *required, *provided, *name=NULL, *default_=NULL; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, | ||||
&required, &provided, &name, &default_)) | ||||
return NULL; | ||||
if (_verify(self) < 0) | ||||
return NULL; | ||||
return _lookup((lookup *)self, required, provided, name, default_); | ||||
} | ||||
static PyObject * | ||||
verifying_lookup1(verify *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"required", "provided", "name", "default", NULL}; | ||||
PyObject *required, *provided, *name=NULL, *default_=NULL; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, | ||||
&required, &provided, &name, &default_)) | ||||
return NULL; | ||||
if (_verify(self) < 0) | ||||
return NULL; | ||||
return _lookup1((lookup *)self, required, provided, name, default_); | ||||
} | ||||
static PyObject * | ||||
verifying_adapter_hook(verify *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"provided", "object", "name", "default", NULL}; | ||||
PyObject *object, *provided, *name=NULL, *default_=NULL; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, | ||||
&provided, &object, &name, &default_)) | ||||
return NULL; | ||||
if (_verify(self) < 0) | ||||
return NULL; | ||||
return _adapter_hook((lookup *)self, provided, object, name, default_); | ||||
} | ||||
static PyObject * | ||||
verifying_queryAdapter(verify *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"object", "provided", "name", "default", NULL}; | ||||
PyObject *object, *provided, *name=NULL, *default_=NULL; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, | ||||
&object, &provided, &name, &default_)) | ||||
return NULL; | ||||
if (_verify(self) < 0) | ||||
return NULL; | ||||
return _adapter_hook((lookup *)self, provided, object, name, default_); | ||||
} | ||||
static PyObject * | ||||
verifying_lookupAll(verify *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"required", "provided", NULL}; | ||||
PyObject *required, *provided; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, | ||||
&required, &provided)) | ||||
return NULL; | ||||
if (_verify(self) < 0) | ||||
return NULL; | ||||
return _lookupAll((lookup *)self, required, provided); | ||||
} | ||||
static PyObject * | ||||
verifying_subscriptions(verify *self, PyObject *args, PyObject *kwds) | ||||
{ | ||||
static char *kwlist[] = {"required", "provided", NULL}; | ||||
PyObject *required, *provided; | ||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, | ||||
&required, &provided)) | ||||
return NULL; | ||||
if (_verify(self) < 0) | ||||
return NULL; | ||||
return _subscriptions((lookup *)self, required, provided); | ||||
} | ||||
static struct PyMethodDef verifying_methods[] = { | ||||
{"changed", (PyCFunction)verifying_changed, METH_O, ""}, | ||||
{"lookup", (PyCFunction)verifying_lookup, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{"lookup1", (PyCFunction)verifying_lookup1, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{"queryAdapter", (PyCFunction)verifying_queryAdapter, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{"adapter_hook", (PyCFunction)verifying_adapter_hook, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{"lookupAll", (PyCFunction)verifying_lookupAll, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{"subscriptions", (PyCFunction)verifying_subscriptions, METH_KEYWORDS | METH_VARARGS, ""}, | ||||
{NULL, NULL} /* sentinel */ | ||||
}; | ||||
static PyTypeObject VerifyingBase = { | ||||
PyVarObject_HEAD_INIT(NULL, 0) | ||||
/* tp_name */ "_zope_interface_coptimizations." | ||||
"VerifyingBase", | ||||
/* tp_basicsize */ sizeof(verify), | ||||
/* tp_itemsize */ 0, | ||||
/* tp_dealloc */ (destructor)&verifying_dealloc, | ||||
/* tp_print */ (printfunc)0, | ||||
/* tp_getattr */ (getattrfunc)0, | ||||
/* tp_setattr */ (setattrfunc)0, | ||||
/* tp_compare */ 0, | ||||
/* tp_repr */ (reprfunc)0, | ||||
/* tp_as_number */ 0, | ||||
/* tp_as_sequence */ 0, | ||||
/* tp_as_mapping */ 0, | ||||
/* tp_hash */ (hashfunc)0, | ||||
/* tp_call */ (ternaryfunc)0, | ||||
/* tp_str */ (reprfunc)0, | ||||
/* tp_getattro */ (getattrofunc)0, | ||||
/* tp_setattro */ (setattrofunc)0, | ||||
/* tp_as_buffer */ 0, | ||||
/* tp_flags */ Py_TPFLAGS_DEFAULT | ||||
| Py_TPFLAGS_BASETYPE | ||||
| Py_TPFLAGS_HAVE_GC, | ||||
/* tp_doc */ "", | ||||
/* tp_traverse */ (traverseproc)verifying_traverse, | ||||
/* tp_clear */ (inquiry)verifying_clear, | ||||
/* tp_richcompare */ (richcmpfunc)0, | ||||
/* tp_weaklistoffset */ (long)0, | ||||
/* tp_iter */ (getiterfunc)0, | ||||
/* tp_iternext */ (iternextfunc)0, | ||||
/* tp_methods */ verifying_methods, | ||||
/* tp_members */ 0, | ||||
/* tp_getset */ 0, | ||||
/* tp_base */ &LookupBase, | ||||
}; | ||||
/* ========================== End: Lookup Bases ======================= */ | ||||
/* ==================================================================== */ | ||||
static struct PyMethodDef m_methods[] = { | ||||
{"implementedBy", (PyCFunction)implementedBy, METH_O, | ||||
"Interfaces implemented by a class or factory.\n" | ||||
"Raises TypeError if argument is neither a class nor a callable."}, | ||||
{"getObjectSpecification", (PyCFunction)getObjectSpecification, METH_O, | ||||
"Get an object's interfaces (internal api)"}, | ||||
{"providedBy", (PyCFunction)providedBy, METH_O, | ||||
"Get an object's interfaces"}, | ||||
{NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */ | ||||
}; | ||||
#if PY_MAJOR_VERSION >= 3 | ||||
static char module_doc[] = "C optimizations for zope.interface\n\n"; | ||||
static struct PyModuleDef _zic_module = { | ||||
PyModuleDef_HEAD_INIT, | ||||
"_zope_interface_coptimizations", | ||||
module_doc, | ||||
-1, | ||||
m_methods, | ||||
NULL, | ||||
NULL, | ||||
NULL, | ||||
NULL | ||||
}; | ||||
#endif | ||||
static PyObject * | ||||
init(void) | ||||
{ | ||||
PyObject *m; | ||||
#if PY_MAJOR_VERSION < 3 | ||||
#define DEFINE_STRING(S) \ | ||||
if(! (str ## S = PyString_FromString(# S))) return NULL | ||||
#else | ||||
#define DEFINE_STRING(S) \ | ||||
if(! (str ## S = PyUnicode_FromString(# S))) return NULL | ||||
#endif | ||||
DEFINE_STRING(__dict__); | ||||
DEFINE_STRING(__implemented__); | ||||
DEFINE_STRING(__provides__); | ||||
DEFINE_STRING(__class__); | ||||
DEFINE_STRING(__providedBy__); | ||||
DEFINE_STRING(extends); | ||||
DEFINE_STRING(_implied); | ||||
DEFINE_STRING(_implements); | ||||
DEFINE_STRING(_cls); | ||||
DEFINE_STRING(__conform__); | ||||
DEFINE_STRING(_call_conform); | ||||
DEFINE_STRING(_uncached_lookup); | ||||
DEFINE_STRING(_uncached_lookupAll); | ||||
DEFINE_STRING(_uncached_subscriptions); | ||||
DEFINE_STRING(_registry); | ||||
DEFINE_STRING(_generation); | ||||
DEFINE_STRING(ro); | ||||
DEFINE_STRING(changed); | ||||
#undef DEFINE_STRING | ||||
adapter_hooks = PyList_New(0); | ||||
if (adapter_hooks == NULL) | ||||
return NULL; | ||||
/* Initialize types: */ | ||||
SpecType.tp_new = PyBaseObject_Type.tp_new; | ||||
if (PyType_Ready(&SpecType) < 0) | ||||
return NULL; | ||||
OSDType.tp_new = PyBaseObject_Type.tp_new; | ||||
if (PyType_Ready(&OSDType) < 0) | ||||
return NULL; | ||||
CPBType.tp_new = PyBaseObject_Type.tp_new; | ||||
if (PyType_Ready(&CPBType) < 0) | ||||
return NULL; | ||||
InterfaceBase.tp_new = PyBaseObject_Type.tp_new; | ||||
if (PyType_Ready(&InterfaceBase) < 0) | ||||
return NULL; | ||||
LookupBase.tp_new = PyBaseObject_Type.tp_new; | ||||
if (PyType_Ready(&LookupBase) < 0) | ||||
return NULL; | ||||
VerifyingBase.tp_new = PyBaseObject_Type.tp_new; | ||||
if (PyType_Ready(&VerifyingBase) < 0) | ||||
return NULL; | ||||
#if PY_MAJOR_VERSION < 3 | ||||
/* Create the module and add the functions */ | ||||
m = Py_InitModule3("_zope_interface_coptimizations", m_methods, | ||||
"C optimizations for zope.interface\n\n"); | ||||
#else | ||||
m = PyModule_Create(&_zic_module); | ||||
#endif | ||||
if (m == NULL) | ||||
return NULL; | ||||
/* Add types: */ | ||||
if (PyModule_AddObject(m, "SpecificationBase", OBJECT(&SpecType)) < 0) | ||||
return NULL; | ||||
if (PyModule_AddObject(m, "ObjectSpecificationDescriptor", | ||||
(PyObject *)&OSDType) < 0) | ||||
return NULL; | ||||
if (PyModule_AddObject(m, "ClassProvidesBase", OBJECT(&CPBType)) < 0) | ||||
return NULL; | ||||
if (PyModule_AddObject(m, "InterfaceBase", OBJECT(&InterfaceBase)) < 0) | ||||
return NULL; | ||||
if (PyModule_AddObject(m, "LookupBase", OBJECT(&LookupBase)) < 0) | ||||
return NULL; | ||||
if (PyModule_AddObject(m, "VerifyingBase", OBJECT(&VerifyingBase)) < 0) | ||||
return NULL; | ||||
if (PyModule_AddObject(m, "adapter_hooks", adapter_hooks) < 0) | ||||
return NULL; | ||||
return m; | ||||
} | ||||
PyMODINIT_FUNC | ||||
#if PY_MAJOR_VERSION < 3 | ||||
init_zope_interface_coptimizations(void) | ||||
{ | ||||
init(); | ||||
} | ||||
#else | ||||
PyInit__zope_interface_coptimizations(void) | ||||
{ | ||||
return init(); | ||||
} | ||||
#endif | ||||