[Python-Dev] __metaclass__ problem
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 :
"""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
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.
Nick Coghlan | ncoghlan at email.com | Brisbane, Australia
More information about the Python-Dev