From 0a773cfe246d7da4d44273e853f36addc22e4bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20=C3=89vrard?= Date: Fri, 19 Jul 2024 19:04:01 +0200 Subject: [PATCH] Implement __deepcopy__ on ImmutableDict Closes #13408 (grafted from cdb34d214369c682c1d8f21fcb8c143371557cb9) --HG-- branch : 7.0 --- trytond/trytond/tests/test_tools.py | 12 ++++++++++++ trytond/trytond/tools/immutabledict.py | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/trytond/trytond/tests/test_tools.py b/trytond/trytond/tests/test_tools.py index 9965927244..012d4971a5 100644 --- a/trytond/trytond/tests/test_tools.py +++ b/trytond/trytond/tests/test_tools.py @@ -6,6 +6,7 @@ import datetime as dt import doctest import sys import unittest +from copy import deepcopy from io import BytesIO import sql @@ -547,6 +548,17 @@ class ImmutableDictTestCase(unittest.TestCase): with self.assertRaises(TypeError): d.update({'foo': 'bar'}) + def test_deepcopy(self): + "deepcopying should be possible" + original = ImmutableDict(foo={'a': 1}, bar=2, baz=1.3) + copy = deepcopy(original) + + self.assertEqual(original, copy) + self.assertIsNot(original, copy) + + self.assertEqual(original['foo'], copy['foo']) + self.assertIsNot(original['foo'], copy['foo']) + class DomainInversionTestCase(unittest.TestCase): "Test domain_inversion" diff --git a/trytond/trytond/tools/immutabledict.py b/trytond/trytond/tools/immutabledict.py index d5448153da..4883a6af09 100644 --- a/trytond/trytond/tools/immutabledict.py +++ b/trytond/trytond/tools/immutabledict.py @@ -1,5 +1,7 @@ # This file is part of Tryton. The COPYRIGHT file at the toplevel of this # repository contains the full copyright notices and license terms. +from copy import deepcopy + class ImmutableDict(dict): @@ -8,6 +10,10 @@ class ImmutableDict(dict): def _not_allowed(cls, *args, **kwargs): raise TypeError("Operation not allowed on ImmutableDict") + def __deepcopy__(self, memo): + return ImmutableDict( + (k, deepcopy(v, memo=memo)) for k, v in self.items()) + __setitem__ = _not_allowed __delitem__ = _not_allowed __ior__ = _not_allowed