I'm trying to use python 3.6's new __init_subclass__
feature (PEP 487) with the abc
module. It doesn't seem to be working. The following code:
from abc import ABCMeta
class Initifier:
def __init_subclass__(cls, x=None, **kwargs):
super().__init_subclass__(**kwargs)
print('got x', x)
class Abstracted(metaclass=ABCMeta):
pass
class Thingy(Abstracted, Initifier, x=1):
pass
thingy = Thingy()
yields the following when run:
Traceback (most recent call last):
File "<filename>", line 10, in <module>
class Thingy(Abstracted, Initifier, x=1):
TypeError: __new__() got an unexpected keyword argument 'x'
Everything works fine if Abstracted doesn't use the ABCMeta
metaclass.
This error is fairly resilient, for example, the following code still fails with a similar type error (presumably because a metaclass' __new__
runs at class instantiation time, whereas the parent class' __new__
doesn't run until object instantiation).
from abc import ABCMeta
class Initifier:
def __new__(cls, name, bases, dct, x=None, **kwargs):
return super().__new__(cls, name, bases, dct, **kwargs)
def __init_subclass__(cls, x=None, **kwargs):
super().__init_subclass__(**kwargs)
print('got x', x)
class Abstracted(metaclass=ABCMeta):
pass
class Thingy(Initifier, Abstracted, x=1):
pass
thingy = Thingy()
Can anyone confirm that this is a bug in the Python 3.6 abc
module and/or __init_subclass__
implementation? (I might be using __init_subclass__
wrong.) Does anyone have a workaround?
It's a bug in abc.ABCMeta
, due to a wart in the design of __init_subclass__
. I recommend reporting it.
Pretty much every metaclass in existence is now supposed to pass unexpected keyword arguments through to super().__new__
so type.__new__
can pass them to __init_subclass__
, but ABCMeta and probably tons of other metaclasses don't do that yet. abc.ABCMeta.__new__
chokes on the x
keyword argument instead of passing it through, causing the exception you see.
Trying to use __init_subclass__
keyword arguments with a metaclass that hasn't been updated for the new design isn't going to work. You'll have to wait for the metaclasses you use to be patched.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With