[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))