From 3221e4adca007e473564734626f3dfb16893363a Mon Sep 17 00:00:00 2001 From: Nate Date: Wed, 15 Mar 2017 11:39:22 -0700 Subject: [PATCH 1/4] bpo-29581: Make ABCMeta.__new__ pass **kwargs to type.__new__ (#527) 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 Note: I'm not sure I backported the NEWS changes correctly; I'm assuming that the cherry_picker tool merged everything corectly except for the explicit merge conflicts, but I'm not sure this is true. (cherry picked from commit bd583ef9857d99f9145ad0bb2c4424cc0baa63fc) --- Lib/abc.py | 4 ++-- Lib/test/test_abc.py | 12 ++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 17 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() 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() diff --git a/Misc/NEWS b/Misc/NEWS index b1f79d612402811..165452abf6be721 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -36,6 +36,9 @@ Core and Builtins Library ------- +- bpo-29581: ABCMeta.__new__ now accepts **kwargs, allowing abstract base + classes to use keyword parameters in __init_subclass__. Patch by Nate Soares. + - bpo-30070: Fixed leaks and crashes in errors handling in the parser module. - bpo-30061: Fixed crashes in IOBase methods __next__() and readlines() when From fc23984b0d11a9399432ee91444b66d1390c88e2 Mon Sep 17 00:00:00 2001 From: Nate Soares Date: Tue, 25 Apr 2017 09:14:44 -0700 Subject: [PATCH 2/4] [3.6] bpo-29581: Make ABCMeta.__new__ pass **kwargs to type.__new__ (GH-527) 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. (cherry picked from commit bd583ef9857d99f9145ad0bb2c4424cc0baa63fc) From e10aa40af10ac90ff1ce5c94c5ac825b1578cf29 Mon Sep 17 00:00:00 2001 From: Nate Date: Tue, 6 Jun 2017 15:42:55 -0700 Subject: [PATCH 3/4] **kwargs -> ``kwargs`` in attempts to fix the Travis build. --- Misc/NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS b/Misc/NEWS index ff96e1b237a7f08..c9632ac678a871d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -45,7 +45,7 @@ Core and Builtins Library ------- -- bpo-29581: ABCMeta.__new__ now accepts **kwargs, allowing abstract base +- bpo-29581: ABCMeta.__new__ now accepts ``kwargs``, allowing abstract base classes to use keyword parameters in __init_subclass__. Patch by Nate Soares. - bpo-30557: faulthandler now correctly filters and displays exception codes From 6f9fd041dbdcd0ea3ceea3f6b2a13325e94cdd87 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Tue, 6 Jun 2017 16:00:11 -0700 Subject: [PATCH 4/4] Quote the **kwargs --- Misc/NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS b/Misc/NEWS index c9632ac678a871d..515960daf7930fc 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -45,7 +45,7 @@ Core and Builtins Library ------- -- bpo-29581: ABCMeta.__new__ now accepts ``kwargs``, allowing abstract base +- bpo-29581: ABCMeta.__new__ now accepts ``**kwargs``, allowing abstract base classes to use keyword parameters in __init_subclass__. Patch by Nate Soares. - bpo-30557: faulthandler now correctly filters and displays exception codes