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