[Zope-Checkins] CVS: Zope/lib/python/Interface - Util.py:1.7.20.1 __init__.py:1.5.96.1 iclass.py:1.11.20.1

Shane Hathaway shane@digicool.com
Wed, 22 Aug 2001 15:32:06 -0400


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

Modified Files:
      Tag: ComponentArchitecture-branch
	Util.py __init__.py iclass.py 
Log Message:
Moved from NR-branch.


=== Zope/lib/python/Interface/Util.py 1.7 => 1.7.20.1 ===
 from iclass import Interface, Class, ClassTypes, Base, \
-     assertTypeImplements, _typeImplements #uuh..
-from types import FunctionType
+     assertTypeImplements, CLASS_INTERFACES, _typeImplements #uuh..
+from types import FunctionType, StringType
 
 
 def impliedInterface(klass, __name__=None, __doc__=None):
@@ -23,11 +23,31 @@
     for b in klass.__bases__: _ii(b, items)
     return items
     
-def objectImplements(object, tiget=_typeImplements.get):        
+def _listInterfaces(object, implements, getInterface, append):
+    if isinstance(implements, Interface):
+        append(implements)
+    elif implements == CLASS_INTERFACES:
+        klass = getattr(object, '__class__', None)
+        if klass is not None:
+            lst = instancesOfObjectImplements(klass, getInterface)
+            for i in lst:
+                append(i)
+    elif type(implements) is StringType:
+        if getInterface is not None:
+            # Look up the interface.
+            real = getInterface(object, implements, None)
+            if real is not None:
+                append(real)
+    else:
+        # A sequence of interfaces.
+        for i in implements:
+            _listInterfaces(object, i, getInterface, append)
+
+def objectImplements(object, getInterface=None,
+                     tiget=_typeImplements.get):
     """Return the interfaces implemented by the object
     """
-    r=[]
-
+    r = []
     t=type(object)
     if t in ClassTypes:
         if hasattr(object, '__class_implements__'):
@@ -38,19 +58,16 @@
         implements=object.__implements__
     else:
         implements=tiget(t, None)
-        if implements is None: return r
-
-    if isinstance(implements,Interface): r.append(implements)
-    else: _wi(implements, r.append)
-
+        if implements is None:
+            return r
+    _listInterfaces(object, implements, getInterface, r.append)
     return r
-
     
-def instancesOfObjectImplements(klass, tiget=_typeImplements.get):
+def instancesOfObjectImplements(klass, getInterface=None,
+                                tiget=_typeImplements.get):
     """Return the interfaces that instanced implement (by default)
     """
-    r=[]
-
+    r = []
     if type(klass) in ClassTypes:
         if hasattr(klass, '__implements__'):
             implements=klass.__implements__
@@ -60,15 +77,7 @@
         implements=klass.instancesImplements()
     else:
         implements=tiget(klass,None)
-
-    if implements is not None: 
-        if isinstance(implements,Interface): r.append(implements)
-        else: _wi(implements, r.append)
-
+    if implements is None:
+        return r
+    _listInterfaces(klass, implements, getInterface, r.append)
     return r
-
-
-def _wi(interfaces, append):
-    for i in interfaces:
-        if isinstance(i,Interface): append(i)
-        else: _wi(i, append)


=== Zope/lib/python/Interface/__init__.py 1.5 => 1.5.96.1 ===
 new=iclass.Interface
 InterfaceInterface=iclass.InterfaceInterface
+CLASS_INTERFACES = iclass.CLASS_INTERFACES
 # del iclass
 
 from Util import impliedInterface


=== Zope/lib/python/Interface/iclass.py 1.11 => 1.11.20.1 ===
 """
 
+from inspect import currentframe
+import sys
+
 from Method import Method
 from Attr import Attribute
-from types import FunctionType, ClassType
+from types import FunctionType, ClassType, StringType
 import Exceptions
 from InterfaceBase import InterfaceBase
 
 try:
-    from ExtensionClass import Base
+    import ExtensionClass
 except ImportError:
     ClassTypes = (ClassType,)
 else:
-    class dummy (Base): pass
+    class dummy (ExtensionClass.Base): pass
     ClassTypes = (type(dummy), ClassType)
 
 
+# Special value indicating the object supports
+# what its class supports.
+CLASS_INTERFACES = 1
+
+
 _typeImplements={}
 
 class Interface(InterfaceBase):
@@ -32,7 +40,7 @@
 
     def __init__(self, name, bases=(), attrs=None, __doc__=None):
         """Create a new interface
-        """        
+        """
         for b in bases:
             if not isinstance(b, Interface):
                 raise TypeError, 'Expected base interfaces'
@@ -68,7 +76,7 @@
         """Does an interface extend another?
         """
         for b in self.__bases__:
-            if b is other: return 1
+            if b == other: return 1
             if b.extends(other): return 1
         return 0
 
@@ -85,12 +93,9 @@
             implements=object.__implements__
         else:
             implements=tiget(t, None)
-            if implements is None: return 0
-    
-        if isinstance(implements,Interface):
-            return implements is self or implements.extends(self)
-        else:
-            return self.__any(implements)
+            if implements is None:
+                return 0
+        return self._isImplemented(object, implements)
 
     def isImplementedByInstancesOf(self, klass,
                                  tiget=_typeImplements.get):
@@ -105,13 +110,9 @@
             implements=klass.instancesImplement()
         else:
             implements=tiget(klass,None)
-
-        if implements is None: return 0
-        
-        if isinstance(implements,Interface):
-            return implements is self or implements.extends(self)
-        else:
-            return self.__any(implements)
+        if implements is None:
+            return 0
+        return self._isImplemented(klass, implements)
 
     def names(self):
         """Return the attribute names defined by the interface
@@ -143,6 +144,12 @@
 
         return klass
 
+    def _getInterface(self, ob, name):
+        '''
+        Retrieve a named interface.
+        '''
+        return None
+            
     def __d(self, dict):
 
         for k, v in self.__attrs.items():
@@ -150,21 +157,93 @@
                 dict[k]=v
 
         for b in self.__bases__: b.__d(dict)
-            
 
-    def __any(self, interfaces):
-        for i in interfaces:
-            if isinstance(i,Interface):
-                if i is self or i.extends(self): return 1
-            else:
-                if self.__any(i): return 1
+    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))
 
 
-Base=Interface("Interface")
+# Persist interfaces created from classes by reference using
+# a module and name.
+
+
+class InterfaceFromClass (Interface):
+    def __init__(self, name, bases=(), attrs=None, __doc__=None,
+                 __module__=None):
+        if __module__ is None:
+            if attrs is not None and attrs.has_key('__module__'):
+                __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__']
+                except AttributeError, KeyError:
+                    pass
+        self.__module__ = __module__
+        Interface.__init__(self, name, bases, attrs, __doc__)
+
+    def __getinitargs__(self):
+        # What this returns will be passed as arguments to
+        # interface_loader.__call__().
+        if not self.__module__:
+            raise SystemError, 'Module of interface object is unknown'
+        return (self.__module__, self.__name__)
+
+    def __getstate__(self):
+        # No need to save details.
+        return None
+
+    def __setstate__(self, state):
+        assert state == None
+
+    def __repr__(self):
+        name = self.__name__
+        m = self.__module__
+        if m:
+            name = '%s.%s' % (m, name)
+        return "<InterfaceFromClass %s at %x>" % (name, id(self))
+
+
+class InterfaceLoader:
+
+    __safe_for_unpickling__ = 1
+
+    def __call__(self, module, name):
+        __import__(module)
+        mod = sys.modules[module]
+        i = getattr(mod, name)
+        return i
+
+interface_loader = InterfaceLoader()
+
+
+InterfaceFromClass.__name__ = 'interface_loader'  # Trick unpicklers.
+
+Base = InterfaceFromClass("Interface")
+
+
 
 class Named(Base):
     "Objects that have a name."