[Zope3-checkins] SVN: Zope3/branches/ZopeX3-3.0/src/zope/interface/adapter. Added apis for unregistering adapters and subscribers.

Jim Fulton jim at zope.com
Wed Aug 25 15:01:44 EDT 2004


Log message for revision 27266:
  Added apis for unregistering adapters and subscribers.
  
  This (now) is needed to support testing.
  
  


Changed:
  U   Zope3/branches/ZopeX3-3.0/src/zope/interface/adapter.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/interface/adapter.txt


-=-
Modified: Zope3/branches/ZopeX3-3.0/src/zope/interface/adapter.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/interface/adapter.py	2004-08-25 18:19:37 UTC (rev 27265)
+++ Zope3/branches/ZopeX3-3.0/src/zope/interface/adapter.py	2004-08-25 19:01:44 UTC (rev 27266)
@@ -250,15 +250,32 @@
 
         self.dirty()
 
+    def _unadaptTo(self, specification, object, name='', with=()):
+        key = False, tuple(with), name, specification
+        old = self.adapters.get(key)
+        if old == object:
+            del self.adapters[key]
+            self.dirty()
+        else:
+            raise ValueError("Adapter not present")
+
+
     def _subscriptionAdaptTo(self, specification, object, with=()):
-        if object is None:
-            raise TypeError, ("Unregistering subscription adapters" 
-                              " isn't implemented")
-
         key = (True, tuple(with), '', specification)
         self.adapters[key] = self.adapters.get(key, ()) + (object, )
         self.dirty()
 
+    def _subscriptionUnAdaptTo(self, specification, object, with=()):
+        key = (True, tuple(with), '', specification)
+        subscribers = self.adapters[key]
+        if object in subscribers:
+            subscribers = list(subscribers)
+            subscribers.remove(object)        
+            self.adapters[key] = tuple(subscribers)
+            self.dirty()
+        else:
+            raise ValueError("Subscriber not present")
+
     def changed(self, which=None):
         self.dirty()
 
@@ -502,7 +519,7 @@
                      ):
             setattr(self, name, getattr(lookup, name))
 
-    def register(self, required, provided, name, value):
+    def _with_required(self, required):
         if required:
             with = []
             for iface in required[1:]:
@@ -514,13 +531,26 @@
         else:
             with = ()
             required = self._null
+        return with, required
+
+    def register(self, required, provided, name, value):
         
         if not isinstance(name, basestring):
-            raise TypeError("The name provided to provideAdapter "
-                            "must be a string or unicode")
+            raise TypeError("adapter names must be a strings or unicode")
 
+        with, required = self._with_required(required)
+
         required._adaptTo(provided, value, unicode(name), with)
 
+    def unregister(self, required, provided, name, value):
+        
+        if not isinstance(name, basestring):
+            raise TypeError("adapter names must be a strings or unicode")
+
+        with, required = self._with_required(required)
+
+        required._unadaptTo(provided, value, unicode(name), with)
+
     def lookupAll(self, required, provided):
         order = len(required)
         if order == 1:
@@ -577,17 +607,23 @@
             first = byname
 
     def subscribe(self, required, provided, value):
-        if required:
-            required, with = self.get(required[0]), tuple(required[1:])
-        else:
-            required = self._null
-            with = ()
 
+        with, required = self._with_required(required)
+
         if provided is None:
             provided = Null
             
         required._subscriptionAdaptTo(provided, value, with)
 
+    def unsubscribe(self, required, provided, value):
+
+        with, required = self._with_required(required)
+
+        if provided is None:
+            provided = Null
+            
+        required._subscriptionUnAdaptTo(provided, value, with)
+
 def mextends(with, rwith):
     if len(with) == len(rwith):
         for w, r in zip(with, rwith):

Modified: Zope3/branches/ZopeX3-3.0/src/zope/interface/adapter.txt
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/interface/adapter.txt	2004-08-25 18:19:37 UTC (rev 27265)
+++ Zope3/branches/ZopeX3-3.0/src/zope/interface/adapter.txt	2004-08-25 19:01:44 UTC (rev 27266)
@@ -223,16 +223,29 @@
 Unregistering
 -------------
 
-You can unregister by registering None, rather than an object::
+You can unregister by calling unregister:
 
+  >>> registry.unregister([zope.interface.implementedBy(C2)], IP1, '', 'C21')
+  >>> registry.lookup([zope.interface.implementedBy(C2)], IP1, '')
+  21
+
+
+(You can also unregister by registering None, rather than an object::
+
+  >>> registry.register([zope.interface.implementedBy(C2)], IP1, '', 'C21')
+  >>> registry.lookup([zope.interface.implementedBy(C2)], IP1, '')
+  'C21'
   >>> registry.register([zope.interface.implementedBy(C2)], IP1, '', None)
   >>> registry.lookup([zope.interface.implementedBy(C2)], IP1, '')
   21
 
-Of course, this means that None can't be registered. This is an
-exception to the statement, made earlier, that the registry doesn't
-care what gets registered.
+  Of course, this means that None can't be registered. This is an
+  exception to the statement, made earlier, that the registry doesn't
+  care what gets registered.
 
+  This way of unregistering is deprecated.
+  )
+
 Multi-adapters
 ==============
 
@@ -432,6 +445,17 @@
   ['sub2']
 
 
+Unsubscribing
+=============
+
+You can unsubscribe subscribers:
+
+  >>> registry.unsubscribe([IR1], IP2, 'sub12 1')
+  >>> subs = registry.subscriptions([IR2], IP2)
+  >>> subs.sort()
+  >>> subs
+  ['sub12 2', 'sub22']
+
 Subscription adapters
 ---------------------
 



More information about the Zope3-Checkins mailing list