Issue 31789: Better error message when failing to overload metaclass.mro (original) (raw)

class meta(type):

mros = (object,)

def __new__(metacls, name, bases, namespace, fake_bases=()):
    print('entering __new__')
    metacls.fake_bases = fake_bases
    cls = type.__new__(metacls, name, bases, namespace)
    print('exiting __new__')
    return cls

@staticmethod
def mro(*args):
    print('entering mro')
    return meta.fake_bases + (object,)

class a(metaclass=meta, fake_bases=()): pass

That puts out the error message:

entering meta.new entering meta.mro Traceback (most recent call last): File "<pyshell#5948>", line 1, in exec(code, u) File "", line 14, in File "", line 6, in new TypeError: super(type, obj): obj must be an instance or subtype of type

That doesn't at all explain why it doesn't work because super was never explicitly called. If the argument fake_bases isn't empty, or if mro isn't made a staticmethod/classmethod, it returns an appropriate message

TypeError: mro() returned base with unsuitable layout ('tuple')