https://github.com/python/cpython/commit/f8d2f9fe67f8ab279cf7c5f6fa6a4feb588ce8f0
commit: f8d2f9fe67f8ab279cf7c5f6fa6a4feb588ce8f0
branch: main
author: Stan Ulbrych <[email protected]>
committer: vstinner <[email protected]>
date: 2026-03-02T20:45:03+01:00
summary:
gh-145118: Add `frozendict` support to `type()` (#145124)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst
M Lib/test/test_builtin.py
M Objects/typeobject.c
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 7b69374b1868d1..eabfdcd447f2bb 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -2993,6 +2993,12 @@ def test_type_doc(self):
A.__doc__ = doc
self.assertEqual(A.__doc__, doc)
+ def test_type_frozendict(self):
+ A = type('A', (), frozendict({'x': 4, 'y': 2}))
+ self.assertEqual(A.x, 4)
+ self.assertEqual(A.y, 2)
+ self.assertEqual(A.__name__, 'A')
+
def test_bad_args(self):
with self.assertRaises(TypeError):
type()
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst
new file mode 100644
index 00000000000000..24507d4a411f85
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst
@@ -0,0 +1 @@
+:func:`type` now accepts :class:`frozendict` as an argument.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index ad26339c9c34df..d77d981085f4da 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -4872,9 +4872,21 @@ type_new_get_slots(type_new_ctx *ctx, PyObject *dict)
static PyTypeObject*
type_new_init(type_new_ctx *ctx)
{
- PyObject *dict = PyDict_Copy(ctx->orig_dict);
- if (dict == NULL) {
- goto error;
+ PyObject *dict;
+ if (PyFrozenDict_Check(ctx->orig_dict)) {
+ dict = PyDict_New();
+ if (dict == NULL) {
+ goto error;
+ }
+ if (PyDict_Merge(dict, ctx->orig_dict, 1) < 0) {
+ goto error;
+ }
+ }
+ else {
+ dict = PyDict_Copy(ctx->orig_dict);
+ if (dict == NULL) {
+ goto error;
+ }
}
if (type_new_get_slots(ctx, dict) < 0) {
@@ -5037,13 +5049,19 @@ type_new(PyTypeObject *metatype, PyObject *args,
PyObject *kwds)
/* Parse arguments: (name, bases, dict) */
PyObject *name, *bases, *orig_dict;
- if (!PyArg_ParseTuple(args, "UO!O!:type.__new__",
+ if (!PyArg_ParseTuple(args, "UO!O:type.__new__",
&name,
&PyTuple_Type, &bases,
- &PyDict_Type, &orig_dict))
+ &orig_dict))
{
return NULL;
}
+ if (!PyAnyDict_Check(orig_dict)) {
+ PyErr_Format(PyExc_TypeError,
+ "type.__new__() argument 3 must be dict or frozendict,
not %T",
+ orig_dict);
+ return NULL;
+ }
type_new_ctx ctx = {
.metatype = metatype,
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]