summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>2024-09-26 21:15:28 (GMT)
committerGitHub <noreply@github.com>2024-09-26 21:15:28 (GMT)
commit5e7eba09bcdafe361b491b3f8cf30d7dd2df0a78 (patch)
treeb65beaf135e8eb2da692ff591be433758c6246f2
parent2c108328877984f2d92604764c66ef15bd82b31e (diff)
downloadcpython-5e7eba09bcdafe361b491b3f8cf30d7dd2df0a78.zip
cpython-5e7eba09bcdafe361b491b3f8cf30d7dd2df0a78.tar.gz
cpython-5e7eba09bcdafe361b491b3f8cf30d7dd2df0a78.tar.bz2
gh-89683: add tests for `deepcopy` on frozen dataclasses (gh-123098)
Co-authored-by: Eric V. Smith <ericvsmith@users.noreply.github.com>
-rw-r--r--Lib/test/test_dataclasses/__init__.py43
1 files changed, 43 insertions, 0 deletions
diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py
index 69e8616..bd2f878 100644
--- a/Lib/test/test_dataclasses/__init__.py
+++ b/Lib/test/test_dataclasses/__init__.py
@@ -17,6 +17,7 @@ from unittest.mock import Mock
from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol, DefaultDict
from typing import get_type_hints
from collections import deque, OrderedDict, namedtuple, defaultdict
+from copy import deepcopy
from functools import total_ordering, wraps
import typing # Needed for the string "typing.ClassVar[int]" to work as an annotation.
@@ -3175,6 +3176,48 @@ class TestFrozen(unittest.TestCase):
with self.assertRaisesRegex(TypeError, 'unhashable type'):
hash(C({}))
+ def test_frozen_deepcopy_without_slots(self):
+ # see: https://github.com/python/cpython/issues/89683
+ @dataclass(frozen=True, slots=False)
+ class C:
+ s: str
+
+ c = C('hello')
+ self.assertEqual(deepcopy(c), c)
+
+ def test_frozen_deepcopy_with_slots(self):
+ # see: https://github.com/python/cpython/issues/89683
+ with self.subTest('generated __slots__'):
+ @dataclass(frozen=True, slots=True)
+ class C:
+ s: str
+
+ c = C('hello')
+ self.assertEqual(deepcopy(c), c)
+
+ with self.subTest('user-defined __slots__ and no __{get,set}state__'):
+ @dataclass(frozen=True, slots=False)
+ class C:
+ __slots__ = ('s',)
+ s: str
+
+ # with user-defined slots, __getstate__ and __setstate__ are not
+ # automatically added, hence the error
+ err = r"^cannot\ assign\ to\ field\ 's'$"
+ self.assertRaisesRegex(FrozenInstanceError, err, deepcopy, C(''))
+
+ with self.subTest('user-defined __slots__ and __{get,set}state__'):
+ @dataclass(frozen=True, slots=False)
+ class C:
+ __slots__ = ('s',)
+ __getstate__ = dataclasses._dataclass_getstate
+ __setstate__ = dataclasses._dataclass_setstate
+
+ s: str
+
+ c = C('hello')
+ self.assertEqual(deepcopy(c), c)
+
class TestSlots(unittest.TestCase):
def test_simple(self):