[Zodb-checkins] CVS: Zope3/src/zope/interface - interface.py:1.13.4.7 interfaces.py:1.15.8.3 surrogate.py:1.1.2.6 type.py:1.10.30.1

Jim Fulton cvs-admin at zope.org
Sun Nov 9 11:09:07 EST 2003


Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv15349/src/zope/interface

Modified Files:
      Tag: adaptergeddon-branch
	interface.py interfaces.py surrogate.py type.py 
Log Message:
Created a global presentation service that replaces the 
global view, resource, and skin services.

Now look up presentation components by adapting from a request type,
rather than adapting to a presentation type.





=== Zope3/src/zope/interface/interface.py 1.13.4.6 => 1.13.4.7 ===
--- Zope3/src/zope/interface/interface.py:1.13.4.6	Thu Nov  6 07:35:10 2003
+++ Zope3/src/zope/interface/interface.py	Sun Nov  9 11:08:33 2003
@@ -230,8 +230,8 @@
             # We directly imply our ancestors:
             implied[ancestor] = ()
 
-        # Now, advize our dependents of change:
-        for dependent in self.dependents:
+        # Now, advise our dependents of change:
+        for dependent in self.dependents.keys():
             dependent.changed()
 
 
@@ -313,6 +313,13 @@
                 and
                 ((not strict) or (self != interface))
                 )
+
+    def weakref(self, callback=None):
+        if callback is None:
+            return weakref.ref(self)
+        else:
+            return weakref.ref(self, callback)
+        
 
 class InterfaceClass(Element, Specification):
     """Prototype (scarecrow) Interfaces Implementation."""


=== Zope3/src/zope/interface/interfaces.py 1.15.8.2 => 1.15.8.3 ===
--- Zope3/src/zope/interface/interfaces.py:1.15.8.2	Thu Nov  6 07:35:10 2003
+++ Zope3/src/zope/interface/interfaces.py	Sun Nov  9 11:08:33 2003
@@ -55,7 +55,44 @@
         """Return a signature string suitable for inclusion in documentation.
         """
 
-class IInterface(IElement):
+class ISpecification(Interface):
+    """Object Behavioral specifications
+    """
+
+    def extends(other, strict=True):
+        """Test whether a specification extends another
+
+        The specification extends other if it has other as a base
+        interface or if one of it's bases extends other.
+
+        If strict is false, then the specification extends itself.
+        
+        """
+
+    def isOrExtends(other):
+        """Test whether the specification is or extends another
+        """
+
+    def weakref(callback=None):
+        """Return a weakref to the specification
+
+        This method is, regrettably, needed to allow weakrefs to be
+        computed to security-proxied specifications.  While the
+        zope.interface package does not require zope.security or
+        zope.proxy, it has to be able to coexist with it.
+
+        """
+
+    __bases__ = Attribute("""Base specifications
+
+    A tuple if specifications from which this specification is
+    directly derived.
+
+    """)
+
+
+        
+class IInterface(ISpecification, IElement):
     """Interface objects
 
     Interface objects describe the behavior of an object by containing
@@ -147,26 +184,6 @@
 
     """
 
-
-    def extends(other, strict=True):
-        """Test whether the interface extends another interface
-
-        A true value is returned in the interface extends the other
-        interface, and false otherwise.
-
-        Normally, an interface doesn't extend itself. If a false value
-        is passed as the second argument, or via the 'strict' keyword
-        argument, then a true value will be returned if the interface
-        and the other interface are the same.
-        """
-
-    def isOrExtends(other):
-        """Test whether the interface is or extends another interface
-
-        A true value is returned in the interface is or extends the other
-        interface, and false otherwise.
-        """
-
     def isImplementedBy(object):
         """Test whether the interface is implemented by the object
 
@@ -239,8 +256,6 @@
         """
 
     __module__ = Attribute("""The name of the module defining the interface""")
-
-    __bases__ = Attribute("""A tuple of base interfaces""")
                                
     
 
@@ -437,7 +452,7 @@
 
         """
 
-class IDeclaration(Interface):
+class IDeclaration(ISpecification):
     """Interface declaration
 
     Declarations are used to express the interfaces implemented by
@@ -466,21 +481,6 @@
         base interfaces are listed after interfaces that extend them
         and, otherwise, interfaces are included in the order that they
         were defined in the specification.
-        """
-
-    def extends(interface):
-        """Test whether an interface specification extends an interface
-
-        An interface specification extends an interface if it contains
-        an interface that extends an interface.
-        
-        """
-
-    def isOrExtends(other):
-        """Test whether the interface is or extends another interface
-
-        A true value is returned in the interface is or extends the other
-        interface, and false otherwise.
         """
 
     def __sub__(interfaces):


=== Zope3/src/zope/interface/surrogate.py 1.1.2.5 => 1.1.2.6 ===
--- Zope3/src/zope/interface/surrogate.py:1.1.2.5	Thu Oct 16 18:48:28 2003
+++ Zope3/src/zope/interface/surrogate.py	Sun Nov  9 11:08:33 2003
@@ -16,59 +16,76 @@
 $Id$
 """
 
-# Optimization notes
+# Implementation notes
 
-# For each surrogate, we store a dict {key -> factories}
+# We keep a collection of surregates.
+
+# A surrogate is a surrogate for a specifiocation (interface or
+# declaration).  We use wek references in order to remove surrogates if
+# the corresponding specification goes away.
+
+# Each surrogate keeps track of:
+
+# - The adapters registered directly for that surrogate, and
+
+# - The "implied" adapters, which is the adapters that can be computed
+#   from instances of that surrogate.
+
+# The later data structure takes into account adapters registered for
+# specifications that the registered surrogate extends.
+
+# The registrations are of the form:
+
+#   {(with, name, specification) -> factories}
+
+# where:
+
+#   with is a tuple of surrogates that is non-empty only in the case
+#   of multi-adapters.  
+
+#   name is a unicode adapter name.  Unnamed adapters have an empty
+#   name.
+
+#   specification is the surrogate of the interface being adapted to.
+
+#   factories is normally a tuple of factories, but can be anything.
+#   (See the "raw" option to the query-adapter calls.)
+
+# The implied adapters are held in a single dictionary. The items in the
+# dictionary are of 3 forms:
+
+#   specification -> factories
+
+#      for simple unnamed adapters
+
+#   (specification, name) -> factories
+
+#      for named adapters
+
+#   (specification, name, order) -> {with -> factories}
+
+#      for multi-adapters.  
 
-# where key is one of
-#  provides,
-#  provided, name
-#  provided, name, order
-
-# Currently, we stora all of the keys in a single dict:
-
-# consider named adapters. Each key is a two-tuple.
-# That's 5 extra words per key for the tuple.
-
-# suppose that the dict was of the form:
-#   {name -> {provided -> factroies}
-
-# This saves n-1 * 5 words, where n is the number of entries for a
-# given name. There is the overhead of an extra dictionary per
-# word. Given that many interfaces only have a single entry, this
-# extra overhead could be significant, however, there are some extra
-# opportunities for savings. See below. There are two dict lookups,
-# but, possibly, each lookup is cheaper, because the cache and
-# comparisons are cheaper.
-
-# It will often be the case that an implied dict (for a required
-# interface and name (and order), will be equal to the implied dict
-# for one of the interfaces bases. This will happen, for example, when
-# there aren't adapters registered for an interface and the interface
-# has one base.  In a case like this, the interface can share the
-# implied dict with the base.
-
-# Additional savings will be permitted for local surrogates.  For
-# example, it will often be the case that the implied dictionary
-# for a local surrogate will be the same as the implied dictionary for
-# it's base (less local) surogate. In this case too, the dictionary
-# can be saved.
 
 from __future__ import generators
 import weakref
 from zope.interface.ro import ro
 from zope.interface.declarations import providedBy
 from zope.interface.interface import InterfaceClass
-from zope.proxy import removeAllProxies
 
 Default = InterfaceClass("Default", (), {})
 
 class Surrogate(object):
+    """Specification surrogate
+
+    A specification surrogate is used to hold adapter registrations on
+    behalf of a specification.
+    """
 
     def __init__(self, interface, registry):
         self._adapters = {}
         self._implied = {}
-        self._interface = weakref.ref(interface)
+        self._interface = interface.weakref()
         interface.subscribe(self)
 
         self._registry = registry
@@ -96,7 +113,7 @@
 
     def changed(self):
         self._computeImplied()
-        for dependent in self.dependents:
+        for dependent in self.dependents.keys():
             dependent.changed()
         
     def _computeImplied(self):
@@ -173,31 +190,62 @@
         return '%s(%s)' % (self.__class__.__name__, self._interface())
 
 class SurrogateRegistry(object):
+    """Surrogate registry
+    """
+
+    # Implementation node:
+    # We are like a weakref dict ourselves. We can't use a weakref
+    # dict because we have to use spec.weakref() rather than
+    # weakref.ref(spec) to get weak refs to specs.
 
     def __init__(self):
-        self._surrogates = weakref.WeakKeyDictionary()
+        self._surrogates = {}
         self._default = Surrogate(Default, self)
 
+        def _remove(k, selfref=weakref.ref(self)):
+            self = selfref()
+            if self is not None:
+                try:
+                    del self._surrogates[k]
+                except KeyError:
+                    pass
+        self._remove = _remove
+
+
     def get(self, declaration):
         if declaration is None:
             return self._default
-        surrogate = self._surrogates.get(declaration)
+
+        ref = declaration.weakref(self._remove)
+        surrogate = self._surrogates.get(ref)
         if surrogate is None:
             surrogate = Surrogate(declaration, self)
-            self._surrogates[declaration] = surrogate
+            self._surrogates[ref] = surrogate
+
         return surrogate
 
+
     def provideAdapter(self, required, provided, factories,
-                       name='', with=()):
+                       name=u'', with=()):
+        """Register an adapter
+
+        Note that the given name must be convertable to unicode.
+        Use an empty string for unnamed adapters. It is impossible to
+        have a named adapter with an empty name.
+        """
         required = self.get(required)
         provided = self.get(provided)
         if with:
             with = tuple(map(self.get, with))
         else:
             with = ()
-        required._adaptTo(provided, factories, name or '', with)
 
-    def queryAdapter(self, ob, interface, default=None):
+        if not isinstance(name, basestring):
+            raise TypeError("The name provided to provideAdapter "
+                            "must be a string or unicode")
+        required._adaptTo(provided, factories, unicode(name), with)
+
+    def queryAdapter(self, ob, interface, default=None, raw=False):
         """Query a simple adapter
 
         >>> import zope.interface
@@ -256,10 +304,7 @@
 
 
         """
-        
-        surrogates = self._surrogates
-        
-        surrogate = surrogates.get(interface)
+        surrogate = self._surrogates.get(interface.weakref())
         if surrogate is None:
             # If there is no surrogate for the interface, then we can't
             # have an adapter for it.
@@ -271,20 +316,24 @@
         
         interface = surrogate
 
-        declaration = removeAllProxies(providedBy(ob))
+        declaration = providedBy(ob)
         s = self.get(declaration)
 
         factories = s._implied.get(interface)
         if factories is None:
             factories = self._default._implied.get(interface)
+
         if factories is not None:
+            if raw:
+                return factories
+            
             for factory in factories:
                 ob = factory(ob)
             return ob
 
         return default
 
-    def queryNamedAdapter(self, ob, interface, name, default=None):
+    def queryNamedAdapter(self, ob, interface, name, default=None, raw=False):
         """Query a named simple adapter
 
         >>> import zope.interface
@@ -333,11 +382,8 @@
         >>> registry.queryNamedAdapter(c, B0, 'bob')
         3
 
-
         """
-        surrogates = self._surrogates
-        
-        interface = surrogates.get(interface)
+        interface = self._surrogates.get(interface.weakref())
         if interface is None:
             # If there is no surrogate for the interface, then we can't
             # have an adapter for it.
@@ -347,15 +393,18 @@
         s = self.get(declaration)
         factories = s._implied.get((interface, name))
         if factories is None:
-            factories = s._implied.get((Default, name))
+            factories = self._default._implied.get((interface, name))
         if factories is not None:
+            if raw:
+                return factories
             for factory in factories:
                 ob = factory(ob)
             return ob
 
         return default
 
-    def queryMultiAdapter(self, objects, interface, name):
+    def queryMultiAdapter(self, objects, interface, name=u'',
+                          default=None, raw=False):
         """
 
         >>> import zope.interface
@@ -379,7 +428,7 @@
 
         >>> registry = SurrogateRegistry()
 
-        If we ask for a named adapter, we won't get a result unless there
+        If we ask for a multi adapter, we won't get a result unless there
         is a named adapter, even if the object implements the interface:
 
         >>> registry.queryMultiAdapter((c, r), IF0, 'bob')
@@ -390,29 +439,36 @@
         ...     pass
 
 
-        >>> def f1(ob):
-        ...     return 1
+        >>> class f1:
+        ...     def __init__(self, x, y):
+        ...         self.x, self.y = x, y
+
 
         >>> registry.provideAdapter(IF0, IB1, [f1], name='bob', with=[IR0])
-        >>> registry.queryMultiAdapter((c, r), IB0, 'bob')
-        1
-        >>> registry.queryMultiAdapter((c, r), IB0, 'bruce')
+        >>> a = registry.queryMultiAdapter((c, r), IB0, 'bob')
+        >>> a.__class__ is f1
+        True
+        >>> a.x is c
+        True
+        >>> a.y is r
+        True
 
+        >>> registry.queryMultiAdapter((c, r), IB0, 'bruce')
 
-        >>> def f2(ob):
-        ...     return 2
+        >>> class f2(f1):
+        ...     pass
 
         >>> registry.provideAdapter(IF1, IB1, [f2], name='bob', with=[IR1])
-        >>> registry.queryMultiAdapter((c, r), IB0, 'bob')
-        2
+        >>> a = registry.queryMultiAdapter((c, r), IB0, 'bob')
+        >>> a.__class__ is f2
+        True
+        >>> a.x is c
+        True
+        >>> a.y is r
+        True
         
-        >>> def f3(ob):
-        ...     return 3
-
         """
-        surrogates = self._surrogates
-        
-        interface = surrogates.get(interface)
+        interface = self._surrogates.get(interface.weakref())
         if interface is None:
             # If there is no surrogate for the interface, then we can't
             # have an adapter for it.
@@ -420,19 +476,20 @@
 
         ob = objects[0]
         order = len(objects)
-        objects = objects[1:]
+        obs = objects[1:]
 
         declaration = providedBy(ob)
         s = self.get(declaration)
 
         adapters = s._implied.get((interface, name, order))
         if adapters is None:
-            adapters = s._implied.get((Default, name, order))
+            adapters = self._default._implied.get((interface, name, order))
+
         if adapters:
             matched = None
             matched_factories = None
             for interfaces, factories in adapters.iteritems():
-                for iface, ob in zip(interfaces, objects):
+                for iface, ob in zip(interfaces, obs):
                     if not iface.isImplementedBy(ob):
                         break # This one is no good
                 else:
@@ -451,11 +508,17 @@
                                 # old is better than new
                                 break                
 
-            for factory in matched_factories:
-                ob = factory(ob)
-            return ob
+            if matched_factories is None:
+                return default
+            
+            if raw:
+                return matched_factories
 
-        return None
+            assert len(matched_factories) == 1
+
+            return matched_factories[0](*objects)
+
+        return default
 
     def getRegisteredMatching(self,
                               required_interfaces=None,
@@ -505,85 +568,88 @@
           ...    pprint(x)
 
           >>> sorted(registry.getRegisteredMatching())
-          [(None, 'P3', (), '', 'default P3'),
-           ('Interface', 'P3', (), '', 'any P3'),
-           ('R2', 'P3', (), '', 'R2 P3'),
-           ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+          [(None, 'P3', (), u'', 'default P3'),
+           ('Interface', 'P3', (), u'', 'any P3'),
+           ('R2', 'P3', (), u'', 'R2 P3'),
+           ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
 
           >>> sorted(registry.getRegisteredMatching(name=''))
-          [(None, 'P3', (), '', 'default P3'),
-           ('Interface', 'P3', (), '', 'any P3'),
-           ('R2', 'P3', (), '', 'R2 P3')]
+          [(None, 'P3', (), u'', 'default P3'),
+           ('Interface', 'P3', (), u'', 'any P3'),
+           ('R2', 'P3', (), u'', 'R2 P3')]
 
           >>> sorted(registry.getRegisteredMatching(required_interfaces=[R1]))
-          [(None, 'P3', (), '', 'default P3'),
-           ('Interface', 'P3', (), '', 'any P3')]
+          [(None, 'P3', (), u'', 'default P3'),
+           ('Interface', 'P3', (), u'', 'any P3')]
           
           >>> sorted(registry.getRegisteredMatching(required_interfaces=R1))
-          [(None, 'P3', (), '', 'default P3'),
-           ('Interface', 'P3', (), '', 'any P3')]
+          [(None, 'P3', (), u'', 'default P3'),
+           ('Interface', 'P3', (), u'', 'any P3')]
           
           >>> sorted(registry.getRegisteredMatching(provided_interfaces=[P1]))
-          [(None, 'P3', (), '', 'default P3'),
-           ('Interface', 'P3', (), '', 'any P3'),
-           ('R2', 'P3', (), '', 'R2 P3'),
-           ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+          [(None, 'P3', (), u'', 'default P3'),
+           ('Interface', 'P3', (), u'', 'any P3'),
+           ('R2', 'P3', (), u'', 'R2 P3'),
+           ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
 
           >>> sorted(registry.getRegisteredMatching(provided_interfaces=P1))
-          [(None, 'P3', (), '', 'default P3'),
-           ('Interface', 'P3', (), '', 'any P3'),
-           ('R2', 'P3', (), '', 'R2 P3'),
-           ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+          [(None, 'P3', (), u'', 'default P3'),
+           ('Interface', 'P3', (), u'', 'any P3'),
+           ('R2', 'P3', (), u'', 'R2 P3'),
+           ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
 
           >>> sorted(registry.getRegisteredMatching(provided_interfaces=P3))
-          [(None, 'P3', (), '', 'default P3'),
-           ('Interface', 'P3', (), '', 'any P3'),
-           ('R2', 'P3', (), '', 'R2 P3'),
-           ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+          [(None, 'P3', (), u'', 'default P3'),
+           ('Interface', 'P3', (), u'', 'any P3'),
+           ('R2', 'P3', (), u'', 'R2 P3'),
+           ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
 
           >>> sorted(registry.getRegisteredMatching(
           ...     required_interfaces = (R4, R12),
           ...     provided_interfaces = (P1, )))
-          [(None, 'P3', (), '', 'default P3'),
-           ('Interface', 'P3', (), '', 'any P3'),
-           ('R2', 'P3', (), '', 'R2 P3'),
-           ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+          [(None, 'P3', (), u'', 'default P3'),
+           ('Interface', 'P3', (), u'', 'any P3'),
+           ('R2', 'P3', (), u'', 'R2 P3'),
+           ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
 
           >>> sorted(registry.getRegisteredMatching(
           ...     required_interfaces = (R4, R12),
           ...     provided_interfaces = (P3, )))
-          [(None, 'P3', (), '', 'default P3'),
-           ('Interface', 'P3', (), '', 'any P3'),
-           ('R2', 'P3', (), '', 'R2 P3'),
-           ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+          [(None, 'P3', (), u'', 'default P3'),
+           ('Interface', 'P3', (), u'', 'any P3'),
+           ('R2', 'P3', (), u'', 'R2 P3'),
+           ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
 
           >>> sorted(registry.getRegisteredMatching(
           ...     required_interfaces = (R2, ),
           ...     provided_interfaces = (P3, )))
-          [(None, 'P3', (), '', 'default P3'),
-           ('Interface', 'P3', (), '', 'any P3'),
-           ('R2', 'P3', (), '', 'R2 P3'),
-           ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+          [(None, 'P3', (), u'', 'default P3'),
+           ('Interface', 'P3', (), u'', 'any P3'),
+           ('R2', 'P3', (), u'', 'R2 P3'),
+           ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
 
           >>> sorted(registry.getRegisteredMatching(
           ...     required_interfaces = (R2, ),
           ...     provided_interfaces = (P3, ),
           ...     name='bob'))
-          [('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+          [('R2', 'P3', (), u'bob', 'bobs R2 P3')]
 
           >>> sorted(registry.getRegisteredMatching(
           ...     required_interfaces = (R3, ),
           ...     provided_interfaces = (P1, ),
           ...     name='bob'))
-          [('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+          [('R2', 'P3', (), u'bob', 'bobs R2 P3')]
 
           """
 
+        if name is not None:
+            name = unicode(name)
         
         if isinstance(required_interfaces, InterfaceClass):
             required_interfaces = (required_interfaces, )
         elif required_interfaces is None:
-            required_interfaces = self._surrogates.keys()
+            required_interfaces = [ref() for ref in self._surrogates.keys()
+                                   if ref() is not None]
 
         required_interfaces = tuple(required_interfaces)+(None,)
 


=== Zope3/src/zope/interface/type.py 1.10 => 1.10.30.1 ===
--- Zope3/src/zope/interface/type.py:1.10	Sat Jun  7 02:37:29 2003
+++ Zope3/src/zope/interface/type.py	Sun Nov  9 11:08:33 2003
@@ -96,7 +96,7 @@
 
         result = []
         for k in self._reg:
-            if k is None or k.extends(interface, strict=False):
+            if k is None or k.extends(interface, False):
                 result.append(k)
         return result
 




More information about the Zodb-checkins mailing list