[Zope3-checkins] CVS: Zope3/src/zope/interface - declarations.py:1.17.10.6 interface.py:1.13.4.5 surrogate.py:1.1.2.4

Jim Fulton jim at zope.com
Thu Oct 16 17:43:09 EDT 2003


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

Modified Files:
      Tag: adaptergeddon-branch
	declarations.py interface.py surrogate.py 
Log Message:
Updated the global adapter service to use the new adapter machinery.


=== Zope3/src/zope/interface/declarations.py 1.17.10.5 => 1.17.10.6 ===
--- Zope3/src/zope/interface/declarations.py:1.17.10.5	Mon Oct 13 11:08:59 2003
+++ Zope3/src/zope/interface/declarations.py	Thu Oct 16 17:42:38 2003
@@ -1093,9 +1093,7 @@
 
 ##############################################################################
 
-
-def _normalizeargs(sequence, output = None,
-                   noexpand=(InterfaceClass, Implements)):
+def _normalizeargs(sequence, output = None):
     """Normalize declaration arguments
 
     Normalization arguments might contain Declarions, tuples, or single
@@ -1105,11 +1103,14 @@
     """
     if output is None:
         output = []
-    for v in sequence:
-        if isinstance(v, noexpand):
-            output.append(v)
-        else:
+
+    cls = sequence.__class__
+    if InterfaceClass in cls.__mro__ or Implements in cls.__mro__:
+        output.append(sequence)
+    else:
+        for v in sequence:
             _normalizeargs(v, output)
+            
     return output
 
 _empty = Declaration()


=== Zope3/src/zope/interface/interface.py 1.13.4.4 => 1.13.4.5 ===
--- Zope3/src/zope/interface/interface.py:1.13.4.4	Sun Oct 12 16:40:12 2003
+++ Zope3/src/zope/interface/interface.py	Thu Oct 16 17:42:38 2003
@@ -17,6 +17,7 @@
 $Id$
 """
 
+from __future__ import generators
 import sys
 import weakref
 from types import FunctionType
@@ -116,15 +117,21 @@
         self.dependents = weakref.WeakKeyDictionary()
         self.__bases__ = tuple(bases)
 
+    def subscribe(self, dependent):
+        self.dependents[dependent] = 1
+
+    def unsubscribe(self, dependent):
+        del self.dependents[dependent]
+
     def __setBases(self, bases):
         # Register ourselves as a dependent of our old bases
         for b in self.__bases__:
-            del b.dependents[self]
+            b.unsubscribe(self)
         
         # Register ourselves as a dependent of our bases
         self.__dict__['__bases__'] = bases
         for b in bases:
-            b.dependents[self] = 1
+            b.subscribe(self)
         
         self.changed()
 


=== Zope3/src/zope/interface/surrogate.py 1.1.2.3 => 1.1.2.4 ===
--- Zope3/src/zope/interface/surrogate.py:1.1.2.3	Sun Oct 12 16:40:12 2003
+++ Zope3/src/zope/interface/surrogate.py	Thu Oct 16 17:42:38 2003
@@ -54,10 +54,14 @@
 # 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):
 
@@ -65,15 +69,21 @@
         self._adapters = {}
         self._implied = {}
         self._interface = weakref.ref(interface)
-        interface.dependents[self] = 1
+        interface.subscribe(self)
 
         self._registry = registry
         self.dependents = weakref.WeakKeyDictionary()
         self.__bases__ = [registry.get(base) for base in interface.__bases__]
         for base in self.__bases__:
-            base.dependents[self] = 1
+            base.subscribe(self)
         self._computeImplied()
 
+    def subscribe(self, dependent):
+        self.dependents[dependent] = 1
+
+    def unsubscribe(self, dependent):
+        del self.dependents[dependent]
+
     def extends(self, other, strict=True):
         if other is self and strict:
             return False
@@ -86,8 +96,8 @@
     def isImplementedBy(self, ob):
         return self._interface().isImplementedBy(ob)
 
-    def _adaptTo(self, specification, factory, name=None, with=()):
-        self._adapters[with, name, specification] = factory
+    def _adaptTo(self, specification, factories, name='', with=()):
+        self._adapters[with, name, specification] = factories
         self.changed()
 
     def changed(self):
@@ -115,19 +125,19 @@
 
             # Add adapters and interfaces directly implied by same:
             items = ancestor._adapters.iteritems()
-            for (with, name, target), factory in items:
+            for (with, name, target), factories in items:
                 if with:
                     self.__add_multi_adapter(with, name, target, target,
                                              implied, registered,
-                                             (factory, ))
-                elif name is not None:
+                                             factories)
+                elif name:
                     self.__add_named_adapter(target, target, name,
                                              implied, registered,
-                                             (factory, ))
+                                             factories)
                 else:
                     self.__add_adapter(target, target,
                                        implied, registered,
-                                       (factory, ))
+                                       factories)
 
 
     def __add_adapter(self, target, provided, implied, registered, factories):
@@ -168,28 +178,33 @@
             self.__add_multi_adapter(interfaces, name, b, provided,
                                      implied, registered, factories)
 
+    def __repr__(self):
+        return '%s(%s)' % (self.__class__.__name__, self._interface())
+
 class SurrogateRegistry(object):
 
     def __init__(self):
         self._surrogates = weakref.WeakKeyDictionary()
-
+        self._default = Surrogate(Default, self)
 
     def get(self, declaration):
+        if declaration is None:
+            return self._default
         surrogate = self._surrogates.get(declaration)
         if surrogate is None:
             surrogate = Surrogate(declaration, self)
             self._surrogates[declaration] = surrogate
         return surrogate
 
-    def provideAdapter(self, required, provided, factory,
-                       name=None, with=()):
+    def provideAdapter(self, required, provided, factories,
+                       name='', with=()):
         required = self.get(required)
         provided = self.get(provided)
         if with:
             with = tuple(map(self.get, with))
         else:
             with = ()
-        required._adaptTo(provided, factory, name, with)
+        required._adaptTo(provided, factories, name or '', with)
 
     def queryAdapter(self, ob, interface, default=None):
         """Query a simple adapter
@@ -228,7 +243,7 @@
         >>> def f1(ob):
         ...     return 1
 
-        >>> registry.provideAdapter(F0, B1, f1)
+        >>> registry.provideAdapter(F0, B1, [f1])
         >>> registry.queryAdapter(c, B0)
         1
 
@@ -237,14 +252,14 @@
         >>> def f2(ob):
         ...     return 2
 
-        >>> registry.provideAdapter(F1, B1, f2)
+        >>> registry.provideAdapter(F1, B1, [f2])
         >>> registry.queryAdapter(c, B0)
         2
         
         >>> def f3(ob):
         ...     return 3
 
-        >>> registry.provideAdapter(F1, B0, f3)
+        >>> registry.provideAdapter(F1, B0, [f3])
         >>> registry.queryAdapter(c, B0)
         3
 
@@ -265,10 +280,12 @@
         
         interface = surrogate
 
-        declaration = providedBy(ob)
+        declaration = removeAllProxies(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:
             for factory in factories:
                 ob = factory(ob)
@@ -305,7 +322,7 @@
         >>> def f1(ob):
         ...     return 1
 
-        >>> registry.provideAdapter(F0, B1, f1, name='bob')
+        >>> registry.provideAdapter(F0, B1, [f1], name='bob')
         >>> registry.queryNamedAdapter(c, B0, 'bob')
         1
         >>> registry.queryNamedAdapter(c, B0, 'bruce')
@@ -314,14 +331,14 @@
         >>> def f2(ob):
         ...     return 2
 
-        >>> registry.provideAdapter(F1, B1, f2, name='bob')
+        >>> registry.provideAdapter(F1, B1, [f2], name='bob')
         >>> registry.queryNamedAdapter(c, B0, 'bob')
         2
         
         >>> def f3(ob):
         ...     return 3
 
-        >>> registry.provideAdapter(F1, B0, f3, name='bob')
+        >>> registry.provideAdapter(F1, B0, [f3], name='bob')
         >>> registry.queryNamedAdapter(c, B0, 'bob')
         3
 
@@ -338,6 +355,8 @@
         declaration = providedBy(ob)
         s = self.get(declaration)
         factories = s._implied.get((interface, name))
+        if factories is None:
+            factories = s._implied.get((Default, name))
         if factories is not None:
             for factory in factories:
                 ob = factory(ob)
@@ -383,7 +402,7 @@
         >>> def f1(ob):
         ...     return 1
 
-        >>> registry.provideAdapter(IF0, IB1, f1, name='bob', with=[IR0])
+        >>> registry.provideAdapter(IF0, IB1, [f1], name='bob', with=[IR0])
         >>> registry.queryMultiAdapter((c, r), IB0, 'bob')
         1
         >>> registry.queryMultiAdapter((c, r), IB0, 'bruce')
@@ -392,7 +411,7 @@
         >>> def f2(ob):
         ...     return 2
 
-        >>> registry.provideAdapter(IF1, IB1, f2, name='bob', with=[IR1])
+        >>> registry.provideAdapter(IF1, IB1, [f2], name='bob', with=[IR1])
         >>> registry.queryMultiAdapter((c, r), IB0, 'bob')
         2
         
@@ -416,6 +435,8 @@
         s = self.get(declaration)
 
         adapters = s._implied.get((interface, name, order))
+        if adapters is None:
+            adapters = s._implied.get((Default, name, order))
         if adapters:
             matched = None
             matched_factories = None
@@ -444,5 +465,166 @@
             return ob
 
         return None
-        
-        
+
+    def getRegisteredMatching(self,
+                              required_interfaces=None,
+                              provided_interfaces=None,
+                              name = None,
+                              ):
+
+        """Search for registered adapters
+
+          Note, this is usually slow!
+
+          >>> from zope.interface import Interface
+
+          >>> class R1(Interface):
+          ...     pass
+          >>> class R12(Interface):
+          ...     pass
+          >>> class R2(R1):
+          ...     pass
+          >>> class R3(R2):
+          ...     pass
+          >>> class R4(R3):
+          ...     pass
+
+          >>> class P1(Interface):
+          ...     pass
+          >>> class P2(P1):
+          ...     pass
+          >>> class P3(P2):
+          ...     pass
+          >>> class P4(P3):
+          ...     pass
+
+
+          >>> registry = SurrogateRegistry()
+          >>> registry.provideAdapter(None, P3, 'default P3')
+          >>> registry.provideAdapter(Interface, P3, 'any P3')
+          >>> registry.provideAdapter(R2, P3, 'R2 P3')
+          >>> registry.provideAdapter(R2, P3, "bobs R2 P3", name='bob')
+
+          >>> from pprint import PrettyPrinter
+          >>> pprint = PrettyPrinter(width=60).pprint
+          >>> def sorted(x):
+          ...    x = [(getattr(r, '__name__', None), p.__name__, w, n, f)
+          ...         for (r, p, w, n, f) in x]
+          ...    x.sort()
+          ...    pprint(x)
+
+          >>> sorted(registry.getRegisteredMatching())
+          [(None, 'P3', (), '', 'default P3'),
+           ('Interface', 'P3', (), '', 'any P3'),
+           ('R2', 'P3', (), '', 'R2 P3'),
+           ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+          >>> sorted(registry.getRegisteredMatching(name=''))
+          [(None, 'P3', (), '', 'default P3'),
+           ('Interface', 'P3', (), '', 'any P3'),
+           ('R2', 'P3', (), '', 'R2 P3')]
+
+          >>> sorted(registry.getRegisteredMatching(required_interfaces=[R1]))
+          [(None, 'P3', (), '', 'default P3'),
+           ('Interface', 'P3', (), '', 'any P3')]
+          
+          >>> sorted(registry.getRegisteredMatching(required_interfaces=R1))
+          [(None, 'P3', (), '', 'default P3'),
+           ('Interface', 'P3', (), '', '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')]
+
+          >>> sorted(registry.getRegisteredMatching(provided_interfaces=P1))
+          [(None, 'P3', (), '', 'default P3'),
+           ('Interface', 'P3', (), '', 'any P3'),
+           ('R2', 'P3', (), '', 'R2 P3'),
+           ('R2', 'P3', (), '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')]
+
+          >>> 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')]
+
+          >>> 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')]
+
+          >>> 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')]
+
+          >>> sorted(registry.getRegisteredMatching(
+          ...     required_interfaces = (R2, ),
+          ...     provided_interfaces = (P3, ),
+          ...     name='bob'))
+          [('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+          >>> sorted(registry.getRegisteredMatching(
+          ...     required_interfaces = (R3, ),
+          ...     provided_interfaces = (P1, ),
+          ...     name='bob'))
+          [('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+          """
+
+        
+        if isinstance(required_interfaces, InterfaceClass):
+            required_interfaces = (required_interfaces, )
+        elif required_interfaces is None:
+            required_interfaces = self._surrogates.keys()
+
+        required_interfaces = tuple(required_interfaces)+(None,)
+
+        if isinstance(provided_interfaces, InterfaceClass):
+            provided_interfaces = (provided_interfaces, )
+
+
+        seen = {}
+
+        for required in required_interfaces:
+            s = self.get(required)
+            for ancestor in ro(s):
+                if ancestor in seen:
+                    continue
+                seen[ancestor] = 1
+                items = ancestor._adapters.iteritems()
+                ancestor = ancestor._interface()
+                if ancestor is Default:
+                    ancestor = None
+                for (with, aname, target), factories in items:
+                    if with:
+                        continue # don't do multi-adapters yet
+                    if name is not None and aname != name:
+                        continue
+
+                    target = target._interface()
+                    if provided_interfaces:
+                        for p in provided_interfaces:
+                            if target.extends(p, False):
+                                break
+                        else:
+                            # None matching
+                            continue
+
+                    yield (ancestor, target, with, aname, factories)




More information about the Zope3-Checkins mailing list