New submission from Neil Girdhar:

Minimum working example:

class MyMetaclass(type):
    pass

class OtherMetaclass(type):
    pass

def metaclass_callable(name, bases, namespace):
    return OtherMetaclass(name, bases, namespace)

class MyClass(metaclass=MyMetaclass):
    pass

try:
    class MyDerived(MyClass, metaclass=metaclass_callable):
        pass
except:
    print("Gotcha!")


from types import new_class
MyDerived = new_class("MyDerived", (), dict(metaclass=metaclass_callable))

print(type(MyDerived))


This is because something happened along the way and 
Objects/typeobject.c:type_new no longer coincides with Lib/types.py:new_class. 
The Python version conditionally calls _calculate_meta whereas the C version 
calls it unconditionally. I consider the C implementation to be the "correct" 
version.

I suggest that
* the Python version be made to coincide with the C version.
* the documentation be made to coincide with the C version.  Specifically, 
section 3.3.3.2 should read:


"The metaclass of a class definition is selected from the explicitly specified 
metaclass (if any) and the metaclasses (i.e. type(cls)) of all specified base 
classes. The selected metaclass is the one which is a subtype of all of these 
candidate metaclasses. If none of the candidate metaclasses meets that 
criterion, then the class definition will fail with TypeError. If provided, the 
explicit metaclass must be a callable accepting the positional arguments (name, 
bases, _dict) as in the three argument form of the built-in type function."

----------
assignee: docs@python
components: Documentation, Library (Lib)
messages: 278625
nosy: docs@python, neil.g
priority: normal
severity: normal
status: open
title: Class definition is not consistent with types.new_class
type: behavior
versions: Python 3.6

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue28437>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to