[Zope-Checkins] CVS: Zope/lib/python/Interface - Util.py:1.7.20.4 iclass.py:1.11.20.3

Shane Hathaway shane@digicool.com
Wed, 12 Sep 2001 17:57:19 -0400


Update of /cvs-repository/Zope/lib/python/Interface
In directory cvs.zope.org:/tmp/cvs-serv3763

Modified Files:
      Tag: ComponentArchitecture-branch
	Util.py iclass.py 
Log Message:
Finally eliminated duplication of logic.


=== Zope/lib/python/Interface/Util.py 1.7.20.3 => 1.7.20.4 ===
-from iclass import Interface, Class, ClassTypes, Base, \
-     assertTypeImplements, CLASS_INTERFACES, _typeImplements #uuh..
+from iclass import Interface, assertTypeImplements, CLASS_INTERFACES, \
+     getImplements, getImplementsOfInstances, visitImplements
 from types import FunctionType, StringType
 
 
@@ -24,72 +24,20 @@
     return items
 
 
-def _visitRecursively(object, implements, visitor, getInterface):
-    r = None
-    if isinstance(implements, Interface):
-        r = visitor(implements)
-    elif implements == CLASS_INTERFACES:
-        klass = getattr(object, '__class__', None)
-        if klass is not None:
-            r = visitInterfacesOfInstances(klass, visitor, getInterface)
-    elif type(implements) is StringType:
-        if getInterface is not None:
-            # Look up a named interface.
-            real = getInterface(object, implements)
-            if real is not None:
-                r = _visitRecursively(object, real, visitor, getInterface)
-    else:
-        # A sequence of interfaces.
-        for i in implements:
-            r = _visitRecursively(object, i, visitor, getInterface)
-            if r:
-                break
-    return r
-
-
-def visitInterfaces(object, visitor, getInterface=None):
-    t = type(object)
-    if t in ClassTypes:
-        if hasattr(object, '__class_implements__'):
-            implements=object.__class_implements__
-        else:
-            implements=Class
-    elif hasattr(object, '__implements__'):
-        implements = object.__implements__
-    else:
-        implements = _typeImplements.get(t, None)
-        if implements is None:
-            return None
-    return _visitRecursively(object, implements, visitor, getInterface)
-
-
-def visitInterfacesOfInstances(klass, visitor, getInterface=None):
-    if type(klass) in ClassTypes:
-        if hasattr(klass, '__implements__'):
-            implements = klass.__implements__
-        else:
-            return None
-    elif hasattr(klass, 'instancesImplements'):
-        # Hook for ExtensionClass. :)
-        # XXX Potential security problem since "instancesImplements"
-        # is a valid Zope identifier.
-        implements = klass.instancesImplements()
-    else:
-        implements = _typeImplements.get(klass, None)
-    if implements is None:
-        return None
-    return _visitRecursively(klass, implements, visitor, getInterface)
-
-
 def objectImplements(object, getInterface=None):
     r = []
-    visitInterfaces(object, r.append, getInterface)
+    implements = getImplements(object)
+    if not implements:
+        return r
+    visitImplements(implements, object, r.append, getInterface)
     return r
 
 
 def instancesOfObjectImplements(klass, getInterface=None):
     r = []
-    visitInterfacesOfInstances(klass, r.append, getInterface)
+    implements = getImplementsOfInstances(klass)
+    if not implements:
+        return r
+    visitImplements(implements, klass, r.append, getInterface)
     return r
-
 


=== Zope/lib/python/Interface/iclass.py 1.11.20.2 => 1.11.20.3 ===
 CLASS_INTERFACES = 1
 
-
 _typeImplements={}
 
+
+def getImplements(object, tiget=_typeImplements.get):
+    t = type(object)
+    if t in ClassTypes:
+        if hasattr(object, '__class_implements__'):
+            return object.__class_implements__
+        else:
+            return Class
+    elif hasattr(object, '__implements__'):
+        return object.__implements__
+    else:
+        return tiget(t, None)
+
+
+def getImplementsOfInstances(klass, tiget=_typeImplements.get):
+    if type(klass) in ClassTypes:
+        if hasattr(klass, '__implements__'):
+            return klass.__implements__
+        else:
+            return None
+    elif hasattr(klass, 'instancesImplements'):
+        # Hook for ExtensionClass. :)
+        # XXX Potential security problem since "instancesImplements"
+        # is a valid Zope identifier.
+        return klass.instancesImplements()
+    else:
+        return tiget(klass, None)
+
+
+def visitImplements(implements, object, visitor, getInterface=None):
+    """
+    Visits the interfaces described by an __implements__ attribute,
+    invoking the visitor for each interface object.
+    If the visitor returns anything true, the loop stops.
+    This does not, and should not, visit superinterfaces.
+    """
+    if isinstance(implements, Interface):
+        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 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)
+    else:
+        # A sequence of interfaces.
+        for i in implements:
+            r = visitImplements(i, object, visitor, getInterface)
+            if r:
+                # If the visitor returns anything true, stop.
+                return r
+    return None
+
+
 class Interface(InterfaceBase):
     """Prototype (scarecrow) Interfaces Implementation
     """
@@ -79,39 +138,30 @@
             if b.extends(other): return 1
         return 0
 
-    def isImplementedBy(self, object,
-                      tiget=_typeImplements.get):
+    def isEqualOrExtendedBy(self, other):
+        """Same interface or extends?
+        """
+        if self == other:
+            return 1
+        return other.extends(self)
+
+    def isImplementedBy(self, object):
         """Does the given object implement the interface?
         """
-        t=type(object)
-        if t in ClassTypes:
-            if hasattr(object, '__class_implements__'):
-                implements=object.__class_implements__
-            else: implements=Class
-        elif hasattr(object, '__implements__'):
-            implements=object.__implements__
-        else:
-            implements=tiget(t, None)
-            if implements is None:
-                return 0
-        return self._isImplemented(object, implements)
+        i = getImplements(object)
+        if i is not None:
+            return visitImplements(
+                i, object, self.isEqualOrExtendedBy, self._getInterface)
+        return 0
 
-    def isImplementedByInstancesOf(self, klass,
-                                 tiget=_typeImplements.get):
+    def isImplementedByInstancesOf(self, klass):
         """Do instances of the given class implement the interface?
         """
-        if type(klass) in ClassTypes:
-            if hasattr(klass, '__implements__'):
-                implements=klass.__implements__
-            else: return 0
-        elif hasattr(klass, 'instancesImplement'):
-            # Hook for ExtensionClass. :)
-            implements=klass.instancesImplement()
-        else:
-            implements=tiget(klass,None)
-        if implements is None:
-            return 0
-        return self._isImplemented(klass, implements)
+        i = getImplementsOfInstances(klass)
+        if i is not None:
+            return visitImplements(
+                i, klass, self.isEqualOrExtendedBy, self._getInterface)
+        return 0
 
     def names(self):
         """Return the attribute names defined by the interface
@@ -156,26 +206,6 @@
                 dict[k]=v
 
         for b in self.__bases__: b.__d(dict)
-
-    def _isImplemented(self, object, implements):
-        if isinstance(implements, Interface):
-            return implements == self or implements.extends(self)
-        elif implements == CLASS_INTERFACES:
-            # Include the interfaces implemented by the
-            # class of the object, if any.
-            klass = getattr(object, '__class__', None)
-            if klass is not None:
-                return self.isImplementedByInstancesOf(klass)
-        elif type(implements) is StringType:
-            # Look up the interface.
-            real = self._getInterface(object, implements)
-            if real is not None:
-                append(real)
-        else:
-            for i in implements:
-                if self._isImplemented(object, i):
-                    return 1
-        return 0
 
     def __repr__(self):
         return "<Interface %s at %x>" % (self.__name__, id(self))