From 83ac508bbde334abbb261b99fdfe54f9917a0698 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Mon, 28 Dec 2020 21:55:02 -0800 Subject: [PATCH] update enum.py; add blurb; update WHATSNEW --- Doc/whatsnew/3.10.rst | 5 +++++ Lib/enum.py | 16 +--------------- .../2020-12-28-21-49-34.bpo-42775.qo_40W.rst | 4 ++++ 3 files changed, 10 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-12-28-21-49-34.bpo-42775.qo_40W.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index b5fb1e9a629..a89311412e7 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -62,6 +62,11 @@ Summary -- Release highlights .. This section singles out the most important changes in Python 3.10. Brevity is key. +The methods :func:`__init_subclass__` and :func:`__set_name__`, introduced +in :pep:`487`, have been moved from :func:`type.__new__` to +:func:`type.__init__`. This ensures that custome metaclasses are able to +finish creating a class before those two methods are called. + .. PEP-sized items next. diff --git a/Lib/enum.py b/Lib/enum.py index 115a49e861e..36ca2b91317 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -230,19 +230,8 @@ class EnumMeta(type): # postpone calling __init_subclass__ if '__init_subclass__' in classdict and classdict['__init_subclass__'] is None: raise TypeError('%s.__init_subclass__ cannot be None') - # remove current __init_subclass__ so previous one can be found with getattr - # new_init_subclass = classdict.pop('__init_subclass__', None) # create our new Enum type - if bases: - # bases = (_NoInitSubclass, ) + bases - enum_class = super().__new__(metacls, cls, bases, classdict, **kwds) - # enum_class.__bases__ = enum_class.__bases__[1:] #or (object, ) - else: - enum_class = super().__new__(metacls, cls, bases, classdict, **kwds) - # old_init_subclass = getattr(enum_class, '__init_subclass__', None) - # and restore the new one (if there was one) - # if new_init_subclass is not None: - # enum_class.__init_subclass__ = classmethod(new_init_subclass) + enum_class = super().__new__(metacls, cls, bases, classdict, **kwds) enum_class._member_names_ = [] # names in definition order enum_class._member_map_ = {} # name->value map enum_class._member_type_ = member_type @@ -354,9 +343,6 @@ class EnumMeta(type): if _order_ != enum_class._member_names_: raise TypeError('member order does not match _order_') - # finally, call parents' __init_subclass__ - # if Enum is not None and old_init_subclass is not None: - # old_init_subclass(**kwds) return enum_class def __bool__(self): diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-12-28-21-49-34.bpo-42775.qo_40W.rst b/Misc/NEWS.d/next/Core and Builtins/2020-12-28-21-49-34.bpo-42775.qo_40W.rst new file mode 100644 index 00000000000..72feac4995b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-12-28-21-49-34.bpo-42775.qo_40W.rst @@ -0,0 +1,4 @@ +Move the calls to ``__init_subclass__`` and ``__set_name__`` from +``type.__new__`` to ``type.__init__``. This ensures that custom metaclasses +are able to completely finish creating a class before the +``__init_subclass__`` and ``__set_name__`` methods are run.