blob: eb8d18cf0b1217490af804bb7a68b86055e89546 [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
Benjamin Petersonee8712c2008-05-20 21:35:26 +000010from 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
Guido van Rossume2a383d2007-01-15 16:59:06 +000099 tests = [None, 42, 2**100, 3.14, True, False, 1j,
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000100 "hello", "hello\u1234", f.__code__,
Antoine Pitroudc9215f2014-02-27 22:14:31 +0100101 b"world", bytes(range(256)),
Alexandre Vassalotti5c1c3b42013-12-01 13:25:26 -0800102 NewStyle, range(10), Classic, max, WithMetaclass]
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]
108 self.assertEqual(copy.copy(x), x)
109
110 def test_copy_tuple(self):
111 x = (1, 2, 3)
112 self.assertEqual(copy.copy(x), x)
113
114 def test_copy_dict(self):
115 x = {"foo": 1, "bar": 2}
116 self.assertEqual(copy.copy(x), x)
117
118 def test_copy_inst_vanilla(self):
119 class C:
120 def __init__(self, foo):
121 self.foo = foo
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000122 def __eq__(self, other):
123 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000124 x = C(42)
125 self.assertEqual(copy.copy(x), x)
126
127 def test_copy_inst_copy(self):
128 class C:
129 def __init__(self, foo):
130 self.foo = foo
131 def __copy__(self):
132 return C(self.foo)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000133 def __eq__(self, other):
134 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000135 x = C(42)
136 self.assertEqual(copy.copy(x), x)
137
138 def test_copy_inst_getinitargs(self):
139 class C:
140 def __init__(self, foo):
141 self.foo = foo
142 def __getinitargs__(self):
143 return (self.foo,)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000144 def __eq__(self, other):
145 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000146 x = C(42)
147 self.assertEqual(copy.copy(x), x)
148
149 def test_copy_inst_getstate(self):
150 class C:
151 def __init__(self, foo):
152 self.foo = foo
153 def __getstate__(self):
154 return {"foo": self.foo}
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000155 def __eq__(self, other):
156 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000157 x = C(42)
158 self.assertEqual(copy.copy(x), x)
159
160 def test_copy_inst_setstate(self):
161 class C:
162 def __init__(self, foo):
163 self.foo = foo
164 def __setstate__(self, state):
165 self.foo = state["foo"]
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000166 def __eq__(self, other):
167 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000168 x = C(42)
169 self.assertEqual(copy.copy(x), x)
170
171 def test_copy_inst_getstate_setstate(self):
172 class C:
173 def __init__(self, foo):
174 self.foo = foo
175 def __getstate__(self):
176 return self.foo
177 def __setstate__(self, state):
178 self.foo = state
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000179 def __eq__(self, other):
180 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000181 x = C(42)
182 self.assertEqual(copy.copy(x), x)
183
184 # The deepcopy() method
185
186 def test_deepcopy_basic(self):
187 x = 42
188 y = copy.deepcopy(x)
189 self.assertEqual(y, x)
190
191 def test_deepcopy_memo(self):
Guido van Rossum99d2c252003-06-13 19:28:47 +0000192 # Tests of reflexive objects are under type-specific sections below.
193 # This tests only repetitions of objects.
Guido van Rossum581cb932003-02-06 17:52:15 +0000194 x = []
Guido van Rossum99d2c252003-06-13 19:28:47 +0000195 x = [x, x]
Guido van Rossum581cb932003-02-06 17:52:15 +0000196 y = copy.deepcopy(x)
197 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200198 self.assertIsNot(y, x)
199 self.assertIsNot(y[0], x[0])
200 self.assertIs(y[0], y[1])
Guido van Rossum581cb932003-02-06 17:52:15 +0000201
202 def test_deepcopy_issubclass(self):
203 # XXX Note: there's no way to test the TypeError coming out of
204 # issubclass() -- this can only happen when an extension
205 # module defines a "type" that doesn't formally inherit from
206 # type.
207 class Meta(type):
208 pass
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000209 class C(metaclass=Meta):
210 pass
Guido van Rossum581cb932003-02-06 17:52:15 +0000211 self.assertEqual(copy.deepcopy(C), C)
212
213 def test_deepcopy_deepcopy(self):
214 class C(object):
215 def __init__(self, foo):
216 self.foo = foo
217 def __deepcopy__(self, memo=None):
218 return C(self.foo)
219 x = C(42)
220 y = copy.deepcopy(x)
221 self.assertEqual(y.__class__, x.__class__)
222 self.assertEqual(y.foo, x.foo)
223
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000224 def test_deepcopy_registry(self):
225 class C(object):
226 def __new__(cls, foo):
227 obj = object.__new__(cls)
228 obj.foo = foo
229 return obj
230 def pickle_C(obj):
231 return (C, (obj.foo,))
232 x = C(42)
233 self.assertRaises(TypeError, copy.deepcopy, x)
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000234 copyreg.pickle(C, pickle_C, C)
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000235 y = copy.deepcopy(x)
236
Guido van Rossume6908832003-02-19 01:19:28 +0000237 def test_deepcopy_reduce_ex(self):
238 class C(object):
239 def __reduce_ex__(self, proto):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200240 c.append(1)
Guido van Rossume6908832003-02-19 01:19:28 +0000241 return ""
242 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200243 self.fail("shouldn't call this")
244 c = []
Guido van Rossume6908832003-02-19 01:19:28 +0000245 x = C()
246 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200247 self.assertIs(y, x)
248 self.assertEqual(c, [1])
Guido van Rossume6908832003-02-19 01:19:28 +0000249
Guido van Rossum581cb932003-02-06 17:52:15 +0000250 def test_deepcopy_reduce(self):
251 class C(object):
252 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200253 c.append(1)
Guido van Rossum581cb932003-02-06 17:52:15 +0000254 return ""
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200255 c = []
Guido van Rossum581cb932003-02-06 17:52:15 +0000256 x = C()
257 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200258 self.assertIs(y, x)
259 self.assertEqual(c, [1])
Guido van Rossum581cb932003-02-06 17:52:15 +0000260
261 def test_deepcopy_cant(self):
Guido van Rossume6908832003-02-19 01:19:28 +0000262 class C(object):
Guido van Rossum581cb932003-02-06 17:52:15 +0000263 def __getattribute__(self, name):
Guido van Rossume6908832003-02-19 01:19:28 +0000264 if name.startswith("__reduce"):
Collin Winter3add4d72007-08-29 23:37:32 +0000265 raise AttributeError(name)
Guido van Rossum581cb932003-02-06 17:52:15 +0000266 return object.__getattribute__(self, name)
267 x = C()
268 self.assertRaises(copy.Error, copy.deepcopy, x)
269
270 # Type-specific _deepcopy_xxx() methods
271
272 def test_deepcopy_atomic(self):
273 class Classic:
274 pass
275 class NewStyle(object):
276 pass
277 def f():
278 pass
Guido van Rossume2a383d2007-01-15 16:59:06 +0000279 tests = [None, 42, 2**100, 3.14, True, False, 1j,
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000280 "hello", "hello\u1234", f.__code__,
Guido van Rossum805365e2007-05-07 22:24:25 +0000281 NewStyle, range(10), Classic, max]
Guido van Rossum581cb932003-02-06 17:52:15 +0000282 for x in tests:
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200283 self.assertIs(copy.deepcopy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000284
285 def test_deepcopy_list(self):
286 x = [[1, 2], 3]
287 y = copy.deepcopy(x)
288 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200289 self.assertIsNot(x, y)
290 self.assertIsNot(x[0], y[0])
Guido van Rossum581cb932003-02-06 17:52:15 +0000291
Guido van Rossum99d2c252003-06-13 19:28:47 +0000292 def test_deepcopy_reflexive_list(self):
293 x = []
294 x.append(x)
295 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000296 for op in comparisons:
297 self.assertRaises(RuntimeError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200298 self.assertIsNot(y, x)
299 self.assertIs(y[0], y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000300 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000301
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200302 def test_deepcopy_empty_tuple(self):
303 x = ()
304 y = copy.deepcopy(x)
305 self.assertIs(x, y)
306
Guido van Rossum581cb932003-02-06 17:52:15 +0000307 def test_deepcopy_tuple(self):
308 x = ([1, 2], 3)
309 y = copy.deepcopy(x)
310 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200311 self.assertIsNot(x, y)
312 self.assertIsNot(x[0], y[0])
313
314 def test_deepcopy_tuple_of_immutables(self):
315 x = ((1, 2), 3)
316 y = copy.deepcopy(x)
317 self.assertIs(x, y)
Guido van Rossum581cb932003-02-06 17:52:15 +0000318
Guido van Rossum99d2c252003-06-13 19:28:47 +0000319 def test_deepcopy_reflexive_tuple(self):
320 x = ([],)
321 x[0].append(x)
322 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000323 for op in comparisons:
324 self.assertRaises(RuntimeError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200325 self.assertIsNot(y, x)
326 self.assertIsNot(y[0], x[0])
327 self.assertIs(y[0][0], y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000328
Guido van Rossum581cb932003-02-06 17:52:15 +0000329 def test_deepcopy_dict(self):
330 x = {"foo": [1, 2], "bar": 3}
331 y = copy.deepcopy(x)
332 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200333 self.assertIsNot(x, y)
334 self.assertIsNot(x["foo"], y["foo"])
Guido van Rossum581cb932003-02-06 17:52:15 +0000335
Guido van Rossum99d2c252003-06-13 19:28:47 +0000336 def test_deepcopy_reflexive_dict(self):
337 x = {}
338 x['foo'] = x
339 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000340 for op in order_comparisons:
341 self.assertRaises(TypeError, op, y, x)
342 for op in equality_comparisons:
343 self.assertRaises(RuntimeError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200344 self.assertIsNot(y, x)
345 self.assertIs(y['foo'], y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000346 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000347
Guido van Rossum581cb932003-02-06 17:52:15 +0000348 def test_deepcopy_keepalive(self):
349 memo = {}
Benjamin Petersone90ec362011-06-27 16:22:46 -0500350 x = []
Guido van Rossum581cb932003-02-06 17:52:15 +0000351 y = copy.deepcopy(x, memo)
Benjamin Petersone90ec362011-06-27 16:22:46 -0500352 self.assertIs(memo[id(memo)][0], x)
353
354 def test_deepcopy_dont_memo_immutable(self):
355 memo = {}
356 x = [1, 2, 3, 4]
357 y = copy.deepcopy(x, memo)
358 self.assertEqual(y, x)
359 # There's the entry for the new list, and the keep alive.
360 self.assertEqual(len(memo), 2)
361
362 memo = {}
363 x = [(1, 2)]
364 y = copy.deepcopy(x, memo)
365 self.assertEqual(y, x)
366 # Tuples with immutable contents are immutable for deepcopy.
367 self.assertEqual(len(memo), 2)
Guido van Rossum581cb932003-02-06 17:52:15 +0000368
369 def test_deepcopy_inst_vanilla(self):
370 class C:
371 def __init__(self, foo):
372 self.foo = foo
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000373 def __eq__(self, other):
374 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000375 x = C([42])
376 y = copy.deepcopy(x)
377 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200378 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000379
380 def test_deepcopy_inst_deepcopy(self):
381 class C:
382 def __init__(self, foo):
383 self.foo = foo
384 def __deepcopy__(self, memo):
385 return C(copy.deepcopy(self.foo, memo))
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000386 def __eq__(self, other):
387 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000388 x = C([42])
389 y = copy.deepcopy(x)
390 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200391 self.assertIsNot(y, x)
392 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000393
394 def test_deepcopy_inst_getinitargs(self):
395 class C:
396 def __init__(self, foo):
397 self.foo = foo
398 def __getinitargs__(self):
399 return (self.foo,)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000400 def __eq__(self, other):
401 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000402 x = C([42])
403 y = copy.deepcopy(x)
404 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200405 self.assertIsNot(y, x)
406 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000407
408 def test_deepcopy_inst_getstate(self):
409 class C:
410 def __init__(self, foo):
411 self.foo = foo
412 def __getstate__(self):
413 return {"foo": self.foo}
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000414 def __eq__(self, other):
415 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000416 x = C([42])
417 y = copy.deepcopy(x)
418 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200419 self.assertIsNot(y, x)
420 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000421
422 def test_deepcopy_inst_setstate(self):
423 class C:
424 def __init__(self, foo):
425 self.foo = foo
426 def __setstate__(self, state):
427 self.foo = state["foo"]
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000428 def __eq__(self, other):
429 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000430 x = C([42])
431 y = copy.deepcopy(x)
432 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200433 self.assertIsNot(y, x)
434 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000435
436 def test_deepcopy_inst_getstate_setstate(self):
437 class C:
438 def __init__(self, foo):
439 self.foo = foo
440 def __getstate__(self):
441 return self.foo
442 def __setstate__(self, state):
443 self.foo = state
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000444 def __eq__(self, other):
445 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000446 x = C([42])
447 y = copy.deepcopy(x)
448 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200449 self.assertIsNot(y, x)
450 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000451
Guido van Rossum99d2c252003-06-13 19:28:47 +0000452 def test_deepcopy_reflexive_inst(self):
453 class C:
454 pass
455 x = C()
456 x.foo = x
457 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200458 self.assertIsNot(y, x)
459 self.assertIs(y.foo, y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000460
Guido van Rossum581cb932003-02-06 17:52:15 +0000461 # _reconstruct()
462
463 def test_reconstruct_string(self):
464 class C(object):
465 def __reduce__(self):
466 return ""
467 x = C()
468 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200469 self.assertIs(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000470 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200471 self.assertIs(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000472
473 def test_reconstruct_nostate(self):
474 class C(object):
475 def __reduce__(self):
476 return (C, ())
477 x = C()
478 x.foo = 42
479 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200480 self.assertIs(y.__class__, x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000481 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200482 self.assertIs(y.__class__, x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000483
484 def test_reconstruct_state(self):
485 class C(object):
486 def __reduce__(self):
487 return (C, (), self.__dict__)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000488 def __eq__(self, other):
489 return self.__dict__ == other.__dict__
Guido van Rossum581cb932003-02-06 17:52:15 +0000490 x = C()
491 x.foo = [42]
492 y = copy.copy(x)
493 self.assertEqual(y, x)
494 y = copy.deepcopy(x)
495 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200496 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000497
498 def test_reconstruct_state_setstate(self):
499 class C(object):
500 def __reduce__(self):
501 return (C, (), self.__dict__)
502 def __setstate__(self, state):
503 self.__dict__.update(state)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000504 def __eq__(self, other):
505 return self.__dict__ == other.__dict__
Guido van Rossum581cb932003-02-06 17:52:15 +0000506 x = C()
507 x.foo = [42]
508 y = copy.copy(x)
509 self.assertEqual(y, x)
510 y = copy.deepcopy(x)
511 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200512 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000513
Guido van Rossum99d2c252003-06-13 19:28:47 +0000514 def test_reconstruct_reflexive(self):
515 class C(object):
516 pass
517 x = C()
518 x.foo = x
519 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200520 self.assertIsNot(y, x)
521 self.assertIs(y.foo, y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000522
Guido van Rossum90e05b02003-02-06 18:18:23 +0000523 # Additions for Python 2.3 and pickle protocol 2
524
525 def test_reduce_4tuple(self):
526 class C(list):
527 def __reduce__(self):
528 return (C, (), self.__dict__, iter(self))
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000529 def __eq__(self, other):
530 return (list(self) == list(other) and
531 self.__dict__ == other.__dict__)
Guido van Rossum90e05b02003-02-06 18:18:23 +0000532 x = C([[1, 2], 3])
533 y = copy.copy(x)
534 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200535 self.assertIsNot(x, y)
536 self.assertIs(x[0], y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000537 y = copy.deepcopy(x)
538 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200539 self.assertIsNot(x, y)
540 self.assertIsNot(x[0], y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000541
542 def test_reduce_5tuple(self):
543 class C(dict):
544 def __reduce__(self):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000545 return (C, (), self.__dict__, None, self.items())
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000546 def __eq__(self, other):
547 return (dict(self) == dict(other) and
548 self.__dict__ == other.__dict__)
Guido van Rossum90e05b02003-02-06 18:18:23 +0000549 x = C([("foo", [1, 2]), ("bar", 3)])
550 y = copy.copy(x)
551 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200552 self.assertIsNot(x, y)
553 self.assertIs(x["foo"], y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000554 y = copy.deepcopy(x)
555 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200556 self.assertIsNot(x, y)
557 self.assertIsNot(x["foo"], y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000558
Guido van Rossumc7557582003-02-06 19:53:22 +0000559 def test_copy_slots(self):
560 class C(object):
561 __slots__ = ["foo"]
562 x = C()
563 x.foo = [42]
564 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200565 self.assertIs(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000566
567 def test_deepcopy_slots(self):
568 class C(object):
569 __slots__ = ["foo"]
570 x = C()
571 x.foo = [42]
572 y = copy.deepcopy(x)
573 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200574 self.assertIsNot(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000575
Antoine Pitrou3941a8f2010-09-04 17:40:21 +0000576 def test_deepcopy_dict_subclass(self):
577 class C(dict):
578 def __init__(self, d=None):
579 if not d:
580 d = {}
581 self._keys = list(d.keys())
582 super().__init__(d)
583 def __setitem__(self, key, item):
584 super().__setitem__(key, item)
585 if key not in self._keys:
586 self._keys.append(key)
587 x = C(d={'foo':0})
588 y = copy.deepcopy(x)
589 self.assertEqual(x, y)
590 self.assertEqual(x._keys, y._keys)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200591 self.assertIsNot(x, y)
Antoine Pitrou3941a8f2010-09-04 17:40:21 +0000592 x['bar'] = 1
593 self.assertNotEqual(x, y)
594 self.assertNotEqual(x._keys, y._keys)
595
Guido van Rossumc7557582003-02-06 19:53:22 +0000596 def test_copy_list_subclass(self):
597 class C(list):
598 pass
599 x = C([[1, 2], 3])
600 x.foo = [4, 5]
601 y = copy.copy(x)
602 self.assertEqual(list(x), list(y))
603 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200604 self.assertIs(x[0], y[0])
605 self.assertIs(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000606
607 def test_deepcopy_list_subclass(self):
608 class C(list):
609 pass
610 x = C([[1, 2], 3])
611 x.foo = [4, 5]
612 y = copy.deepcopy(x)
613 self.assertEqual(list(x), list(y))
614 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200615 self.assertIsNot(x[0], y[0])
616 self.assertIsNot(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000617
Guido van Rossum85233bf2003-02-06 21:25:12 +0000618 def test_copy_tuple_subclass(self):
619 class C(tuple):
620 pass
621 x = C([1, 2, 3])
622 self.assertEqual(tuple(x), (1, 2, 3))
623 y = copy.copy(x)
624 self.assertEqual(tuple(y), (1, 2, 3))
625
626 def test_deepcopy_tuple_subclass(self):
627 class C(tuple):
628 pass
629 x = C([[1, 2], 3])
630 self.assertEqual(tuple(x), ([1, 2], 3))
631 y = copy.deepcopy(x)
632 self.assertEqual(tuple(y), ([1, 2], 3))
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200633 self.assertIsNot(x, y)
634 self.assertIsNot(x[0], y[0])
Guido van Rossum85233bf2003-02-06 21:25:12 +0000635
Neal Norwitze2fdc612003-06-08 13:19:58 +0000636 def test_getstate_exc(self):
637 class EvilState(object):
638 def __getstate__(self):
Collin Winter3add4d72007-08-29 23:37:32 +0000639 raise ValueError("ain't got no stickin' state")
Neal Norwitze2fdc612003-06-08 13:19:58 +0000640 self.assertRaises(ValueError, copy.copy, EvilState())
641
Guido van Rossum1968ad32006-02-25 22:38:04 +0000642 def test_copy_function(self):
643 self.assertEqual(copy.copy(global_foo), global_foo)
644 def foo(x, y): return x+y
645 self.assertEqual(copy.copy(foo), foo)
646 bar = lambda: None
647 self.assertEqual(copy.copy(bar), bar)
648
649 def test_deepcopy_function(self):
650 self.assertEqual(copy.deepcopy(global_foo), global_foo)
651 def foo(x, y): return x+y
652 self.assertEqual(copy.deepcopy(foo), foo)
653 bar = lambda: None
654 self.assertEqual(copy.deepcopy(bar), bar)
655
Antoine Pitrou6e610062009-05-15 17:04:50 +0000656 def _check_weakref(self, _copy):
657 class C(object):
658 pass
659 obj = C()
660 x = weakref.ref(obj)
661 y = _copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200662 self.assertIs(y, x)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000663 del obj
664 y = _copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200665 self.assertIs(y, x)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000666
667 def test_copy_weakref(self):
668 self._check_weakref(copy.copy)
669
670 def test_deepcopy_weakref(self):
671 self._check_weakref(copy.deepcopy)
672
673 def _check_copy_weakdict(self, _dicttype):
674 class C(object):
675 pass
676 a, b, c, d = [C() for i in range(4)]
677 u = _dicttype()
678 u[a] = b
679 u[c] = d
680 v = copy.copy(u)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200681 self.assertIsNot(v, u)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000682 self.assertEqual(v, u)
683 self.assertEqual(v[a], b)
684 self.assertEqual(v[c], d)
685 self.assertEqual(len(v), 2)
686 del c, d
687 self.assertEqual(len(v), 1)
688 x, y = C(), C()
689 # The underlying containers are decoupled
690 v[x] = y
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000691 self.assertNotIn(x, u)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000692
693 def test_copy_weakkeydict(self):
694 self._check_copy_weakdict(weakref.WeakKeyDictionary)
695
696 def test_copy_weakvaluedict(self):
697 self._check_copy_weakdict(weakref.WeakValueDictionary)
698
699 def test_deepcopy_weakkeydict(self):
700 class C(object):
701 def __init__(self, i):
702 self.i = i
703 a, b, c, d = [C(i) for i in range(4)]
704 u = weakref.WeakKeyDictionary()
705 u[a] = b
706 u[c] = d
707 # Keys aren't copied, values are
708 v = copy.deepcopy(u)
709 self.assertNotEqual(v, u)
710 self.assertEqual(len(v), 2)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200711 self.assertIsNot(v[a], b)
712 self.assertIsNot(v[c], d)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000713 self.assertEqual(v[a].i, b.i)
714 self.assertEqual(v[c].i, d.i)
715 del c
716 self.assertEqual(len(v), 1)
717
718 def test_deepcopy_weakvaluedict(self):
719 class C(object):
720 def __init__(self, i):
721 self.i = i
722 a, b, c, d = [C(i) for i in range(4)]
723 u = weakref.WeakValueDictionary()
724 u[a] = b
725 u[c] = d
726 # Keys are copied, values aren't
727 v = copy.deepcopy(u)
728 self.assertNotEqual(v, u)
729 self.assertEqual(len(v), 2)
730 (x, y), (z, t) = sorted(v.items(), key=lambda pair: pair[0].i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200731 self.assertIsNot(x, a)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000732 self.assertEqual(x.i, a.i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200733 self.assertIs(y, b)
734 self.assertIsNot(z, c)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000735 self.assertEqual(z.i, c.i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200736 self.assertIs(t, d)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000737 del x, y, z, t
738 del d
739 self.assertEqual(len(v), 1)
740
Antoine Pitrou1fc0d2b2009-11-28 15:58:27 +0000741 def test_deepcopy_bound_method(self):
742 class Foo(object):
743 def m(self):
744 pass
745 f = Foo()
746 f.b = f.m
747 g = copy.deepcopy(f)
748 self.assertEqual(g.m, g.b)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200749 self.assertIs(g.b.__self__, g)
Antoine Pitrou1fc0d2b2009-11-28 15:58:27 +0000750 g.b()
751
Antoine Pitrou6e610062009-05-15 17:04:50 +0000752
Guido van Rossum1968ad32006-02-25 22:38:04 +0000753def global_foo(x, y): return x+y
754
Guido van Rossum581cb932003-02-06 17:52:15 +0000755def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000756 support.run_unittest(TestCopy)
Guido van Rossum581cb932003-02-06 17:52:15 +0000757
758if __name__ == "__main__":
759 test_main()