I would like to get the "C++ cast like" adaption to work with the code from zope.interface
. In my real use case, I'm using a registry from Pyramid
but it derives from zope.interface.registry.Components
, which according to the changes.txt was introduced to be able to use this stuff without any dependency on zope.components
. And the following example is complete and self contained:
from zope.interface import Interface, implements
from zope.interface.registry import Components
registry = Components()
class IA(Interface):
pass
class IB(Interface):
pass
class A(object):
implements(IA)
class B(object):
implements(IB)
def __init__(self,other):
pass
registry.registerAdapter(
factory=B,
required=[IA]
)
a = A()
b = registry.getAdapter(a,IB) # why instance of B and not B?
b = IB(A()) # how to make it work?
I wonder why registry.getAdapter
already returns the adapted object, which is an instance of B
in my case. I would have expected to get back the class B
, but perhaps my understanding of the term adapter is wrong. As this line works and obviously the adapting code is registered correctly, I would also expect the last line to work. But it fails with an error like this:
TypeError: ('Could not adapt', <....A object at 0x4d1c3d0>, < InterfaceClass ....IB>)
Any idea how to get this working?
To make IB(A())
work, you need to add a hook to the the zope.interface.adapter_hooks
list; the IAdapterRegistry
interface has a dedicated IAdapterRegistry.adapter_hook
method we can use for this:
from zope.interface.interface import adapter_hooks
adapter_hooks.append(registry.adapters.adapter_hook)
See Adaptation in the zope.interface
README.
You can use the IAdapterRegistry.lookup1()
method to do single-adapter lookups without invoking the factory:
from zope.interface import providedBy
adapter_factory = registry.adapters.lookup1(providedBy(a), IB)
Building on your sample:
>>> from zope.interface.interface import adapter_hooks
>>> adapter_hooks.append(registry.adapters.adapter_hook)
>>> a = A()
>>> IB(a)
<__main__.B object at 0x100721110>
>>> from zope.interface import providedBy
>>> registry.adapters.lookup1(providedBy(a), IB)
<class '__main__.B'>