Robin De Schepper
Robin De Schepper

Reputation: 6355

How to pass `__init_subclass__` keyword arguments when using `type`?

I have a class that accepts keyword arguments, something that was introduced together with __init_subclass__ in Python 3.6:

class Parent:
  def __init_subclass__(cls, key=None, **kwargs):
    super().__init_subclass__(**kwargs)
    assert key is not None

class Child(Parent, key=5):
  pass

Child2 = type("Child2", (Parent,), {})

But it gives an AssertionError since no key was passed. If I try to give an additional dictionary of arguments I get the following error:

>>> type("Child2", (Parent,), {}, {"key": 5})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: type() takes 1 or 3 arguments

And also the documentation on the type function do not allow for them to be specified. How can I pass these kwargs to __init_subclass__?

Upvotes: 1

Views: 693

Answers (1)

Robin De Schepper
Robin De Schepper

Reputation: 6355

You can pass keyword arguments to the type() call:

Child2 = type("Child2", (base,), {}, key=5)

This has been available together with __init_subclass__ since Python 3.6.0 but is actually an oversight in the Python documentation. It has been corrected in the Python 3.10 development docs (here) whose type() signature shows you how to do it:

type(name, bases, dict, **kwds)

And states this possibility:

Keyword arguments provided to the three argument form are passed to the appropriate metaclass machinery (usually __init_subclass__()) in the same way that keywords in a class definition (besides metaclass) would.

Upvotes: 3

Related Questions