From de5d514e649729a1f9e6f3e132d8ffb872d38b08 Mon Sep 17 00:00:00 2001 From: Nate Soares Date: Mon, 6 Mar 2017 14:56:28 -0800 Subject: [PATCH 1/3] Make ABCMeta.__new__ pass **kwargs to type.__new__ 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. --- Lib/abc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/abc.py b/Lib/abc.py index 1cbf96a61f238f6..43a34a0bbded786 100644 --- a/Lib/abc.py +++ b/Lib/abc.py @@ -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() From 87dc688aa09b56f22f3566956ec95b79d2ce4c1d Mon Sep 17 00:00:00 2001 From: Nate Soares Date: Mon, 6 Mar 2017 15:24:52 -0800 Subject: [PATCH 2/3] added a test combining ABCMeta and __init_subclass__ --- Lib/test/test_abc.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Lib/test/test_abc.py b/Lib/test/test_abc.py index e1765f0d5a54cba..4bc838200413af8 100644 --- a/Lib/test/test_abc.py +++ b/Lib/test/test_abc.py @@ -404,5 +404,17 @@ class C(A, B): 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() From f2b4f4ba8ca95b92c26fbe5a732fcb3312ebf53b Mon Sep 17 00:00:00 2001 From: Nate Soares Date: Tue, 14 Mar 2017 21:15:06 -0700 Subject: [PATCH 3/3] Added NEWS item --- Misc/NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Misc/NEWS b/Misc/NEWS index bcd049661edb1f2..5c9513f0a7c6815 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -714,6 +714,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 -------