[Zodb-checkins] CVS: Zope3/src/zope/interface - adapter.py:1.4
implementor.py:1.5 implements.py:1.5 interface.py:1.9
type.py:1.8 verify.py:1.6
Jim Fulton
jim at zope.com
Sat May 3 13:36:36 EDT 2003
Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv24176/src/zope/interface
Modified Files:
adapter.py implementor.py implements.py interface.py type.py
verify.py
Log Message:
Updated to use new interface declaration machinery.
=== Zope3/src/zope/interface/adapter.py 1.3 => 1.4 ===
--- Zope3/src/zope/interface/adapter.py:1.3 Mon Jan 20 15:02:52 2003
+++ Zope3/src/zope/interface/adapter.py Sat May 3 12:36:05 2003
@@ -19,16 +19,17 @@
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
-from zope.interface import Interface
+from zope.interface import Interface, implements, providedBy
+from zope.interface import InterfaceSpecification
from zope.interface.interfaces import IInterface
-from zope.interface._flatten import _flatten
from zope.interface.interfaces import IAdapterRegistry
+from _flatten import _flatten
class AdapterRegistry:
"""Adapter-style interface registry
"""
- __implements__ = IAdapterRegistry
+ implements(IAdapterRegistry)
# The implementation uses a mapping:
#
@@ -90,7 +91,18 @@
cache = getattr(self, '_v_cache', self)
if cache is self:
cache = self._v_cache = {}
- key = `ob_interface_provide`
+
+ # 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__
+
cached = cache.get(key, self)
if cached is self:
cached = self._uncached_get(ob_interface_provide,
@@ -102,8 +114,20 @@
default, filter)
def _uncached_get(self, (ob_interface, provide), default, filter):
+
+ try:
+ flattened = ob_interface.flattened
+ except AttributeError:
+ # Somebodey (probably a test) passed us a bare interface
+ if ob_interface is not None:
+ flattened = InterfaceSpecification(ob_interface).flattened()
+ else:
+ flattened = None,
+ else:
+ flattened = flattened()
- for interface in _flatten(ob_interface, 1):
+
+ for interface in flattened:
c = self._reg.get((interface, provide))
if c:
c = c[1]
@@ -111,12 +135,21 @@
return c
if filter(c):
return c
+
+ c = self._reg.get((None, provide))
+ if c:
+ c = c[1]
+ if filter is None:
+ return c
+ if filter(c):
+ return c
+
+
return default
def getForObject(self, object, interface, filter=None):
- return self.get((getattr(object, '__implements__', None), interface),
- filter=filter)
+ return self.get((providedBy(object), interface), filter=filter)
def getRegistered(self, require, provide):
data = self._reg.get((require, provide))
=== Zope3/src/zope/interface/implementor.py 1.4 => 1.5 ===
--- Zope3/src/zope/interface/implementor.py:1.4 Thu Apr 3 17:05:35 2003
+++ Zope3/src/zope/interface/implementor.py Sat May 3 12:36:05 2003
@@ -19,7 +19,7 @@
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
-from zope.interface import Interface
+from zope.interface import Interface, implements
from zope.interface.interfaces import IInterface
from zope.interface.interfaces import IImplementorRegistry
@@ -27,7 +27,7 @@
"""Implementor-style interface registry
"""
- __implements__ = IImplementorRegistry
+ implements(IImplementorRegistry)
# The implementation uses a mapping:
#
=== Zope3/src/zope/interface/implements.py 1.4 => 1.5 ===
--- Zope3/src/zope/interface/implements.py:1.4 Thu Apr 10 11:43:16 2003
+++ Zope3/src/zope/interface/implements.py Sat May 3 12:36:05 2003
@@ -17,42 +17,20 @@
$Id$
"""
+from zope.interface.declarations import providedBy, implementedBy
+from zope.interface.declarations import classImplements
+from zope.interface.declarations import InterfaceSpecification
+
+
from zope.interface import exceptions
from zope.interface.verify import verifyClass
from zope.interface.interface import InterfaceClass
from types import TupleType, ClassType, StringType
-# Special value indicating the object supports
-# what its class supports.
-CLASS_INTERFACES = 1
-
-ClassTypes = ClassType, type
-
-_typeImplements = {}
-
-def getImplements(object):
- # Decide whether or not the object is a class. If it is a class,
- # return it's __class_implements__ rather than its __implements__.
- if isinstance(object, ClassTypes):
- ci = getattr(object, '__class_implements__', None)
- if ci is not None:
- return ci
- else:
- impl = getattr(object, '__implements__', None)
- if impl is not None:
- return impl
-
- return _typeImplements.get(type(object))
-
+getImplements = providedBy
+getImplementsOfInstances = implementedBy
-def getImplementsOfInstances(klass):
- if isinstance(klass, ClassTypes):
- return getattr(klass, '__implements__', None)
- else:
- return _typeImplements.get(klass)
-
-
-def visitImplements(implements, object, visitor, getInterface=None):
+def visitImplements(implements, object, visitor):
"""Call visitor for each interace.
Visits the interfaces described by an __implements__ attribute,
@@ -60,76 +38,27 @@
If the visitor returns anything true, the loop stops.
This does not, and should not, visit superinterfaces.
"""
- # this allows us to work with proxy wrappers in Python 2.2,
- # yet remain compatible with earlier versions of python.
- implements_class = getattr(implements, '__class__', None)
-
- if InterfaceClass in implements_class.__mro__:
- return visitor(implements)
- elif implements == CLASS_INTERFACES:
- klass = getattr(object, '__class__', None)
- if klass is not None:
- i = getImplementsOfInstances(klass)
- if i:
- return visitImplements(i, object, visitor, getInterface)
- elif implements_class == StringType or type(implements) is StringType:
- if getInterface is not None:
- # Look up a named interface.
- i = getInterface(object, implements)
- if i is not None:
- return visitImplements(i, object, visitor, getInterface)
- elif implements_class == TupleType or type(implements) is TupleType:
- for i in implements:
- r = visitImplements(i, object, visitor, getInterface)
- if r:
- # If the visitor returns anything true, stop.
- return r
- else:
- if implements_class is not None and \
- type(implements) != implements_class:
- raise exceptions.BadImplements(
- """__implements__ should be an interface or tuple,
- not a %s pretending to be a %s"""
- % (type(implements).__name__, implements_class.__name__)
- )
- raise exceptions.BadImplements(
- """__implements__ should be an interface or tuple,
- not a %s""" % type(implements).__name__)
- return None
-
-
-def assertTypeImplements(type, interfaces):
- """Assign a set of interfaces to a Python type such as int, str, tuple,
- list and dict.
- """
- _typeImplements[type] = interfaces
-def objectImplements(object, getInterface=None):
- r = []
- implements = getImplements(object)
- if not implements:
- return r
- visitImplements(implements, object, r.append, getInterface)
- return r
-
-def instancesOfObjectImplements(klass, getInterface=None):
- r = []
- implements = getImplementsOfInstances(klass)
- if not implements:
- return r
- visitImplements(implements, klass, r.append, getInterface)
- return r
+ for interface in InterfaceSpecification(implements):
+ if visitor(interface):
+ break
+
+
+assertTypeImplements = classImplements
+
+objectImplements = providedBy
+instancesOfObjectImplements = implementedBy
def _flatten(i, append):
- if isinstance(i, (list, tuple)):
- for iface in i:
- _flatten(iface, append)
- else:
+ if InterfaceClass in i.__class__.__mro__:
append(i)
bases = i.getBases()
if bases:
for b in bases:
_flatten(b, append)
+ else:
+ for iface in i:
+ _flatten(iface, append)
def flattenInterfaces(interfaces, remove_duplicates=1):
res = []
=== Zope3/src/zope/interface/interface.py 1.8 => 1.9 ===
--- Zope3/src/zope/interface/interface.py:1.8 Mon Apr 14 04:29:09 2003
+++ Zope3/src/zope/interface/interface.py Sat May 3 12:36:05 2003
@@ -17,6 +17,7 @@
$Id$
"""
+import sys
from inspect import currentframe
from types import FunctionType
@@ -75,17 +76,22 @@
__module__=None):
if __module__ is None:
- if attrs is not None and ('__module__' in attrs):
+ if (attrs is not None and
+ ('__module__' in attrs) and
+ isinstance(attrs['__module__'], str)
+ ):
__module__ = attrs['__module__']
del attrs['__module__']
else:
+
try:
# Figure out what module defined the interface.
# This is how cPython figures out the module of
# a class, but of course it does it in C. :-/
- __module__ = currentframe().f_back.f_globals['__name__']
+ __module__ = sys._getframe(1).f_globals['__name__']
except (AttributeError, KeyError):
pass
+
self.__module__ = __module__
for b in bases:
@@ -108,6 +114,8 @@
Element.__init__(self, name, __doc__)
+ self.__iro__ = mergeOrderings([_flattenInterface(self, [])])
+
for k, v in attrs.items():
if isinstance(v, Attribute):
v.interface = name
@@ -120,6 +128,9 @@
self.__attrs = attrs
+ self.__identifier__ = "%s.%s" % (self.__module__, self.__name__)
+
+
def getBases(self):
return self.__bases__
@@ -143,34 +154,25 @@
"""Does the given object implement the interface?"""
# OPT Cache implements lookups
- implements = getImplements(object)
- if implements is None:
- return False
-
+ implements = providedBy(object)
cache = getattr(self, '_v_cache', self)
if cache is self:
cache = self._v_cache = {}
- key = `implements`
+
+ key = implements.__signature__
r = cache.get(key)
if r is None:
- r = bool(
- visitImplements(
- implements, object, self.isEqualOrExtendedBy,
- self._getInterface)
- )
+ r = bool(implements.extends(self))
cache[key] = r
return r
def isImplementedByInstancesOf(self, klass):
"""Do instances of the given class implement the interface?"""
- i = getImplementsOfInstances(klass)
- if i is not None:
- return visitImplements(
- i, klass, self.isEqualOrExtendedBy, self._getInterface)
- return False
+ i = implementedBy(klass)
+ return bool(i.extends(self))
def names(self, all=False):
"""Return the attribute names defined by the interface."""
@@ -329,7 +331,48 @@
return c > 0
-Interface = InterfaceClass("Interface")
+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')
class Attribute(Element):
"""Attribute descriptions
@@ -427,23 +470,21 @@
func = meth.im_func
return fromFunction(func, interface, imlevel=1)
+
# Now we can create the interesting interfaces and wire them up:
def _wire():
-
- from zope.interface.implements import implements
+ from zope.interface.declarations import classImplements
from zope.interface.interfaces import IAttribute
- implements(Attribute, IAttribute)
+ classImplements(Attribute, IAttribute)
from zope.interface.interfaces import IMethod
- implements(Method, IMethod)
+ classImplements(Method, IMethod)
from zope.interface.interfaces import IInterface
- implements(InterfaceClass, IInterface)
+ classImplements(InterfaceClass, IInterface)
# We import this here to deal with module dependencies.
-from zope.interface.implements import getImplementsOfInstances
-from zope.interface.implements import visitImplements, getImplements
-from zope.interface.implements import instancesOfObjectImplements
+from zope.interface.declarations import providedBy, implementedBy
from zope.interface.exceptions import InvalidInterface
from zope.interface.exceptions import BrokenImplementation
=== Zope3/src/zope/interface/type.py 1.7 => 1.8 ===
--- Zope3/src/zope/interface/type.py:1.7 Thu May 1 15:35:44 2003
+++ Zope3/src/zope/interface/type.py Sat May 3 12:36:05 2003
@@ -19,8 +19,8 @@
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
+from zope.interface import Interface, providedBy
from zope.interface.interfaces import IInterface
-from zope.interface._flatten import _flatten
from zope.interface.interfaces import ITypeRegistry
class TypeRegistry:
@@ -72,7 +72,7 @@
def getAll(self, interface_spec):
result = []
- for interface in _flatten(interface_spec):
+ for interface in interface_spec.flattened():
object = self._reg.get(interface)
if object is not None:
result.append(object)
@@ -88,7 +88,7 @@
# XXX This isn't quite right, since it doesn't take into
# account implementation registries for objects that can't
# have '__implements__' attributes.
- return self.getAll(getattr(object, '__implements__', None))
+ return self.getAll(providedBy(object))
def getTypesMatching(self, interface):
if interface is None:
=== Zope3/src/zope/interface/verify.py 1.5 => 1.6 ===
--- Zope3/src/zope/interface/verify.py:1.5 Fri Apr 18 09:59:54 2003
+++ Zope3/src/zope/interface/verify.py Sat May 3 12:36:05 2003
@@ -15,7 +15,7 @@
from zope.interface.exceptions import BrokenImplementation, DoesNotImplement
from zope.interface.exceptions import BrokenMethodImplementation
from types import FunctionType, MethodType
-from zope.interface.interface import fromMethod, fromFunction
+from zope.interface.interface import fromMethod, fromFunction, Method
# This will be monkey-patched when running under Zope 2, so leave this
# here:
@@ -49,6 +49,11 @@
for n, d in iface.namesAndDescriptions(1):
if not hasattr(candidate, n):
+ if (not isinstance(d, Method)) and vtype == 'c':
+ # We can't verify non-methods on classes, since the
+ # class may provide attrs in it's __init__.
+ continue
+
raise BrokenImplementation(iface, n)
attr = getattr(candidate, n)
More information about the Zodb-checkins
mailing list