]> granicus.if.org Git - python/commitdiff
bpo-29581: Make ABCMeta.__new__ pass **kwargs to type.__new__ (#527)
authorNate <nate@so8r.es>
Wed, 15 Mar 2017 18:39:22 +0000 (11:39 -0700)
committerŁukasz Langa <lukasz@langa.pl>
Wed, 15 Mar 2017 18:39:22 +0000 (11:39 -0700)
Many metaclasses in the standard library don't play nice with
__init_subclass__. This bug makes ABCMeta in particular with
__init_subclass__, which is an 80/20 solution for me personally.
AFAICT, a general solution to this problem requires updating all
metaclasses in the standard library to make sure they pass **kwargs to
type.__new__, whereas this PR only fixes ABCMeta. For context, see
https://bugs.python.org/issue29581.

* added a test combining ABCMeta and __init_subclass__
* Added NEWS item

Lib/abc.py
Lib/test/test_abc.py
Misc/NEWS

index 1cbf96a61f238f6b40f65682dedc7e2786a028b9..43a34a0bbded7864987f57a855bf788c4b74138f 100644 (file)
@@ -129,8 +129,8 @@ class ABCMeta(type):
     #       external code.
     _abc_invalidation_counter = 0
 
-    def __new__(mcls, name, bases, namespace):
-        cls = super().__new__(mcls, name, bases, namespace)
+    def __new__(mcls, name, bases, namespace, **kwargs):
+        cls = super().__new__(mcls, name, bases, namespace, **kwargs)
         # Compute set of abstract method names
         abstracts = {name
                      for name, value in namespace.items()
index e1765f0d5a54cbaf9407882aebda74a388b421b2..4bc838200413af824a36f76aa7c36911ea7a1006 100644 (file)
@@ -404,5 +404,17 @@ class TestABC(unittest.TestCase):
         self.assertEqual(B.counter, 1)
 
 
+class TestABCWithInitSubclass(unittest.TestCase):
+    def test_works_with_init_subclass(self):
+        saved_kwargs = {}
+        class ReceivesClassKwargs:
+            def __init_subclass__(cls, **kwargs):
+                super().__init_subclass__()
+                saved_kwargs.update(kwargs)
+        class Receiver(ReceivesClassKwargs, abc.ABC, x=1, y=2, z=3):
+            pass
+        self.assertEqual(saved_kwargs, dict(x=1, y=2, z=3))
+
+
 if __name__ == "__main__":
     unittest.main()
index 2f7bd7ac7b20d4e14c5edc19c96589fb926a986a..b7990c62e4f74416df885b8d2b1c7c45293d9733 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -761,6 +761,9 @@ Library
 - Issue #24142: Reading a corrupt config file left configparser in an
   invalid state.  Original patch by Florian Höch.
 
+- Issue #29581: ABCMeta.__new__ now accepts **kwargs, allowing abstract base
+  classes to use keyword parameters in __init_subclass__. Patch by Nate Soares.
+
 Windows
 -------