From e74eb9c3cfd44e1211cbaf1c9f11e219318afb17 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 7 Oct 2019 13:10:34 +0300 Subject: [PATCH 1/2] bpo-28869: Set up inheritance registry in ABCMeta.__init__. Move setting up inheritance registry from ABCMeta.__new__ to ABCMeta.__init__. This makes the __module__ attribute be properly set for types created by calling ABCMeta(). --- Lib/_py_abc.py | 4 +--- Lib/abc.py | 4 +--- Lib/test/test_abc.py | 7 +++++++ .../next/Library/2019-10-07-13-10-09.bpo-28869.6epshM.rst | 2 ++ 4 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-10-07-13-10-09.bpo-28869.6epshM.rst 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..2079b6e20b74a00 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-07-13-10-09.bpo-28869.6epshM.rst @@ -0,0 +1,2 @@ +Types created by calling :func:`~abc.ABCMeta` have now a proper +:attr:`__module__` attribute. From 1b083203967f250e7c6c8a22d569aae76bf7f555 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 8 Mar 2020 15:09:17 +0200 Subject: [PATCH 2/2] Document backwards incompatible change. --- Doc/whatsnew/3.9.rst | 6 ++++++ .../next/Library/2019-10-07-13-10-09.bpo-28869.6epshM.rst | 2 ++ 2 files changed, 8 insertions(+) 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/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 index 2079b6e20b74a00..36ed0958d7b8e67 100644 --- 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 @@ -1,2 +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.