[Zope3-checkins] SVN: Zope3/trunk/ Fixed issue 349.

Stephan Richter srichter at cosmos.phy.tufts.edu
Sat Feb 26 11:54:05 EST 2005


Log message for revision 29315:
  Fixed issue 349.
  
  Thanks to "foom" for the report and the fix.
  
  

Changed:
  U   Zope3/trunk/doc/CHANGES.txt
  U   Zope3/trunk/src/zope/interface/adapter.py
  U   Zope3/trunk/src/zope/interface/tests/test_adapter.py

-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2005-02-26 16:20:57 UTC (rev 29314)
+++ Zope3/trunk/doc/CHANGES.txt	2005-02-26 16:54:05 UTC (rev 29315)
@@ -461,6 +461,10 @@
 
     Bug Fixes
 
+      - Fixed issue #349 (Adapter registry doesn't notice __bases__ changes.)
+
+        Thanks to "foom" for the report and the fix.
+
       - Fixed issue #354 (apidoc: 'SubscriptionRegistration' object has no 
                           attribute 'name')
 

Modified: Zope3/trunk/src/zope/interface/adapter.py
===================================================================
--- Zope3/trunk/src/zope/interface/adapter.py	2005-02-26 16:20:57 UTC (rev 29314)
+++ Zope3/trunk/src/zope/interface/adapter.py	2005-02-26 16:54:05 UTC (rev 29315)
@@ -127,6 +127,7 @@
         self.adapters = {}
         self.dependents = weakref.WeakKeyDictionary()
 
+        self.registry = registry
         self.__bases__ = [registry.get(base) for base in spec.__bases__]
         for base in self.__bases__:
             base.subscribe(self)
@@ -141,6 +142,13 @@
             dependent.dirty()
 
     def clean(self):
+        for base in self.__bases__:
+            base.unsubscribe(self)
+        self.__bases__ = [self.registry.get(base)
+                          for base in self.spec().__bases__]
+        for base in self.__bases__:
+            base.subscribe(self)
+
         self.selfImplied, self.multImplied = adapterImplied(self.adapters)
 
         implied = {}

Modified: Zope3/trunk/src/zope/interface/tests/test_adapter.py
===================================================================
--- Zope3/trunk/src/zope/interface/tests/test_adapter.py	2005-02-26 16:20:57 UTC (rev 29314)
+++ Zope3/trunk/src/zope/interface/tests/test_adapter.py	2005-02-26 16:54:05 UTC (rev 29315)
@@ -15,7 +15,7 @@
 
 $Id$
 """
-import unittest, doctest
+import unittest
 import zope.interface
 from zope.interface.adapter import AdapterRegistry
 import zope.interface
@@ -229,13 +229,67 @@
     >>> registry.adapter_hook(IB0, Object2(), default=default) is default
     True
     """
+
+def test_adapter_registry_update_upon_interface_bases_change():
+    """
+    Let's first create a adapter registry and a simple adaptation hook:
+
+    >>> globalRegistry = AdapterRegistry()
+
+    >>> def _hook(iface, ob, lookup=globalRegistry.lookup1):
+    ...     factory = lookup(zope.interface.providedBy(ob), iface)
+    ...     if factory is None:
+    ...         return None
+    ...     else:
+    ...         return factory(ob)
+
+    >>> zope.interface.interface.adapter_hooks.append(_hook)
+
+    Now we create some interfaces and an implementation:
     
+    >>> class IX(zope.interface.Interface):
+    ...   pass
 
+    >>> class IY(zope.interface.Interface):
+    ...   pass
+
+    >>> class X(object):
+    ...  pass
+
+    >>> class Y(object):
+    ...  zope.interface.implements(IY)
+    ...  def __init__(self, original):
+    ...   self.original=original
+
+    and register an adapter:
+    
+    >>> globalRegistry.register((IX,), IY, '', Y)
+
+    at first, we still expect the adapter lookup from `X` to `IY` to fail:
+    
+    >>> IY(X()) #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+    Traceback (most recent call last):
+    ...
+    TypeError: ('Could not adapt',
+                <zope.interface.tests.test_adapter.X object at ...>,
+                <InterfaceClass zope.interface.tests.test_adapter.IY>)
+
+    But after we declare an interface on the class `X`, it should pass:
+
+    >>> zope.interface.classImplementsOnly(X, IX)
+
+    >>> IY(X()) #doctest: +ELLIPSIS
+    <zope.interface.tests.test_adapter.Y object at ...>
+
+    >>> hook = zope.interface.interface.adapter_hooks.pop()
+    """
+
 def test_suite():
-    from zope.testing.doctestunit import DocFileSuite
+    from zope.testing import doctest, doctestunit
     return unittest.TestSuite((
-        DocFileSuite('../adapter.txt', '../human.txt', 'foodforthought.txt',
-                     globs={'__name__': '__main__'}),
+        doctestunit.DocFileSuite('../adapter.txt', '../human.txt',
+                                 'foodforthought.txt',
+                                 globs={'__name__': '__main__'}),
         doctest.DocTestSuite(),
         ))
 



More information about the Zope3-Checkins mailing list