blob: f1ca8cb254d1887f166d6d9a2081f1ee878b5589 [file] [log] [blame]
Guido van Rossum581cb932003-02-06 17:52:15 +00001"""Unit tests for the copy module."""
2
Guido van Rossum581cb932003-02-06 17:52:15 +00003import copy
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00004import copyreg
Antoine Pitrou6e610062009-05-15 17:04:50 +00005import weakref
Alexandre Vassalotti5c1c3b42013-12-01 13:25:26 -08006import abc
Mark Dickinsona56c4672009-01-27 18:17:45 +00007from operator import le, lt, ge, gt, eq, ne
Antoine Pitrou6e610062009-05-15 17:04:50 +00008
Guido van Rossum581cb932003-02-06 17:52:15 +00009import unittest
Serhiy Storchaka462c1f02021-09-08 18:08:57 +030010from test import support
Guido van Rossum581cb932003-02-06 17:52:15 +000011
Mark Dickinsona56c4672009-01-27 18:17:45 +000012order_comparisons = le, lt, ge, gt
13equality_comparisons = eq, ne
14comparisons = order_comparisons + equality_comparisons
15
Guido van Rossum581cb932003-02-06 17:52:15 +000016class TestCopy(unittest.TestCase):
17
18 # Attempt full line coverage of copy.py from top to bottom
19
20 def test_exceptions(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020021 self.assertIs(copy.Error, copy.error)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000022 self.assertTrue(issubclass(copy.Error, Exception))
Guido van Rossum581cb932003-02-06 17:52:15 +000023
24 # The copy() method
25
26 def test_copy_basic(self):
27 x = 42
28 y = copy.copy(x)
29 self.assertEqual(x, y)
30
31 def test_copy_copy(self):
32 class C(object):
33 def __init__(self, foo):
34 self.foo = foo
35 def __copy__(self):
36 return C(self.foo)
37 x = C(42)
38 y = copy.copy(x)
39 self.assertEqual(y.__class__, x.__class__)
40 self.assertEqual(y.foo, x.foo)
41
Guido van Rossumc06e3ac2003-02-07 17:30:18 +000042 def test_copy_registry(self):
43 class C(object):
44 def __new__(cls, foo):
45 obj = object.__new__(cls)
46 obj.foo = foo
47 return obj
48 def pickle_C(obj):
49 return (C, (obj.foo,))
50 x = C(42)
51 self.assertRaises(TypeError, copy.copy, x)
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000052 copyreg.pickle(C, pickle_C, C)
Guido van Rossumc06e3ac2003-02-07 17:30:18 +000053 y = copy.copy(x)
54
Guido van Rossume6908832003-02-19 01:19:28 +000055 def test_copy_reduce_ex(self):
56 class C(object):
57 def __reduce_ex__(self, proto):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020058 c.append(1)
Guido van Rossume6908832003-02-19 01:19:28 +000059 return ""
60 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020061 self.fail("shouldn't call this")
62 c = []
Guido van Rossume6908832003-02-19 01:19:28 +000063 x = C()
64 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +020065 self.assertIs(y, x)
66 self.assertEqual(c, [1])
Guido van Rossume6908832003-02-19 01:19:28 +000067
Guido van Rossum581cb932003-02-06 17:52:15 +000068 def test_copy_reduce(self):
69 class C(object):
70 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020071 c.append(1)
Guido van Rossum581cb932003-02-06 17:52:15 +000072 return ""
Sandro Tosi4dc9c842011-08-05 23:05:35 +020073 c = []
Guido van Rossum581cb932003-02-06 17:52:15 +000074 x = C()
75 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +020076 self.assertIs(y, x)
77 self.assertEqual(c, [1])
Guido van Rossum581cb932003-02-06 17:52:15 +000078
79 def test_copy_cant(self):
Guido van Rossume6908832003-02-19 01:19:28 +000080 class C(object):
Guido van Rossum581cb932003-02-06 17:52:15 +000081 def __getattribute__(self, name):
Guido van Rossume6908832003-02-19 01:19:28 +000082 if name.startswith("__reduce"):
Collin Winter3add4d72007-08-29 23:37:32 +000083 raise AttributeError(name)
Guido van Rossum581cb932003-02-06 17:52:15 +000084 return object.__getattribute__(self, name)
85 x = C()
86 self.assertRaises(copy.Error, copy.copy, x)
87
88 # Type-specific _copy_xxx() methods
89
90 def test_copy_atomic(self):
91 class Classic:
92 pass
93 class NewStyle(object):
94 pass
95 def f():
96 pass
Alexandre Vassalotti5c1c3b42013-12-01 13:25:26 -080097 class WithMetaclass(metaclass=abc.ABCMeta):
98 pass
Serhiy Storchaka818e18d2016-03-06 14:56:57 +020099 tests = [None, ..., NotImplemented,
100 42, 2**100, 3.14, True, False, 1j,
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000101 "hello", "hello\u1234", f.__code__,
Serhiy Storchaka818e18d2016-03-06 14:56:57 +0200102 b"world", bytes(range(256)), range(10), slice(1, 10, 2),
Guðni Natan Gunnarsson9f3fc6c2020-01-12 17:41:49 +0000103 NewStyle, Classic, max, WithMetaclass, property()]
Guido van Rossum581cb932003-02-06 17:52:15 +0000104 for x in tests:
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200105 self.assertIs(copy.copy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000106
107 def test_copy_list(self):
108 x = [1, 2, 3]
Serhiy Storchaka818e18d2016-03-06 14:56:57 +0200109 y = copy.copy(x)
110 self.assertEqual(y, x)
111 self.assertIsNot(y, x)
112 x = []
113 y = copy.copy(x)
114 self.assertEqual(y, x)
115 self.assertIsNot(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000116
117 def test_copy_tuple(self):
118 x = (1, 2, 3)
Serhiy Storchaka818e18d2016-03-06 14:56:57 +0200119 self.assertIs(copy.copy(x), x)
120 x = ()
121 self.assertIs(copy.copy(x), x)
122 x = (1, 2, 3, [])
123 self.assertIs(copy.copy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000124
125 def test_copy_dict(self):
126 x = {"foo": 1, "bar": 2}
Serhiy Storchaka818e18d2016-03-06 14:56:57 +0200127 y = copy.copy(x)
128 self.assertEqual(y, x)
129 self.assertIsNot(y, x)
130 x = {}
131 y = copy.copy(x)
132 self.assertEqual(y, x)
133 self.assertIsNot(y, x)
134
135 def test_copy_set(self):
136 x = {1, 2, 3}
137 y = copy.copy(x)
138 self.assertEqual(y, x)
139 self.assertIsNot(y, x)
140 x = set()
141 y = copy.copy(x)
142 self.assertEqual(y, x)
143 self.assertIsNot(y, x)
144
145 def test_copy_frozenset(self):
146 x = frozenset({1, 2, 3})
147 self.assertIs(copy.copy(x), x)
148 x = frozenset()
149 self.assertIs(copy.copy(x), x)
150
151 def test_copy_bytearray(self):
152 x = bytearray(b'abc')
153 y = copy.copy(x)
154 self.assertEqual(y, x)
155 self.assertIsNot(y, x)
156 x = bytearray()
157 y = copy.copy(x)
158 self.assertEqual(y, x)
159 self.assertIsNot(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000160
161 def test_copy_inst_vanilla(self):
162 class C:
163 def __init__(self, foo):
164 self.foo = foo
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000165 def __eq__(self, other):
166 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000167 x = C(42)
168 self.assertEqual(copy.copy(x), x)
169
170 def test_copy_inst_copy(self):
171 class C:
172 def __init__(self, foo):
173 self.foo = foo
174 def __copy__(self):
175 return C(self.foo)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000176 def __eq__(self, other):
177 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000178 x = C(42)
179 self.assertEqual(copy.copy(x), x)
180
181 def test_copy_inst_getinitargs(self):
182 class C:
183 def __init__(self, foo):
184 self.foo = foo
185 def __getinitargs__(self):
186 return (self.foo,)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000187 def __eq__(self, other):
188 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000189 x = C(42)
190 self.assertEqual(copy.copy(x), x)
191
Serhiy Storchaka32af7542015-03-24 18:06:42 +0200192 def test_copy_inst_getnewargs(self):
193 class C(int):
194 def __new__(cls, foo):
195 self = int.__new__(cls)
196 self.foo = foo
197 return self
198 def __getnewargs__(self):
199 return self.foo,
200 def __eq__(self, other):
201 return self.foo == other.foo
202 x = C(42)
203 y = copy.copy(x)
204 self.assertIsInstance(y, C)
205 self.assertEqual(y, x)
206 self.assertIsNot(y, x)
207 self.assertEqual(y.foo, x.foo)
208
209 def test_copy_inst_getnewargs_ex(self):
210 class C(int):
211 def __new__(cls, *, foo):
212 self = int.__new__(cls)
213 self.foo = foo
214 return self
215 def __getnewargs_ex__(self):
216 return (), {'foo': self.foo}
217 def __eq__(self, other):
218 return self.foo == other.foo
219 x = C(foo=42)
220 y = copy.copy(x)
221 self.assertIsInstance(y, C)
222 self.assertEqual(y, x)
223 self.assertIsNot(y, x)
224 self.assertEqual(y.foo, x.foo)
225
Guido van Rossum581cb932003-02-06 17:52:15 +0000226 def test_copy_inst_getstate(self):
227 class C:
228 def __init__(self, foo):
229 self.foo = foo
230 def __getstate__(self):
231 return {"foo": self.foo}
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000232 def __eq__(self, other):
233 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000234 x = C(42)
235 self.assertEqual(copy.copy(x), x)
236
237 def test_copy_inst_setstate(self):
238 class C:
239 def __init__(self, foo):
240 self.foo = foo
241 def __setstate__(self, state):
242 self.foo = state["foo"]
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000243 def __eq__(self, other):
244 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000245 x = C(42)
246 self.assertEqual(copy.copy(x), x)
247
248 def test_copy_inst_getstate_setstate(self):
249 class C:
250 def __init__(self, foo):
251 self.foo = foo
252 def __getstate__(self):
253 return self.foo
254 def __setstate__(self, state):
255 self.foo = state
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000256 def __eq__(self, other):
257 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000258 x = C(42)
259 self.assertEqual(copy.copy(x), x)
Serhiy Storchakacbbec1c2015-11-30 17:20:02 +0200260 # State with boolean value is false (issue #25718)
261 x = C(0.0)
262 self.assertEqual(copy.copy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000263
264 # The deepcopy() method
265
266 def test_deepcopy_basic(self):
267 x = 42
268 y = copy.deepcopy(x)
269 self.assertEqual(y, x)
270
271 def test_deepcopy_memo(self):
Guido van Rossum99d2c252003-06-13 19:28:47 +0000272 # Tests of reflexive objects are under type-specific sections below.
273 # This tests only repetitions of objects.
Guido van Rossum581cb932003-02-06 17:52:15 +0000274 x = []
Guido van Rossum99d2c252003-06-13 19:28:47 +0000275 x = [x, x]
Guido van Rossum581cb932003-02-06 17:52:15 +0000276 y = copy.deepcopy(x)
277 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200278 self.assertIsNot(y, x)
279 self.assertIsNot(y[0], x[0])
280 self.assertIs(y[0], y[1])
Guido van Rossum581cb932003-02-06 17:52:15 +0000281
282 def test_deepcopy_issubclass(self):
283 # XXX Note: there's no way to test the TypeError coming out of
284 # issubclass() -- this can only happen when an extension
285 # module defines a "type" that doesn't formally inherit from
286 # type.
287 class Meta(type):
288 pass
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000289 class C(metaclass=Meta):
290 pass
Guido van Rossum581cb932003-02-06 17:52:15 +0000291 self.assertEqual(copy.deepcopy(C), C)
292
293 def test_deepcopy_deepcopy(self):
294 class C(object):
295 def __init__(self, foo):
296 self.foo = foo
297 def __deepcopy__(self, memo=None):
298 return C(self.foo)
299 x = C(42)
300 y = copy.deepcopy(x)
301 self.assertEqual(y.__class__, x.__class__)
302 self.assertEqual(y.foo, x.foo)
303
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000304 def test_deepcopy_registry(self):
305 class C(object):
306 def __new__(cls, foo):
307 obj = object.__new__(cls)
308 obj.foo = foo
309 return obj
310 def pickle_C(obj):
311 return (C, (obj.foo,))
312 x = C(42)
313 self.assertRaises(TypeError, copy.deepcopy, x)
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000314 copyreg.pickle(C, pickle_C, C)
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000315 y = copy.deepcopy(x)
316
Guido van Rossume6908832003-02-19 01:19:28 +0000317 def test_deepcopy_reduce_ex(self):
318 class C(object):
319 def __reduce_ex__(self, proto):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200320 c.append(1)
Guido van Rossume6908832003-02-19 01:19:28 +0000321 return ""
322 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200323 self.fail("shouldn't call this")
324 c = []
Guido van Rossume6908832003-02-19 01:19:28 +0000325 x = C()
326 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200327 self.assertIs(y, x)
328 self.assertEqual(c, [1])
Guido van Rossume6908832003-02-19 01:19:28 +0000329
Guido van Rossum581cb932003-02-06 17:52:15 +0000330 def test_deepcopy_reduce(self):
331 class C(object):
332 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200333 c.append(1)
Guido van Rossum581cb932003-02-06 17:52:15 +0000334 return ""
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200335 c = []
Guido van Rossum581cb932003-02-06 17:52:15 +0000336 x = C()
337 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200338 self.assertIs(y, x)
339 self.assertEqual(c, [1])
Guido van Rossum581cb932003-02-06 17:52:15 +0000340
341 def test_deepcopy_cant(self):
Guido van Rossume6908832003-02-19 01:19:28 +0000342 class C(object):
Guido van Rossum581cb932003-02-06 17:52:15 +0000343 def __getattribute__(self, name):
Guido van Rossume6908832003-02-19 01:19:28 +0000344 if name.startswith("__reduce"):
Collin Winter3add4d72007-08-29 23:37:32 +0000345 raise AttributeError(name)
Guido van Rossum581cb932003-02-06 17:52:15 +0000346 return object.__getattribute__(self, name)
347 x = C()
348 self.assertRaises(copy.Error, copy.deepcopy, x)
349
350 # Type-specific _deepcopy_xxx() methods
351
352 def test_deepcopy_atomic(self):
353 class Classic:
354 pass
355 class NewStyle(object):
356 pass
357 def f():
358 pass
Guido van Rossume2a383d2007-01-15 16:59:06 +0000359 tests = [None, 42, 2**100, 3.14, True, False, 1j,
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000360 "hello", "hello\u1234", f.__code__,
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300361 NewStyle, range(10), Classic, max, property()]
Guido van Rossum581cb932003-02-06 17:52:15 +0000362 for x in tests:
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200363 self.assertIs(copy.deepcopy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000364
365 def test_deepcopy_list(self):
366 x = [[1, 2], 3]
367 y = copy.deepcopy(x)
368 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200369 self.assertIsNot(x, y)
370 self.assertIsNot(x[0], y[0])
Guido van Rossum581cb932003-02-06 17:52:15 +0000371
Guido van Rossum99d2c252003-06-13 19:28:47 +0000372 def test_deepcopy_reflexive_list(self):
373 x = []
374 x.append(x)
375 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000376 for op in comparisons:
Yury Selivanovf488fb42015-07-03 01:04:23 -0400377 self.assertRaises(RecursionError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200378 self.assertIsNot(y, x)
379 self.assertIs(y[0], y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000380 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000381
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200382 def test_deepcopy_empty_tuple(self):
383 x = ()
384 y = copy.deepcopy(x)
385 self.assertIs(x, y)
386
Guido van Rossum581cb932003-02-06 17:52:15 +0000387 def test_deepcopy_tuple(self):
388 x = ([1, 2], 3)
389 y = copy.deepcopy(x)
390 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200391 self.assertIsNot(x, y)
392 self.assertIsNot(x[0], y[0])
393
394 def test_deepcopy_tuple_of_immutables(self):
395 x = ((1, 2), 3)
396 y = copy.deepcopy(x)
397 self.assertIs(x, y)
Guido van Rossum581cb932003-02-06 17:52:15 +0000398
Guido van Rossum99d2c252003-06-13 19:28:47 +0000399 def test_deepcopy_reflexive_tuple(self):
400 x = ([],)
401 x[0].append(x)
402 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000403 for op in comparisons:
Yury Selivanovf488fb42015-07-03 01:04:23 -0400404 self.assertRaises(RecursionError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200405 self.assertIsNot(y, x)
406 self.assertIsNot(y[0], x[0])
407 self.assertIs(y[0][0], y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000408
Guido van Rossum581cb932003-02-06 17:52:15 +0000409 def test_deepcopy_dict(self):
410 x = {"foo": [1, 2], "bar": 3}
411 y = copy.deepcopy(x)
412 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200413 self.assertIsNot(x, y)
414 self.assertIsNot(x["foo"], y["foo"])
Guido van Rossum581cb932003-02-06 17:52:15 +0000415
Guido van Rossum99d2c252003-06-13 19:28:47 +0000416 def test_deepcopy_reflexive_dict(self):
417 x = {}
418 x['foo'] = x
419 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000420 for op in order_comparisons:
421 self.assertRaises(TypeError, op, y, x)
422 for op in equality_comparisons:
Yury Selivanovf488fb42015-07-03 01:04:23 -0400423 self.assertRaises(RecursionError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200424 self.assertIsNot(y, x)
425 self.assertIs(y['foo'], y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000426 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000427
Guido van Rossum581cb932003-02-06 17:52:15 +0000428 def test_deepcopy_keepalive(self):
429 memo = {}
Benjamin Petersone90ec362011-06-27 16:22:46 -0500430 x = []
Guido van Rossum581cb932003-02-06 17:52:15 +0000431 y = copy.deepcopy(x, memo)
Benjamin Petersone90ec362011-06-27 16:22:46 -0500432 self.assertIs(memo[id(memo)][0], x)
433
434 def test_deepcopy_dont_memo_immutable(self):
435 memo = {}
436 x = [1, 2, 3, 4]
437 y = copy.deepcopy(x, memo)
438 self.assertEqual(y, x)
439 # There's the entry for the new list, and the keep alive.
440 self.assertEqual(len(memo), 2)
441
442 memo = {}
443 x = [(1, 2)]
444 y = copy.deepcopy(x, memo)
445 self.assertEqual(y, x)
446 # Tuples with immutable contents are immutable for deepcopy.
447 self.assertEqual(len(memo), 2)
Guido van Rossum581cb932003-02-06 17:52:15 +0000448
449 def test_deepcopy_inst_vanilla(self):
450 class C:
451 def __init__(self, foo):
452 self.foo = foo
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000453 def __eq__(self, other):
454 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000455 x = C([42])
456 y = copy.deepcopy(x)
457 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200458 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000459
460 def test_deepcopy_inst_deepcopy(self):
461 class C:
462 def __init__(self, foo):
463 self.foo = foo
464 def __deepcopy__(self, memo):
465 return C(copy.deepcopy(self.foo, memo))
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000466 def __eq__(self, other):
467 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000468 x = C([42])
469 y = copy.deepcopy(x)
470 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200471 self.assertIsNot(y, x)
472 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000473
474 def test_deepcopy_inst_getinitargs(self):
475 class C:
476 def __init__(self, foo):
477 self.foo = foo
478 def __getinitargs__(self):
479 return (self.foo,)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000480 def __eq__(self, other):
481 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000482 x = C([42])
483 y = copy.deepcopy(x)
484 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200485 self.assertIsNot(y, x)
486 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000487
Serhiy Storchaka32af7542015-03-24 18:06:42 +0200488 def test_deepcopy_inst_getnewargs(self):
489 class C(int):
490 def __new__(cls, foo):
491 self = int.__new__(cls)
492 self.foo = foo
493 return self
494 def __getnewargs__(self):
495 return self.foo,
496 def __eq__(self, other):
497 return self.foo == other.foo
498 x = C([42])
499 y = copy.deepcopy(x)
500 self.assertIsInstance(y, C)
501 self.assertEqual(y, x)
502 self.assertIsNot(y, x)
503 self.assertEqual(y.foo, x.foo)
504 self.assertIsNot(y.foo, x.foo)
505
506 def test_deepcopy_inst_getnewargs_ex(self):
507 class C(int):
508 def __new__(cls, *, foo):
509 self = int.__new__(cls)
510 self.foo = foo
511 return self
512 def __getnewargs_ex__(self):
513 return (), {'foo': self.foo}
514 def __eq__(self, other):
515 return self.foo == other.foo
516 x = C(foo=[42])
517 y = copy.deepcopy(x)
518 self.assertIsInstance(y, C)
519 self.assertEqual(y, x)
520 self.assertIsNot(y, x)
521 self.assertEqual(y.foo, x.foo)
522 self.assertIsNot(y.foo, x.foo)
523
Guido van Rossum581cb932003-02-06 17:52:15 +0000524 def test_deepcopy_inst_getstate(self):
525 class C:
526 def __init__(self, foo):
527 self.foo = foo
528 def __getstate__(self):
529 return {"foo": self.foo}
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000530 def __eq__(self, other):
531 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000532 x = C([42])
533 y = copy.deepcopy(x)
534 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200535 self.assertIsNot(y, x)
536 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000537
538 def test_deepcopy_inst_setstate(self):
539 class C:
540 def __init__(self, foo):
541 self.foo = foo
542 def __setstate__(self, state):
543 self.foo = state["foo"]
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000544 def __eq__(self, other):
545 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000546 x = C([42])
547 y = copy.deepcopy(x)
548 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200549 self.assertIsNot(y, x)
550 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000551
552 def test_deepcopy_inst_getstate_setstate(self):
553 class C:
554 def __init__(self, foo):
555 self.foo = foo
556 def __getstate__(self):
557 return self.foo
558 def __setstate__(self, state):
559 self.foo = state
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000560 def __eq__(self, other):
561 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000562 x = C([42])
563 y = copy.deepcopy(x)
564 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200565 self.assertIsNot(y, x)
566 self.assertIsNot(y.foo, x.foo)
Serhiy Storchakacbbec1c2015-11-30 17:20:02 +0200567 # State with boolean value is false (issue #25718)
568 x = C([])
569 y = copy.deepcopy(x)
570 self.assertEqual(y, x)
571 self.assertIsNot(y, x)
572 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000573
Guido van Rossum99d2c252003-06-13 19:28:47 +0000574 def test_deepcopy_reflexive_inst(self):
575 class C:
576 pass
577 x = C()
578 x.foo = x
579 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200580 self.assertIsNot(y, x)
581 self.assertIs(y.foo, y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000582
Guido van Rossum581cb932003-02-06 17:52:15 +0000583 # _reconstruct()
584
585 def test_reconstruct_string(self):
586 class C(object):
587 def __reduce__(self):
588 return ""
589 x = C()
590 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200591 self.assertIs(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000592 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200593 self.assertIs(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000594
595 def test_reconstruct_nostate(self):
596 class C(object):
597 def __reduce__(self):
598 return (C, ())
599 x = C()
600 x.foo = 42
601 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200602 self.assertIs(y.__class__, x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000603 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200604 self.assertIs(y.__class__, x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000605
606 def test_reconstruct_state(self):
607 class C(object):
608 def __reduce__(self):
609 return (C, (), self.__dict__)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000610 def __eq__(self, other):
611 return self.__dict__ == other.__dict__
Guido van Rossum581cb932003-02-06 17:52:15 +0000612 x = C()
613 x.foo = [42]
614 y = copy.copy(x)
615 self.assertEqual(y, x)
616 y = copy.deepcopy(x)
617 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200618 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000619
620 def test_reconstruct_state_setstate(self):
621 class C(object):
622 def __reduce__(self):
623 return (C, (), self.__dict__)
624 def __setstate__(self, state):
625 self.__dict__.update(state)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000626 def __eq__(self, other):
627 return self.__dict__ == other.__dict__
Guido van Rossum581cb932003-02-06 17:52:15 +0000628 x = C()
629 x.foo = [42]
630 y = copy.copy(x)
631 self.assertEqual(y, x)
632 y = copy.deepcopy(x)
633 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200634 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000635
Guido van Rossum99d2c252003-06-13 19:28:47 +0000636 def test_reconstruct_reflexive(self):
637 class C(object):
638 pass
639 x = C()
640 x.foo = x
641 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200642 self.assertIsNot(y, x)
643 self.assertIs(y.foo, y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000644
Guido van Rossum90e05b02003-02-06 18:18:23 +0000645 # Additions for Python 2.3 and pickle protocol 2
646
647 def test_reduce_4tuple(self):
648 class C(list):
649 def __reduce__(self):
650 return (C, (), self.__dict__, iter(self))
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000651 def __eq__(self, other):
652 return (list(self) == list(other) and
653 self.__dict__ == other.__dict__)
Guido van Rossum90e05b02003-02-06 18:18:23 +0000654 x = C([[1, 2], 3])
655 y = copy.copy(x)
656 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200657 self.assertIsNot(x, y)
658 self.assertIs(x[0], y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000659 y = copy.deepcopy(x)
660 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200661 self.assertIsNot(x, y)
662 self.assertIsNot(x[0], y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000663
664 def test_reduce_5tuple(self):
665 class C(dict):
666 def __reduce__(self):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000667 return (C, (), self.__dict__, None, self.items())
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000668 def __eq__(self, other):
669 return (dict(self) == dict(other) and
670 self.__dict__ == other.__dict__)
Guido van Rossum90e05b02003-02-06 18:18:23 +0000671 x = C([("foo", [1, 2]), ("bar", 3)])
672 y = copy.copy(x)
673 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200674 self.assertIsNot(x, y)
675 self.assertIs(x["foo"], y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000676 y = copy.deepcopy(x)
677 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200678 self.assertIsNot(x, y)
679 self.assertIsNot(x["foo"], y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000680
Guido van Rossumc7557582003-02-06 19:53:22 +0000681 def test_copy_slots(self):
682 class C(object):
683 __slots__ = ["foo"]
684 x = C()
685 x.foo = [42]
686 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200687 self.assertIs(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000688
689 def test_deepcopy_slots(self):
690 class C(object):
691 __slots__ = ["foo"]
692 x = C()
693 x.foo = [42]
694 y = copy.deepcopy(x)
695 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200696 self.assertIsNot(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000697
Antoine Pitrou3941a8f2010-09-04 17:40:21 +0000698 def test_deepcopy_dict_subclass(self):
699 class C(dict):
700 def __init__(self, d=None):
701 if not d:
702 d = {}
703 self._keys = list(d.keys())
704 super().__init__(d)
705 def __setitem__(self, key, item):
706 super().__setitem__(key, item)
707 if key not in self._keys:
708 self._keys.append(key)
709 x = C(d={'foo':0})
710 y = copy.deepcopy(x)
711 self.assertEqual(x, y)
712 self.assertEqual(x._keys, y._keys)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200713 self.assertIsNot(x, y)
Antoine Pitrou3941a8f2010-09-04 17:40:21 +0000714 x['bar'] = 1
715 self.assertNotEqual(x, y)
716 self.assertNotEqual(x._keys, y._keys)
717
Guido van Rossumc7557582003-02-06 19:53:22 +0000718 def test_copy_list_subclass(self):
719 class C(list):
720 pass
721 x = C([[1, 2], 3])
722 x.foo = [4, 5]
723 y = copy.copy(x)
724 self.assertEqual(list(x), list(y))
725 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200726 self.assertIs(x[0], y[0])
727 self.assertIs(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000728
729 def test_deepcopy_list_subclass(self):
730 class C(list):
731 pass
732 x = C([[1, 2], 3])
733 x.foo = [4, 5]
734 y = copy.deepcopy(x)
735 self.assertEqual(list(x), list(y))
736 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200737 self.assertIsNot(x[0], y[0])
738 self.assertIsNot(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000739
Guido van Rossum85233bf2003-02-06 21:25:12 +0000740 def test_copy_tuple_subclass(self):
741 class C(tuple):
742 pass
743 x = C([1, 2, 3])
744 self.assertEqual(tuple(x), (1, 2, 3))
745 y = copy.copy(x)
746 self.assertEqual(tuple(y), (1, 2, 3))
747
748 def test_deepcopy_tuple_subclass(self):
749 class C(tuple):
750 pass
751 x = C([[1, 2], 3])
752 self.assertEqual(tuple(x), ([1, 2], 3))
753 y = copy.deepcopy(x)
754 self.assertEqual(tuple(y), ([1, 2], 3))
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200755 self.assertIsNot(x, y)
756 self.assertIsNot(x[0], y[0])
Guido van Rossum85233bf2003-02-06 21:25:12 +0000757
Neal Norwitze2fdc612003-06-08 13:19:58 +0000758 def test_getstate_exc(self):
759 class EvilState(object):
760 def __getstate__(self):
Collin Winter3add4d72007-08-29 23:37:32 +0000761 raise ValueError("ain't got no stickin' state")
Neal Norwitze2fdc612003-06-08 13:19:58 +0000762 self.assertRaises(ValueError, copy.copy, EvilState())
763
Guido van Rossum1968ad32006-02-25 22:38:04 +0000764 def test_copy_function(self):
765 self.assertEqual(copy.copy(global_foo), global_foo)
766 def foo(x, y): return x+y
767 self.assertEqual(copy.copy(foo), foo)
768 bar = lambda: None
769 self.assertEqual(copy.copy(bar), bar)
770
771 def test_deepcopy_function(self):
772 self.assertEqual(copy.deepcopy(global_foo), global_foo)
773 def foo(x, y): return x+y
774 self.assertEqual(copy.deepcopy(foo), foo)
775 bar = lambda: None
776 self.assertEqual(copy.deepcopy(bar), bar)
777
Antoine Pitrou6e610062009-05-15 17:04:50 +0000778 def _check_weakref(self, _copy):
779 class C(object):
780 pass
781 obj = C()
782 x = weakref.ref(obj)
783 y = _copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200784 self.assertIs(y, x)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000785 del obj
786 y = _copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200787 self.assertIs(y, x)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000788
789 def test_copy_weakref(self):
790 self._check_weakref(copy.copy)
791
792 def test_deepcopy_weakref(self):
793 self._check_weakref(copy.deepcopy)
794
795 def _check_copy_weakdict(self, _dicttype):
796 class C(object):
797 pass
798 a, b, c, d = [C() for i in range(4)]
799 u = _dicttype()
800 u[a] = b
801 u[c] = d
802 v = copy.copy(u)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200803 self.assertIsNot(v, u)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000804 self.assertEqual(v, u)
805 self.assertEqual(v[a], b)
806 self.assertEqual(v[c], d)
807 self.assertEqual(len(v), 2)
808 del c, d
Serhiy Storchaka462c1f02021-09-08 18:08:57 +0300809 support.gc_collect() # For PyPy or other GCs.
Antoine Pitrou6e610062009-05-15 17:04:50 +0000810 self.assertEqual(len(v), 1)
811 x, y = C(), C()
812 # The underlying containers are decoupled
813 v[x] = y
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000814 self.assertNotIn(x, u)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000815
816 def test_copy_weakkeydict(self):
817 self._check_copy_weakdict(weakref.WeakKeyDictionary)
818
819 def test_copy_weakvaluedict(self):
820 self._check_copy_weakdict(weakref.WeakValueDictionary)
821
822 def test_deepcopy_weakkeydict(self):
823 class C(object):
824 def __init__(self, i):
825 self.i = i
826 a, b, c, d = [C(i) for i in range(4)]
827 u = weakref.WeakKeyDictionary()
828 u[a] = b
829 u[c] = d
830 # Keys aren't copied, values are
831 v = copy.deepcopy(u)
832 self.assertNotEqual(v, u)
833 self.assertEqual(len(v), 2)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200834 self.assertIsNot(v[a], b)
835 self.assertIsNot(v[c], d)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000836 self.assertEqual(v[a].i, b.i)
837 self.assertEqual(v[c].i, d.i)
838 del c
Serhiy Storchaka462c1f02021-09-08 18:08:57 +0300839 support.gc_collect() # For PyPy or other GCs.
Antoine Pitrou6e610062009-05-15 17:04:50 +0000840 self.assertEqual(len(v), 1)
841
842 def test_deepcopy_weakvaluedict(self):
843 class C(object):
844 def __init__(self, i):
845 self.i = i
846 a, b, c, d = [C(i) for i in range(4)]
847 u = weakref.WeakValueDictionary()
848 u[a] = b
849 u[c] = d
850 # Keys are copied, values aren't
851 v = copy.deepcopy(u)
852 self.assertNotEqual(v, u)
853 self.assertEqual(len(v), 2)
854 (x, y), (z, t) = sorted(v.items(), key=lambda pair: pair[0].i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200855 self.assertIsNot(x, a)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000856 self.assertEqual(x.i, a.i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200857 self.assertIs(y, b)
858 self.assertIsNot(z, c)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000859 self.assertEqual(z.i, c.i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200860 self.assertIs(t, d)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000861 del x, y, z, t
862 del d
Serhiy Storchaka462c1f02021-09-08 18:08:57 +0300863 support.gc_collect() # For PyPy or other GCs.
Antoine Pitrou6e610062009-05-15 17:04:50 +0000864 self.assertEqual(len(v), 1)
865
Antoine Pitrou1fc0d2b2009-11-28 15:58:27 +0000866 def test_deepcopy_bound_method(self):
867 class Foo(object):
868 def m(self):
869 pass
870 f = Foo()
871 f.b = f.m
872 g = copy.deepcopy(f)
873 self.assertEqual(g.m, g.b)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200874 self.assertIs(g.b.__self__, g)
Antoine Pitrou1fc0d2b2009-11-28 15:58:27 +0000875 g.b()
876
Antoine Pitrou6e610062009-05-15 17:04:50 +0000877
Guido van Rossum1968ad32006-02-25 22:38:04 +0000878def global_foo(x, y): return x+y
879
Guido van Rossum581cb932003-02-06 17:52:15 +0000880if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500881 unittest.main()