Suggestion: Deprecate metaclasses that are not instances of type
Background: I asked a stackoverflow question here http://stackoverflow.com/questions/40029807/why-does-the-class-definitions-m... . The Python documentation https://docs.python.org/3.6/reference/datamodel.html#determining-the-appropr... is very confusing to me. It says that: if an explicit metaclass is given and it is not an instance of type, then it is used directly as the metaclass This seems to suggest that in this case, the "explicit metaclass" does not need to be "subtype of all of these candidate metaclasses" as it would in the third case. (This is not true.) Also, providing a callable as a metaclass doesn't seem to be any more flexible, readable, or powerful than providing an instance of type. Therefore, I suggest that we deprecate the second case and replace the entire section (3.3.3.2) of the documentation to say: "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 most derived metaclass is 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 an instance of type()."
On Thu, Oct 13, 2016 at 01:46:34PM -0700, Neil Girdhar wrote:
If provided, the explicit metaclass must be an instance of type()."
-1 for pointless breakage. The metaclass has always been permitted to be any callable. You haven't given any good reason for gratuitously changing this. -- Steve
That's fair. However, the documentation should at least be repaired by
replacing section 3.3.3.2 with:
"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 most derived metaclass is 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)."
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.
Best,
Neil
On Thu, Oct 13, 2016 at 5:41 PM Steven D'Aprano
On Thu, Oct 13, 2016 at 01:46:34PM -0700, Neil Girdhar wrote:
If provided, the explicit metaclass must be an instance of type()."
-1 for pointless breakage.
The metaclass has always been permitted to be any callable. You haven't given any good reason for gratuitously changing this.
-- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
--
--- You received this message because you are subscribed to a topic in the Google Groups "python-ideas" group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/python-ideas/wrHDM0SOIqE/unsubscribe. To unsubscribe from this group and all its topics, send an email to python-ideas+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Bug: http://bugs.python.org/issue28437
On Thu, Oct 13, 2016 at 7:15 PM Neil Girdhar
That's fair. However, the documentation should at least be repaired by replacing section 3.3.3.2 with:
"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 most derived metaclass is 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)."
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.
Best,
Neil
On Thu, Oct 13, 2016 at 5:41 PM Steven D'Aprano
wrote: On Thu, Oct 13, 2016 at 01:46:34PM -0700, Neil Girdhar wrote:
If provided, the explicit metaclass must be an instance of type()."
-1 for pointless breakage.
The metaclass has always been permitted to be any callable. You haven't given any good reason for gratuitously changing this.
-- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
--
--- You received this message because you are subscribed to a topic in the Google Groups "python-ideas" group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/python-ideas/wrHDM0SOIqE/unsubscribe. To unsubscribe from this group and all its topics, send an email to python-ideas+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
participants (2)
-
Neil Girdhar
-
Steven D'Aprano