[Zope3-checkins] CVS: Zope3/src/zope/interface - surrogate.py:1.1.2.9

Jim Fulton cvs-admin at zope.org
Tue Nov 11 10:52:34 EST 2003


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

Modified Files:
      Tag: adaptergeddon-branch
	surrogate.py 
Log Message:
Did some refactoring in preparation for local surrogate registries.

- Changed adapter registrations to not use weakrefs.

- Factored out code for computing implied info based on adapter
  registrations.

- Changed the strategy for computing the "implied" data structure to
  merge surrogate-local implied data structures, reducing the amound
  of computation done.


=== Zope3/src/zope/interface/surrogate.py 1.1.2.8 => 1.1.2.9 ===
--- Zope3/src/zope/interface/surrogate.py:1.1.2.8	Mon Nov 10 15:45:20 2003
+++ Zope3/src/zope/interface/surrogate.py	Tue Nov 11 10:52:33 2003
@@ -97,8 +97,6 @@
         for base in self.__bases__:
             base.subscribe(self)
 
-        self._computeImplied()
-
     def subscribe(self, dependent):
         self.dependents[dependent] = 1
 
@@ -112,8 +110,17 @@
         return self._interface().isImplementedBy(ob)
 
     def _adaptTo(self, specification, factories, name='', with=()):
-        self._adapters[with, name, specification] = factories
-        self._computeSelfImplied()
+        if factories is None:
+            try:
+                del self._adapters[with, name, specification]
+            except KeyError:
+                pass
+        else:
+            self._adapters[with, name, specification] = factories
+
+        adapterImplied(self._adapters,
+                       self._selfimplied,
+                       self._multimplied)
         self.changed()
 
     def changed(self):
@@ -121,28 +128,6 @@
         for dependent in self.dependents.keys():
             dependent.changed()
 
-    def _computeSelfImplied(self):
-        implied = self._selfimplied
-        implied.clear()
-        multi = self._multimplied
-        multi.clear()
-        registered = {}
-
-        # Add adapters and interfaces directly implied by same:
-        for (with, name, target), factories in self._adapters.iteritems():
-            if with:
-                self.__add_multi_adapter(with, name, target, target,
-                                         multi, factories)
-            elif name:
-                self.__add_named_adapter(target, target, name,
-                                         implied, registered,
-                                         factories)
-            else:
-                self.__add_adapter(target, target,
-                                   implied, registered,
-                                   factories)
-
-        
     def _computeImplied(self):
         implied = self._implied
         implied.clear()
@@ -162,44 +147,6 @@
                     implied[k] = ancestor_adapters.copy()
             
 
-    def __add_adapter(self, target, provided, implied, registered, factories):
-        if (target not in implied
-            or
-            (target in registered and registered[target].extends(provided))
-            ):
-            registered[target] = provided
-            implied[target] = factories
-            for b in target.__bases__:
-                self.__add_adapter(b, provided, implied, registered, factories)
-
-    def __add_named_adapter(self, target, provided, name,
-                            implied, registered, factories):
-        key = target, name
-        if (key not in implied
-            or
-            (key in registered and registered[key].extends(provided))
-            ):
-            registered[key] = provided
-            implied[key] = factories
-            for b in target.__bases__:
-                self.__add_named_adapter(b, provided, name,
-                                         implied, registered, factories)
-
-    def __add_multi_adapter(self, interfaces, name, target, provided,
-                            implied, factories):
-
-        order = len(interfaces)+1
-        adapters = implied.get((target, name, order))
-        if adapters is None:
-            adapters = {}
-            implied[(target, name, order)] = adapters
-
-        adapters.setdefault(interfaces, factories)
-        
-        for b in target.__bases__:
-            self.__add_multi_adapter(interfaces, name, b, provided,
-                                     implied, factories)
-
     def __repr__(self):
         return '%s(%s)' % (self.__class__.__name__, self._interface())
 
@@ -212,30 +159,20 @@
     # dict because we have to use spec.weakref() rather than
     # weakref.ref(spec) to get weak refs to specs.
 
+    _surrogateClass = Surrogate
+
     def __init__(self):
         self._surrogates = 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._default = self._surrogateClass(Default, self)
 
-        def _remove(k, surrogates=surrogates):
+        def _remove(k):
             try:
                 del surrogates[k]
             except KeyError:
                 pass
 
-
-
         self._remove = _remove
 
-
     def get(self, declaration):
         if declaration is None:
             return self._default
@@ -243,7 +180,8 @@
         ref = declaration.weakref(self._remove)
         surrogate = self._surrogates.get(ref)
         if surrogate is None:
-            surrogate = Surrogate(declaration, self)
+            surrogate = self._surrogateClass(declaration, self)
+            surrogate._computeImplied()
             self._surrogates[ref] = surrogate
 
         return surrogate
@@ -258,9 +196,8 @@
         have a named adapter with an empty name.
         """
         required = self.get(required)
-        provided = self.get(provided)
         if with:
-            with = tuple(map(self.get, with))
+            with = tuple(with)
         else:
             with = ()
 
@@ -272,73 +209,55 @@
     def queryAdapter(self, ob, interface, default=None, raw=False):
         """Query a simple adapter
 
-        >>> import zope.interface
-        >>> class F0(zope.interface.Interface):
-        ...     pass
-        >>> class F1(F0):
-        ...     pass
+           >>> import zope.interface
+           >>> class F0(zope.interface.Interface):
+           ...     pass
+           >>> class F1(F0):
+           ...     pass
 
-        >>> class C:
-        ...     zope.interface.implements(F1)
-        >>> c = C()
+           >>> class C:
+           ...     zope.interface.implements(F1)
+           >>> c = C()
 
-        >>> registry = SurrogateRegistry()
+           >>> registry = SurrogateRegistry()
 
-        When we adapt an object to an interface it implements, we get
-        the object back:
+           Adapting to some other interface for which there is no
+           adapter returns the default:
 
-        >>> registry.queryAdapter(c, F0) is c
-        1
+           >>> class B0(zope.interface.Interface):
+           ...     pass
+           >>> class B1(B0):
+           ...     pass
 
-        But adapting to some other interface returns the default:
-            
-        >>> class B0(zope.interface.Interface):
-        ...     pass
-        >>> class B1(B0):
-        ...     pass
+           >>> registry.queryAdapter(c, B0)
+           >>> registry.queryAdapter(c, B0, 42)
+           42
 
-        >>> registry.queryAdapter(c, B0)
-        >>> registry.queryAdapter(c, B0, 42)
-        42
+           Unless we define an adapter:
 
-        Unless we define an adapter:
+           >>> def f1(ob):
+           ...     return 1
 
-        >>> def f1(ob):
-        ...     return 1
+           >>> registry.provideAdapter(F0, B1, [f1])
+           >>> registry.queryAdapter(c, B0)
+           1
 
-        >>> registry.provideAdapter(F0, B1, [f1])
-        >>> registry.queryAdapter(c, B0)
-        1
-
-        If we define a more specific adapter (for F1), we'll get that:
-
-        >>> def f2(ob):
-        ...     return 2
+           If we define a more specific adapter (for F1), we'll get that:
 
-        >>> registry.provideAdapter(F1, B1, [f2])
-        >>> registry.queryAdapter(c, B0)
-        2
-        
-        >>> def f3(ob):
-        ...     return 3
+           >>> def f2(ob):
+           ...     return 2
 
-        >>> registry.provideAdapter(F1, B0, [f3])
-        >>> registry.queryAdapter(c, B0)
-        3
+           >>> registry.provideAdapter(F1, B1, [f2])
+           >>> registry.queryAdapter(c, B0)
+           2
 
+           >>> def f3(ob):
+           ...     return 3
 
-        """
-        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.
-
-            # But we may implement it
-            if interface.isImplementedBy(ob):
-                return ob
-            return default
-        
-        interface = surrogate
+           >>> registry.provideAdapter(F1, B0, [f3])
+           >>> registry.queryAdapter(c, B0)
+           3
+           """
 
         declaration = providedBy(ob)
         s = self.get(declaration)
@@ -407,12 +326,7 @@
         3
 
         """
-        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.
-            return default
-    
+
         declaration = providedBy(ob)
         s = self.get(declaration)
         factories = s._implied.get((interface, name))
@@ -492,12 +406,6 @@
         True
         
         """
-        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.
-            return None
-
         ob = objects[0]
         order = len(objects)
         obs = objects[1:]
@@ -549,122 +457,121 @@
                               provided_interfaces=None,
                               name = None,
                               ):
-
         """Search for registered adapters
 
-          Note, this is usually slow!
+           Note, this is usually slow!
 
-          >>> from zope.interface import Interface
+           >>> 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', (), 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', (), u'', 'default P3'),
-           ('Interface', 'P3', (), u'', 'any P3'),
-           ('R2', 'P3', (), u'', 'R2 P3')]
-
-          >>> sorted(registry.getRegisteredMatching(required_interfaces=[R1]))
-          [(None, 'P3', (), u'', 'default P3'),
-           ('Interface', 'P3', (), u'', 'any P3')]
-          
-          >>> sorted(registry.getRegisteredMatching(required_interfaces=R1))
-          [(None, 'P3', (), u'', 'default P3'),
-           ('Interface', 'P3', (), u'', 'any P3')]
-          
-          >>> sorted(registry.getRegisteredMatching(provided_interfaces=[P1]))
-          [(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', (), 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', (), 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', (), 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', (), 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', (), 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', (), u'bob', 'bobs R2 P3')]
-
-          >>> sorted(registry.getRegisteredMatching(
-          ...     required_interfaces = (R3, ),
-          ...     provided_interfaces = (P1, ),
-          ...     name='bob'))
-          [('R2', 'P3', (), u'bob', 'bobs R2 P3')]
+           >>> 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', (), 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', (), u'', 'default P3'),
+            ('Interface', 'P3', (), u'', 'any P3'),
+            ('R2', 'P3', (), u'', 'R2 P3')]
+
+           >>> sorted(registry.getRegisteredMatching(required_interfaces=[R1]))
+           [(None, 'P3', (), u'', 'default P3'),
+            ('Interface', 'P3', (), u'', 'any P3')]
+
+           >>> sorted(registry.getRegisteredMatching(required_interfaces=R1))
+           [(None, 'P3', (), u'', 'default P3'),
+            ('Interface', 'P3', (), u'', 'any P3')]
+
+           >>> sorted(registry.getRegisteredMatching(provided_interfaces=[P1]))
+           [(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', (), 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', (), 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', (), 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', (), 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', (), 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', (), u'bob', 'bobs R2 P3')]
+
+           >>> sorted(registry.getRegisteredMatching(
+           ...     required_interfaces = (R3, ),
+           ...     provided_interfaces = (P1, ),
+           ...     name='bob'))
+           [('R2', 'P3', (), u'bob', 'bobs R2 P3')]
 
-          """
+           """
 
         if name is not None:
             name = unicode(name)
@@ -689,25 +596,76 @@
                 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
+                adapters = ancestor._adapters
+                if adapters:
+                    items = 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
 
-                    yield (ancestor, target, with, aname, factories)
+                        if provided_interfaces:
+                            for p in provided_interfaces:
+                                if target.extends(p, False):
+                                    break
+                            else:
+                                # None matching
+                                continue
+
+                        yield (ancestor, target, with, aname, factories)
+
+
+
+def adapterImplied(adapters, implied, multi):
+    implied.clear()
+    multi.clear()
+    registered = {}
+
+    # Add adapters and interfaces directly implied by same:
+    for (with, name, target), factories in adapters.iteritems():
+        if with:
+            _add_multi_adapter(with, name, target, target, multi, factories)
+        elif name:
+            _add_named_adapter(target, target, name, implied, registered,
+                               factories)
+        else:
+            _add_adapter(target, target, implied, registered, factories)
+
+def _add_adapter(target, provided, implied, registered, factories):
+    if (target not in implied
+        or
+        (target in registered and registered[target].extends(provided))
+        ):
+        registered[target] = provided
+        implied[target] = factories
+        for b in target.__bases__:
+            _add_adapter(b, provided, implied, registered, factories)
+
+def _add_named_adapter(target, provided, name,
+                        implied, registered, factories):
+    key = target, name
+    if (key not in implied
+        or
+        (key in registered and registered[key].extends(provided))
+        ):
+        registered[key] = provided
+        implied[key] = factories
+        for b in target.__bases__:
+            _add_named_adapter(b, provided, name,
+                               implied, registered, factories)
+
+def _add_multi_adapter(interfaces, name, target, provided, implied, factories):
+    order = len(interfaces)+1
+    adapters = implied.get((target, name, order))
+    if adapters is None:
+        adapters = {}
+        implied[(target, name, order)] = adapters
 
+    adapters.setdefault(interfaces, factories)
 
+    for b in target.__bases__:
+        _add_multi_adapter(interfaces, name, b, provided, implied, factories)




More information about the Zope3-Checkins mailing list