[Zope3-checkins]
SVN: Zope3/branches/jim-adapter/src/zope/interface/adapter.
Committed to subscription-result order.
Jim Fulton
jim at zope.com
Wed Apr 26 19:44:19 EDT 2006
Log message for revision 67629:
Committed to subscription-result order.
Added unsubscription tests. Fixed a bug in unsubscription without a
value.
Changed:
U Zope3/branches/jim-adapter/src/zope/interface/adapter.py
U Zope3/branches/jim-adapter/src/zope/interface/adapter.txt
-=-
Modified: Zope3/branches/jim-adapter/src/zope/interface/adapter.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/interface/adapter.py 2006-04-26 22:28:30 UTC (rev 67628)
+++ Zope3/branches/jim-adapter/src/zope/interface/adapter.py 2006-04-26 23:44:19 UTC (rev 67629)
@@ -150,7 +150,26 @@
del self.__dict__['_v_extendors']
self.changed(self)
+
+ def registered(self, required, provided, name=u''):
+ required = tuple(map(_convert_None_to_Interface, required))
+ name = _normalize_name(name)
+ order = len(required)
+ byorder = self._adapters
+ if len(byorder) <= order:
+ return None
+
+ components = byorder[order]
+ key = required + (provided,)
+ for k in key:
+ d = components.get(k)
+ if d is None:
+ return None
+ components = d
+
+ return components.get(name)
+
def unregister(self, required, provided, name, value=None):
required = tuple(map(_convert_None_to_Interface, required))
order = len(required)
@@ -218,7 +237,7 @@
order = len(required)
byorder = self._subscribers
if order >= len(byorder):
- return False
+ return
components = byorder[order]
key = required + (provided,)
@@ -228,13 +247,22 @@
return
components = d
- components[u''] = tuple([
- v for v in components.get(u'', ())
- if (v != value) or (value is None)
- ])
+ old = components.get(u'')
+ if not old:
+ return
+ if value is None:
+ new = ()
+ else:
+ new = tuple([v for v in old if v != value])
+
+ if new == old:
+ return
+
+ components[u''] = new
+
if provided is not None:
- n = self._provided[provided] - 1
+ n = self._provided[provided] + len(new) - len(old)
if n == 0:
del self._provided[provided]
if '_v_extendors' in self.__dict__:
@@ -242,11 +270,8 @@
self.changed(self)
- return
-
- # XXX hack to fake out twisted's use of a private api. We'll need
- # to add a public api to mean twisted's needs and get them to use
- # it.
+ # XXX hack to fake out twisted's use of a private api. We need to get them
+ # to use the new registed method.
def get(self, _):
class XXXTwistedFakeOut:
selfImplied = {}
Modified: Zope3/branches/jim-adapter/src/zope/interface/adapter.txt
===================================================================
--- Zope3/branches/jim-adapter/src/zope/interface/adapter.txt 2006-04-26 22:28:30 UTC (rev 67628)
+++ Zope3/branches/jim-adapter/src/zope/interface/adapter.txt 2006-04-26 23:44:19 UTC (rev 67629)
@@ -115,6 +115,32 @@
>>> registry.lookup([IR2], IP1, '')
21
+Finding out what, if anything, is registered
+--------------------------------------------
+
+We can ask if there is an adapter registered for a collection of
+interfaces. This is different than lookup, because it looks for an
+exact match.
+
+ >>> print registry.registered([IR1], IP1)
+ 11
+
+ >>> print registry.registered([IR1], IP2)
+ 12
+
+ >>> print registry.registered([IR1], IP2, 'bob')
+ Bob's 12
+
+
+ >>> print registry.registered([IR2], IP1)
+ 21
+
+ >>> print registry.registered([IR2], IP2)
+ None
+
+In the last example, None was returned because nothing was registered
+exactly for the given interfaces.
+
lookup1
-------
@@ -382,11 +408,6 @@
Subscriptions
=============
-XXX need tests that demonstrate that more general subscribers are
- called before more specific subscribers
-
-XXX Need unscription tests
-
Normally, we want to look up an object that most-closely matches a
specification. Sometimes, we want to get all of the objects that
match some specification. We use subscriptions for this. We
@@ -399,43 +420,36 @@
Note that, unlike regular adapters, subscriptions are unnamed.
-The order of returned subscriptions is not specified.
-
You can have multiple subscribers for the same specification::
>>> registry.subscribe([IR1], IP2, 'sub12 2')
- >>> subs = registry.subscriptions([IR1], IP2)
- >>> subs.sort()
- >>> subs
+ >>> registry.subscriptions([IR1], IP2)
['sub12 1', 'sub12 2']
+If subscribers are registered for the same required interfaces, they
+are returned in the order of definition.
+
You can register subscribers for all specifications using None::
>>> registry.subscribe([None], IP1, 'sub_1')
- >>> subs = registry.subscriptions([IR2], IP1)
- >>> subs.sort()
- >>> subs
- ['sub12 1', 'sub12 2', 'sub_1']
+ >>> registry.subscriptions([IR2], IP1)
+ ['sub_1', 'sub12 1', 'sub12 2']
+Note that the new subscriber is returned first. Subscribers defined
+for more general required interfaces are returned before subscribers
+for more general interfaces.
+
Subscriptions may be combined over multiple compatible specifications::
- >>> subs = registry.subscriptions([IR2], IP1)
- >>> subs.sort()
- >>> subs
- ['sub12 1', 'sub12 2', 'sub_1']
+ >>> registry.subscriptions([IR2], IP1)
+ ['sub_1', 'sub12 1', 'sub12 2']
>>> registry.subscribe([IR1], IP1, 'sub11')
- >>> subs = registry.subscriptions([IR2], IP1)
- >>> subs.sort()
- >>> subs
- ['sub11', 'sub12 1', 'sub12 2', 'sub_1']
+ >>> registry.subscriptions([IR2], IP1)
+ ['sub_1', 'sub12 1', 'sub12 2', 'sub11']
>>> registry.subscribe([IR2], IP2, 'sub22')
- >>> subs = registry.subscriptions([IR2], IP1)
- >>> subs.sort()
- >>> subs
- ['sub11', 'sub12 1', 'sub12 2', 'sub22', 'sub_1']
- >>> subs = registry.subscriptions([IR2], IP2)
- >>> subs.sort()
- >>> subs
+ >>> registry.subscriptions([IR2], IP1)
+ ['sub_1', 'sub12 1', 'sub12 2', 'sub11', 'sub22']
+ >>> registry.subscriptions([IR2], IP2)
['sub12 1', 'sub12 2', 'sub22']
Subscriptions can be on multiple specifications::
@@ -450,10 +464,8 @@
>>> registry.subscribe([None, IQ], IP2, 'sub_q2')
>>> registry.subscriptions([IS, IQ], IP2)
['sub_q2']
- >>> subs = registry.subscriptions([IR1, IQ], IP2)
- >>> subs.sort()
- >>> subs
- ['sub1q2', 'sub_q2']
+ >>> registry.subscriptions([IR1, IQ], IP2)
+ ['sub_q2', 'sub1q2']
You can have subscriptions that are indepenent of any specifications::
@@ -464,14 +476,29 @@
>>> registry.subscriptions([], IP1)
['sub2']
>>> registry.subscribe([], IP1, 'sub1')
- >>> subs = registry.subscriptions([], IP1)
- >>> subs.sort()
- >>> subs
- ['sub1', 'sub2']
+ >>> registry.subscriptions([], IP1)
+ ['sub2', 'sub1']
>>> registry.subscriptions([], IP2)
['sub2']
+Unregistering subscribers
+-------------------------
+We can unregister subscribers. When unregistering a subscriber, we
+can unregister a specific subscriber:
+
+ >>> registry.unsubscribe([IR1], IP1, 'sub11')
+ >>> registry.subscriptions([IR1], IP1)
+ ['sub_1', 'sub12 1', 'sub12 2']
+
+If we don't specify a value, then all subscribers matching the given
+interfaces will be unsubscribed:
+
+ >>> registry.unsubscribe([IR1], IP2)
+ >>> registry.subscriptions([IR1], IP1)
+ ['sub_1']
+
+
Subscription adapters
---------------------
More information about the Zope3-Checkins
mailing list