From adf39919c717a3359b26c2db8e421b6de71c60cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ka=C4=9Fan=20Ar=C4=B1ba=C5=9F?= <172207405+aribaskagan@users.noreply.github.com> Date: Thu, 12 Nov 2026 17:44:49 +0000 Subject: [PATCH] gh-77371: Clarify that types.new_class() kwds are class keywords MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kwds corresponds to keywords in the class statement, such as metaclass, rather than the namespace dictionary accepted by type(). The class body is filled in by exec_body. Note the same distinction on prepare_class(). Co-authored-by: Kağan Arıbaş --- Lib/types.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Lib/types.py b/Lib/types.py index 6c069591ab26ef0..585a4d9764d9a0e 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -84,7 +84,26 @@ def _m(self): pass # Provide a PEP 3115 compliant mechanism for class creation def new_class(name, bases=(), kwds=None, exec_body=None): - """Create a class object dynamically using the appropriate metaclass.""" + """Create a class object dynamically using the appropriate metaclass. + + *name*, *bases*, and *kwds* are the class name, the base classes, + and the keywords of the equivalent class definition (such as + 'metaclass'). *kwds* is not a namespace like the third argument + of type(). For example: + + new_class('Test', (A, B), {'metaclass': Meta, 'foo': 42}) + + is equivalent to: + + class Test(A, B, metaclass=Meta, foo=42): + pass + + To populate the namespace, pass *exec_body*, a callable that takes + the newly created dictionary and populates it. For example: + + new_class('C', (MyABC,), {}, + exec_body=lambda ns: ns.update(namespace)) + """ resolved_bases = resolve_bases(bases) meta, ns, kwds = prepare_class(name, resolved_bases, kwds) if exec_body is not None: @@ -123,7 +142,8 @@ def prepare_class(name, bases=(), kwds=None): *namespace* is the prepared class namespace *kwds* is an updated copy of the passed in kwds argument with any 'metaclass' entry removed. If no kwds argument is passed in, this will - be an empty dict. + be an empty dict. Passed in keywords are those of the class definition + (such as 'metaclass'), not a class namespace. """ if kwds is None: kwds = {}