bpo-29581: bpo-29581: Make ABCMeta.__new__ pass **kwargs to type.__new__ (GH-527) (GH-1282)

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 bd583ef985)

* [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 bd583ef985)

* **kwargs -> ``kwargs`` in attempts to fix the Travis build.

* Quote the **kwargs
This commit is contained in:
Nate 2017-06-06 17:31:03 -07:00 committed by Mariatta
parent 063f0b3583
commit 6fb12b5c43
3 changed files with 17 additions and 2 deletions

View file

@ -129,8 +129,8 @@ class ABCMeta(type):
# external code. # external code.
_abc_invalidation_counter = 0 _abc_invalidation_counter = 0
def __new__(mcls, name, bases, namespace): def __new__(mcls, name, bases, namespace, **kwargs):
cls = super().__new__(mcls, name, bases, namespace) cls = super().__new__(mcls, name, bases, namespace, **kwargs)
# Compute set of abstract method names # Compute set of abstract method names
abstracts = {name abstracts = {name
for name, value in namespace.items() for name, value in namespace.items()

View file

@ -404,5 +404,17 @@ class TestABC(unittest.TestCase):
self.assertEqual(B.counter, 1) 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__": if __name__ == "__main__":
unittest.main() unittest.main()

View file

@ -45,6 +45,9 @@ Core and Builtins
Library Library
------- -------
- 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 - bpo-30557: faulthandler now correctly filters and displays exception codes
on Windows on Windows