Inheriting Generic and ABC: Which order?

When inheriting both ABC, Generic and maybe some other classes, how to order inheritance correctly, to always have correct consistent MRO?

# Which one is correct?
class MyClass(collections.abc.Mapping, Generic[TV], ABC):
    ...

class MyClass(collections.abc.Mapping, ABC, Generic[TV]):
    ...

I made some tests, get correct MRO in both cases.

But which is preferred way to order these classes when inheriting (and why)?

Both options are over-egging the pudding. A Mapping already has the ABC Metaclass.

I’d use 3.12 Syntax:

class MyClass[TV](collections.abc.Mapping):
    pass

Sized

Collection

Mapping

Also note that Mapping is itself generic, so you’ll likely want to supply some type arguments when inheriting from it. You can also omit Generic from the base classes if other base classes include the type variables. For example, you could have:

class MyClass(Mapping[str, TV]): ...
1 Like

I gave mapping just for example (it can be anything else), the question is about precedence between ABC and Generic.

I’d still get rid of explicit inheritance from Generic altogether and use the 3.12 syntax.

In general, for base classes whose methods or class variables which clash, the base class whose methods or class variable you want on the child class should go earlier. p

Pick which ever order you like if the base classes have no methods in common, it doesn’t matter. It could be micro-optimised to put the one whose methods will be looked up more often earlier.

I use Generic inheritance to use explicitly-defined TypeVar and explicitly specify variance.