adapter.rst 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. .. _adapter-registry:
  2. ==================
  3. Adapter Registry
  4. ==================
  5. Adapter registries provide a way to register objects that depend on
  6. one or more interface specifications and provide (perhaps indirectly)
  7. some interface. In addition, the registrations have names. (You can
  8. think of the names as qualifiers of the provided interfaces.)
  9. The term "interface specification" refers both to interfaces and to
  10. interface declarations, such as declarations of interfaces implemented
  11. by a class.
  12. Single Adapters
  13. ===============
  14. Let's look at a simple example, using a single required specification:
  15. .. doctest::
  16. >>> from zope.interface.adapter import AdapterRegistry
  17. >>> import zope.interface
  18. >>> class IRequire1(zope.interface.Interface):
  19. ... pass
  20. >>> class IProvide1(zope.interface.Interface):
  21. ... pass
  22. >>> class IProvide2(IProvide1):
  23. ... pass
  24. >>> registry = AdapterRegistry()
  25. We'll register an object that depends on ``IRequire1`` and "provides" ``IProvide2``:
  26. .. doctest::
  27. >>> registry.register([IRequire1], IProvide2, '', 12)
  28. Given the registration, we can look it up again:
  29. .. doctest::
  30. >>> registry.lookup([IRequire1], IProvide2, '')
  31. 12
  32. Note that we used an integer in the example. In real applications,
  33. one would use some objects that actually depend on or provide
  34. interfaces. The registry doesn't care about what gets registered, so
  35. we'll use integers and strings to keep the examples simple. There is
  36. one exception. Registering a value of ``None`` unregisters any
  37. previously-registered value.
  38. If an object depends on a specification, it can be looked up with a
  39. specification that extends the specification that it depends on:
  40. .. doctest::
  41. >>> class IRequire2(IRequire1):
  42. ... pass
  43. >>> registry.lookup([IRequire2], IProvide2, '')
  44. 12
  45. We can use a class implementation specification to look up the object:
  46. .. doctest::
  47. >>> class C2:
  48. ... zope.interface.implements(IRequire2)
  49. >>> registry.lookup([zope.interface.implementedBy(C2)], IProvide2, '')
  50. 12
  51. and it can be looked up for interfaces that its provided interface
  52. extends:
  53. .. doctest::
  54. >>> registry.lookup([IRequire1], IProvide1, '')
  55. 12
  56. >>> registry.lookup([IRequire2], IProvide1, '')
  57. 12
  58. But if you require a specification that doesn't extend the specification the
  59. object depends on, you won't get anything:
  60. .. doctest::
  61. >>> registry.lookup([zope.interface.Interface], IProvide1, '')
  62. By the way, you can pass a default value to lookup:
  63. .. doctest::
  64. >>> registry.lookup([zope.interface.Interface], IProvide1, '', 42)
  65. 42
  66. If you try to get an interface the object doesn't provide, you also
  67. won't get anything:
  68. .. doctest::
  69. >>> class IProvide3(IProvide2):
  70. ... pass
  71. >>> registry.lookup([IRequire1], IProvide3, '')
  72. You also won't get anything if you use the wrong name:
  73. .. doctest::
  74. >>> registry.lookup([IRequire1], IProvide1, 'bob')
  75. >>> registry.register([IRequire1], IProvide2, 'bob', "Bob's 12")
  76. >>> registry.lookup([IRequire1], IProvide1, 'bob')
  77. "Bob's 12"
  78. You can leave the name off when doing a lookup:
  79. .. doctest::
  80. >>> registry.lookup([IRequire1], IProvide1)
  81. 12
  82. If we register an object that provides ``IProvide1``:
  83. .. doctest::
  84. >>> registry.register([IRequire1], IProvide1, '', 11)
  85. then that object will be prefered over ``O(12)``:
  86. .. doctest::
  87. >>> registry.lookup([IRequire1], IProvide1, '')
  88. 11
  89. Also, if we register an object for ``IRequire2``, then that will be preferred
  90. when using ``IRequire2``:
  91. .. doctest::
  92. >>> registry.register([IRequire2], IProvide1, '', 21)
  93. >>> registry.lookup([IRequire2], IProvide1, '')
  94. 21
  95. Finding out what, if anything, is registered
  96. --------------------------------------------
  97. We can ask if there is an adapter registered for a collection of
  98. interfaces. This is different than lookup, because it looks for an
  99. exact match:
  100. .. doctest::
  101. >>> print registry.registered([IRequire1], IProvide1)
  102. 11
  103. >>> print registry.registered([IRequire1], IProvide2)
  104. 12
  105. >>> print registry.registered([IRequire1], IProvide2, 'bob')
  106. Bob's 12
  107. >>> print registry.registered([IRequire2], IProvide1)
  108. 21
  109. >>> print registry.registered([IRequire2], IProvide2)
  110. None
  111. In the last example, ``None`` was returned because nothing was registered
  112. exactly for the given interfaces.
  113. lookup1
  114. -------
  115. Lookup of single adapters is common enough that there is a specialized
  116. version of lookup that takes a single required interface:
  117. .. doctest::
  118. >>> registry.lookup1(IRequire2, IProvide1, '')
  119. 21
  120. >>> registry.lookup1(IRequire2, IProvide1)
  121. 21
  122. Actual Adaptation
  123. -----------------
  124. The adapter registry is intended to support adaptation, where one
  125. object that implements an interface is adapted to another object that
  126. supports a different interface. The adapter registry supports the
  127. computation of adapters. In this case, we have to register adapter
  128. factories:
  129. .. doctest::
  130. >>> class IR(zope.interface.Interface):
  131. ... pass
  132. >>> class X:
  133. ... zope.interface.implements(IR)
  134. >>> class Y:
  135. ... zope.interface.implements(IProvide1)
  136. ... def __init__(self, context):
  137. ... self.context = context
  138. >>> registry.register([IR], IProvide1, '', Y)
  139. In this case, we registered a class as the factory. Now we can call
  140. ``queryAdapter`` to get the adapted object:
  141. .. doctest::
  142. >>> x = X()
  143. >>> y = registry.queryAdapter(x, IProvide1)
  144. >>> y.__class__.__name__
  145. 'Y'
  146. >>> y.context is x
  147. True
  148. We can register and lookup by name too:
  149. .. doctest::
  150. >>> class Y2(Y):
  151. ... pass
  152. >>> registry.register([IR], IProvide1, 'bob', Y2)
  153. >>> y = registry.queryAdapter(x, IProvide1, 'bob')
  154. >>> y.__class__.__name__
  155. 'Y2'
  156. >>> y.context is x
  157. True
  158. When the adapter factory produces ``None``, then this is treated as if no
  159. adapter has been found. This allows us to prevent adaptation (when desired)
  160. and let the adapter factory determine whether adaptation is possible based on
  161. the state of the object being adapted:
  162. .. doctest::
  163. >>> def factory(context):
  164. ... if context.name == 'object':
  165. ... return 'adapter'
  166. ... return None
  167. >>> class Object(object):
  168. ... zope.interface.implements(IR)
  169. ... name = 'object'
  170. >>> registry.register([IR], IProvide1, 'conditional', factory)
  171. >>> obj = Object()
  172. >>> registry.queryAdapter(obj, IProvide1, 'conditional')
  173. 'adapter'
  174. >>> obj.name = 'no object'
  175. >>> registry.queryAdapter(obj, IProvide1, 'conditional') is None
  176. True
  177. >>> registry.queryAdapter(obj, IProvide1, 'conditional', 'default')
  178. 'default'
  179. An alternate method that provides the same function as ``queryAdapter()`` is
  180. `adapter_hook()`:
  181. .. doctest::
  182. >>> y = registry.adapter_hook(IProvide1, x)
  183. >>> y.__class__.__name__
  184. 'Y'
  185. >>> y.context is x
  186. True
  187. >>> y = registry.adapter_hook(IProvide1, x, 'bob')
  188. >>> y.__class__.__name__
  189. 'Y2'
  190. >>> y.context is x
  191. True
  192. The ``adapter_hook()`` simply switches the order of the object and
  193. interface arguments. It is used to hook into the interface call
  194. mechanism.
  195. Default Adapters
  196. ----------------
  197. Sometimes, you want to provide an adapter that will adapt anything.
  198. For that, provide ``None`` as the required interface:
  199. .. doctest::
  200. >>> registry.register([None], IProvide1, '', 1)
  201. then we can use that adapter for interfaces we don't have specific
  202. adapters for:
  203. .. doctest::
  204. >>> class IQ(zope.interface.Interface):
  205. ... pass
  206. >>> registry.lookup([IQ], IProvide1, '')
  207. 1
  208. Of course, specific adapters are still used when applicable:
  209. .. doctest::
  210. >>> registry.lookup([IRequire2], IProvide1, '')
  211. 21
  212. Class adapters
  213. --------------
  214. You can register adapters for class declarations, which is almost the
  215. same as registering them for a class:
  216. .. doctest::
  217. >>> registry.register([zope.interface.implementedBy(C2)], IProvide1, '', 'C21')
  218. >>> registry.lookup([zope.interface.implementedBy(C2)], IProvide1, '')
  219. 'C21'
  220. Dict adapters
  221. -------------
  222. At some point it was impossible to register dictionary-based adapters due a
  223. bug. Let's make sure this works now:
  224. .. doctest::
  225. >>> adapter = {}
  226. >>> registry.register((), IQ, '', adapter)
  227. >>> registry.lookup((), IQ, '') is adapter
  228. True
  229. Unregistering
  230. -------------
  231. You can unregister by registering ``None``, rather than an object:
  232. .. doctest::
  233. >>> registry.register([zope.interface.implementedBy(C2)], IProvide1, '', None)
  234. >>> registry.lookup([zope.interface.implementedBy(C2)], IProvide1, '')
  235. 21
  236. Of course, this means that ``None`` can't be registered. This is an
  237. exception to the statement, made earlier, that the registry doesn't
  238. care what gets registered.
  239. Multi-adapters
  240. ==============
  241. You can adapt multiple specifications:
  242. .. doctest::
  243. >>> registry.register([IRequire1, IQ], IProvide2, '', '1q2')
  244. >>> registry.lookup([IRequire1, IQ], IProvide2, '')
  245. '1q2'
  246. >>> registry.lookup([IRequire2, IQ], IProvide1, '')
  247. '1q2'
  248. >>> class IS(zope.interface.Interface):
  249. ... pass
  250. >>> registry.lookup([IRequire2, IS], IProvide1, '')
  251. >>> class IQ2(IQ):
  252. ... pass
  253. >>> registry.lookup([IRequire2, IQ2], IProvide1, '')
  254. '1q2'
  255. >>> registry.register([IRequire1, IQ2], IProvide2, '', '1q22')
  256. >>> registry.lookup([IRequire2, IQ2], IProvide1, '')
  257. '1q22'
  258. Multi-adaptation
  259. ----------------
  260. You can adapt multiple objects:
  261. .. doctest::
  262. >>> class Q:
  263. ... zope.interface.implements(IQ)
  264. As with single adapters, we register a factory, which is often a class:
  265. .. doctest::
  266. >>> class IM(zope.interface.Interface):
  267. ... pass
  268. >>> class M:
  269. ... zope.interface.implements(IM)
  270. ... def __init__(self, x, q):
  271. ... self.x, self.q = x, q
  272. >>> registry.register([IR, IQ], IM, '', M)
  273. And then we can call ``queryMultiAdapter`` to compute an adapter:
  274. .. doctest::
  275. >>> q = Q()
  276. >>> m = registry.queryMultiAdapter((x, q), IM)
  277. >>> m.__class__.__name__
  278. 'M'
  279. >>> m.x is x and m.q is q
  280. True
  281. and, of course, we can use names:
  282. .. doctest::
  283. >>> class M2(M):
  284. ... pass
  285. >>> registry.register([IR, IQ], IM, 'bob', M2)
  286. >>> m = registry.queryMultiAdapter((x, q), IM, 'bob')
  287. >>> m.__class__.__name__
  288. 'M2'
  289. >>> m.x is x and m.q is q
  290. True
  291. Default Adapters
  292. ----------------
  293. As with single adapters, you can define default adapters by specifying
  294. ``None`` for the *first* specification:
  295. .. doctest::
  296. >>> registry.register([None, IQ], IProvide2, '', 'q2')
  297. >>> registry.lookup([IS, IQ], IProvide2, '')
  298. 'q2'
  299. Null Adapters
  300. =============
  301. You can also adapt **no** specification:
  302. .. doctest::
  303. >>> registry.register([], IProvide2, '', 2)
  304. >>> registry.lookup([], IProvide2, '')
  305. 2
  306. >>> registry.lookup([], IProvide1, '')
  307. 2
  308. Listing named adapters
  309. ----------------------
  310. Adapters are named. Sometimes, it's useful to get all of the named
  311. adapters for given interfaces:
  312. .. doctest::
  313. >>> adapters = list(registry.lookupAll([IRequire1], IProvide1))
  314. >>> adapters.sort()
  315. >>> assert adapters == [(u'', 11), (u'bob', "Bob's 12")]
  316. This works for multi-adapters too:
  317. .. doctest::
  318. >>> registry.register([IRequire1, IQ2], IProvide2, 'bob', '1q2 for bob')
  319. >>> adapters = list(registry.lookupAll([IRequire2, IQ2], IProvide1))
  320. >>> adapters.sort()
  321. >>> assert adapters == [(u'', '1q22'), (u'bob', '1q2 for bob')]
  322. And even null adapters:
  323. .. doctest::
  324. >>> registry.register([], IProvide2, 'bob', 3)
  325. >>> adapters = list(registry.lookupAll([], IProvide1))
  326. >>> adapters.sort()
  327. >>> assert adapters == [(u'', 2), (u'bob', 3)]
  328. Subscriptions
  329. =============
  330. Normally, we want to look up an object that most closely matches a
  331. specification. Sometimes, we want to get all of the objects that
  332. match some specification. We use *subscriptions* for this. We
  333. subscribe objects against specifications and then later find all of
  334. the subscribed objects:
  335. .. doctest::
  336. >>> registry.subscribe([IRequire1], IProvide2, 'sub12 1')
  337. >>> registry.subscriptions([IRequire1], IProvide2)
  338. ['sub12 1']
  339. Note that, unlike regular adapters, subscriptions are unnamed.
  340. You can have multiple subscribers for the same specification:
  341. .. doctest::
  342. >>> registry.subscribe([IRequire1], IProvide2, 'sub12 2')
  343. >>> registry.subscriptions([IRequire1], IProvide2)
  344. ['sub12 1', 'sub12 2']
  345. If subscribers are registered for the same required interfaces, they
  346. are returned in the order of definition.
  347. You can register subscribers for all specifications using ``None``:
  348. .. doctest::
  349. >>> registry.subscribe([None], IProvide1, 'sub_1')
  350. >>> registry.subscriptions([IRequire2], IProvide1)
  351. ['sub_1', 'sub12 1', 'sub12 2']
  352. Note that the new subscriber is returned first. Subscribers defined
  353. for less general required interfaces are returned before subscribers
  354. for more general interfaces.
  355. Subscriptions may be combined over multiple compatible specifications:
  356. .. doctest::
  357. >>> registry.subscriptions([IRequire2], IProvide1)
  358. ['sub_1', 'sub12 1', 'sub12 2']
  359. >>> registry.subscribe([IRequire1], IProvide1, 'sub11')
  360. >>> registry.subscriptions([IRequire2], IProvide1)
  361. ['sub_1', 'sub12 1', 'sub12 2', 'sub11']
  362. >>> registry.subscribe([IRequire2], IProvide2, 'sub22')
  363. >>> registry.subscriptions([IRequire2], IProvide1)
  364. ['sub_1', 'sub12 1', 'sub12 2', 'sub11', 'sub22']
  365. >>> registry.subscriptions([IRequire2], IProvide2)
  366. ['sub12 1', 'sub12 2', 'sub22']
  367. Subscriptions can be on multiple specifications:
  368. .. doctest::
  369. >>> registry.subscribe([IRequire1, IQ], IProvide2, 'sub1q2')
  370. >>> registry.subscriptions([IRequire1, IQ], IProvide2)
  371. ['sub1q2']
  372. As with single subscriptions and non-subscription adapters, you can
  373. specify ``None`` for the first required interface, to specify a default:
  374. .. doctest::
  375. >>> registry.subscribe([None, IQ], IProvide2, 'sub_q2')
  376. >>> registry.subscriptions([IS, IQ], IProvide2)
  377. ['sub_q2']
  378. >>> registry.subscriptions([IRequire1, IQ], IProvide2)
  379. ['sub_q2', 'sub1q2']
  380. You can have subscriptions that are independent of any specifications:
  381. .. doctest::
  382. >>> list(registry.subscriptions([], IProvide1))
  383. []
  384. >>> registry.subscribe([], IProvide2, 'sub2')
  385. >>> registry.subscriptions([], IProvide1)
  386. ['sub2']
  387. >>> registry.subscribe([], IProvide1, 'sub1')
  388. >>> registry.subscriptions([], IProvide1)
  389. ['sub2', 'sub1']
  390. >>> registry.subscriptions([], IProvide2)
  391. ['sub2']
  392. Unregistering subscribers
  393. -------------------------
  394. We can unregister subscribers. When unregistering a subscriber, we
  395. can unregister a *specific* subscriber:
  396. .. doctest::
  397. >>> registry.unsubscribe([IRequire1], IProvide1, 'sub11')
  398. >>> registry.subscriptions([IRequire1], IProvide1)
  399. ['sub_1', 'sub12 1', 'sub12 2']
  400. If we don't specify a value, then *all* subscribers matching the given
  401. interfaces will be unsubscribed:
  402. .. doctest::
  403. >>> registry.unsubscribe([IRequire1], IProvide2)
  404. >>> registry.subscriptions([IRequire1], IProvide1)
  405. ['sub_1']
  406. Subscription adapters
  407. ---------------------
  408. We normally register adapter factories, which then allow us to compute
  409. adapters, but with subscriptions, we get multiple adapters. Here's an
  410. example of multiple-object subscribers:
  411. .. doctest::
  412. >>> registry.subscribe([IR, IQ], IM, M)
  413. >>> registry.subscribe([IR, IQ], IM, M2)
  414. >>> subscribers = registry.subscribers((x, q), IM)
  415. >>> len(subscribers)
  416. 2
  417. >>> class_names = [s.__class__.__name__ for s in subscribers]
  418. >>> class_names.sort()
  419. >>> class_names
  420. ['M', 'M2']
  421. >>> [(s.x is x and s.q is q) for s in subscribers]
  422. [True, True]
  423. Adapter factory subscribers can't return ``None`` values:
  424. .. doctest::
  425. >>> def M3(x, y):
  426. ... return None
  427. >>> registry.subscribe([IR, IQ], IM, M3)
  428. >>> subscribers = registry.subscribers((x, q), IM)
  429. >>> len(subscribers)
  430. 2
  431. Handlers
  432. --------
  433. A handler is a subscriber factory that doesn't produce any normal
  434. output. It returns ``None``. A handler is unlike adapters in that it does
  435. all of its work when the factory is called.
  436. To register a handler, simply provide ``None`` as the provided interface:
  437. .. doctest::
  438. >>> def handler(event):
  439. ... print 'handler', event
  440. >>> registry.subscribe([IRequire1], None, handler)
  441. >>> registry.subscriptions([IRequire1], None) == [handler]
  442. True
  443. Components
  444. ==========
  445. A :class:`zope.interface.registry.Components` object implements the
  446. :class:`zope.interface.interfaces.IComponents` interface. This
  447. interface uses multiple adapter registries to implement multiple
  448. higher-level concerns (utilities, adapters and handlers), while also
  449. providing event notifications and query capabilities.