[Python-Dev] __metaclass__ problem

Nick Coghlan ncoghlan at iinet.net.au
Sat Mar 19 02:27:40 CET 2005

Phillip J. Eby wrote:
> At 10:11 AM 3/19/05 +1000, Nick Coghlan wrote:
>> 'Meta1' is NOT a subclass of 'Meta2', yet the exception is not thrown. 
>> Instead, the explicitly requested metaclass has been silently replaced 
>> with a subclass. I think the OP is justified in calling that 'suprising'.
> This is precisely the documented (in Guido's essay) behavior.  That is, 
> type.__new__ uses the "most derived" of the explicit metaclass and the 
> __class__ attributes of the bases.

Hmm, you're right. From Guido's essay [1]:

"""However, if one of the base metaclasses satisfies the constraint (including 
the explicitly given __metaclass__, if any), the first base metaclass found 
satisfying the constraint will be used as the metaclass."""

I missed this when re-reading it earlier. Unfortunately, that means an 
explicitly set __metaclass__ may be ignored, if a base class has a subclass of 
the explicitly supplied type as its metaclass (the exact problem the OP was 
objecting to).

IOW, I was extremely surprised to learn that "('__metaclass__' in vars(C)) and 
(type(C) is C.__metaclass__)" is NOT an invariant Python supports for new-style 
classes (it breaks for C3 in my example).

I have no objection to the standard rule when __metaclass__ is not given, or if 
it is __metaclass__ that satisifies the constraint. It's only when __metaclass__ 
*is* given, but doesn't meet the constraint, that I would expect an exception 
rather than for Python to choose to use one of the base metaclasses instead.

Anyway, assuming Guido is happy with the status quo, it just means the above 
text needs to be included when the __metaclass__ documentation is updated.


[1] http://www.python.org/2.2/descrintro.html#metaclasses

Nick Coghlan   |   ncoghlan at email.com   |   Brisbane, Australia

More information about the Python-Dev mailing list