Skip to content

Commit b1257f0

Browse files
picnixzericvsmith
andcommitted
pythongh-89683: add tests for deepcopy on frozen dataclasses (pythongh-123098)
Co-authored-by: Bénédikt Tran <[email protected]> Co-authored-by: Eric V. Smith <[email protected]>
1 parent fb8d604 commit b1257f0

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

Lib/test/test_dataclasses/__init__.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from unittest.mock import Mock
1717
from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol, DefaultDict
1818
from typing import get_type_hints
19+
from copy import deepcopy
1920
from collections import deque, OrderedDict, namedtuple, defaultdict
2021
from functools import total_ordering
2122

@@ -3071,6 +3072,48 @@ class C:
30713072
with self.assertRaisesRegex(TypeError, 'unhashable type'):
30723073
hash(C({}))
30733074

3075+
def test_frozen_deepcopy_without_slots(self):
3076+
# see: https://github.com/python/cpython/issues/89683
3077+
@dataclass(frozen=True, slots=False)
3078+
class C:
3079+
s: str
3080+
3081+
c = C('hello')
3082+
self.assertEqual(deepcopy(c), c)
3083+
3084+
def test_frozen_deepcopy_with_slots(self):
3085+
# see: https://github.com/python/cpython/issues/89683
3086+
with self.subTest('generated __slots__'):
3087+
@dataclass(frozen=True, slots=True)
3088+
class C:
3089+
s: str
3090+
3091+
c = C('hello')
3092+
self.assertEqual(deepcopy(c), c)
3093+
3094+
with self.subTest('user-defined __slots__ and no __{get,set}state__'):
3095+
@dataclass(frozen=True, slots=False)
3096+
class C:
3097+
__slots__ = ('s',)
3098+
s: str
3099+
3100+
# with user-defined slots, __getstate__ and __setstate__ are not
3101+
# automatically added, hence the error
3102+
err = r"^cannot\ assign\ to\ field\ 's'$"
3103+
self.assertRaisesRegex(FrozenInstanceError, err, deepcopy, C(''))
3104+
3105+
with self.subTest('user-defined __slots__ and __{get,set}state__'):
3106+
@dataclass(frozen=True, slots=False)
3107+
class C:
3108+
__slots__ = ('s',)
3109+
__getstate__ = dataclasses._dataclass_getstate
3110+
__setstate__ = dataclasses._dataclass_setstate
3111+
3112+
s: str
3113+
3114+
c = C('hello')
3115+
self.assertEqual(deepcopy(c), c)
3116+
30743117

30753118
class TestSlots(unittest.TestCase):
30763119
def test_simple(self):

0 commit comments

Comments
 (0)