I encoutered a weird case of class inheritance in Python 3.8.
I can create a class by inheriting from an instance which is not itself a type. I expected a TypeError in that case, but that is not what happens.
class B:
def __new__(cls, *args, **kwargs):
print(args, kwargs)
return super().__new__(cls)
b = B() # prints: () {}
class A(b): # I expected a TypeError here
x = "foo"
# prints: ('A', (<__main__.B object at 0x7f32bd102390>,),
# {'__module__': '__main__', '__qualname__': 'A', 'x': 'foo'}) {}
print(A) # <__main__.B object at 0x7f20556c93d0>
print(isinstance(A, B)) # True
print(isinstance(A, type)) # False
It looks like when I give B() as base for A, then B is being used as the metaclass.
Is my understanding correct? Why is that the case? And I cannot seem to find anything regarding this behaviour, is it documented or is it an implementation quirk specific to cPython?