[Zope3-checkins]
SVN: Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/
Added C version support for AdapterLookup
Ruslan Spivak
rspivak at nuxeo.com
Tue Aug 2 20:42:41 EDT 2005
Log message for revision 37675:
Added C version support for AdapterLookup
Changed:
A Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_adapter_lookup_coptimizations.c
U Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_interface_coptimizations.c
A Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_interface_coptimizations.h
U Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/adapter.py
-=-
Added: Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_adapter_lookup_coptimizations.c
===================================================================
--- Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_adapter_lookup_coptimizations.c 2005-08-03 00:19:25 UTC (rev 37674)
+++ Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_adapter_lookup_coptimizations.c 2005-08-03 00:42:41 UTC (rev 37675)
@@ -0,0 +1,1166 @@
+/*###########################################################################
+ #
+ # Copyright (c) 2005 Zope Corporation 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"
+#include "_zope_interface_coptimizations.h"
+
+#define TRUE 1
+#define FALSE 0
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *_registry;
+ PyObject *_surrogateClass;
+ PyObject *_default;
+ PyObject *_null;
+ PyObject *_surrogates;
+ PyObject *_remove;
+} AdapterLookup;
+
+
+static PyObject *strget, *strisOrExtends, *str__sro__, *strindex, *Null;
+
+static int
+AdapterLookup_init(AdapterLookup *self, PyObject *args, PyObject *keywds)
+{
+ PyObject *_registry = NULL, *_surrogates = NULL, *_remove = NULL;
+ PyObject *tmp, *attr;
+
+ if (!PyArg_ParseTuple(args, "OOO", &_registry, &_surrogates, &_remove))
+ return -1;
+
+ if (_registry) {
+ tmp = self->_registry;
+ Py_INCREF(_registry);
+ self->_registry = _registry;
+ Py_XDECREF(tmp);
+
+ tmp = self->_surrogateClass;
+ attr = PyObject_GetAttrString(_registry, "_surrogateClass");
+ self->_surrogateClass = attr;
+ Py_XDECREF(tmp);
+
+ tmp = self->_default;
+ attr = PyObject_GetAttrString(_registry, "_default");
+ self->_default = attr;
+ Py_XDECREF(tmp);
+
+ tmp = self->_null;
+ attr = PyObject_GetAttrString(_registry, "_null");
+ self->_null = attr;
+ Py_XDECREF(tmp);
+ }
+ if (_surrogates) {
+ tmp = self->_surrogates;
+ Py_XINCREF(_surrogates);
+ self->_surrogates = _surrogates;
+ Py_XDECREF(tmp);
+ }
+ if (_remove) {
+ tmp = self->_remove;
+ Py_XINCREF(_remove);
+ self->_remove = _remove;
+ Py_XDECREF(tmp);
+ }
+ return 0;
+}
+
+
+static int
+AdapterLookup_traverse(AdapterLookup *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->_registry);
+ Py_VISIT(self->_surrogateClass);
+ Py_VISIT(self->_default);
+ Py_VISIT(self->_null);
+ Py_VISIT(self->_surrogates);
+ Py_VISIT(self->_remove);
+ return 0;
+}
+
+static int
+AdapterLookup_clear(AdapterLookup *self)
+{
+ Py_CLEAR(self->_registry);
+ Py_CLEAR(self->_surrogateClass);
+ Py_CLEAR(self->_default);
+ Py_CLEAR(self->_null);
+ Py_CLEAR(self->_surrogates);
+ Py_CLEAR(self->_remove);
+ return 0;
+}
+
+static void
+AdapterLookup_dealloc(AdapterLookup *self)
+{
+ AdapterLookup_clear(self);
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+
+
+static PyMemberDef AdapterLookup_members[] = {
+ {"_registry", T_OBJECT_EX, offsetof(AdapterLookup, _registry), 0, ""},
+ {"_surrogateClass", T_OBJECT_EX,
+ offsetof(AdapterLookup, _surrogateClass), 0, ""},
+ {"_default", T_OBJECT_EX, offsetof(AdapterLookup, _default), 0, ""},
+ {"_null", T_OBJECT_EX, offsetof(AdapterLookup, _null), 0, ""},
+ {"_surrogates", T_OBJECT_EX, offsetof(AdapterLookup, _surrogates),
+ 0, ""},
+ {"_remove", T_OBJECT_EX, offsetof(AdapterLookup, _remove), 0, ""},
+ {NULL}
+};
+
+
+
+static PyObject*
+zip(PyObject *args)
+{
+ PyObject *ret;
+ const int itemsize = PySequence_Length(args);
+ int i;
+ PyObject *itlist; /* tuple of iterators */
+ int len; /* guess at result length */
+
+ if (itemsize == 0)
+ return PyList_New(0);
+
+ /* args must be a tuple */
+ assert(PyTuple_Check(args));
+
+ /* Guess at result length: the shortest of the input lengths.
+ If some argument refuses to say, we refuse to guess too, lest
+ an argument like xrange(sys.maxint) lead us astray.*/
+ len = -1; /* unknown */
+ for (i = 0; i < itemsize; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(args, i);
+ int thislen = PyObject_Size(item);
+ if (thislen < 0) {
+ PyErr_Clear();
+ len = -1;
+ break;
+ }
+ else if (len < 0 || thislen < len)
+ len = thislen;
+ }
+
+ /* allocate result list */
+ if (len < 0)
+ len = 10; /* arbitrary */
+ if ((ret = PyList_New(len)) == NULL)
+ return NULL;
+
+ /* obtain iterators */
+ itlist = PyTuple_New(itemsize);
+ if (itlist == NULL)
+ goto Fail_ret;
+ for (i = 0; i < itemsize; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(args, i);
+ PyObject *it = PyObject_GetIter(item);
+ if (it == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError,
+ "zip argument #%d must support iteration",
+ i+1);
+ goto Fail_ret_itlist;
+ }
+ PyTuple_SET_ITEM(itlist, i, it);
+ }
+
+ /* build result into ret list */
+ for (i = 0; ; ++i) {
+ int j;
+ PyObject *next = PyTuple_New(itemsize);
+ if (!next)
+ goto Fail_ret_itlist;
+
+ for (j = 0; j < itemsize; j++) {
+ PyObject *it = PyTuple_GET_ITEM(itlist, j);
+ PyObject *item = PyIter_Next(it);
+ if (!item) {
+ if (PyErr_Occurred()) {
+ Py_DECREF(ret);
+ ret = NULL;
+ }
+ Py_DECREF(next);
+ Py_DECREF(itlist);
+ goto Done;
+ }
+ PyTuple_SET_ITEM(next, j, item);
+ }
+
+ if (i < len)
+ PyList_SET_ITEM(ret, i, next);
+ else {
+ int status = PyList_Append(ret, next);
+ Py_DECREF(next);
+ ++len;
+ if (status < 0)
+ goto Fail_ret_itlist;
+ }
+ }
+
+Done:
+ if (ret != NULL && i < len) {
+ /* The list is too big. */
+ if (PyList_SetSlice(ret, i, len, NULL) < 0)
+ return NULL;
+ }
+ return ret;
+
+Fail_ret_itlist:
+ Py_DECREF(itlist);
+Fail_ret:
+ Py_DECREF(ret);
+ return NULL;
+}
+
+
+static PyObject *
+AdapterLookup_lookup(AdapterLookup *self, PyObject *args, PyObject *keywds)
+{
+ int i, j, k;
+ PyObject *required, *provided;
+ PyObject *name = NULL;
+ PyObject *_default = Py_None;
+ PyObject *surrogate, *byname, *value = NULL;
+
+
+ static char *kwlist[] = {"required", "provided", "name", "default",
+ NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO|OO", kwlist,
+ &required, &provided,
+ &name, &_default))
+ return NULL;
+
+ const int order = PySequence_Length(required);
+
+ if (name == NULL)
+ name = PyString_FromString("");
+ else
+ Py_INCREF(name);
+
+ if (order == 1) {
+ /* Simple adapter */
+ PyObject *req = PySequence_GetItem(required, 0);
+ if (req == NULL)
+ goto on_error;
+ surrogate = PyObject_CallMethodObjArgs((PyObject *)self,
+ strget, req, NULL);
+ Py_DECREF(req);
+ if (surrogate == NULL)
+ goto on_error;
+
+ byname = PyObject_CallMethodObjArgs(surrogate, strget,
+ provided, NULL);
+ Py_XDECREF(surrogate);
+ if (byname == NULL)
+ goto on_error;
+
+ if (byname != Py_None) {
+ value = PyDict_GetItem(byname, name);
+ if (value == NULL)
+ value = Py_None;
+ } else
+ value = Py_None;
+
+ Py_XDECREF(byname);
+
+ if (value == Py_None) {
+ byname = PyObject_CallMethodObjArgs(self->_default,
+ strget,
+ provided, NULL);
+ if (byname == NULL)
+ goto on_error;
+
+ if (byname != Py_None) {
+ value = PyDict_GetItem(byname, name);
+ Py_XDECREF(byname);
+ if (value == NULL)
+ value = _default;
+ } else {
+ Py_XDECREF(byname);
+ Py_XDECREF(name);
+ Py_INCREF(_default);
+ return _default;
+ }
+ }
+
+ Py_XDECREF(name);
+ Py_INCREF(value);
+ return value;
+
+ on_error:
+ Py_XDECREF(name);
+ return NULL;
+
+ } else if (!order) {
+ /* null adapter */
+ byname = PyObject_CallMethodObjArgs(self->_null,
+ strget,
+ provided, NULL);
+ if (byname == NULL) {
+ Py_XDECREF(name);
+ return NULL;
+ }
+
+ if (byname != Py_None) {
+ value = PyDict_GetItem(byname, name);
+ Py_XDECREF(byname);
+ if (value == NULL)
+ value = _default;
+ Py_XDECREF(name);
+ Py_XINCREF(value);
+ return value;
+ }
+
+ Py_XDECREF(byname);
+ Py_XDECREF(name);
+ Py_INCREF(_default);
+ return _default;
+ }
+
+ /* Multi adapter */
+ PyObject *with, *tmp;
+
+ with = PySequence_GetSlice(required, 1, order); /* new reference */
+ if (with == NULL)
+ goto fail_with;
+ PyObject *key = Py_BuildValue("Oi", provided, order);
+
+ PyObject *req = PySequence_GetItem(required, 0);
+ if (req == NULL)
+ goto fail_req;
+
+ surrogate = PyObject_CallMethodObjArgs((PyObject *)self, strget,
+ req, NULL);
+ Py_DECREF(req);
+ if (surrogate == NULL)
+ goto fail_req;
+
+ PyObject *surrogates = Py_BuildValue("OO", surrogate, self->_default);
+ Py_XDECREF(surrogate);
+
+ int surrogates_len = PyTuple_GET_SIZE(surrogates);
+
+ /* for surrogate in self.get(required[0]), self._default: */
+ for (i = 0; i < surrogates_len; i++) {
+ surrogate = PyTuple_GET_ITEM(surrogates, i);
+ byname = PyObject_CallMethodObjArgs(surrogate, strget,
+ key, NULL);
+ if (byname == NULL) {
+ Py_DECREF(surrogates);
+ goto fail_req;
+ }
+
+ if (byname == Py_None) {
+ Py_DECREF(byname);
+ continue;
+ }
+
+ PyObject *bywith = PyDict_GetItem(byname, name);
+ Py_DECREF(byname);
+ if (bywith == NULL)
+ continue;
+
+ PyObject *best = NULL;
+ PyObject *rwith, *value;
+
+ /* for rwith, value in bywith: */
+ int bywith_length = PySequence_Length(bywith);
+ for (j = 0; j < bywith_length; j++) {
+ tmp = PySequence_GetItem(bywith, j);
+ if (!PyArg_ParseTuple(tmp, "OO", &rwith, &value)) {
+ Py_DECREF(tmp);
+ Py_DECREF(surrogates);
+ goto fail_req;
+ }
+ Py_DECREF(tmp);
+
+ PyObject *rank = PyList_New(0);
+
+ tmp = Py_BuildValue("OO", rwith, with);
+ PyObject *seq = zip(tmp);
+ Py_DECREF(tmp);
+
+ int seq_length = PySequence_Length(seq);
+
+ /* for rspec, spec in zip(rwith, with): */
+ for (k = 0; k < seq_length; k++) {
+ PyObject *spec, *rspec;
+
+ tmp = PyList_GET_ITEM(seq, k);
+ rspec = PyTuple_GET_ITEM(tmp, 0);
+ spec = PyTuple_GET_ITEM(tmp, 1);
+
+ PyObject *res;
+ res = PyObject_CallMethodObjArgs(spec,
+ strisOrExtends,
+ rspec,
+ NULL);
+ if (res == NULL) {
+ Py_DECREF(rank);
+ Py_XDECREF(seq);
+ goto fail_req;
+ }
+ if (PyObject_Not(res)) {
+ Py_DECREF(res);
+ goto done;
+ }
+ Py_DECREF(res);
+
+ PyObject *sro = PyObject_GetAttr(spec,
+ str__sro__);
+ PyObject *sro_list = PySequence_List(sro);
+
+ Py_XDECREF(sro);
+
+ PyObject *index;
+ index = PyObject_CallMethodObjArgs(sro_list,
+ strindex,
+ rspec,
+ NULL);
+ Py_XDECREF(sro_list);
+ if (index == NULL) {
+ Py_DECREF(rank);
+ Py_XDECREF(seq);
+ goto fail_req;
+ }
+
+ if (PyList_Append(rank, index) < 0) {
+ Py_XDECREF(index);
+ Py_DECREF(rank);
+ Py_XDECREF(seq);
+ goto fail_req;
+ }
+
+ Py_XDECREF(index);
+ }
+
+ /* rank = tuple(rank)
+ if best is None or rank < best[0]:
+ best = rank, value
+ */
+ tmp = rank;
+ rank = PySequence_Tuple(rank);
+ Py_XDECREF(tmp);
+
+ if (best == NULL ||
+ PyObject_Compare(rank,
+ PyTuple_GET_ITEM(best, 0)) < 0) {
+ Py_XDECREF(best);
+ best = Py_BuildValue("OO", rank, value);
+ }
+ done:
+ Py_XDECREF(seq);
+ Py_XDECREF(rank);
+ }
+ /* if best:
+ return best[1]
+ */
+ if (best != NULL) {
+ tmp = PyTuple_GET_ITEM(best, 1);
+ Py_XINCREF(tmp);
+ Py_XDECREF(best);
+ _default = tmp;
+ goto finish;
+ }
+ }
+
+finish:
+ Py_XDECREF(surrogates);
+ Py_XDECREF(key);
+ Py_XDECREF(with);
+ Py_XDECREF(name);
+ if (_default == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ return _default;
+
+fail_req:
+ Py_DECREF(with);
+fail_with:
+ Py_XDECREF(name);
+ return NULL;
+}
+
+static PyObject *
+AdapterLookup_lookup1(AdapterLookup *self, PyObject *args, PyObject *keywds)
+{
+ PyObject *required, *provided;
+ PyObject *name = NULL;
+ PyObject *_default = Py_None;
+ PyObject *required_list;
+ PyObject *res;
+ PyObject *param_args, *kw;
+
+ static char *kwlist[] = {"required", "provided", "name", "default",
+ NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO|OO", kwlist,
+ &required, &provided,
+ &name, &_default))
+ return NULL;
+
+ if (name == NULL)
+ name = PyString_FromString("");
+ else
+ Py_INCREF(name);
+
+ required_list = Py_BuildValue("[O]", required);
+
+ param_args = Py_BuildValue("OO", required_list, provided);
+ kw = Py_BuildValue("{s:O,s:O}", "name", name, "default", _default);
+ Py_DECREF(required_list);
+
+ res = AdapterLookup_lookup(self, param_args, kw);
+
+ Py_DECREF(kw);
+ Py_DECREF(param_args);
+ Py_XDECREF(name);
+
+ return res;
+}
+
+static PyObject *
+AdapterLookup_adapter_hook(AdapterLookup *self, PyObject *args,
+ PyObject *keywds)
+{
+ PyObject *interface;
+ PyObject *object;
+ PyObject *name = NULL;
+ PyObject *_default = NULL;
+
+ static char *kwlist[] = {"interface", "object", "name", "default",
+ NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO|OO", kwlist,
+ &interface, &object,
+ &name, &_default))
+ return NULL;
+
+ if (name == NULL)
+ name = PyString_FromString("");
+ else
+ Py_INCREF(name);
+
+ /* factory = self.lookup1(providedBy(object), interface, name) */
+ PyObject *required = providedBy(NULL, object);
+ PyObject *lookup_args = Py_BuildValue("OO", required, interface);
+ PyObject *kw = Py_BuildValue("{s:O}", "name", name);
+ Py_DECREF(required);
+
+ PyObject *factory = AdapterLookup_lookup1(self, lookup_args, kw);
+ Py_DECREF(lookup_args);
+ Py_DECREF(kw);
+
+ /*
+ if factory is not None:
+ adapter = factory(object)
+ if adapter is not None:
+ return adapter
+ return default
+ */
+ if (factory != Py_None) {
+ PyObject *params = Py_BuildValue("(O)", object);
+ PyObject *adapter = PyObject_CallObject(factory, params);
+ Py_DECREF(params);
+ if (adapter == NULL) {
+ Py_DECREF(factory);
+ Py_XDECREF(name);
+ return NULL;
+ }
+ if (adapter != Py_None) {
+ Py_DECREF(factory);
+ Py_XDECREF(name);
+ return adapter;
+ }
+ }
+ Py_XDECREF(factory);
+ if (_default == NULL) {
+ Py_XDECREF(name);
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ Py_XDECREF(name);
+ Py_INCREF(_default);
+ return _default;
+}
+
+static PyObject *
+AdapterLookup_queryAdapter(AdapterLookup *self, PyObject *args,
+ PyObject *keywds)
+{
+ PyObject *interface;
+ PyObject *object;
+ PyObject *name = NULL;
+ PyObject *_default = Py_None;
+
+ static char *kwlist[] = {"object", "interface", "name", "default",
+ NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO|OO", kwlist,
+ &object, &interface,
+ &name, &_default))
+ return NULL;
+
+ if (name == NULL)
+ name = PyString_FromString("");
+ else
+ Py_INCREF(name);
+
+ PyObject *params = Py_BuildValue("OO", interface, object);
+ PyObject *kw = Py_BuildValue("{s:O,s:O}", "name", name,
+ "default", _default);
+ PyObject *result = AdapterLookup_adapter_hook(self, params, kw);
+ Py_DECREF(kw);
+ Py_DECREF(params);
+ Py_XDECREF(name);
+ return result;
+}
+
+static PyObject *
+AdapterLookup_subscriptions(AdapterLookup* self, PyObject *args)
+{
+ int i, j, k;
+ PyObject *required, *provided;
+ PyObject *surrogate, *result, *tmp;
+
+ if (!PyArg_ParseTuple(args, "OO", &required, &provided))
+ return NULL;
+
+ if (provided == Py_None)
+ provided = Null;
+
+ const int order = PySequence_Length(required);
+
+
+ if (order == 1) {
+ /* Simple subscriptions */
+ PyObject *req = PySequence_GetItem(required, 0);
+ if (req == NULL)
+ return NULL;
+ surrogate = PyObject_CallMethodObjArgs((PyObject *)self,
+ strget, req, NULL);
+ Py_DECREF(req);
+
+ PyObject *params = Py_BuildValue("sO", "s", provided);
+
+ /*
+ result = s.get(('s', provided))
+ if result:
+ result = list(result)
+ else:
+ result = []
+ */
+ result = PyObject_CallMethodObjArgs(surrogate, strget,
+ params, NULL);
+ Py_DECREF(surrogate);
+
+ if (result == NULL) {
+ Py_DECREF(params);
+ return NULL;
+ }
+
+ if (result != Py_None) {
+ tmp = result;
+ result = PySequence_List(result);
+ Py_XDECREF(tmp);
+ } else {
+ Py_DECREF(result);
+ result = PyList_New(0);
+ }
+
+ PyObject *_default;
+ _default = PyObject_CallMethodObjArgs(self->_default,
+ strget,
+ params, NULL);
+ Py_DECREF(params);
+ if (_default == NULL) {
+ Py_DECREF(result);
+ }
+
+ /*
+ if default:
+ result.extend(default)
+
+ return result
+ */
+ if (_default != Py_None) {
+ int len = PyList_GET_SIZE(result);
+ int status;
+ status = PyList_SetSlice(result, len, len, _default);
+
+ if (status < 0) {
+ Py_DECREF(_default);
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ Py_DECREF(_default);
+ return result;
+
+ } else if (!order) {
+ /*
+ result = self._null.get(('s', provided))
+ if result:
+ return list(result)
+ else:
+ return []
+ */
+ PyObject *params = Py_BuildValue("sO", "s", provided);
+
+ result = PyObject_CallMethodObjArgs(self->_null,
+ strget,
+ params, NULL);
+ Py_DECREF(params);
+
+ if (result == NULL)
+ return NULL;
+
+ if (result != Py_None) {
+ tmp = result;
+ result = PySequence_List(result);
+ Py_XDECREF(tmp);
+ return result;
+ }
+ Py_DECREF(result);
+ return PyList_New(0);
+ }
+
+ /* Multi */
+ PyObject *surrogates = NULL;
+ PyObject *with = PySequence_GetSlice(required, 1, order);
+ if (with == NULL)
+ return NULL;
+
+ PyObject *key = Py_BuildValue("sOi", "s", provided, order);
+
+ PyObject *req = PySequence_GetItem(required, 0);
+ if (req == NULL)
+ goto on_error;
+
+ surrogate = PyObject_CallMethodObjArgs((PyObject *)self,
+ strget, req, NULL);
+ Py_DECREF(req);
+ if (surrogate == NULL)
+ goto on_error;
+
+ surrogates = Py_BuildValue("OO", surrogate, self->_default);
+ Py_XDECREF(surrogate);
+ int surrogates_len = PyTuple_GET_SIZE(surrogates);
+
+ result = PyList_New(0);
+
+ /* for surrogate in self.get(required[0]), self._default: */
+ for (i = 0; i < surrogates_len; i++) {
+ surrogate = PySequence_GetItem(surrogates, i);
+ PyObject *bywith = PyObject_CallMethodObjArgs(surrogate,
+ strget,
+ key, NULL);
+ Py_DECREF(surrogate);
+ if (bywith == NULL)
+ goto on_error;
+
+ if (PyObject_Not(bywith)) {
+ Py_DECREF(bywith);
+ continue;
+ }
+
+ PyObject *rwith, *values;
+
+ /* for rwith, values in bywith: */
+ int bywith_length = PySequence_Length(bywith);
+ for (j = 0; j < bywith_length; j++) {
+ tmp = PySequence_GetItem(bywith, j);
+ if (!PyArg_ParseTuple(tmp, "OO", &rwith, &values)) {
+ Py_XDECREF(tmp);
+ Py_XDECREF(bywith);
+ goto on_error;
+ }
+ Py_DECREF(tmp);
+
+ tmp = Py_BuildValue("OO", rwith, with);
+ PyObject *seq = zip(tmp);
+ Py_DECREF(tmp);
+
+ int seq_length = PySequence_Length(seq);
+
+ int spec_extends = TRUE;
+ /* for rspec, spec in zip(rwith, with): */
+ for (k = 0; k < seq_length; k++) {
+ PyObject *spec, *rspec;
+
+ tmp = PyList_GET_ITEM(seq, k);
+
+ rspec = PyTuple_GET_ITEM(tmp, 0);
+ spec = PyTuple_GET_ITEM(tmp, 1);
+
+ PyObject *res;
+ res = PyObject_CallMethodObjArgs(spec,
+ strisOrExtends,
+ rspec,
+ NULL);
+
+ if (res == NULL) {
+ Py_XDECREF(seq);
+ Py_XDECREF(bywith);
+ goto on_error;
+ }
+ if (PyObject_Not(res)) {
+ spec_extends = FALSE;
+ Py_DECREF(res);
+ break;
+ }
+ Py_DECREF(res);
+ }
+ if (spec_extends) {
+ /* result.extend(values) */
+ int len = PyList_GET_SIZE(result);
+ if (PyList_SetSlice(result, len, len,
+ values) < 0)
+ goto on_error;
+ }
+ Py_XDECREF(seq);
+ }
+ Py_XDECREF(bywith);
+ }
+
+ Py_XDECREF(surrogates);
+ Py_XDECREF(key);
+ Py_XDECREF(with);
+ return result;
+
+on_error:
+ Py_DECREF(result);
+ Py_XDECREF(surrogates);
+ Py_XDECREF(key);
+ Py_XDECREF(with);
+ return NULL;
+}
+
+
+static PyObject *
+AdapterLookup_queryMultiAdapter(AdapterLookup* self, PyObject *args,
+ PyObject *keywds)
+{
+ PyObject *interface;
+ PyObject *objects;
+ PyObject *name = NULL;
+ PyObject *_default = Py_None;
+ PyObject *tmp;
+ int nobjects;
+ int i;
+
+ static char *kwlist[] = {"object", "interface", "name", "default",
+ NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO|OO", kwlist,
+ &objects, &interface,
+ &name, &_default))
+ return NULL;
+
+ nobjects = PySequence_Length(objects);
+
+ if (name == NULL)
+ name = PyString_FromString("");
+ else
+ Py_INCREF(name);
+
+ /* factory = self.lookup(map(providedBy, objects), interface, name) */
+ PyObject *required = PyList_New(nobjects);
+ for (i = 0; i < nobjects; i++) {
+ tmp = PySequence_GetItem(objects, i);
+ PyList_SetItem(required, i, providedBy(NULL, tmp));
+ Py_DECREF(tmp);
+ }
+
+ PyObject *lookup_args = Py_BuildValue("OO", required, interface);
+ PyObject *kw = Py_BuildValue("{s:O}", "name", name);
+ Py_DECREF(required);
+
+ PyObject *factory = AdapterLookup_lookup(self, lookup_args, kw);
+ Py_DECREF(kw);
+ Py_DECREF(lookup_args);
+
+ /*
+ if factory is not None:
+ return factory(*objects)
+ return default
+ */
+ if (factory != Py_None) {
+ objects = PySequence_Tuple(objects);
+ PyObject *result = PyObject_CallObject(factory, objects);
+ Py_DECREF(objects);
+ Py_DECREF(factory);
+ Py_XDECREF(name);
+ return result;
+ }
+
+ Py_DECREF(factory);
+ Py_XDECREF(name);
+
+ Py_INCREF(_default);
+ return _default;
+}
+
+static PyObject *
+AdapterLookup_subscribers(AdapterLookup *self, PyObject *args)
+{
+ PyObject *interface;
+ PyObject *objects;
+ PyObject *tmp;
+ int nobjects;
+ int i;
+
+ if (!PyArg_ParseTuple(args, "OO", &objects, &interface))
+ return NULL;
+
+ nobjects = PySequence_Length(objects);
+
+ PyObject *required = PyList_New(nobjects);
+ for (i = 0; i < nobjects; i++) {
+ tmp = PySequence_GetItem(objects, i);
+ PyList_SetItem(required, i, providedBy(NULL, tmp));
+ Py_DECREF(tmp);
+ }
+
+ PyObject *subs_args = Py_BuildValue("OO", required, interface);
+ Py_DECREF(required);
+
+ PyObject *subscriptions = AdapterLookup_subscriptions(self, subs_args);
+ Py_DECREF(subs_args);
+
+ if (subscriptions == NULL)
+ return NULL;
+
+ PyObject *it = PyObject_GetIter(subscriptions);
+ PyObject *item;
+
+ if (it == NULL)
+ goto on_error;
+
+ /*
+ subscribers = [subscription(*objects)
+ for subscription in subscriptions]
+ */
+ PyObject *subscribers = PyList_New(0);
+ while (item = PyIter_Next(it)) {
+ /* make sure we pass tuple as argument list to method call */
+ PyObject *objects_tuple = PySequence_Tuple(objects);
+ tmp = PyObject_CallObject(item, objects_tuple);
+ Py_DECREF(objects_tuple);
+ if (tmp == NULL) {
+ Py_DECREF(item);
+ Py_DECREF(it);
+ goto on_error;
+ }
+ PyList_Append(subscribers, tmp);
+ Py_DECREF(tmp);
+ Py_DECREF(item);
+ }
+
+ Py_DECREF(it);
+
+ if (PyErr_Occurred()) {
+ Py_XDECREF(subscribers);
+ goto on_error;
+ }
+
+ it = PyObject_GetIter(subscribers);
+ if (it == NULL) {
+ Py_XDECREF(subscribers);
+ goto on_error;
+ }
+
+ PyObject *result = PyList_New(0);
+ while (item = PyIter_Next(it)) {
+ if (item != Py_None)
+ PyList_Append(result, item);
+ Py_DECREF(item);
+ }
+
+ Py_DECREF(it);
+
+ if (PyErr_Occurred()) {
+ Py_XDECREF(result);
+ Py_XDECREF(subscribers);
+ goto on_error;
+ }
+
+ Py_XDECREF(subscriptions);
+ return result;
+
+on_error:
+ Py_XDECREF(subscriptions);
+ return NULL;
+
+}
+
+static PyObject *
+AdapterLookup_get(AdapterLookup *self, PyObject *args)
+{
+ PyObject *decl = NULL, *ref, *surrogate, *init_args;
+
+ if (!PyArg_ParseTuple(args, "O", &decl))
+ return NULL;
+
+ if (decl == Py_None) {
+ Py_INCREF(self->_default);
+ return self->_default;
+ }
+
+ ref = PyObject_CallMethod(decl, "weakref", "O", self->_remove);
+
+ if (ref == NULL)
+ return NULL;
+
+ surrogate = PyDict_GetItem(self->_surrogates, ref);
+ /* no ref key in dictionary */
+ if (surrogate == NULL || surrogate == Py_None) {
+ init_args = Py_BuildValue("OO", decl, self->_registry);
+
+ surrogate = PyObject_CallObject(self->_surrogateClass,
+ init_args);
+ if (surrogate == NULL) {
+ Py_DECREF(init_args);
+ Py_XDECREF(ref);
+ return NULL;
+ }
+ PyDict_SetItem(self->_surrogates, ref, surrogate);
+
+ Py_DECREF(init_args);
+ Py_XDECREF(ref);
+ return surrogate;
+ }
+
+ Py_XDECREF(ref);
+ Py_INCREF(surrogate);
+ return surrogate;
+}
+
+static PyMethodDef AdapterLookup_methods[] = {
+ {"lookup", (PyCFunction)AdapterLookup_lookup,
+ METH_VARARGS | METH_KEYWORDS, ""},
+ {"lookup1", (PyCFunction)AdapterLookup_lookup1,
+ METH_VARARGS | METH_KEYWORDS, ""},
+ {"adapter_hook", (PyCFunction)AdapterLookup_adapter_hook,
+ METH_VARARGS | METH_KEYWORDS, ""},
+ {"queryAdapter", (PyCFunction)AdapterLookup_queryAdapter,
+ METH_VARARGS | METH_KEYWORDS, ""},
+ {"subscriptions", (PyCFunction)AdapterLookup_subscriptions,
+ METH_VARARGS, ""},
+ {"queryMultiAdapter", (PyCFunction)AdapterLookup_queryMultiAdapter,
+ METH_VARARGS | METH_KEYWORDS, ""},
+ {"subscribers", (PyCFunction)AdapterLookup_subscribers,
+ METH_VARARGS, ""},
+ {"get", (PyCFunction)AdapterLookup_get, METH_VARARGS, ""},
+ {NULL} /* Sentinel */
+};
+
+
+static PyTypeObject AdapterLookupType = {
+ PyObject_HEAD_INIT(NULL)
+ /* ob_size */ 0,
+ /* tp_name */ "_adapter_lookup_coptimizations."
+ "AdapterLookup",
+ /* tp_basicsize */ sizeof(AdapterLookup),
+ /* tp_itemsize */ 0,
+ /* tp_dealloc */ (destructor)AdapterLookup_dealloc,
+ /* tp_print */ (printfunc)0,
+ /* tp_getattr */ (getattrfunc)0,
+ /* tp_setattr */ (setattrfunc)0,
+ /* tp_compare */ (cmpfunc)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,
+ "C class for AdapterLookup",
+ /* tp_traverse */ (traverseproc)AdapterLookup_traverse,
+ /* tp_clear */ (inquiry)AdapterLookup_clear,
+ /* tp_richcompare */ (richcmpfunc)0,
+ /* tp_weaklistoffset */ (long)0,
+ /* tp_iter */ (getiterfunc)0,
+ /* tp_iternext */ (iternextfunc)0,
+ /* tp_methods */ AdapterLookup_methods,
+ /* tp_members */ AdapterLookup_members,
+ /* tp_getset */ 0,
+ /* tp_base */ 0,
+ /* tp_dict */ 0, /* internal use */
+ /* tp_descr_get */ (descrgetfunc)0,
+ /* tp_descr_set */ (descrsetfunc)0,
+ /* tp_dictoffset */ 0,
+ /* tp_init */ (initproc)AdapterLookup_init,
+};
+
+
+static struct PyMethodDef m_methods[] = {
+ {NULL} /* Sentinel */
+};
+
+#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+init_zope_adapter_lookup_coptimizations(void)
+{
+ PyObject *m;
+
+#define DEFINE_STRING(s) \
+if (!(str##s = PyString_FromString(#s))) return
+ DEFINE_STRING(get);
+ DEFINE_STRING(isOrExtends);
+ DEFINE_STRING(__sro__);
+ DEFINE_STRING(index);
+#undef DEFINE_STRING
+
+ /* Initialize types: */
+ AdapterLookupType.tp_new = PyType_GenericNew;
+ if (PyType_Ready(&AdapterLookupType) < 0)
+ return;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule3("_zope_adapter_lookup_coptimizations", m_methods,
+ "C optimizations for "
+ "zope.interface.adapter.AdapterLookup\n\n"
+ "$Id$");
+ if (m == NULL)
+ return;
+
+ if (import_zope_interface_coptimizations() < 0)
+ return;
+
+ PyObject *adapter = PyImport_ImportModule("zope.interface.adapter");
+ if (adapter == NULL)
+ return;
+
+ Null = PyObject_GetAttrString(adapter, "Null");
+ Py_DECREF(adapter);
+
+ if (Null == NULL)
+ return;
+
+ /* Add types: */
+ Py_INCREF(&AdapterLookupType);
+ if (PyModule_AddObject(m, "AdapterLookup",
+ (PyObject *)&AdapterLookupType) < 0)
+ return;
+}
Property changes on: Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_adapter_lookup_coptimizations.c
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_interface_coptimizations.c
===================================================================
--- Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_interface_coptimizations.c 2005-08-03 00:19:25 UTC (rev 37674)
+++ Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_interface_coptimizations.c 2005-08-03 00:42:41 UTC (rev 37675)
@@ -15,6 +15,9 @@
#include "Python.h"
#include "structmember.h"
+#define _ZOPE_INTERFACE_COPTIMIZATIONS
+#include "_zope_interface_coptimizations.h"
+
#define TYPE(O) ((PyTypeObject*)(O))
#define OBJECT(O) ((PyObject*)(O))
#define CLASSIC(O) ((PyClassObject*)(O))
@@ -27,7 +30,7 @@
static int imported_declarations = 0;
-static int
+static int
import_declarations(void)
{
PyObject *declarations, *i;
@@ -35,7 +38,7 @@
declarations = PyImport_ImportModule("zope.interface.declarations");
if (declarations == NULL)
return -1;
-
+
BuiltinImplementationSpecifications = PyObject_GetAttrString(
declarations, "BuiltinImplementationSpecifications");
if (BuiltinImplementationSpecifications == NULL)
@@ -57,7 +60,7 @@
if (! PyType_Check(i))
{
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_TypeError,
"zope.declarations.Implements is not a type");
return -1;
}
@@ -126,7 +129,7 @@
/* Maybe we have a builtin */
if (imported_declarations == 0 && import_declarations() < 0)
return NULL;
-
+
spec = PyDict_GetItem(BuiltinImplementationSpecifications, cls);
if (spec != NULL)
{
@@ -170,13 +173,13 @@
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
@@ -185,7 +188,7 @@
*/
if (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
@@ -200,13 +203,13 @@
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)
@@ -251,7 +254,7 @@
static PyObject *
Spec_extends(PyObject *self, PyObject *other)
-{
+{
PyObject *implied;
implied = inst_attr(self, str_implied);
@@ -271,11 +274,11 @@
#endif
}
-static char Spec_extends__doc__[] =
+static char Spec_extends__doc__[] =
"Test whether a specification is or extends another"
;
-static char Spec_providedBy__doc__[] =
+static char Spec_providedBy__doc__[] =
"Test whether an interface is implemented by the specification"
;
@@ -292,7 +295,7 @@
item = Spec_extends(decl, self);
else
/* decl is probably a security proxy. We have to go the long way
- around.
+ around.
*/
item = PyObject_CallMethodObjArgs(decl, strisOrExtends, self, NULL);
@@ -301,7 +304,7 @@
}
-static char Spec_implementedBy__doc__[] =
+static char Spec_implementedBy__doc__[] =
"Test whether the specification is implemented by instances of a class"
;
@@ -313,7 +316,7 @@
decl = implementedBy(NULL, cls);
if (decl == NULL)
return NULL;
-
+
if (PyObject_TypeCheck(decl, &SpecType))
item = Spec_extends(decl, self);
else
@@ -324,10 +327,10 @@
}
static struct PyMethodDef Spec_methods[] = {
- {"providedBy",
+ {"providedBy",
(PyCFunction)Spec_providedBy, METH_O,
Spec_providedBy__doc__},
- {"implementedBy",
+ {"implementedBy",
(PyCFunction)Spec_implementedBy, METH_O,
Spec_implementedBy__doc__},
{"isOrExtends", (PyCFunction)Spec_extends, METH_O,
@@ -444,7 +447,7 @@
Py_XINCREF(implements);
return implements;
}
-
+
PyErr_SetObject(PyExc_AttributeError, str__provides__);
return NULL;
}
@@ -495,7 +498,7 @@
"Get an object's interfaces (internal api)"},
{"providedBy", (PyCFunction)providedBy, METH_O,
"Get an object's interfaces"},
-
+
{NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
};
@@ -506,6 +509,8 @@
init_zope_interface_coptimizations(void)
{
PyObject *m;
+ static void *Interface_API[Interface_API_pointers];
+ PyObject *c_api_object;
#define DEFINE_STRING(S) \
if(! (str ## S = PyString_FromString(# S))) return
@@ -521,8 +526,8 @@
DEFINE_STRING(_implements);
DEFINE_STRING(_cls);
#undef DEFINE_STRING
-
-
+
+
/* Initialize types: */
SpecType.tp_new = PyBaseObject_Type.tp_new;
if (PyType_Ready(&SpecType) < 0)
@@ -533,21 +538,29 @@
CPBType.tp_new = PyBaseObject_Type.tp_new;
if (PyType_Ready(&CPBType) < 0)
return;
-
+
/* Create the module and add the functions */
m = Py_InitModule3("_zope_interface_coptimizations", m_methods,
"C optimizations for zope.interface\n\n"
- "$Id$");
+ "$Id$");
if (m == NULL)
return;
-
+
/* Add types: */
if (PyModule_AddObject(m, "SpecificationBase", (PyObject *)&SpecType) < 0)
return;
- if (PyModule_AddObject(m, "ObjectSpecificationDescriptor",
+ if (PyModule_AddObject(m, "ObjectSpecificationDescriptor",
(PyObject *)&OSDType) < 0)
return;
if (PyModule_AddObject(m, "ClassProvidesBase", (PyObject *)&CPBType) < 0)
return;
+
+ /* Initialize the C API pointer array */
+ Interface_API[providedBy_NUM] = (void *)providedBy;
+
+ /* Create a CObject containing the API pointer array's address */
+ c_api_object= PyCObject_FromVoidPtr((void *)Interface_API, NULL);
+
+ if (c_api_object)
+ PyModule_AddObject(m, "_C_API", c_api_object);
}
-
Added: Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_interface_coptimizations.h
===================================================================
--- Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_interface_coptimizations.h 2005-08-03 00:19:25 UTC (rev 37674)
+++ Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_interface_coptimizations.h 2005-08-03 00:42:41 UTC (rev 37675)
@@ -0,0 +1,76 @@
+/*###########################################################################
+ #
+ # Copyright (c) 2005 Zope Corporation 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.
+ #
+ ############################################################################*/
+
+/*
+ $Id$
+*/
+#ifndef Py_ZOPE_INTERFACE_COPTIMIZATIONS_H
+#define Py_ZOPE_INTERFACE_COPTIMIZATIONS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* C API functions */
+#define providedBy_NUM 0
+#define providedBy_RETURN PyObject *
+#define providedBy_PROTO (PyObject *ignored, PyObject *ob)
+
+/* Total number of C API pointers */
+#define Interface_API_pointers 1
+
+
+#ifdef _ZOPE_INTERFACE_COPTIMIZATIONS
+/* This section is used when compiling _zope_interface_coptimizations.c */
+
+static providedBy_RETURN providedBy providedBy_PROTO;
+
+#else
+/* This section is used in modules that uses
+ _zope_interface_coptimizations's API
+*/
+
+static void **Interface_API;
+
+#define providedBy \
+ (*(providedBy_RETURN (*)providedBy_PROTO) Interface_API[providedBy_NUM])
+
+/* Return -1 and set exception on error, 0 on success. */
+static int
+import_zope_interface_coptimizations(void)
+{
+ PyObject *module;
+ module = PyImport_ImportModule("_zope_interface_coptimizations");
+
+ if (module != NULL) {
+ PyObject *c_api_object = PyObject_GetAttrString(module,
+ "_C_API");
+ if (c_api_object == NULL)
+ return -1;
+ if (PyCObject_Check(c_api_object))
+ Interface_API = \
+ (void **)PyCObject_AsVoidPtr(c_api_object);
+ Py_DECREF(c_api_object);
+ }
+ return 0;
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+
+#endif
+
+#endif /* !defined(Py_ZOPE_INTERFACE_COPTIMIZATIONS_H) */
Property changes on: Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/_zope_interface_coptimizations.h
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/adapter.py
===================================================================
--- Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/adapter.py 2005-08-03 00:19:25 UTC (rev 37674)
+++ Zope3/branches/alienoid-adapter_lookup_coptimizations/src/zope/interface/adapter.py 2005-08-03 00:42:41 UTC (rev 37675)
@@ -46,7 +46,7 @@
# subscription adapters.
# 'with' is a tuple of specs that is non-empty only in the case
-# of multi-adapters.
+# of multi-adapters.
# 'name' is a unicode adapter name. Unnamed adapters have an empty
# name.
@@ -172,7 +172,7 @@
# override less-specific data.
ancestors.reverse()
for ancestor in ancestors:
-
+
for key, v in ancestor.selfImplied.iteritems():
# key is specification or ('s', specification)
@@ -184,7 +184,7 @@
oldbyname = implied.get(key)
if not oldbyname:
implied[key] = oldbyname = {}
-
+
# v is name -> object
oldbyname.update(v)
@@ -196,11 +196,11 @@
oldwithobs = implied.get(key)
if not oldwithobs:
oldwithobs = implied[key] = {}
-
+
# v is {with -> tuple([object])}
for with, objects in v.iteritems():
oldwithobs[with] = oldwithobs.get(with, ()) + objects
-
+
else:
oldbyname = implied.get(key)
if not oldbyname:
@@ -274,7 +274,7 @@
def _subscriptionAdaptTo(self, specification, object, with=()):
if object is None:
- raise TypeError, ("Unregistering subscription adapters"
+ raise TypeError, ("Unregistering subscription adapters"
" isn't implemented")
key = (True, tuple(with), '', specification)
@@ -301,10 +301,10 @@
break
else:
withs.append((with, value))
-
+
return withs
-
+
def withextends(with1, with2):
for spec1, spec2 in zip(with1, with2):
if spec1.extends(spec2):
@@ -349,7 +349,7 @@
value = byname.get(name, default)
else:
return default
-
+
return value
elif order == 0:
@@ -391,7 +391,7 @@
rank.append(list(spec.__sro__).index(rspec))
else:
# If the new rank is better than the best previously
- # recorded one, make the new adapter the best one found.
+ # recorded one, make the new adapter the best one found.
rank = tuple(rank)
if best is None or rank < best[0]:
best = rank, value
@@ -443,7 +443,7 @@
default = self._default.get(('s', provided))
if default:
result.extend(default)
-
+
return result
elif order == 0:
@@ -452,12 +452,12 @@
return list(result)
else:
return []
-
+
# Multi
key = 's', provided, order
with = required[1:]
result = []
-
+
for surrogate in self.get(required[0]), self._default:
bywith = surrogate.get(key)
if not bywith:
@@ -473,8 +473,8 @@
return result
-
+
def queryMultiAdapter(self, objects, interface, name='', default=None):
factory = self.lookup(map(providedBy, objects), interface, name)
if factory is not None:
@@ -502,6 +502,12 @@
return surrogate
+try:
+ from _zope_adapter_lookup_coptimizations import AdapterLookup
+except ImportError:
+ pass
+
+
class AdapterRegistry(object):
"""Adapter registry
"""
@@ -527,7 +533,7 @@
except KeyError:
pass
lookup = AdapterLookup(self, surrogates, _remove)
-
+
for name in ('lookup', 'lookup1', 'queryAdapter', 'get',
'adapter_hook', 'subscriptions',
'queryMultiAdapter', 'subscribers',
@@ -546,7 +552,7 @@
else:
with = ()
required = self._null
-
+
if not isinstance(name, basestring):
raise TypeError("The name provided to provideAdapter "
"must be a string or unicode")
@@ -629,7 +635,7 @@
if provided is None:
provided = Null
-
+
required._subscriptionAdaptTo(provided, value, with)
def mextends(with, rwith):
@@ -679,7 +685,7 @@
def _add_named_adapter(target, provided, name, implied,
registered, value):
-
+
ikey = target
rkey = target, name
@@ -711,7 +717,7 @@
if not bywith:
bywith = byname[name] = {}
-
+
rkey = ikey, name, with # The full key has all 4
if (with not in bywith
or
@@ -730,7 +736,7 @@
def _add_named_sub_adapter(target, implied, objects):
key = ('s', target)
implied[key] = implied.get(key, ()) + objects
-
+
for b in target.__bases__:
_add_named_sub_adapter(b, implied, objects)
More information about the Zope3-Checkins
mailing list