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 thezope.interface.adapter_hookslist; theIAdapterRegistryinterface has a dedicatedIAdapterRegistry.adapter_hookmethod we can use for this:See Adaptation in the
zope.interfaceREADME.You can use the
IAdapterRegistry.lookup1()method to do single-adapter lookups without invoking the factory:Building on your sample: