[Zope3-checkins] CVS: Zope3/src/zope/interface -
_zope_interface_coptimizations.c:1.2 ro.py:1.2
__init__.py:1.10 _flatten.py:1.7 adapter.py:1.7
declarations.py:1.18 document.py:1.5 implementor.py:1.7
interface.py:1.15 interfaces.py:1.17 type.py:1.11
_zope_interface_ospec.c:NONE
Jim Fulton
cvs-admin at zope.org
Fri Nov 21 12:12:14 EST 2003
Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv31759/src/zope/interface
Modified Files:
__init__.py _flatten.py adapter.py declarations.py document.py
implementor.py interface.py interfaces.py type.py
Added Files:
_zope_interface_coptimizations.c ro.py
Removed Files:
_zope_interface_ospec.c
Log Message:
Refactored interfaces to use more efficient structures internally to
track relationships between interfaces. Interfaces now maintain a
mapping with keys for all of the interfaces they extend. This allows
questions like "Does this interface extend another" to be anwered much
more quickly.
Unified interfaces and declarations into "specifications". Like
interfaces, declarations also keep track of the specifications they
extend.
Class implementation declarations now have bases that include the
interfaces declared for them directly as well as declarations for base
classes.
Similarly, instance declarations now have, as one of their bases, the
declarations for their classes.
=== Zope3/src/zope/interface/_zope_interface_coptimizations.c 1.1 => 1.2 ===
--- /dev/null Fri Nov 21 12:12:14 2003
+++ Zope3/src/zope/interface/_zope_interface_coptimizations.c Fri Nov 21 12:11:43 2003
@@ -0,0 +1,504 @@
+/*
+
+ Copyright (c) 2003 Zope Corporation and Contributors.
+ All Rights Reserved.
+
+ This software is subject to the provisions of the Zope Public License,
+ Version 2.0 (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))
+
+static PyObject *str__dict__, *str__implements__, *strextends;
+static PyObject *BuiltinImplementationSpecifications, *str__provides__;
+static PyObject *str__class__, *str__providedBy__, *strisOrExtends;
+static PyObject *empty, *fallback, *str_implied, *str_cls, *str_implements;
+static PyTypeObject *Implements;
+
+static int imported_declarations = 0;
+
+static int
+import_declarations(void)
+{
+ PyObject *declarations, *i;
+
+ declarations = PyImport_ImportModule("zope.interface.declarations");
+ 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.declarations.Implements is not a type");
+ return -1;
+ }
+
+ Implements = (PyTypeObject *)i;
+
+ Py_DECREF(declarations);
+
+ imported_declarations = 1;
+ return 0;
+}
+
+extern 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__implements__);
+ 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)
+ 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;
+
+ result = PyObject_GetAttr(ob, str__providedBy__);
+ if (result != NULL)
+ {
+ /* 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_HasAttr(result, strextends))
+ return result;
+ Py_DECREF(result);
+ }
+
+ PyErr_Clear();
+
+ return getObjectSpecification(NULL, ob);
+}
+
+static PyObject *
+inst_attr(PyObject *self, PyObject *name)
+{
+ /* Get an attribute from an inst dict. Return a borrowed reference.
+ */
+
+ 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 implied;
+
+#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_isImplementedBy__doc__[] =
+"Test whether an interface is implemented by the specification"
+;
+
+static PyObject *
+Spec_isImplementedBy(PyObject *self, PyObject *ob)
+{
+ PyObject *decl, *item;
+
+ decl = providedBy(NULL, ob);
+
+ if (PyObject_TypeCheck(ob, &SpecType))
+ item = Spec_extends(decl, self);
+ else
+ /* decl is probably a security proxy. We have to go the long way
+ around.
+ */
+ item = PyObject_CallMethodObjArgs(decl, strisOrExtends, self, NULL);
+
+ Py_DECREF(decl);
+ return item;
+}
+
+
+static char Spec_isImplementedByInstancesOf__doc__[] =
+"Test whether the specification is implemented by instances of a class"
+;
+
+static PyObject *
+Spec_isImplementedByInstancesOf(PyObject *self, PyObject *cls)
+{
+ PyObject *decl, *item;
+
+ decl = implementedBy(NULL, cls);
+
+ if (PyObject_TypeCheck(decl, &SpecType))
+ item = Spec_extends(decl, self);
+ else
+ item = PyObject_CallMethodObjArgs(decl, strisOrExtends, self, NULL);
+
+ Py_DECREF(decl);
+ return item;
+}
+
+static struct PyMethodDef Spec_methods[] = {
+ {"isImplementedBy",
+ (PyCFunction)Spec_isImplementedBy, METH_O,
+ Spec_isImplementedBy__doc__},
+ {"isImplementedByInstancesOf",
+ (PyCFunction)Spec_isImplementedByInstancesOf, METH_O,
+ Spec_isImplementedByInstancesOf__doc__},
+ {"isOrExtends", (PyCFunction)Spec_extends, METH_O,
+ Spec_extends__doc__},
+
+ {NULL, NULL} /* sentinel */
+};
+
+static PyTypeObject SpecType = {
+ PyObject_HEAD_INIT(NULL)
+ /* ob_size */ 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 */ (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,
+ "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 = {
+ PyObject_HEAD_INIT(NULL)
+ /* ob_size */ 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 */ (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 ,
+ "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 = {
+ PyObject_HEAD_INIT(NULL)
+ /* ob_size */ 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 */ (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,
+ "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,
+};
+
+
+static struct PyMethodDef m_methods[] = {
+ {"implementedBy", (PyCFunction)implementedBy, METH_O,
+ "Interfaces implemented by instances of a class"},
+ {"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 */
+};
+
+#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+init_zope_interface_coptimizations(void)
+{
+ PyObject *m;
+
+#define DEFINE_STRING(S) \
+ if(! (str ## S = PyString_FromString(# S))) return
+
+ DEFINE_STRING(__dict__);
+ DEFINE_STRING(__implements__);
+ DEFINE_STRING(__provides__);
+ DEFINE_STRING(__class__);
+ DEFINE_STRING(__providedBy__);
+ DEFINE_STRING(isOrExtends);
+ DEFINE_STRING(extends);
+ DEFINE_STRING(_implied);
+ DEFINE_STRING(_implements);
+ DEFINE_STRING(_cls);
+#undef DEFINE_STRING
+
+
+ /* Initialize types: */
+ SpecType.tp_new = PyType_GenericNew;
+ if (PyType_Ready(&SpecType) < 0)
+ return;
+ OSDType.tp_new = PyType_GenericNew;
+ if (PyType_Ready(&OSDType) < 0)
+ return;
+ CPBType.tp_new = PyType_GenericNew;
+ 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$");
+ if (m == NULL)
+ return;
+
+ /* Add types: */
+ if (PyModule_AddObject(m, "SpecificationBase", (PyObject *)&SpecType) < 0)
+ return;
+ if (PyModule_AddObject(m, "ObjectSpecificationDescriptor",
+ (PyObject *)&OSDType) < 0)
+ return;
+ if (PyModule_AddObject(m, "ClassProvidesBase", (PyObject *)&CPBType) < 0)
+ return;
+}
+
=== Zope3/src/zope/interface/ro.py 1.1 => 1.2 ===
--- /dev/null Fri Nov 21 12:12:14 2003
+++ Zope3/src/zope/interface/ro.py Fri Nov 21 12:11:43 2003
@@ -0,0 +1,63 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""Compute a resolution order for an object and it's bases
+
+$Id$
+"""
+
+def ro(object):
+ """Compute a "resolution order" for an object
+ """
+ return mergeOrderings([_flatten(object, [])])
+
+def mergeOrderings(orderings, seen=None):
+ """Merge multiple orderings so that within-ordering order is preserved
+
+ Orderings are constrained in such a way that if an object appears
+ in two or more orderings, then the suffix that begins with the
+ object must be in both orderings.
+
+ For example:
+
+ >>> _mergeOrderings([
+ ... ['x', 'y', 'z'],
+ ... ['q', 'z'],
+ ... [1, 3, 5],
+ ... ['z']
+ ... ])
+ ['x', 'y', 'q', 1, 3, 5, 'z']
+
+ """
+
+ if seen is None:
+ seen = {}
+ result = []
+ orderings.reverse()
+ for ordering in orderings:
+ ordering = list(ordering)
+ ordering.reverse()
+ for o in ordering:
+ if o not in seen:
+ seen[o] = 1
+ result.append(o)
+
+ result.reverse()
+ return result
+
+def _flatten(ob, result):
+ result.append(ob)
+ for base in ob.__bases__:
+ _flatten(base, result)
+
+ return result
=== Zope3/src/zope/interface/__init__.py 1.9 => 1.10 ===
--- Zope3/src/zope/interface/__init__.py:1.9 Tue Oct 7 13:27:03 2003
+++ Zope3/src/zope/interface/__init__.py Fri Nov 21 12:11:43 2003
@@ -83,10 +83,10 @@
from zope.interface.declarations import directlyProvidedBy, directlyProvides
from zope.interface.declarations import implements, implementsOnly
from zope.interface.declarations import classProvides, moduleProvides
-from zope.interface.declarations import InterfaceSpecification, Spec
+from zope.interface.declarations import Declaration
# The following are to make spec pickles cleaner
-from zope.interface.declarations import Implements, Only, Provides
+from zope.interface.declarations import Provides
from zope.interface.interfaces import IInterfaceDeclaration
=== Zope3/src/zope/interface/_flatten.py 1.6 => 1.7 ===
--- Zope3/src/zope/interface/_flatten.py:1.6 Tue Jun 3 18:46:25 2003
+++ Zope3/src/zope/interface/_flatten.py Fri Nov 21 12:11:43 2003
@@ -19,7 +19,7 @@
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
-from zope.interface import InterfaceSpecification
+from zope.interface import Declaration
def _flatten(implements, include_None=0):
@@ -29,7 +29,7 @@
if implements is None:
r=()
else:
- r = InterfaceSpecification(implements).flattened()
+ r = Declaration(implements).flattened()
if not include_None:
return r
=== Zope3/src/zope/interface/adapter.py 1.6 => 1.7 ===
--- Zope3/src/zope/interface/adapter.py:1.6 Mon Jun 23 18:44:01 2003
+++ Zope3/src/zope/interface/adapter.py Fri Nov 21 12:11:43 2003
@@ -20,7 +20,7 @@
__metaclass__ = type # All classes are new style when run with Python 2.2+
from zope.interface import Interface, implements, providedBy
-from zope.interface import InterfaceSpecification
+from zope.interface import Declaration
from zope.interface.interfaces import IInterface
from zope.interface.interfaces import IAdapterRegistry
from _flatten import _flatten
@@ -33,8 +33,7 @@
# The implementation uses a mapping:
#
- # { (required_interface, provided_interface) ->
- # (registered_provides, component) }
+ # { (required, provided) -> (registered_provided, component) }
#
# Where the registered provides is what was registered and
# provided may be some base interface
@@ -94,15 +93,7 @@
cache = self._v_cache = {}
# get the cache key
- interfaces, provide = ob_interface_provide
- try:
- key = interfaces.__signature__
- except AttributeError:
- if interfaces is None:
- key = None
- else:
- key = InterfaceSpecification(interfaces).__signature__
- key = key, provide.__identifier__
+ key = ob_interface_provide
cached = cache.get(key, self)
if cached is self:
@@ -121,7 +112,7 @@
except AttributeError:
# Somebodey (probably a test) passed us a bare interface
if ob_interface is not None:
- flattened = InterfaceSpecification(ob_interface).flattened()
+ flattened = Declaration(ob_interface).flattened()
else:
flattened = None,
else:
@@ -161,9 +152,12 @@
return None
def getRegisteredMatching(self,
- required_interfaces=None,
- provided_interfaces=None):
+ required=None,
+ provided=None):
+
+ required_interfaces = required
+ provided_interfaces = provided
if IInterface.isImplementedBy(required_interfaces):
required_interfaces = (required_interfaces, )
=== Zope3/src/zope/interface/declarations.py 1.17 => 1.18 === (1776/2176 lines abridged)
--- Zope3/src/zope/interface/declarations.py:1.17 Fri Aug 15 20:44:44 2003
+++ Zope3/src/zope/interface/declarations.py Fri Nov 21 12:11:43 2003
@@ -11,467 +11,43 @@
##############################################################################
"""Implementation of interface declarations
+There are three flavors of declarations:
+
+ - Declarations are used to simply name declared interfaces.
+
+ - ImplementsDeclarations are used to express the interfaces that a
+ class implements (that instances of the class provides).
+
+ Implements specifications support inheriting interfaces.
+
+ - ProvidesDeclarations are used to express interfaces directly
+ provided by objects.
+
+
$Id$
"""
import sys
-from zope.interface.interface import InterfaceClass, mergeOrderings
+import weakref
+from zope.interface.interface import InterfaceClass, Specification
+from ro import mergeOrderings, ro
import exceptions
from types import ClassType
from zope.interface.advice import addClassAdvisor
-# There are imports from _zope_interface_ospec later in the file
-# because _zope_interface_ospec depends on some functions defined
-# here.
-
+# Registry of class-implementation specifications
+BuiltinImplementationSpecifications = {}
-DescriptorAwareMetaClasses = ClassType, type
__metaclass__ = type
-heap = 1 << 9
-
-# Notes:
-#
-# We have 3 implementations of interface specifications:
-#
-# ImplementsSpecification
-# Holds specifications of interfaces of instances of classes.
-#
-# ProvidesSpecification
-# These are specifications for interfaces directly provided by
-# objects. This is a descriptor that assures
-# that if we get it from a class for an instance, we get an attribute
-# error.
-#
-# ObjectSpecification
-# Holds the specification for all of the interfaces of an object.
-# These are computed on the floy based on provides and implements
-# specs.
-#
-# We also have a descriptor to support providedBy
-
-
-# implementation info for immutable classes (heap flag clear)
-# This is overridden by _zope_interface_ospec.
-_implements_reg = {}
-
-# This is overridden by _zope_interface_ospec.
-class InterfaceSpecificationBase:
- __slots__ = ['__signature__']
-
-
-# This function is needed by _zope_interface_ospec and, so, must be
-# defined before _zope_interface_ospec is imported.
-def classImplements(cls, *interfaces):
- """Declare additional interfaces implemented for instances of a class
-
- The arguments after the class are one or more interfaces or
- interface specifications (IInterfaceSpecification objects).
-
- The interfaces given (including the interfaces in the
- specifications) are added to any interfaces previously
- declared.
-
- Consider the following example::
-
-
- for example:
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(Interface): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I4(Interface): pass
- ...
- >>> class I5(Interface): pass
- ...
- >>> class A:
- ... implements(I3)
- >>> class B:
- ... implements(I4)
- >>> class C(A, B):
- ... pass
- >>> classImplements(C, I1, I2)
- >>> [i.getName() for i in implementedBy(C)]
- ['I1', 'I2', 'I3', 'I4']
- >>> classImplements(C, I5)
- >>> [i.getName() for i in implementedBy(C)]
- ['I1', 'I2', 'I5', 'I3', 'I4']
-
- Instances of ``C`` provide ``I1``, ``I2``, ``I5``, and whatever interfaces
- instances of ``A`` and ``B`` provide.
+class Declaration(Specification):
+ """Interface declarations
"""
- _setImplements(cls,
- _getImplements(cls) + ImplementsSpecification(*interfaces)
- )
-
-# This function is needed by _zope_interface_ospec and, so, must be
-# defined before _zope_interface_ospec is imported.
-def proxySig(cls):
- # Get an implementation signature from a proxied class
-
- # XXX If we got here, we must have a
- # security-proxied class. This introduces an
- # indirect dependency on security proxies,
- # which we don't want. This is necessary to
- # support old-style __implements__ interface
- # declarations.
-
- # If we got here, we must have an old-style
- # declaration, so we'll just look for an
- # __implements__. We can't fix it because the class
- # is probably security proxied.
-
- implements = getattr(cls, '__implements__', None)
- if implements is not None:
- assert ((implements.__class__ == tuple)
- or
- (InterfaceClass in
- implements.__class__.__mro__)
- )
- sig = `implements`
-
- return sig
-
-# This function is needed by _zope_interface_ospec and, so, must be
-# defined before _zope_interface_ospec is imported.
-def oldSpecSig(cls, implements):
- implements = ImplementsOnlySpecification(implements)
- _setImplements(cls, implements)
- return implements.__signature__
-
-# This is overridden by _zope_interface_ospec.
-
-def combinedSpec(provides, cls):
- if provides is not None:
- result = [provides]
- else:
- result = []
-
- _gatherSpecs(cls, result)
-
- return InterfaceSpecification(*result)
-
-class ObjectSpecification_py:
- """Provide object specifications
-
- These combine information for the object and for it's classes.
-
- For example::
-
- >>> from zope.interface import Interface
- >>> class I1(Interface): pass
- ...
- >>> class I2(Interface): pass
- ...
- >>> class I3(Interface): pass
- ...
- >>> class I31(I3): pass
- ...
- >>> class I4(Interface): pass
- ...
- >>> class I5(Interface): pass
- ...
- >>> class A: implements(I1)
- ...
- >>> class B: __implements__ = I2
- ...
- >>> class C(A, B): implements(I31)
- ...
- >>> c = C()
[-=- -=- -=- 1776 lines omitted -=- -=- -=-]
+ try:
+ r = ob.__providedBy__
- implements = getattr(cls, '__implements__', None)
- if implements is not None:
- implements = ImplementsOnlySpecification(implements)
+ # We might have gotten a descriptor from an instance of a
+ # class (like an ExtensionClass) that doesn't support
+ # descriptors. We'll make sure we got one by trying to get
+ # the only attribute, which all specs have.
+ r.extends
- return implements
+ except AttributeError:
+ # No descriptor, so fall back to a plain object spec
+ r = getObjectSpecification(ob)
- k = '__implements__'
- else:
- d = _implements_reg
- k = cls
+ return r
- return d.get(k)
+class ObjectSpecificationDescriptorPy(object):
+ """Implement the __providedBy__ attribute
-def _finddescr(cls):
- # Try to find the __providedBy__ descriptor. If we can't find it,
- # just return the class.
-
- d = cls.__dict__.get("__providedBy__", cls)
- if d is not cls:
- return d
- for b in cls.__bases__:
- d = _finddescr(b)
- if d is not b:
- return d
+ The __providedBy__ attribute computes the interfaces peovided by
+ an object.
+ """
- return cls
+ def __get__(self, inst, cls):
+ """Get an object specification for an object
+
+ For example::
+
+ >>> from zope.interface import Interface
+ >>> class IFoo(Interface): pass
+ ...
+ >>> class IFooFactory(Interface): pass
+ ...
+ >>> class C:
+ ... implements(IFoo)
+ ... classProvides(IFooFactory)
+ >>> [i.getName() for i in C.__providedBy__]
+ ['IFooFactory']
+ >>> [i.getName() for i in C().__providedBy__]
+ ['IFoo']
+
+ """
+
+ # Get an ObjectSpecification bound to either an instance or a class,
+ # depending on how we were accessed.
+
+ if inst is None:
+ return getObjectSpecification(cls)
-def _setImplements(cls, v):
- flags = getattr(cls, '__flags__', heap)
+ provides = getattr(inst, '__provides__', None)
+ if provides is not None:
+ return provides
- if flags & heap:
- cls.__implements__ = v
+ return implementedBy(cls)
- # Add a __providedBy__ descriptor if there isn't already one.
- # If there is one and it's not in the dict, then make a copy
- # here.
-
- try:
- cls.__providedBy__
- except AttributeError:
- # No existing descriptor, add one
- cls.__providedBy__ = _objectSpecificationDescriptor
- else:
- # Hm, the class already has a descriptor, let's get it and
- # see if it's the right kind.
- try:
- mro = cls.__mro__
- except AttributeError:
- pb = _finddescr(cls)
- if pb is cls:
- pb = None
- else:
- for c in mro:
- pb = c.__dict__.get("__providedBy__", c)
- if pb is not c:
- break
- else: # no break
- pb = None
-
- if not isinstance(pb, ObjectSpecificationDescriptor):
- raise TypeError(
- cls,
- "has a __providedBy__ descriptor of the wrong type",
- pb)
+ObjectSpecificationDescriptor = ObjectSpecificationDescriptorPy
- if "__providedBy__" not in cls.__dict__:
- cls.__providedBy__ = pb
+objectSpecificationDescriptor = ObjectSpecificationDescriptor()
- else:
- _implements_reg[cls] = v
+##############################################################################
- v.setClass(cls)
+def _normalizeargs(sequence, output = None):
+ """Normalize declaration arguments
-def _getmro(C, r):
- if C not in r: r.append(C)
- for b in C.__bases__:
- _getmro(b, r)
- return r
-
-def _gatherSpecs(cls, result):
- implements = _getImplements(cls)
- if implements is not None:
- try:
- stop = implements.only
- except AttributeError:
- # Must be an old-style interface spec
- implements = ImplementsOnlySpecification(
- _flattenSpecs([implements], []))
- stop = 1
- _setImplements(cls, implements)
-
- if stop:
- result.append(implements)
- return result
-
- cspec = implements._cspec
- if cspec is not None:
- # We have a cached spec.
- # This makes out job much easier
- result.append(cspec)
- return result
-
- # No cached cspec. Compute one if we're being called recursively.
- # We know we're being called recursively is result is not empty!
- if result:
- implements.setClass(cls)
- cspec = implements._cspec
- # Now we have one
- result.append(cspec)
- return result
-
- result.append(implements)
-
- for b in cls.__bases__:
- _gatherSpecs(b, result)
-
- return result
-
-# DocTest:
-if __name__ == "__main__":
- import doctest, __main__
- doctest.testmod(__main__, isprivate=lambda *a: False)
+ Normalization arguments might contain Declarions, tuples, or single
+ interfaces.
+
+ Anything but individial interfaces or implements specs will be expanded.
+ """
+ if output is None:
+ output = []
+
+ cls = sequence.__class__
+ if InterfaceClass in cls.__mro__ or Implements in cls.__mro__:
+ output.append(sequence)
+ else:
+ for v in sequence:
+ _normalizeargs(v, output)
+
+ return output
+
+_empty = Declaration()
+
+try:
+ import _zope_interface_coptimizations
+except ImportError:
+ pass
+else:
+ from _zope_interface_coptimizations import implementedBy, providedBy
+ from _zope_interface_coptimizations import getObjectSpecification
+ from _zope_interface_coptimizations import ObjectSpecificationDescriptor
=== Zope3/src/zope/interface/document.py 1.4 => 1.5 ===
--- Zope3/src/zope/interface/document.py:1.4 Mon Apr 14 04:31:00 2003
+++ Zope3/src/zope/interface/document.py Fri Nov 21 12:11:43 2003
@@ -36,7 +36,7 @@
outp(_justify_and_indent(_trim_doc_string(I.getDoc()), level)+ "\n\n")
bases = [base
- for base in I.getBases()
+ for base in I.__bases__
if base is not zope.interface.Interface
]
if bases:
=== Zope3/src/zope/interface/implementor.py 1.6 => 1.7 ===
--- Zope3/src/zope/interface/implementor.py:1.6 Wed Aug 6 17:16:58 2003
+++ Zope3/src/zope/interface/implementor.py Fri Nov 21 12:11:43 2003
@@ -31,7 +31,7 @@
# The implementation uses a mapping:
#
- # { provided_interface -> (registered_provides, component) }
+ # { provided -> (registered_provided, component) }
#
# Where the registered provides is what was registered and
# provided may be some base interface
=== Zope3/src/zope/interface/interface.py 1.14 => 1.15 ===
--- Zope3/src/zope/interface/interface.py:1.14 Fri Nov 21 02:49:11 2003
+++ Zope3/src/zope/interface/interface.py Fri Nov 21 12:11:43 2003
@@ -17,8 +17,11 @@
$Id$
"""
+from __future__ import generators
import sys
+import weakref
from types import FunctionType
+from ro import ro
CO_VARARGS = 4
CO_VARKEYWORDS = 8
@@ -61,8 +64,264 @@
""" Associates 'value' with 'key'. """
self.__tagged_values[tag] = value
+class SpecificationBasePy(object):
-class InterfaceClass(Element):
+ def isImplementedBy(self, ob):
+ """Is the interface implemented by an object
+
+ >>> from zope.interface import *
+ >>> class I1(Interface):
+ ... pass
+ >>> class C:
+ ... implements(I1)
+ >>> c = C()
+ >>> class X:
+ ... pass
+ >>> x = X()
+ >>> I1.isImplementedBy(x)
+ False
+ >>> I1.isImplementedBy(C)
+ False
+ >>> I1.isImplementedBy(c)
+ True
+ >>> directlyProvides(x, I1)
+ >>> I1.isImplementedBy(x)
+ True
+ >>> directlyProvides(C, I1)
+ >>> I1.isImplementedBy(C)
+ True
+
+ """
+ spec = providedBy(ob)
+ return self in spec._implied
+
+ def isImplementedByInstancesOf(self, cls):
+ """Do instances of the given class implement the interface?"""
+ spec = implementedBy(cls)
+ return self in spec._implied
+
+ def isOrExtends(self, interface):
+ """Is the interface the same as or extend the given interface
+
+ Examples::
+
+ >>> from zope.interface import Interface
+ >>> from zope.interface.declarations import Declaration
+ >>> class I1(Interface): pass
+ ...
+ >>> class I2(I1): pass
+ ...
+ >>> class I3(Interface): pass
+ ...
+ >>> class I4(I3): pass
+ ...
+ >>> spec = Declaration()
+ >>> int(spec.extends(Interface))
+ 0
+ >>> spec = Declaration(I2)
+ >>> int(spec.extends(Interface))
+ 1
+ >>> int(spec.extends(I1))
+ 1
+ >>> int(spec.extends(I2))
+ 1
+ >>> int(spec.extends(I3))
+ 0
+ >>> int(spec.extends(I4))
+ 0
+
+ """
+ return interface in self._implied
+
+SpecificationBase = SpecificationBasePy
+
+try:
+ from _zope_interface_coptimizations import SpecificationBase
+except ImportError:
+ pass
+
+class Specification(SpecificationBase):
+ """Specifications
+
+ An interface specification is used to track interface declarations
+ and component registrations.
+
+ This class is a base class for both interfaces themselves and for
+ interface specifications (declarations).
+
+ Specifications are mutable. If you reassign their cases, their
+ relations with other specifications are adjusted accordingly.
+
+ For example:
+
+ >>> from zope.interface import Interface
+ >>> class I1(Interface):
+ ... pass
+ >>> class I2(I1):
+ ... pass
+ >>> class I3(I2):
+ ... pass
+
+ >>> [i.__name__ for i in I1.__bases__]
+ ['Interface']
+
+ >>> [i.__name__ for i in I2.__bases__]
+ ['I1']
+
+ >>> I3.extends(I1)
+ 1
+
+ >>> I2.__bases__ = (Interface, )
+
+ >>> [i.__name__ for i in I2.__bases__]
+ ['Interface']
+
+ >>> I3.extends(I1)
+ 0
+
+ """
+
+ # Copy some base class methods for speed
+ isOrExtends = SpecificationBase.isOrExtends
+ isImplementedBy = SpecificationBase.isImplementedBy
+
+ def __init__(self, bases=()):
+ self._implied = {}
+ self.dependents = weakref.WeakKeyDictionary()
+ self.__bases__ = tuple(bases)
+
+ def subscribe(self, dependent):
+ self.dependents[dependent] = 1
+
+ def unsubscribe(self, dependent):
+ del self.dependents[dependent]
+
+ def __setBases(self, bases):
+ # Register ourselves as a dependent of our old bases
+ for b in self.__bases__:
+ b.unsubscribe(self)
+
+ # Register ourselves as a dependent of our bases
+ self.__dict__['__bases__'] = bases
+ for b in bases:
+ b.subscribe(self)
+
+ self.changed()
+
+ __bases__ = property(
+
+ lambda self: self.__dict__.get('__bases__', ()),
+ __setBases,
+ )
+
+ def changed(self):
+ """We, or something we depend on, have changed
+ """
+
+ implied = self._implied
+ implied.clear()
+
+ ancestors = ro(self)
+ self.__iro__ = tuple([ancestor for ancestor in ancestors
+ if isinstance(ancestor, InterfaceClass)
+ ])
+
+ for ancestor in ancestors:
+ # We directly imply our ancestors:
+ implied[ancestor] = ()
+
+ # Now, advise our dependents of change:
+ for dependent in self.dependents.keys():
+ dependent.changed()
+
+
+ def interfaces(self):
+ """Return an iterator for the interfaces in the specification
+
+ for example::
+
+ >>> from zope.interface import Interface
+ >>> class I1(Interface): pass
+ ...
+ >>> class I2(I1): pass
+ ...
+ >>> class I3(Interface): pass
+ ...
+ >>> class I4(I3): pass
+ ...
+ >>> spec = Specification((I2, I3))
+ >>> spec = Specification((I4, spec))
+ >>> i = spec.interfaces()
+ >>> i.next().getName()
+ 'I4'
+ >>> i.next().getName()
+ 'I2'
+ >>> i.next().getName()
+ 'I3'
+ >>> list(i)
+ []
+ """
+ seen = {}
+ for base in self.__bases__:
+ for interface in base.interfaces():
+ if interface not in seen:
+ seen[interface] = 1
+ yield interface
+
+
+ def extends(self, interface, strict=True):
+ """Does the specification extend the given interface?
+
+ Test whether an interface in the specification extends the
+ given interface
+
+ Examples::
+
+ >>> from zope.interface import Interface
+ >>> from zope.interface.declarations import Declaration
+ >>> class I1(Interface): pass
+ ...
+ >>> class I2(I1): pass
+ ...
+ >>> class I3(Interface): pass
+ ...
+ >>> class I4(I3): pass
+ ...
+ >>> spec = Declaration()
+ >>> int(spec.extends(Interface))
+ 0
+ >>> spec = Declaration(I2)
+ >>> int(spec.extends(Interface))
+ 1
+ >>> int(spec.extends(I1))
+ 1
+ >>> int(spec.extends(I2))
+ 1
+ >>> int(spec.extends(I3))
+ 0
+ >>> int(spec.extends(I4))
+ 0
+ >>> I2.extends(I2)
+ 0
+ >>> I2.extends(I2, False)
+ 1
+ >>> I2.extends(I2, strict=False)
+ 1
+
+ """
+ return ((interface in self._implied)
+ and
+ ((not strict) or (self != interface))
+ )
+
+ def weakref(self, callback=None):
+ if callback is None:
+ return weakref.ref(self)
+ else:
+ return weakref.ref(self, callback)
+
+
+class InterfaceClass(Element, Specification):
"""Prototype (scarecrow) Interfaces Implementation."""
# We can't say this yet because we don't have enough
@@ -92,12 +351,6 @@
self.__module__ = __module__
- for b in bases:
- if not isinstance(b, InterfaceClass):
- raise TypeError, 'Expected base interfaces'
- # Python expects __bases__ to be a tuple.
- self.__bases__ = tuple(bases)
-
if attrs is None:
attrs = {}
@@ -113,7 +366,11 @@
Element.__init__(self, name, __doc__)
- self.__iro__ = mergeOrderings([_flattenInterface(self, [])])
+ for b in bases:
+ if not isinstance(b, InterfaceClass):
+ raise TypeError, 'Expected base interfaces'
+
+ Specification.__init__(self, bases)
for k, v in attrs.items():
if isinstance(v, Attribute):
@@ -129,19 +386,27 @@
self.__identifier__ = "%s.%s" % (self.__module__, self.__name__)
+ def interfaces(self):
+ """Return an iterator for the interfaces in the specification
- def getBases(self):
- return self.__bases__
+ for example::
- def extends(self, other, strict=True):
- """Does an interface extend another?"""
- if not strict and self == other:
- return True
+ >>> from zope.interface import Interface
+ >>> class I1(Interface): pass
+ ...
+ >>>
+ >>> i = I1.interfaces()
+ >>> i.next().getName()
+ 'I1'
+ >>> list(i)
+ []
+ """
+ yield self
- for b in self.__bases__:
- if b == other: return True
- if b.extends(other): return True
- return False
+
+
+ def getBases(self):
+ return self.__bases__
def isEqualOrExtendedBy(self, other):
"""Same interface or extends?"""
@@ -149,30 +414,6 @@
return True
return other.extends(self)
- def isImplementedBy(self, object):
- """Does the given object implement the interface?"""
-
- # OPT Cache implements lookups
- implements = providedBy(object)
- cache = getattr(self, '_v_cache', self)
- if cache is self:
- cache = self._v_cache = {}
-
-
- key = implements.__signature__
-
- r = cache.get(key)
- if r is None:
- r = bool(implements.extends(self))
- cache[key] = r
-
- return r
-
- def isImplementedByInstancesOf(self, klass):
- """Do instances of the given class implement the interface?"""
- i = implementedBy(klass)
- return bool(i.extends(self))
-
def names(self, all=False):
"""Return the attribute names defined by the interface."""
if not all:
@@ -328,48 +569,6 @@
c = self.__cmp(self, other)
#print '>', self, other, c > 0, c
return c > 0
-
-
-def mergeOrderings(orderings, seen=None):
- """Merge multiple orderings so that within-ordering order is preserved
-
- Orderings are constrained in such a way that if an object appears
- in two or more orderings, then the suffix that begins with the
- object must be in both orderings.
-
- For example:
-
- >>> _mergeOrderings([
- ... ['x', 'y', 'z'],
- ... ['q', 'z'],
- ... [1, 3, 5],
- ... ['z']
- ... ])
- ['x', 'y', 'q', 1, 3, 5, 'z']
-
- """
-
- if seen is None:
- seen = {}
- result = []
- orderings.reverse()
- for ordering in orderings:
- ordering = list(ordering)
- ordering.reverse()
- for o in ordering:
- if o not in seen:
- seen[o] = 1
- result.append(o)
-
- result.reverse()
- return result
-
-def _flattenInterface(iface, result):
- result.append(iface)
- for base in iface.__bases__:
- _flattenInterface(base, result)
-
- return result
Interface = InterfaceClass("Interface", __module__ = 'zope.interface')
=== Zope3/src/zope/interface/interfaces.py 1.16 => 1.17 ===
--- Zope3/src/zope/interface/interfaces.py:1.16 Fri Oct 17 04:05:53 2003
+++ Zope3/src/zope/interface/interfaces.py Fri Nov 21 12:11:43 2003
@@ -55,8 +55,44 @@
"""Return a signature string suitable for inclusion in documentation.
"""
+class ISpecification(Interface):
+ """Object Behavioral specifications
+ """
+
+ def extends(other, strict=True):
+ """Test whether a specification extends another
+
+ The specification extends other if it has other as a base
+ interface or if one of it's bases extends other.
+
+ If strict is false, then the specification extends itself.
+
+ """
+
+ def isOrExtends(other):
+ """Test whether the specification is or extends another
+ """
+
+ def weakref(callback=None):
+ """Return a weakref to the specification
+
+ This method is, regrettably, needed to allow weakrefs to be
+ computed to security-proxied specifications. While the
+ zope.interface package does not require zope.security or
+ zope.proxy, it has to be able to coexist with it.
+
+ """
-class IInterface(IElement):
+ __bases__ = Attribute("""Base specifications
+
+ A tuple if specifications from which this specification is
+ directly derived.
+
+ """)
+
+
+
+class IInterface(ISpecification, IElement):
"""Interface objects
Interface objects describe the behavior of an object by containing
@@ -148,22 +184,6 @@
"""
-
- def getBases():
- """Return a sequence of the base interfaces."""
-
- def extends(other, strict=True):
- """Test whether the interface extends another interface
-
- A true value is returned in the interface extends the other
- interface, and false otherwise.
-
- Normally, an interface doesn't extend itself. If a false value
- is passed as the second argument, or via the 'strict' keyword
- argument, then a true value will be returned if the interface
- and the other interface are the same.
- """
-
def isImplementedBy(object):
"""Test whether the interface is implemented by the object
@@ -237,25 +257,6 @@
__module__ = Attribute("""The name of the module defining the interface""")
- __bases__ = Attribute("""A tuple of base interfaces""")
- __iro__ = Attribute(
- """A tuple of all interfaces extended by the interface
-
- The first item in the tuple is the interface itself. The
- interfaces are listed in order from most specific to most
- general, preserving the original order of base interfaces
- where possible.
-
- """)
-
- __identifier__ = Attribute("""A unique identifier for the interface
-
- This identifier should be different for different interfaces.
-
- The identifier is not allowed to contain tab characters.
- """)
-
-
class ITypeRegistry(Interface):
"""Type-specific registry
@@ -377,8 +378,8 @@
None is returned if nothing is registered.
"""
- def getRegisteredMatching(required_interfaces=None,
- provided_interfaces=None):
+ def getRegisteredMatching(required=None,
+ provided=None):
"""Return information about registered data
Zero or more required and provided interfaces may be
@@ -452,7 +453,13 @@
"""
-class IInterfaceSpecification(Interface):
+class IDeclaration(ISpecification):
+ """Interface declaration
+
+ Declarations are used to express the interfaces implemented by
+ classes or provided by objects.
+
+ """
def __contains__(interface):
"""Test whether an interface is in the specification
@@ -477,14 +484,6 @@
were defined in the specification.
"""
- def extends(interface):
- """Test whether an interface specification extends an interface
-
- An interface specification extends an interface if it contains
- an interface that extends an interface.
-
- """
-
def __sub__(interfaces):
"""Create an interface specification with some interfaces excluded
@@ -514,21 +513,6 @@
"""Return a true value of the interface specification is non-empty
"""
- __signature__ = Attribute("""A specification signature
-
- The signature should change if any of the interfaces in the
- specification change.
-
- """)
-
- only = Attribute("""\
- A flag (boolean) indicating whether a specification extends others
-
- If only is true, then a class implementing the specification
- doesn't implement base-class specifications.
-
- """)
-
class IInterfaceDeclaration(Interface):
"""Declare and check the interfaces of objects
@@ -559,20 +543,20 @@
This is the union of the interfaces directly provided by an
object and interfaces implemented by it's class.
- The value returned is an IInterfaceSpecification.
+ The value returned is an IDeclaration.
"""
def implementedBy(class_):
"""Return the interfaces implemented for a class' instances
- The value returned is an IInterfaceSpecification.
+ The value returned is an IDeclaration.
"""
def classImplements(class_, *interfaces):
"""Declare additional interfaces implemented for instances of a class
The arguments after the class are one or more interfaces or
- interface specifications (IInterfaceSpecification objects).
+ interface specifications (IDeclaration objects).
The interfaces given (including the interfaces in the
specifications) are added to any interfaces previously
@@ -594,7 +578,7 @@
"""Declare the only interfaces implemented by instances of a class
The arguments after the class are one or more interfaces or
- interface specifications (IInterfaceSpecification objects).
+ interface specifications (IDeclaration objects).
The interfaces given (including the interfaces in the
specifications) replace any previous declarations.
@@ -614,14 +598,14 @@
def directlyProvidedBy(object):
"""Return the interfaces directly provided by the given object
- The value returned is an IInterfaceSpecification.
+ The value returned is an IDeclaration.
"""
def directlyProvides(object, *interfaces):
"""Declare interfaces declared directly for an object
The arguments after the object are one or more interfaces or
- interface specifications (IInterfaceSpecification objects).
+ interface specifications (IDeclaration objects).
The interfaces given (including the interfaces in the
specifications) replace interfaces previously
@@ -662,7 +646,7 @@
This function is called in a class definition.
The arguments are one or more interfaces or interface
- specifications (IInterfaceSpecification objects).
+ specifications (IDeclaration objects).
The interfaces given (including the interfaces in the
specifications) are added to any interfaces previously
@@ -698,7 +682,7 @@
This function is called in a class definition.
The arguments are one or more interfaces or interface
- specifications (IInterfaceSpecification objects).
+ specifications (IDeclaration objects).
Previous declarations including declarations for base classes
are overridden.
@@ -730,7 +714,7 @@
This function is called in a class definition.
The arguments are one or more interfaces or interface
- specifications (IInterfaceSpecification objects).
+ specifications (IDeclaration objects).
The given interfaces (including the interfaces in the
specifications) are used to create the class's direct-object
@@ -760,7 +744,7 @@
This function is used in a module definition.
The arguments are one or more interfaces or interface
- specifications (IInterfaceSpecification objects).
+ specifications (IDeclaration objects).
The given interfaces (including the interfaces in the
specifications) are used to create the module's direct-object
@@ -779,13 +763,13 @@
directlyProvides(sys.modules[__name__], I1)
"""
- def InterfaceSpecification(*interfaces):
+ def Declaration(*interfaces):
"""Create an interface specification
The arguments are one or more interfaces or interface
- specifications (IInterfaceSpecification objects).
+ specifications (IDeclaration objects).
- A new interface specification (IInterfaceSpecification) with
+ A new interface specification (IDeclaration) with
the given interfaces is returned.
"""
@@ -803,7 +787,7 @@
This function is called in a class definition.
The arguments are one or more interfaces or interface
- specifications (IInterfaceSpecification objects).
+ specifications (IDeclaration objects).
The interfaces given (including the interfaces in the
specifications) are removed from any interfaces previously
@@ -837,7 +821,7 @@
"""Declare the interfaces not implemented for instances of a class
The arguments after the class are one or more interfaces or
- interface specifications (IInterfaceSpecification objects).
+ interface specifications (IDeclaration objects).
The interfaces given (including the interfaces in the
specifications) cancel previous declarations for the same
=== Zope3/src/zope/interface/type.py 1.10 => 1.11 ===
--- Zope3/src/zope/interface/type.py:1.10 Sat Jun 7 02:37:29 2003
+++ Zope3/src/zope/interface/type.py Fri Nov 21 12:11:43 2003
@@ -19,6 +19,8 @@
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
+import zope.interface
+import types
from zope.interface import providedBy, implements
from zope.interface.interfaces import IInterface
from zope.interface.interfaces import ITypeRegistry
@@ -33,8 +35,7 @@
# The implementation uses a mapping:
#
- # { (required_interface, provided_interface) ->
- # (registered_provides, component) }
+ # { (required, provided) -> (registered_provided, component) }
#
# Where the registered provides is what was registered and
# provided may be some base interface
@@ -46,12 +47,15 @@
self._reg = data
def register(self, interface, object):
- if interface is None or IInterface.isImplementedBy(interface):
- self._reg[interface] = object
- else:
- raise TypeError(
- "The interface argument must be an interface (or None)")
-
+ if not (interface is None or IInterface.isImplementedBy(interface)):
+ if isinstance(interface, (type, types.ClassType)):
+ interface = zope.interface.implementedBy(interface)
+ else:
+ raise TypeError(
+ "The interface argument must be an interface (or None)")
+
+ self._reg[interface] = object
+
def unregister(self, interface):
if interface is None or IInterface.isImplementedBy(interface):
if interface in self._reg:
@@ -96,7 +100,7 @@
result = []
for k in self._reg:
- if k is None or k.extends(interface, strict=False):
+ if k is None or k.extends(interface, False):
result.append(k)
return result
=== Removed File Zope3/src/zope/interface/_zope_interface_ospec.c ===
More information about the Zope3-Checkins
mailing list