blob: ba3d233f63d1c1c944d80bb683e4cdbb1fffc34d [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
Guido van Rossum581cb932003-02-06 17:52:15 +000010
Mark Dickinsona56c4672009-01-27 18:17:45 +000011order_comparisons = le, lt, ge, gt
12equality_comparisons = eq, ne
13comparisons = order_comparisons + equality_comparisons
14
Guido van Rossum581cb932003-02-06 17:52:15 +000015class TestCopy(unittest.TestCase):
16
17 # Attempt full line coverage of copy.py from top to bottom
18
19 def test_exceptions(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020020 self.assertIs(copy.Error, copy.error)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000021 self.assertTrue(issubclass(copy.Error, Exception))
Guido van Rossum581cb932003-02-06 17:52:15 +000022
23 # The copy() method
24
25 def test_copy_basic(self):
26 x = 42
27 y = copy.copy(x)
28 self.assertEqual(x, y)
29
30 def test_copy_copy(self):
31 class C(object):
32 def __init__(self, foo):
33 self.foo = foo
34 def __copy__(self):
35 return C(self.foo)
36 x = C(42)
37 y = copy.copy(x)
38 self.assertEqual(y.__class__, x.__class__)
39 self.assertEqual(y.foo, x.foo)
40
Guido van Rossumc06e3ac2003-02-07 17:30:18 +000041 def test_copy_registry(self):
42 class C(object):
43 def __new__(cls, foo):
44 obj = object.__new__(cls)
45 obj.foo = foo
46 return obj
47 def pickle_C(obj):
48 return (C, (obj.foo,))
49 x = C(42)
50 self.assertRaises(TypeError, copy.copy, x)
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000051 copyreg.pickle(C, pickle_C, C)
Guido van Rossumc06e3ac2003-02-07 17:30:18 +000052 y = copy.copy(x)
53
Guido van Rossume6908832003-02-19 01:19:28 +000054 def test_copy_reduce_ex(self):
55 class C(object):
56 def __reduce_ex__(self, proto):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020057 c.append(1)
Guido van Rossume6908832003-02-19 01:19:28 +000058 return ""
59 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020060 self.fail("shouldn't call this")
61 c = []
Guido van Rossume6908832003-02-19 01:19:28 +000062 x = C()
63 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +020064 self.assertIs(y, x)
65 self.assertEqual(c, [1])
Guido van Rossume6908832003-02-19 01:19:28 +000066
Guido van Rossum581cb932003-02-06 17:52:15 +000067 def test_copy_reduce(self):
68 class C(object):
69 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020070 c.append(1)
Guido van Rossum581cb932003-02-06 17:52:15 +000071 return ""
Sandro Tosi4dc9c842011-08-05 23:05:35 +020072 c = []
Guido van Rossum581cb932003-02-06 17:52:15 +000073 x = C()
74 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +020075 self.assertIs(y, x)
76 self.assertEqual(c, [1])
Guido van Rossum581cb932003-02-06 17:52:15 +000077
78 def test_copy_cant(self):
Guido van Rossume6908832003-02-19 01:19:28 +000079 class C(object):
Guido van Rossum581cb932003-02-06 17:52:15 +000080 def __getattribute__(self, name):
Guido van Rossume6908832003-02-19 01:19:28 +000081 if name.startswith("__reduce"):
Collin Winter3add4d72007-08-29 23:37:32 +000082 raise AttributeError(name)
Guido van Rossum581cb932003-02-06 17:52:15 +000083 return object.__getattribute__(self, name)
84 x = C()
85 self.assertRaises(copy.Error, copy.copy, x)
86
87 # Type-specific _copy_xxx() methods
88
89 def test_copy_atomic(self):
90 class Classic:
91 pass
92 class NewStyle(object):
93 pass
94 def f():
95 pass
Alexandre Vassalotti5c1c3b42013-12-01 13:25:26 -080096 class WithMetaclass(metaclass=abc.ABCMeta):
97 pass
Serhiy Storchaka818e18d2016-03-06 14:56:57 +020098 tests = [None, ..., NotImplemented,
99 42, 2**100, 3.14, True, False, 1j,
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000100 "hello", "hello\u1234", f.__code__,
Serhiy Storchaka818e18d2016-03-06 14:56:57 +0200101 b"world", bytes(range(256)), range(10), slice(1, 10, 2),
Guðni Natan Gunnarsson9f3fc6c2020-01-12 17:41:49 +0000102 NewStyle, Classic, max, WithMetaclass, property()]
Guido van Rossum581cb932003-02-06 17:52:15 +0000103 for x in tests:
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200104 self.assertIs(copy.copy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000105
106 def test_copy_list(self):
107 x = [1, 2, 3]
Serhiy Storchaka818e18d2016-03-06 14:56:57 +0200108 y = copy.copy(x)
109 self.assertEqual(y, x)
110 self.assertIsNot(y, x)
111 x = []
112 y = copy.copy(x)
113 self.assertEqual(y, x)
114 self.assertIsNot(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000115
116 def test_copy_tuple(self):
117 x = (1, 2, 3)
Serhiy Storchaka818e18d2016-03-06 14:56:57 +0200118 self.assertIs(copy.copy(x), x)
119 x = ()
120 self.assertIs(copy.copy(x), x)
121 x = (1, 2, 3, [])
122 self.assertIs(copy.copy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000123
124 def test_copy_dict(self):
125 x = {"foo": 1, "bar": 2}
Serhiy Storchaka818e18d2016-03-06 14:56:57 +0200126 y = copy.copy(x)
127 self.assertEqual(y, x)
128 self.assertIsNot(y, x)
129 x = {}
130 y = copy.copy(x)
131 self.assertEqual(y, x)
132 self.assertIsNot(y, x)
133
134 def test_copy_set(self):
135 x = {1, 2, 3}
136 y = copy.copy(x)
137 self.assertEqual(y, x)
138 self.assertIsNot(y, x)
139 x = set()
140 y = copy.copy(x)
141 self.assertEqual(y, x)
142 self.assertIsNot(y, x)
143
144 def test_copy_frozenset(self):
145 x = frozenset({1, 2, 3})
146 self.assertIs(copy.copy(x), x)
147 x = frozenset()
148 self.assertIs(copy.copy(x), x)
149
150 def test_copy_bytearray(self):
151 x = bytearray(b'abc')
152 y = copy.copy(x)
153 self.assertEqual(y, x)
154 self.assertIsNot(y, x)
155 x = bytearray()
156 y = copy.copy(x)
157 self.assertEqual(y, x)
158 self.assertIsNot(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000159
160 def test_copy_inst_vanilla(self):
161 class C:
162 def __init__(self, foo):
163 self.foo = foo
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000164 def __eq__(self, other):
165 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000166 x = C(42)
167 self.assertEqual(copy.copy(x), x)
168
169 def test_copy_inst_copy(self):
170 class C:
171 def __init__(self, foo):
172 self.foo = foo
173 def __copy__(self):
174 return C(self.foo)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000175 def __eq__(self, other):
176 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000177 x = C(42)
178 self.assertEqual(copy.copy(x), x)
179
180 def test_copy_inst_getinitargs(self):
181 class C:
182 def __init__(self, foo):
183 self.foo = foo
184 def __getinitargs__(self):
185 return (self.foo,)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000186 def __eq__(self, other):
187 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000188 x = C(42)
189 self.assertEqual(copy.copy(x), x)
190
Serhiy Storchaka32af7542015-03-24 18:06:42 +0200191 def test_copy_inst_getnewargs(self):
192 class C(int):
193 def __new__(cls, foo):
194 self = int.__new__(cls)
195 self.foo = foo
196 return self
197 def __getnewargs__(self):
198 return self.foo,
199 def __eq__(self, other):
200 return self.foo == other.foo
201 x = C(42)
202 y = copy.copy(x)
203 self.assertIsInstance(y, C)
204 self.assertEqual(y, x)
205 self.assertIsNot(y, x)
206 self.assertEqual(y.foo, x.foo)
207
208 def test_copy_inst_getnewargs_ex(self):
209 class C(int):
210 def __new__(cls, *, foo):
211 self = int.__new__(cls)
212 self.foo = foo
213 return self
214 def __getnewargs_ex__(self):
215 return (), {'foo': self.foo}
216 def __eq__(self, other):
217 return self.foo == other.foo
218 x = C(foo=42)
219 y = copy.copy(x)
220 self.assertIsInstance(y, C)
221 self.assertEqual(y, x)
222 self.assertIsNot(y, x)
223 self.assertEqual(y.foo, x.foo)
224
Guido van Rossum581cb932003-02-06 17:52:15 +0000225 def test_copy_inst_getstate(self):
226 class C:
227 def __init__(self, foo):
228 self.foo = foo
229 def __getstate__(self):
230 return {"foo": self.foo}
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000231 def __eq__(self, other):
232 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000233 x = C(42)
234 self.assertEqual(copy.copy(x), x)
235
236 def test_copy_inst_setstate(self):
237 class C:
238 def __init__(self, foo):
239 self.foo = foo
240 def __setstate__(self, state):
241 self.foo = state["foo"]
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000242 def __eq__(self, other):
243 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000244 x = C(42)
245 self.assertEqual(copy.copy(x), x)
246
247 def test_copy_inst_getstate_setstate(self):
248 class C:
249 def __init__(self, foo):
250 self.foo = foo
251 def __getstate__(self):
252 return self.foo
253 def __setstate__(self, state):
254 self.foo = state
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000255 def __eq__(self, other):
256 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000257 x = C(42)
258 self.assertEqual(copy.copy(x), x)
Serhiy Storchakacbbec1c2015-11-30 17:20:02 +0200259 # State with boolean value is false (issue #25718)
260 x = C(0.0)
261 self.assertEqual(copy.copy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000262
263 # The deepcopy() method
264
265 def test_deepcopy_basic(self):
266 x = 42
267 y = copy.deepcopy(x)
268 self.assertEqual(y, x)
269
270 def test_deepcopy_memo(self):
Guido van Rossum99d2c252003-06-13 19:28:47 +0000271 # Tests of reflexive objects are under type-specific sections below.
272 # This tests only repetitions of objects.
Guido van Rossum581cb932003-02-06 17:52:15 +0000273 x = []
Guido van Rossum99d2c252003-06-13 19:28:47 +0000274 x = [x, x]
Guido van Rossum581cb932003-02-06 17:52:15 +0000275 y = copy.deepcopy(x)
276 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200277 self.assertIsNot(y, x)
278 self.assertIsNot(y[0], x[0])
279 self.assertIs(y[0], y[1])
Guido van Rossum581cb932003-02-06 17:52:15 +0000280
281 def test_deepcopy_issubclass(self):
282 # XXX Note: there's no way to test the TypeError coming out of
283 # issubclass() -- this can only happen when an extension
284 # module defines a "type" that doesn't formally inherit from
285 # type.
286 class Meta(type):
287 pass
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000288 class C(metaclass=Meta):
289 pass
Guido van Rossum581cb932003-02-06 17:52:15 +0000290 self.assertEqual(copy.deepcopy(C), C)
291
292 def test_deepcopy_deepcopy(self):
293 class C(object):
294 def __init__(self, foo):
295 self.foo = foo
296 def __deepcopy__(self, memo=None):
297 return C(self.foo)
298 x = C(42)
299 y = copy.deepcopy(x)
300 self.assertEqual(y.__class__, x.__class__)
301 self.assertEqual(y.foo, x.foo)
302
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000303 def test_deepcopy_registry(self):
304 class C(object):
305 def __new__(cls, foo):
306 obj = object.__new__(cls)
307 obj.foo = foo
308 return obj
309 def pickle_C(obj):
310 return (C, (obj.foo,))
311 x = C(42)
312 self.assertRaises(TypeError, copy.deepcopy, x)
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000313 copyreg.pickle(C, pickle_C, C)
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000314 y = copy.deepcopy(x)
315
Guido van Rossume6908832003-02-19 01:19:28 +0000316 def test_deepcopy_reduce_ex(self):
317 class C(object):
318 def __reduce_ex__(self, proto):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200319 c.append(1)
Guido van Rossume6908832003-02-19 01:19:28 +0000320 return ""
321 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200322 self.fail("shouldn't call this")
323 c = []
Guido van Rossume6908832003-02-19 01:19:28 +0000324 x = C()
325 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200326 self.assertIs(y, x)
327 self.assertEqual(c, [1])
Guido van Rossume6908832003-02-19 01:19:28 +0000328
Guido van Rossum581cb932003-02-06 17:52:15 +0000329 def test_deepcopy_reduce(self):
330 class C(object):
331 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200332 c.append(1)
Guido van Rossum581cb932003-02-06 17:52:15 +0000333 return ""
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200334 c = []
Guido van Rossum581cb932003-02-06 17:52:15 +0000335 x = C()
336 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200337 self.assertIs(y, x)
338 self.assertEqual(c, [1])
Guido van Rossum581cb932003-02-06 17:52:15 +0000339
340 def test_deepcopy_cant(self):
Guido van Rossume6908832003-02-19 01:19:28 +0000341 class C(object):
Guido van Rossum581cb932003-02-06 17:52:15 +0000342 def __getattribute__(self, name):
Guido van Rossume6908832003-02-19 01:19:28 +0000343 if name.startswith("__reduce"):
Collin Winter3add4d72007-08-29 23:37:32 +0000344 raise AttributeError(name)
Guido van Rossum581cb932003-02-06 17:52:15 +0000345 return object.__getattribute__(self, name)
346 x = C()
347 self.assertRaises(copy.Error, copy.deepcopy, x)
348
349 # Type-specific _deepcopy_xxx() methods
350
351 def test_deepcopy_atomic(self):
352 class Classic:
353 pass
354 class NewStyle(object):
355 pass
356 def f():
357 pass
Guido van Rossume2a383d2007-01-15 16:59:06 +0000358 tests = [None, 42, 2**100, 3.14, True, False, 1j,
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000359 "hello", "hello\u1234", f.__code__,
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300360 NewStyle, range(10), Classic, max, property()]
Guido van Rossum581cb932003-02-06 17:52:15 +0000361 for x in tests:
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200362 self.assertIs(copy.deepcopy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000363
364 def test_deepcopy_list(self):
365 x = [[1, 2], 3]
366 y = copy.deepcopy(x)
367 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200368 self.assertIsNot(x, y)
369 self.assertIsNot(x[0], y[0])
Guido van Rossum581cb932003-02-06 17:52:15 +0000370
Guido van Rossum99d2c252003-06-13 19:28:47 +0000371 def test_deepcopy_reflexive_list(self):
372 x = []
373 x.append(x)
374 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000375 for op in comparisons:
Yury Selivanovf488fb42015-07-03 01:04:23 -0400376 self.assertRaises(RecursionError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200377 self.assertIsNot(y, x)
378 self.assertIs(y[0], y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000379 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000380
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200381 def test_deepcopy_empty_tuple(self):
382 x = ()
383 y = copy.deepcopy(x)
384 self.assertIs(x, y)
385
Guido van Rossum581cb932003-02-06 17:52:15 +0000386 def test_deepcopy_tuple(self):
387 x = ([1, 2], 3)
388 y = copy.deepcopy(x)
389 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200390 self.assertIsNot(x, y)
391 self.assertIsNot(x[0], y[0])
392
393 def test_deepcopy_tuple_of_immutables(self):
394 x = ((1, 2), 3)
395 y = copy.deepcopy(x)
396 self.assertIs(x, y)
Guido van Rossum581cb932003-02-06 17:52:15 +0000397
Guido van Rossum99d2c252003-06-13 19:28:47 +0000398 def test_deepcopy_reflexive_tuple(self):
399 x = ([],)
400 x[0].append(x)
401 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000402 for op in comparisons:
Yury Selivanovf488fb42015-07-03 01:04:23 -0400403 self.assertRaises(RecursionError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200404 self.assertIsNot(y, x)
405 self.assertIsNot(y[0], x[0])
406 self.assertIs(y[0][0], y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000407
Guido van Rossum581cb932003-02-06 17:52:15 +0000408 def test_deepcopy_dict(self):
409 x = {"foo": [1, 2], "bar": 3}
410 y = copy.deepcopy(x)
411 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200412 self.assertIsNot(x, y)
413 self.assertIsNot(x["foo"], y["foo"])
Guido van Rossum581cb932003-02-06 17:52:15 +0000414
Guido van Rossum99d2c252003-06-13 19:28:47 +0000415 def test_deepcopy_reflexive_dict(self):
416 x = {}
417 x['foo'] = x
418 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000419 for op in order_comparisons:
420 self.assertRaises(TypeError, op, y, x)
421 for op in equality_comparisons:
Yury Selivanovf488fb42015-07-03 01:04:23 -0400422 self.assertRaises(RecursionError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200423 self.assertIsNot(y, x)
424 self.assertIs(y['foo'], y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000425 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000426
Guido van Rossum581cb932003-02-06 17:52:15 +0000427 def test_deepcopy_keepalive(self):
428 memo = {}
Benjamin Petersone90ec362011-06-27 16:22:46 -0500429 x = []
Guido van Rossum581cb932003-02-06 17:52:15 +0000430 y = copy.deepcopy(x, memo)
Benjamin Petersone90ec362011-06-27 16:22:46 -0500431 self.assertIs(memo[id(memo)][0], x)
432
433 def test_deepcopy_dont_memo_immutable(self):
434 memo = {}
435 x = [1, 2, 3, 4]
436 y = copy.deepcopy(x, memo)
437 self.assertEqual(y, x)
438 # There's the entry for the new list, and the keep alive.
439 self.assertEqual(len(memo), 2)
440
441 memo = {}
442 x = [(1, 2)]
443 y = copy.deepcopy(x, memo)
444 self.assertEqual(y, x)
445 # Tuples with immutable contents are immutable for deepcopy.
446 self.assertEqual(len(memo), 2)
Guido van Rossum581cb932003-02-06 17:52:15 +0000447
448 def test_deepcopy_inst_vanilla(self):
449 class C:
450 def __init__(self, foo):
451 self.foo = foo
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000452 def __eq__(self, other):
453 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000454 x = C([42])
455 y = copy.deepcopy(x)
456 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200457 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000458
459 def test_deepcopy_inst_deepcopy(self):
460 class C:
461 def __init__(self, foo):
462 self.foo = foo
463 def __deepcopy__(self, memo):
464 return C(copy.deepcopy(self.foo, memo))
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000465 def __eq__(self, other):
466 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000467 x = C([42])
468 y = copy.deepcopy(x)
469 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200470 self.assertIsNot(y, x)
471 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000472
473 def test_deepcopy_inst_getinitargs(self):
474 class C:
475 def __init__(self, foo):
476 self.foo = foo
477 def __getinitargs__(self):
478 return (self.foo,)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000479 def __eq__(self, other):
480 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000481 x = C([42])
482 y = copy.deepcopy(x)
483 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200484 self.assertIsNot(y, x)
485 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000486
Serhiy Storchaka32af7542015-03-24 18:06:42 +0200487 def test_deepcopy_inst_getnewargs(self):
488 class C(int):
489 def __new__(cls, foo):
490 self = int.__new__(cls)
491 self.foo = foo
492 return self
493 def __getnewargs__(self):
494 return self.foo,
495 def __eq__(self, other):
496 return self.foo == other.foo
497 x = C([42])
498 y = copy.deepcopy(x)
499 self.assertIsInstance(y, C)
500 self.assertEqual(y, x)
501 self.assertIsNot(y, x)
502 self.assertEqual(y.foo, x.foo)
503 self.assertIsNot(y.foo, x.foo)
504
505 def test_deepcopy_inst_getnewargs_ex(self):
506 class C(int):
507 def __new__(cls, *, foo):
508 self = int.__new__(cls)
509 self.foo = foo
510 return self
511 def __getnewargs_ex__(self):
512 return (), {'foo': self.foo}
513 def __eq__(self, other):
514 return self.foo == other.foo
515 x = C(foo=[42])
516 y = copy.deepcopy(x)
517 self.assertIsInstance(y, C)
518 self.assertEqual(y, x)
519 self.assertIsNot(y, x)
520 self.assertEqual(y.foo, x.foo)
521 self.assertIsNot(y.foo, x.foo)
522
Guido van Rossum581cb932003-02-06 17:52:15 +0000523 def test_deepcopy_inst_getstate(self):
524 class C:
525 def __init__(self, foo):
526 self.foo = foo
527 def __getstate__(self):
528 return {"foo": self.foo}
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000529 def __eq__(self, other):
530 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000531 x = C([42])
532 y = copy.deepcopy(x)
533 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200534 self.assertIsNot(y, x)
535 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000536
537 def test_deepcopy_inst_setstate(self):
538 class C:
539 def __init__(self, foo):
540 self.foo = foo
541 def __setstate__(self, state):
542 self.foo = state["foo"]
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000543 def __eq__(self, other):
544 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000545 x = C([42])
546 y = copy.deepcopy(x)
547 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200548 self.assertIsNot(y, x)
549 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000550
551 def test_deepcopy_inst_getstate_setstate(self):
552 class C:
553 def __init__(self, foo):
554 self.foo = foo
555 def __getstate__(self):
556 return self.foo
557 def __setstate__(self, state):
558 self.foo = state
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000559 def __eq__(self, other):
560 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000561 x = C([42])
562 y = copy.deepcopy(x)
563 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200564 self.assertIsNot(y, x)
565 self.assertIsNot(y.foo, x.foo)
Serhiy Storchakacbbec1c2015-11-30 17:20:02 +0200566 # State with boolean value is false (issue #25718)
567 x = C([])
568 y = copy.deepcopy(x)
569 self.assertEqual(y, x)
570 self.assertIsNot(y, x)
571 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000572
Guido van Rossum99d2c252003-06-13 19:28:47 +0000573 def test_deepcopy_reflexive_inst(self):
574 class C:
575 pass
576 x = C()
577 x.foo = x
578 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200579 self.assertIsNot(y, x)
580 self.assertIs(y.foo, y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000581
Guido van Rossum581cb932003-02-06 17:52:15 +0000582 # _reconstruct()
583
584 def test_reconstruct_string(self):
585 class C(object):
586 def __reduce__(self):
587 return ""
588 x = C()
589 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200590 self.assertIs(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000591 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200592 self.assertIs(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000593
594 def test_reconstruct_nostate(self):
595 class C(object):
596 def __reduce__(self):
597 return (C, ())
598 x = C()
599 x.foo = 42
600 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200601 self.assertIs(y.__class__, x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000602 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200603 self.assertIs(y.__class__, x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000604
605 def test_reconstruct_state(self):
606 class C(object):
607 def __reduce__(self):
608 return (C, (), self.__dict__)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000609 def __eq__(self, other):
610 return self.__dict__ == other.__dict__
Guido van Rossum581cb932003-02-06 17:52:15 +0000611 x = C()
612 x.foo = [42]
613 y = copy.copy(x)
614 self.assertEqual(y, x)
615 y = copy.deepcopy(x)
616 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200617 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000618
619 def test_reconstruct_state_setstate(self):
620 class C(object):
621 def __reduce__(self):
622 return (C, (), self.__dict__)
623 def __setstate__(self, state):
624 self.__dict__.update(state)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000625 def __eq__(self, other):
626 return self.__dict__ == other.__dict__
Guido van Rossum581cb932003-02-06 17:52:15 +0000627 x = C()
628 x.foo = [42]
629 y = copy.copy(x)
630 self.assertEqual(y, x)
631 y = copy.deepcopy(x)
632 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200633 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000634
Guido van Rossum99d2c252003-06-13 19:28:47 +0000635 def test_reconstruct_reflexive(self):
636 class C(object):
637 pass
638 x = C()
639 x.foo = x
640 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200641 self.assertIsNot(y, x)
642 self.assertIs(y.foo, y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000643
Guido van Rossum90e05b02003-02-06 18:18:23 +0000644 # Additions for Python 2.3 and pickle protocol 2
645
646 def test_reduce_4tuple(self):
647 class C(list):
648 def __reduce__(self):
649 return (C, (), self.__dict__, iter(self))
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000650 def __eq__(self, other):
651 return (list(self) == list(other) and
652 self.__dict__ == other.__dict__)
Guido van Rossum90e05b02003-02-06 18:18:23 +0000653 x = C([[1, 2], 3])
654 y = copy.copy(x)
655 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200656 self.assertIsNot(x, y)
657 self.assertIs(x[0], y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000658 y = copy.deepcopy(x)
659 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200660 self.assertIsNot(x, y)
661 self.assertIsNot(x[0], y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000662
663 def test_reduce_5tuple(self):
664 class C(dict):
665 def __reduce__(self):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000666 return (C, (), self.__dict__, None, self.items())
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000667 def __eq__(self, other):
668 return (dict(self) == dict(other) and
669 self.__dict__ == other.__dict__)
Guido van Rossum90e05b02003-02-06 18:18:23 +0000670 x = C([("foo", [1, 2]), ("bar", 3)])
671 y = copy.copy(x)
672 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200673 self.assertIsNot(x, y)
674 self.assertIs(x["foo"], y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000675 y = copy.deepcopy(x)
676 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200677 self.assertIsNot(x, y)
678 self.assertIsNot(x["foo"], y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000679
Guido van Rossumc7557582003-02-06 19:53:22 +0000680 def test_copy_slots(self):
681 class C(object):
682 __slots__ = ["foo"]
683 x = C()
684 x.foo = [42]
685 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200686 self.assertIs(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000687
688 def test_deepcopy_slots(self):
689 class C(object):
690 __slots__ = ["foo"]
691 x = C()
692 x.foo = [42]
693 y = copy.deepcopy(x)
694 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200695 self.assertIsNot(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000696
Antoine Pitrou3941a8f2010-09-04 17:40:21 +0000697 def test_deepcopy_dict_subclass(self):
698 class C(dict):
699 def __init__(self, d=None):
700 if not d:
701 d = {}
702 self._keys = list(d.keys())
703 super().__init__(d)
704 def __setitem__(self, key, item):
705 super().__setitem__(key, item)
706 if key not in self._keys:
707 self._keys.append(key)
708 x = C(d={'foo':0})
709 y = copy.deepcopy(x)
710 self.assertEqual(x, y)
711 self.assertEqual(x._keys, y._keys)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200712 self.assertIsNot(x, y)
Antoine Pitrou3941a8f2010-09-04 17:40:21 +0000713 x['bar'] = 1
714 self.assertNotEqual(x, y)
715 self.assertNotEqual(x._keys, y._keys)
716
Guido van Rossumc7557582003-02-06 19:53:22 +0000717 def test_copy_list_subclass(self):
718 class C(list):
719 pass
720 x = C([[1, 2], 3])
721 x.foo = [4, 5]
722 y = copy.copy(x)
723 self.assertEqual(list(x), list(y))
724 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200725 self.assertIs(x[0], y[0])
726 self.assertIs(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000727
728 def test_deepcopy_list_subclass(self):
729 class C(list):
730 pass
731 x = C([[1, 2], 3])
732 x.foo = [4, 5]
733 y = copy.deepcopy(x)
734 self.assertEqual(list(x), list(y))
735 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200736 self.assertIsNot(x[0], y[0])
737 self.assertIsNot(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000738
Guido van Rossum85233bf2003-02-06 21:25:12 +0000739 def test_copy_tuple_subclass(self):
740 class C(tuple):
741 pass
742 x = C([1, 2, 3])
743 self.assertEqual(tuple(x), (1, 2, 3))
744 y = copy.copy(x)
745 self.assertEqual(tuple(y), (1, 2, 3))
746
747 def test_deepcopy_tuple_subclass(self):
748 class C(tuple):
749 pass
750 x = C([[1, 2], 3])
751 self.assertEqual(tuple(x), ([1, 2], 3))
752 y = copy.deepcopy(x)
753 self.assertEqual(tuple(y), ([1, 2], 3))
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200754 self.assertIsNot(x, y)
755 self.assertIsNot(x[0], y[0])
Guido van Rossum85233bf2003-02-06 21:25:12 +0000756
Neal Norwitze2fdc612003-06-08 13:19:58 +0000757 def test_getstate_exc(self):
758 class EvilState(object):
759 def __getstate__(self):
Collin Winter3add4d72007-08-29 23:37:32 +0000760 raise ValueError("ain't got no stickin' state")
Neal Norwitze2fdc612003-06-08 13:19:58 +0000761 self.assertRaises(ValueError, copy.copy, EvilState())
762
Guido van Rossum1968ad32006-02-25 22:38:04 +0000763 def test_copy_function(self):
764 self.assertEqual(copy.copy(global_foo), global_foo)
765 def foo(x, y): return x+y
766 self.assertEqual(copy.copy(foo), foo)
767 bar = lambda: None
768 self.assertEqual(copy.copy(bar), bar)
769
770 def test_deepcopy_function(self):
771 self.assertEqual(copy.deepcopy(global_foo), global_foo)
772 def foo(x, y): return x+y
773 self.assertEqual(copy.deepcopy(foo), foo)
774 bar = lambda: None
775 self.assertEqual(copy.deepcopy(bar), bar)
776
Antoine Pitrou6e610062009-05-15 17:04:50 +0000777 def _check_weakref(self, _copy):
778 class C(object):
779 pass
780 obj = C()
781 x = weakref.ref(obj)
782 y = _copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200783 self.assertIs(y, x)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000784 del obj
785 y = _copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200786 self.assertIs(y, x)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000787
788 def test_copy_weakref(self):
789 self._check_weakref(copy.copy)
790
791 def test_deepcopy_weakref(self):
792 self._check_weakref(copy.deepcopy)
793
794 def _check_copy_weakdict(self, _dicttype):
795 class C(object):
796 pass
797 a, b, c, d = [C() for i in range(4)]
798 u = _dicttype()
799 u[a] = b
800 u[c] = d
801 v = copy.copy(u)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200802 self.assertIsNot(v, u)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000803 self.assertEqual(v, u)
804 self.assertEqual(v[a], b)
805 self.assertEqual(v[c], d)
806 self.assertEqual(len(v), 2)
807 del c, d
808 self.assertEqual(len(v), 1)
809 x, y = C(), C()
810 # The underlying containers are decoupled
811 v[x] = y
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000812 self.assertNotIn(x, u)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000813
814 def test_copy_weakkeydict(self):
815 self._check_copy_weakdict(weakref.WeakKeyDictionary)
816
817 def test_copy_weakvaluedict(self):
818 self._check_copy_weakdict(weakref.WeakValueDictionary)
819
820 def test_deepcopy_weakkeydict(self):
821 class C(object):
822 def __init__(self, i):
823 self.i = i
824 a, b, c, d = [C(i) for i in range(4)]
825 u = weakref.WeakKeyDictionary()
826 u[a] = b
827 u[c] = d
828 # Keys aren't copied, values are
829 v = copy.deepcopy(u)
830 self.assertNotEqual(v, u)
831 self.assertEqual(len(v), 2)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200832 self.assertIsNot(v[a], b)
833 self.assertIsNot(v[c], d)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000834 self.assertEqual(v[a].i, b.i)
835 self.assertEqual(v[c].i, d.i)
836 del c
837 self.assertEqual(len(v), 1)
838
839 def test_deepcopy_weakvaluedict(self):
840 class C(object):
841 def __init__(self, i):
842 self.i = i
843 a, b, c, d = [C(i) for i in range(4)]
844 u = weakref.WeakValueDictionary()
845 u[a] = b
846 u[c] = d
847 # Keys are copied, values aren't
848 v = copy.deepcopy(u)
849 self.assertNotEqual(v, u)
850 self.assertEqual(len(v), 2)
851 (x, y), (z, t) = sorted(v.items(), key=lambda pair: pair[0].i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200852 self.assertIsNot(x, a)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000853 self.assertEqual(x.i, a.i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200854 self.assertIs(y, b)
855 self.assertIsNot(z, c)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000856 self.assertEqual(z.i, c.i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200857 self.assertIs(t, d)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000858 del x, y, z, t
859 del d
860 self.assertEqual(len(v), 1)
861
Antoine Pitrou1fc0d2b2009-11-28 15:58:27 +0000862 def test_deepcopy_bound_method(self):
863 class Foo(object):
864 def m(self):
865 pass
866 f = Foo()
867 f.b = f.m
868 g = copy.deepcopy(f)
869 self.assertEqual(g.m, g.b)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200870 self.assertIs(g.b.__self__, g)
Antoine Pitrou1fc0d2b2009-11-28 15:58:27 +0000871 g.b()
872
Antoine Pitrou6e610062009-05-15 17:04:50 +0000873
Guido van Rossum1968ad32006-02-25 22:38:04 +0000874def global_foo(x, y): return x+y
875
Guido van Rossum581cb932003-02-06 17:52:15 +0000876if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500877 unittest.main()