Nick Coghlan added the comment:
I'm not clear on what discrepancy you're referring to, as I get the same
(expected) exception for both the class statement and the dynamic type creation:
>>> class MyDerived(MyClass, metaclass=metaclass_callable):
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in metaclass_callable
TypeError: metaclass conflict: the metaclass of a derived class must be a
(non-strict) subclass of the metaclasses of all its bases
>>> MyDerivedDynamic = new_class("MyDerivedDynamic", (MyClass,),
>>> dict(metaclass=metaclass_callable))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.5/types.py", line 57, in new_class
return meta(name, bases, ns, **kwds)
File "<stdin>", line 2, in metaclass_callable
TypeError: metaclass conflict: the metaclass of a derived class must be a
(non-strict) subclass of the metaclasses of all its bases
This is due to the fact that your custom metaclass function returns an instance
of a subclass of type, so we end up in type_new to actually create the type,
which fails the metaclass consistency check.
One of the subtle intricacies here is that, for class statements, the logic
that corresponds to types.prepare_class in the Python implementation is
actually in the __build_class__ builtin for the C implementation - when there's
a custom metaclass that *doesn't* return a subclass of type, we don't end up
running type_new at all.
As a result of this, *both* implementations include a conditional check for a
more derived metaclass in their namespace preparation logic, as well as an
unconditional call to that metaclass derivation logic from type_new if the
calculated metaclass is either type itself, or a subclass that calls up to
super().__new__.
Most relevant issues and commit history:
- last update to C implementation
- http://bugs.python.org/issue1294232
- https://hg.python.org/cpython/rev/c2a89b509be4
- addition of pure Python implementation
- http://bugs.python.org/issue14588
- https://hg.python.org/cpython/rev/befd56673c80
The test cases in those commits (particularly the first one) should help make
it clear what is and isn't supported behaviour.
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue28437>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com