diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index befd6d0d940ab68..c29708c293953bd 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -645,6 +645,12 @@ Changes in the Python API since the *buffering* parameter has been removed. (Contributed by Victor Stinner in :issue:`39357`.) +* The inheritance registry for an :class:`~abc.ABCMeta` instance is now + set up in the ``__init__()`` method instead of the ``__new__()`` method. + Be aware of this if you implement a subclass of ``ABCMeta`` and override + its ``__new__()`` or ``__init__()`` methods. + (Contributed by Serhiy Storchaka in :issue:`28869`.) + CPython bytecode changes ------------------------ diff --git a/Lib/_py_abc.py b/Lib/_py_abc.py index c870ae9048b4f13..0be1eb5b1da1271 100644 --- a/Lib/_py_abc.py +++ b/Lib/_py_abc.py @@ -32,8 +32,7 @@ class ABCMeta(type): # external code. _abc_invalidation_counter = 0 - def __new__(mcls, name, bases, namespace, /, **kwargs): - cls = super().__new__(mcls, name, bases, namespace, **kwargs) + def __init__(cls, name, bases, namespace, /, **kwargs): # Compute set of abstract method names abstracts = {name for name, value in namespace.items() @@ -49,7 +48,6 @@ def __new__(mcls, name, bases, namespace, /, **kwargs): cls._abc_cache = WeakSet() cls._abc_negative_cache = WeakSet() cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter - return cls def register(cls, subclass): """Register a virtual subclass of an ABC. diff --git a/Lib/abc.py b/Lib/abc.py index 431b64040a66e8c..ae5b208592a2223 100644 --- a/Lib/abc.py +++ b/Lib/abc.py @@ -81,10 +81,8 @@ class ABCMeta(type): implementations defined by the registering ABC be callable (not even via super()). """ - def __new__(mcls, name, bases, namespace, **kwargs): - cls = super().__new__(mcls, name, bases, namespace, **kwargs) + def __init__(cls, name, bases, namespace, /, **kwargs): _abc_init(cls) - return cls def register(cls, subclass): """Register a virtual subclass of an ABC. diff --git a/Lib/test/test_abc.py b/Lib/test/test_abc.py index 000e5838e3c712b..5a24c0a9b113a9c 100644 --- a/Lib/test/test_abc.py +++ b/Lib/test/test_abc.py @@ -488,6 +488,13 @@ class C(with_metaclass(abc_ABCMeta, A, B)): pass self.assertEqual(C.__class__, abc_ABCMeta) + def test_type_module(self): + class A(metaclass=abc_ABCMeta): + pass + self.assertEqual(A.__module__, __name__) + B = abc_ABCMeta('B', (), {}) + self.assertEqual(B.__module__, __name__) + class TestABCWithInitSubclass(unittest.TestCase): def test_works_with_init_subclass(self): diff --git a/Misc/NEWS.d/next/Library/2019-10-07-13-10-09.bpo-28869.6epshM.rst b/Misc/NEWS.d/next/Library/2019-10-07-13-10-09.bpo-28869.6epshM.rst new file mode 100644 index 000000000000000..36ed0958d7b8e67 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-07-13-10-09.bpo-28869.6epshM.rst @@ -0,0 +1,4 @@ +Types created by calling :func:`~abc.ABCMeta` have now a proper +:attr:`__module__` attribute. +The inheritance registry for an ``ABCMeta`` instance is now +set up in the ``__init__()`` method instead of the ``__new__()`` method.