What could cause Interface(obj) to return obj, while getAdapter(obj, Interface) returns a properly adapted object?
Asked
Active
Viewed 92 times
0

Martijn Pieters
- 1,048,767
- 296
- 4,058
- 3,343

Ben
- 2,422
- 2
- 16
- 23
-
Does `obj` itself already provide `Interface`? – Martijn Pieters Dec 17 '12 at 16:59
-
Yes. It both implements() the interface and adapts() obj's class. I added those explicitly after the ZCML
tag alone exhibited this behavior. – Ben Dec 17 '12 at 17:02 -
`Interface()` returns `obj` if it already provides the interface, why would you need an adapter at all then? – Martijn Pieters Dec 17 '12 at 17:03
-
Interface(obj) should return Adapter(obj). Instead it just returns obj. getAdapter(obj, Interface) does return Adapter(obj) though. – Ben Dec 17 '12 at 17:04
-
No, if `obj` already provides `Interface` (so `obj.__class__` implements `Interface`) then no adaptation is needed and `obj` itself is returned. – Martijn Pieters Dec 17 '12 at 17:06
-
Sorry, I misstated things. Adapter implements(Interface) and adapts(obj.__class__). I am trying to isolate things down, but for some reason I keep ending up with this behavior. I've written dozens of adapters without encountering this issue, so it is a bit strange... – Ben Dec 17 '12 at 17:14
-
As stated, `IInterface(instance)` will not consult the adapter registry if `instance` already provides the interface. So your object is already providing the interface and does not require adapting. This is regardless of what adapters have been registered or not. – Martijn Pieters Dec 17 '12 at 17:15
-
You need to think of calling-an-interface adaptation having similar semantics to a cast, that helps frame the idea of IFoo(myfoo) being not so dissimilar to list(mylist). – sdupton Dec 17 '12 at 18:49
1 Answers
2
If a given instance already provides the interface, then IInterface(instance)
will return the passed-in instance. After all, it already satisfies the requirement, you can use instance
directly if you need to use IInterface
methods:
>>> import zope.interface
>>> class IFoo(zope.interface.Interface):
... pass
...
>>> class Foo(object):
... zope.interface.implements(IFoo)
... pass
...
>>> foo = Foo()
>>> IFoo(foo)
<__main__.Foo object at 0x10eed22d0>
>>> IFoo.providedBy(foo)
True
getAdapter()
goes directly to the adapter registry, and if you registered an adapter for the given class to IInterface
then that adapter will be returned. This is somewhat pointless, since the original object already provided the interface, so no adaptation was needed.

Martijn Pieters
- 1,048,767
- 296
- 4,058
- 3,343
-
You are 100% correct. I had declared that the object I was adapting implemented my Interface. I must have done it last week at some point and completely forgot. Thanks! – Ben Dec 17 '12 at 17:17