|
17 | 17 | from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol, DefaultDict
|
18 | 18 | from typing import get_type_hints
|
19 | 19 | from collections import deque, OrderedDict, namedtuple, defaultdict
|
| 20 | +from copy import deepcopy |
20 | 21 | from functools import total_ordering, wraps
|
21 | 22 |
|
22 | 23 | import typing # Needed for the string "typing.ClassVar[int]" to work as an annotation.
|
@@ -3175,6 +3176,48 @@ class C:
|
3175 | 3176 | with self.assertRaisesRegex(TypeError, 'unhashable type'):
|
3176 | 3177 | hash(C({}))
|
3177 | 3178 |
|
| 3179 | + def test_frozen_deepcopy_without_slots(self): |
| 3180 | + # see: https://github.com/python/cpython/issues/89683 |
| 3181 | + @dataclass(frozen=True, slots=False) |
| 3182 | + class C: |
| 3183 | + s: str |
| 3184 | + |
| 3185 | + c = C('hello') |
| 3186 | + self.assertEqual(deepcopy(c), c) |
| 3187 | + |
| 3188 | + def test_frozen_deepcopy_with_slots(self): |
| 3189 | + # see: https://github.com/python/cpython/issues/89683 |
| 3190 | + with self.subTest('generated __slots__'): |
| 3191 | + @dataclass(frozen=True, slots=True) |
| 3192 | + class C: |
| 3193 | + s: str |
| 3194 | + |
| 3195 | + c = C('hello') |
| 3196 | + self.assertEqual(deepcopy(c), c) |
| 3197 | + |
| 3198 | + with self.subTest('user-defined __slots__ and no __{get,set}state__'): |
| 3199 | + @dataclass(frozen=True, slots=False) |
| 3200 | + class C: |
| 3201 | + __slots__ = ('s',) |
| 3202 | + s: str |
| 3203 | + |
| 3204 | + # with user-defined slots, __getstate__ and __setstate__ are not |
| 3205 | + # automatically added, hence the error |
| 3206 | + err = r"^cannot\ assign\ to\ field\ 's'$" |
| 3207 | + self.assertRaisesRegex(FrozenInstanceError, err, deepcopy, C('')) |
| 3208 | + |
| 3209 | + with self.subTest('user-defined __slots__ and __{get,set}state__'): |
| 3210 | + @dataclass(frozen=True, slots=False) |
| 3211 | + class C: |
| 3212 | + __slots__ = ('s',) |
| 3213 | + __getstate__ = dataclasses._dataclass_getstate |
| 3214 | + __setstate__ = dataclasses._dataclass_setstate |
| 3215 | + |
| 3216 | + s: str |
| 3217 | + |
| 3218 | + c = C('hello') |
| 3219 | + self.assertEqual(deepcopy(c), c) |
| 3220 | + |
3178 | 3221 |
|
3179 | 3222 | class TestSlots(unittest.TestCase):
|
3180 | 3223 | def test_simple(self):
|
|
0 commit comments