[Zope-Checkins] CVS: Zope3/lib/python/Interface - Verify.py:1.1.2.2 _InterfaceClass.py:1.1.2.2

Jim Fulton jim@zope.com
Tue, 5 Mar 2002 17:48:25 -0500


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

Modified Files:
      Tag: Zope-3x-branch
	Verify.py _InterfaceClass.py 
Log Message:
Interface didn't properly implementg IInterface, because I changed
IImplements today. :)

I fixed this:

- Fixed Verify so that it would at least recognize that the
  implementation didn't accept enough arguments for a couple of
  methods. 

- Added unit tests to check the semantics that Verify can't check.

- Fixed the implementation to pass the tests (and the stricter
  verification.)

Note that a previous checkin failed to mention that verify no longer
checks parameter names, since we have decided that these are not part
of the contract. It would be sort of nice, in the future to be able to
spell which names *are* part of the contact (i.e. which parameters can
be given as keyword arguments)



=== Zope3/lib/python/Interface/Verify.py 1.1.2.1 => 1.1.2.2 ===
     if len(implemented['required']) > len(required['required']):
         return 'implementation requires too many arguments'
+    if ((len(implemented['positional']) < len(required['positional']))
+        and not implemented['varargs']):
+        return "implementation doesn't allow enough arguments"
     if required['kwargs'] and not implemented['kwargs']:
         return "implementation doesn't support keyword arguments"
     if required['varargs'] and not implemented['varargs']:


=== Zope3/lib/python/Interface/_InterfaceClass.py 1.1.2.1 => 1.1.2.2 ===
 from _Element import Element
 
+_marker = object()
+
 class Interface(Element):
     """Prototype (scarecrow) Interfaces Implementation
     """
@@ -85,9 +87,12 @@
     def getBases(self):
         return self.__bases__
 
-    def extends(self, other):
+    def extends(self, other, strict=1):
         """Does an interface extend another?
         """
+        if not strict and self is other:
+            return 1
+        
         for b in self.__bases__:
             if b == other: return 1
             if b.extends(other): return 1
@@ -118,20 +123,52 @@
                 i, klass, self.isEqualOrExtendedBy, self._getInterface)
         return 0
 
-    def names(self):
+    def names(self, all=0):
         """Return the attribute names defined by the interface
         """
-        return self.__attrs.keys()
+        if not all:
+            return self.__attrs.keys()
 
-    def namesAndDescriptions(self):
+        r = {}
+        for name in self.__attrs.keys():
+            r[name] = 1
+        for base in self.__bases__:
+            for name in base.names():
+                r[name] = 1
+        return r.keys()
+            
+    def namesAndDescriptions(self, all=0):
         """Return the attribute names and descriptions defined by the interface
         """
-        return self.__attrs.items()
+        if not all:
+            return self.__attrs.items()
 
-    def getDescriptionFor(self, name, default=None):
+        r = {}
+        for name, d in self.__attrs.items():
+            r[name] = d
+            
+        for base in self.__bases__:
+            for name, d in base.namesAndDescriptions():
+                if name not in r:
+                    r[name] = d
+
+        return r.items()
+
+    def getDescriptionFor(self, name, default=_marker):
         """Return the attribute description for the given name
         """
-        return self.__attrs.get(name, default)
+        r = self.__attrs.get(name, self)
+        if r is not self:
+            return r
+        for base in self.__bases__:
+            r = base.getDescriptionFor(name, self)
+            if r is not self:
+                return r
+            
+        if default is not _marker:
+            return default
+
+        raise KeyError, name
 
     def deferred(self):
         """Return a defered class corresponding to the interface