Search code examples
pythonpython-3.xabstract-classsubclassabc

Find all the abstract base classes that a class is registered with


How can I find all the abstract base classes that a given class is a "virtual subclass" of?

In other words, I'm looking for a magic function virtual_base_classes() that does something like this:

>>> for cls in virtual_base_classes(list):
>>>   print(cls)
<class 'collections.abc.MutableSequence'>
<class 'collections.abc.Sequence'>
<class 'collections.abc.Sized'>
<class 'collections.abc.Iterable'>
<class 'collections.abc.Container'>

(I don't know all the abc classes that list is registered with, so the above example may not be complete.)

Note that not every abstract base class will be defined in collections.abc. There is a module abc (distinct from collections.abc) which provides the metaclass ABCMeta. Any class that is an instance of ABCMeta supports registration of "virtual subclasses" using the standard interface (the register method). There's nothing that stops someone (whether a programmer or Python library) from creating an instance of ABCMeta that does not belong in collections.abc.


Solution

  • Use issubclass and a list comprehension:

    >>> import collections.abc
    >>> import inspect
    >>> [v for k, v in vars(collections.abc).items()
                                      if inspect.isclass(v) and issubclass(list, v) ]
    [<class 'collections.abc.Container'>,
     <class 'collections.abc.Sequence'>,
     <class 'collections.abc.MutableSequence'>,
     <class 'collections.abc.Iterable'>,
     <class 'collections.abc.Sized'>
    ]