bpo-29581: bpo-29581: Make ABCMeta.new pass **kwargs to type.__ne… · python/cpython@6fb12b5 (original) (raw)

Skip to content

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

Appearance settings

Commit 6fb12b5

NateMariatta

authored and

committed

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, seehttps://bugs.python.org/issue29581. * added a test combining ABCMeta and __init_subclass__ * Added NEWS item (cherry picked from commit bd583ef) * [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, seehttps://bugs.python.org/issue29581. * added a test combining ABCMeta and __init_subclass__ * Added NEWS item. (cherry picked from commit bd583ef) * **kwargs -> ``kwargs`` in attempts to fix the Travis build. * Quote the **kwargs

File tree

3 files changed

lines changed

3 files changed

lines changed

Lines changed: 2 additions & 2 deletions

Original file line number Diff line number Diff line change
@@ -129,8 +129,8 @@ class ABCMeta(type):
129 129 # external code.
130 130 _abc_invalidation_counter = 0
131 131
132 -def __new__(mcls, name, bases, namespace):
133 -cls = super().__new__(mcls, name, bases, namespace)
132 +def __new__(mcls, name, bases, namespace, **kwargs):
133 +cls = super().__new__(mcls, name, bases, namespace, **kwargs)
134 134 # Compute set of abstract method names
135 135 abstracts = {name
136 136 for name, value in namespace.items()

Lines changed: 12 additions & 0 deletions

Original file line number Diff line number Diff line change
@@ -404,5 +404,17 @@ class C(A, B):
404 404 self.assertEqual(B.counter, 1)
405 405
406 406
407 +class TestABCWithInitSubclass(unittest.TestCase):
408 +def test_works_with_init_subclass(self):
409 +saved_kwargs = {}
410 +class ReceivesClassKwargs:
411 +def __init_subclass__(cls, **kwargs):
412 +super().__init_subclass__()
413 +saved_kwargs.update(kwargs)
414 +class Receiver(ReceivesClassKwargs, abc.ABC, x=1, y=2, z=3):
415 +pass
416 +self.assertEqual(saved_kwargs, dict(x=1, y=2, z=3))
417 +
418 +
407 419 if __name__ == "__main__":
408 420 unittest.main()

Lines changed: 3 additions & 0 deletions

Original file line number Diff line number Diff line change
@@ -45,6 +45,9 @@ Core and Builtins
45 45 Library
46 46 -------
47 47
48 +- bpo-29581: ABCMeta.__new__ now accepts ``**kwargs``, allowing abstract base
49 + classes to use keyword parameters in __init_subclass__. Patch by Nate Soares.
50 +
48 51 - bpo-30557: faulthandler now correctly filters and displays exception codes
49 52 on Windows
50 53