Title: `type` takes **kwargs for __init_subclass__
Type: behavior Stage: patch review
Components: Versions: Python 3.10, Python 3.9, Python 3.8, Python 3.7, Python 3.6
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: esoma, gvanrossum
Priority: normal Keywords: patch

Created on 2021-01-06 15:21 by esoma, last changed 2021-01-09 01:49 by esoma.

Pull Requests
URL Status Linked Edit
PR 24173 open esoma, 2021-01-08 21:11
Messages (5)
msg384506 - (view) Author: Erik Soma (esoma) * Date: 2021-01-06 15:21
The documentation ( shows type's signature as:

class type(object)
class type(name, bases, dict)

But the "actual" 2nd signature in CPython 3.6+ is:

class type(name, bases, dict, **kwargs)

**kwargs here gets passed to __init_subclass__ in the same way that keywords in a class statement do so that:

type("Bar", (Foo,), {}, spam='ham')

is equivalent to

class Bar(Foo, spam='ham'): pass

It's not clear to me whether this is behavior to rely on. I started using this intuitively, but found that my type checker reasonably complained.

Looking through the commit that implemented PEP 487 (d78448e9), it seems this may have been incidental. Additionally I haven't found mention of this in PEP 487 or the documentation and I can't seem to find any tests for it.
msg384522 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2021-01-06 17:36
That sounds intentional to me (else the class statement would have a capability that cannot be dynamically emulated by calling type()).

We should probably update the docs (if you could submit a small PR that would be appreciated) and also typeshed (ditto).
msg384530 - (view) Author: Erik Soma (esoma) * Date: 2021-01-06 18:37
Can do.

I have found a blurb in the 3.6 What's New that confirms it was purposeful (
msg384533 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2021-01-06 19:00
msg384707 - (view) Author: Erik Soma (esoma) * Date: 2021-01-09 01:49
Seems I misframed the issue a bit. I didn't realize keyword arguments besides 'metaclass' were introduced with PEP 3115 with Python 3.0.

In any case I've posted a PR to update the docs and typeshed.
Typeshed PR for reference:
Date User Action Args
2021-01-09 01:49:33esomasetmessages: + msg384707
2021-01-08 21:11:44esomasetkeywords: + patch
stage: patch review
pull_requests: + pull_request23000
2021-01-06 19:00:05gvanrossumsetmessages: + msg384533
2021-01-06 18:37:18esomasetmessages: + msg384530
2021-01-06 17:36:24gvanrossumsetnosy: + gvanrossum
messages: + msg384522
2021-01-06 15:21:21esomacreate