pythonzope.interface

Zope interface inheritance: Why doesn't it show up in interface.providedBy()?


I would expect when I make an interface IB inherit from IA, then use interface.providedBy() to query an instance of B (which implements IB), I would see both IA and IB in the list. However, that doesn't seem to be the case.

from zope import interface

class IA(interface.Interface):
    pass

class IB(IA): # We inherit from IA
    pass

class B(object):
    interface.implements(IB)

if __name__ == '__main__':
    b = B()
    print 'Does B() provide IA? %s' % IA.providedBy(b)
    print 'providedBy(B()): %s' % list(interface.providedBy(b))

Running this code produces the following output:

Does B() provide IA? True
providedBy(B()): [<InterfaceClass __main__.IB>]

If B() provides IA, as shown in the first line of output, why doesn't IA show up in the second line of output?

UPDATE: I resolved the issue by using the following workaround. I had no interest in seeing any of the provider classes, the base class (zope.interface.Interface) or any kind of duplicates in the results, so I did the following.

def getAllInterfaces(obj):
    all_ifaces = set()

    def buildSet(ifaces):
        for iface in ifaces:
            if iface != interface.Interface:
                all_ifaces.add(iface)
                buildSet(iface.__bases__)

    buildSet(list(interface.providedBy(obj)))
    return tuple(all_ifaces)

Solution

  • providedBy only returns immediately provided interfaces. See https://github.com/Pylons/substanced/blob/master/substanced/util/init.py#L398 for an example of how to obtain all the interfaces.