]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-141510: Implement copy and deepcopy for frozendict (#144905)
authorPieter Eendebak <pieter.eendebak@gmail.com>
Wed, 18 Feb 2026 11:30:26 +0000 (12:30 +0100)
committerGitHub <noreply@github.com>
Wed, 18 Feb 2026 11:30:26 +0000 (12:30 +0100)
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
Lib/copy.py
Lib/test/test_copy.py
Misc/NEWS.d/next/Library/2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst [new file with mode: 0644]

index 4c024ab5311d2ddcde0391f05bfcdcd5cd6668cd..33dabb3395a7c0adfba3a48915aada7c09e5464f 100644 (file)
@@ -101,7 +101,7 @@ def copy(x):
 
 
 _copy_atomic_types = frozenset({types.NoneType, int, float, bool, complex, str, tuple,
-          bytes, frozenset, type, range, slice, property,
+          bytes, frozendict, frozenset, type, range, slice, property,
           types.BuiltinFunctionType, types.EllipsisType,
           types.NotImplementedType, types.FunctionType, types.CodeType,
           weakref.ref, super})
@@ -203,6 +203,11 @@ def _deepcopy_dict(x, memo, deepcopy=deepcopy):
     return y
 d[dict] = _deepcopy_dict
 
+def _deepcopy_frozendict(x, memo, deepcopy=deepcopy):
+    y = _deepcopy_dict(x, memo, deepcopy)
+    return frozendict(y)
+d[frozendict] = _deepcopy_frozendict
+
 def _deepcopy_method(x, memo): # Copy instance methods
     return type(x)(x.__func__, deepcopy(x.__self__, memo))
 d[types.MethodType] = _deepcopy_method
index cfef24727e8c82eb0f75a85596fa0de339e66213..858e5e089d5abac5a58aff4a0376193a89391ce8 100644 (file)
@@ -133,6 +133,12 @@ class TestCopy(unittest.TestCase):
         self.assertEqual(y, x)
         self.assertIsNot(y, x)
 
+    def test_copy_frozendict(self):
+        x = frozendict(x=1, y=2)
+        self.assertIs(copy.copy(x), x)
+        x = frozendict()
+        self.assertIs(copy.copy(x), x)
+
     def test_copy_set(self):
         x = {1, 2, 3}
         y = copy.copy(x)
@@ -419,6 +425,13 @@ class TestCopy(unittest.TestCase):
         self.assertIsNot(x, y)
         self.assertIsNot(x["foo"], y["foo"])
 
+    def test_deepcopy_frozendict(self):
+        x = frozendict({"foo": [1, 2], "bar": 3})
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assertIsNot(x, y)
+        self.assertIsNot(x["foo"], y["foo"])
+
     @support.skip_emscripten_stack_overflow()
     @support.skip_wasi_stack_overflow()
     def test_deepcopy_reflexive_dict(self):
diff --git a/Misc/NEWS.d/next/Library/2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst b/Misc/NEWS.d/next/Library/2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst
new file mode 100644 (file)
index 0000000..5b60412
--- /dev/null
@@ -0,0 +1,2 @@
+The :mod:`copy` module now supports the :class:`frozendict` type. Patch by\r
+Pieter Eendebak based on work by Victor Stinner.