You can obtain the MRO (Method Resolution Order) of a class C with either the __mro__ attribute or the mro() method:
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
>>> C.mro()
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
__mro__ is a read-only attribute of an immutable tuple, but mro() returns a list.
I know that metaclasses can override mro() to customize the order, but that's not what's happening in this example class C. Even object returns a list:
>>> object.mro()
[<class 'object'>]
The fact that it's a mutable list would suggest modifying it serves some purpose, but changing the list has no effect on the actual MRO resolution process. In fact, a different list is returned every time mro() is called:
>>> x, y = object.mro(), object.mro()
>>> x is y, id(x), id(y)
(False, 123145300859648, 123145300859584)
Several sources describe mro() as returning a tuple. The Python 2.3 Method Resolution Order still referenced by the current documentation shows mro() returning a tuple. In addition, a section of PEP 447 shows the pseudo-code of the then-current implementation of object.__getattribute__ where mro() is expected to return a tuple:
def _PyType_Lookup(tp, name):
mro = tp.mro()
assert isinstance(mro, tuple)
So why is mro() returning a list rather than a tuple? I can't find anything in the documentation that explains this.