1
"""Unit tests for the copy module."""
8
from test import test_support
10
class TestCopy(unittest.TestCase):
12
# Attempt full line coverage of copy.py from top to bottom
14
def test_exceptions(self):
15
self.assert_(copy.Error is copy.error)
16
self.assert_(issubclass(copy.Error, Exception))
20
def test_copy_basic(self):
23
self.assertEqual(x, y)
25
def test_copy_copy(self):
27
def __init__(self, foo):
33
self.assertEqual(y.__class__, x.__class__)
34
self.assertEqual(y.foo, x.foo)
36
def test_copy_registry(self):
38
def __new__(cls, foo):
39
obj = object.__new__(cls)
43
return (C, (obj.foo,))
45
self.assertRaises(TypeError, copy.copy, x)
46
copy_reg.pickle(C, pickle_C, C)
49
def test_copy_reduce_ex(self):
51
def __reduce_ex__(self, proto):
54
raise test_support.TestFailed, "shouldn't call this"
59
def test_copy_reduce(self):
67
def test_copy_cant(self):
69
def __getattribute__(self, name):
70
if name.startswith("__reduce"):
71
raise AttributeError, name
72
return object.__getattribute__(self, name)
74
self.assertRaises(copy.Error, copy.copy, x)
76
# Type-specific _copy_xxx() methods
78
def test_copy_atomic(self):
81
class NewStyle(object):
85
tests = [None, 42, 2L**100, 3.14, True, False, 1j,
86
"hello", u"hello\u1234", f.func_code,
87
NewStyle, xrange(10), Classic, max]
89
self.assert_(copy.copy(x) is x, repr(x))
91
def test_copy_list(self):
93
self.assertEqual(copy.copy(x), x)
95
def test_copy_tuple(self):
97
self.assertEqual(copy.copy(x), x)
99
def test_copy_dict(self):
100
x = {"foo": 1, "bar": 2}
101
self.assertEqual(copy.copy(x), x)
103
def test_copy_inst_vanilla(self):
105
def __init__(self, foo):
107
def __cmp__(self, other):
108
return cmp(self.foo, other.foo)
110
self.assertEqual(copy.copy(x), x)
112
def test_copy_inst_copy(self):
114
def __init__(self, foo):
118
def __cmp__(self, other):
119
return cmp(self.foo, other.foo)
121
self.assertEqual(copy.copy(x), x)
123
def test_copy_inst_getinitargs(self):
125
def __init__(self, foo):
127
def __getinitargs__(self):
129
def __cmp__(self, other):
130
return cmp(self.foo, other.foo)
132
self.assertEqual(copy.copy(x), x)
134
def test_copy_inst_getstate(self):
136
def __init__(self, foo):
138
def __getstate__(self):
139
return {"foo": self.foo}
140
def __cmp__(self, other):
141
return cmp(self.foo, other.foo)
143
self.assertEqual(copy.copy(x), x)
145
def test_copy_inst_setstate(self):
147
def __init__(self, foo):
149
def __setstate__(self, state):
150
self.foo = state["foo"]
151
def __cmp__(self, other):
152
return cmp(self.foo, other.foo)
154
self.assertEqual(copy.copy(x), x)
156
def test_copy_inst_getstate_setstate(self):
158
def __init__(self, foo):
160
def __getstate__(self):
162
def __setstate__(self, state):
164
def __cmp__(self, other):
165
return cmp(self.foo, other.foo)
167
self.assertEqual(copy.copy(x), x)
169
# These test make no sense in PyPy
170
# tests for copying extension types, iff module trycopy is installed
171
#def test_copy_classictype(self):
172
# from _testcapi import make_copyable
173
# x = make_copyable([23])
175
# self.assertEqual(x, y)
176
# self.assertEqual(x.tag, y.tag)
177
# self.assert_(x is not y)
178
# self.assert_(x.tag is y.tag)
180
#def test_deepcopy_classictype(self):
181
# from _testcapi import make_copyable
182
# x = make_copyable([23])
183
# y = copy.deepcopy(x)
184
# self.assertEqual(x, y)
185
# self.assertEqual(x.tag, y.tag)
186
# self.assert_(x is not y)
187
# self.assert_(x.tag is not y.tag)
189
# regression tests for class-vs-instance and metaclass-confusion
190
def test_copy_classoverinstance(self):
192
def __init__(self, v):
194
def __cmp__(self, other):
195
return -cmp(other, self.v)
197
return self.__class__(self.v)
199
self.assertEqual(copy.copy(x), x)
200
x.__copy__ = lambda: 42
201
self.assertEqual(copy.copy(x), x)
203
def test_deepcopy_classoverinstance(self):
205
def __init__(self, v):
207
def __cmp__(self, other):
208
return -cmp(other, self.v)
209
def __deepcopy__(self, memo):
210
return self.__class__(copy.deepcopy(self.v, memo))
212
self.assertEqual(copy.deepcopy(x), x)
213
x.__deepcopy__ = lambda memo: 42
214
self.assertEqual(copy.deepcopy(x), x)
217
def test_copy_metaclassconfusion(self):
218
class MyOwnError(copy.Error):
222
raise MyOwnError("can't copy classes w/this metaclass")
225
def __init__(self, tag):
227
def __cmp__(self, other):
228
return -cmp(other, self.tag)
229
# the metaclass can forbid shallow copying of its classes
230
self.assertRaises(MyOwnError, copy.copy, C)
231
# check that there is no interference with instances
233
self.assertEqual(copy.copy(x), x)
235
def test_deepcopy_metaclassconfusion(self):
236
class MyOwnError(copy.Error):
239
def __deepcopy__(cls, memo):
240
raise MyOwnError("can't deepcopy classes w/this metaclass")
243
def __init__(self, tag):
245
def __cmp__(self, other):
246
return -cmp(other, self.tag)
247
# types are ALWAYS deepcopied atomically, no matter what
248
self.assertEqual(copy.deepcopy(C), C)
249
# check that there is no interference with instances
251
self.assertEqual(copy.deepcopy(x), x)
255
def __getattribute__(self, attr):
256
if attr == '__mro__':
257
raise AttributeError, "What, *me*, a __mro__? Nevah!"
258
return super(C, self).__getattribute__(attr)
263
def test_copy_mro(self):
267
def test_deepcopy_mro(self):
271
# The deepcopy() method
273
def test_deepcopy_basic(self):
276
self.assertEqual(y, x)
278
def test_deepcopy_memo(self):
279
# Tests of reflexive objects are under type-specific sections below.
280
# This tests only repetitions of objects.
284
self.assertEqual(y, x)
285
self.assert_(y is not x)
286
self.assert_(y[0] is not x[0])
287
self.assert_(y[0] is y[1])
289
def test_deepcopy_issubclass(self):
290
# XXX Note: there's no way to test the TypeError coming out of
291
# issubclass() -- this can only happen when an extension
292
# module defines a "type" that doesn't formally inherit from
298
self.assertEqual(copy.deepcopy(C), C)
300
def test_deepcopy_deepcopy(self):
302
def __init__(self, foo):
304
def __deepcopy__(self, memo=None):
308
self.assertEqual(y.__class__, x.__class__)
309
self.assertEqual(y.foo, x.foo)
311
def test_deepcopy_registry(self):
313
def __new__(cls, foo):
314
obj = object.__new__(cls)
318
return (C, (obj.foo,))
320
self.assertRaises(TypeError, copy.deepcopy, x)
321
copy_reg.pickle(C, pickle_C, C)
324
def test_deepcopy_reduce_ex(self):
326
def __reduce_ex__(self, proto):
328
def __reduce__(self):
329
raise test_support.TestFailed, "shouldn't call this"
334
def test_deepcopy_reduce(self):
336
def __reduce__(self):
342
def test_deepcopy_cant(self):
344
def __getattribute__(self, name):
345
if name.startswith("__reduce"):
346
raise AttributeError, name
347
return object.__getattribute__(self, name)
349
self.assertRaises(copy.Error, copy.deepcopy, x)
351
# Type-specific _deepcopy_xxx() methods
353
def test_deepcopy_atomic(self):
356
class NewStyle(object):
360
tests = [None, 42, 2L**100, 3.14, True, False, 1j,
361
"hello", u"hello\u1234", f.func_code,
362
NewStyle, xrange(10), Classic, max]
364
self.assert_(copy.deepcopy(x) is x, repr(x))
366
def test_deepcopy_list(self):
369
self.assertEqual(y, x)
370
self.assert_(x is not y)
371
self.assert_(x[0] is not y[0])
373
def test_deepcopy_reflexive_list(self):
377
self.assert_(y is not x)
378
self.assert_(y[0] is y)
379
self.assertEqual(len(y), 1)
381
def test_deepcopy_tuple(self):
384
self.assertEqual(y, x)
385
self.assert_(x is not y)
386
self.assert_(x[0] is not y[0])
388
def test_deepcopy_reflexive_tuple(self):
392
self.assert_(y is not x)
393
self.assertEqual(type(y), tuple)
394
self.assertEqual(len(y), 1)
395
self.assertEqual(type(y[0]), list)
396
self.assertEqual(len(y[0]), 1)
397
self.assert_(y[0][0] is y)
399
def test_deepcopy_dict(self):
400
x = {"foo": [1, 2], "bar": 3}
402
self.assertEqual(y, x)
403
self.assert_(x is not y)
404
self.assert_(x["foo"] is not y["foo"])
406
def test_deepcopy_reflexive_dict(self):
410
self.assert_(y is not x)
411
self.assert_(y['foo'] is y)
412
self.assertEqual(len(y), 1)
414
def test_deepcopy_keepalive(self):
417
y = copy.deepcopy(x, memo)
418
self.assert_(memo[id(x)] is x)
420
def test_deepcopy_inst_vanilla(self):
422
def __init__(self, foo):
424
def __cmp__(self, other):
425
return cmp(self.foo, other.foo)
428
self.assertEqual(y, x)
429
self.assert_(y.foo is not x.foo)
431
def test_deepcopy_inst_deepcopy(self):
433
def __init__(self, foo):
435
def __deepcopy__(self, memo):
436
return C(copy.deepcopy(self.foo, memo))
437
def __cmp__(self, other):
438
return cmp(self.foo, other.foo)
441
self.assertEqual(y, x)
442
self.assert_(y is not x)
443
self.assert_(y.foo is not x.foo)
445
def test_deepcopy_inst_getinitargs(self):
447
def __init__(self, foo):
449
def __getinitargs__(self):
451
def __cmp__(self, other):
452
return cmp(self.foo, other.foo)
455
self.assertEqual(y, x)
456
self.assert_(y is not x)
457
self.assert_(y.foo is not x.foo)
459
def test_deepcopy_inst_getstate(self):
461
def __init__(self, foo):
463
def __getstate__(self):
464
return {"foo": self.foo}
465
def __cmp__(self, other):
466
return cmp(self.foo, other.foo)
469
self.assertEqual(y, x)
470
self.assert_(y is not x)
471
self.assert_(y.foo is not x.foo)
473
def test_deepcopy_inst_setstate(self):
475
def __init__(self, foo):
477
def __setstate__(self, state):
478
self.foo = state["foo"]
479
def __cmp__(self, other):
480
return cmp(self.foo, other.foo)
483
self.assertEqual(y, x)
484
self.assert_(y is not x)
485
self.assert_(y.foo is not x.foo)
487
def test_deepcopy_inst_getstate_setstate(self):
489
def __init__(self, foo):
491
def __getstate__(self):
493
def __setstate__(self, state):
495
def __cmp__(self, other):
496
return cmp(self.foo, other.foo)
499
self.assertEqual(y, x)
500
self.assert_(y is not x)
501
self.assert_(y.foo is not x.foo)
503
def test_deepcopy_reflexive_inst(self):
509
self.assert_(y is not x)
510
self.assert_(y.foo is y)
514
def test_reconstruct_string(self):
516
def __reduce__(self):
524
def test_reconstruct_nostate(self):
526
def __reduce__(self):
531
self.assert_(y.__class__ is x.__class__)
533
self.assert_(y.__class__ is x.__class__)
535
def test_reconstruct_state(self):
537
def __reduce__(self):
538
return (C, (), self.__dict__)
539
def __cmp__(self, other):
540
return cmp(self.__dict__, other.__dict__)
544
self.assertEqual(y, x)
546
self.assertEqual(y, x)
547
self.assert_(y.foo is not x.foo)
549
def test_reconstruct_state_setstate(self):
551
def __reduce__(self):
552
return (C, (), self.__dict__)
553
def __setstate__(self, state):
554
self.__dict__.update(state)
555
def __cmp__(self, other):
556
return cmp(self.__dict__, other.__dict__)
560
self.assertEqual(y, x)
562
self.assertEqual(y, x)
563
self.assert_(y.foo is not x.foo)
565
def test_reconstruct_reflexive(self):
571
self.assert_(y is not x)
572
self.assert_(y.foo is y)
574
# Additions for Python 2.3 and pickle protocol 2
576
def test_reduce_4tuple(self):
578
def __reduce__(self):
579
return (C, (), self.__dict__, iter(self))
580
def __cmp__(self, other):
581
return (cmp(list(self), list(other)) or
582
cmp(self.__dict__, other.__dict__))
585
self.assertEqual(x, y)
586
self.assert_(x is not y)
587
self.assert_(x[0] is y[0])
589
self.assertEqual(x, y)
590
self.assert_(x is not y)
591
self.assert_(x[0] is not y[0])
593
def test_reduce_5tuple(self):
595
def __reduce__(self):
596
return (C, (), self.__dict__, None, self.iteritems())
597
def __cmp__(self, other):
598
return (cmp(dict(self), list(dict)) or
599
cmp(self.__dict__, other.__dict__))
600
x = C([("foo", [1, 2]), ("bar", 3)])
602
self.assertEqual(x, y)
603
self.assert_(x is not y)
604
self.assert_(x["foo"] is y["foo"])
606
self.assertEqual(x, y)
607
self.assert_(x is not y)
608
self.assert_(x["foo"] is not y["foo"])
610
def test_copy_slots(self):
616
self.assert_(x.foo is y.foo)
618
def test_deepcopy_slots(self):
624
self.assertEqual(x.foo, y.foo)
625
self.assert_(x.foo is not y.foo)
627
def test_copy_list_subclass(self):
633
self.assertEqual(list(x), list(y))
634
self.assertEqual(x.foo, y.foo)
635
self.assert_(x[0] is y[0])
636
self.assert_(x.foo is y.foo)
638
def test_deepcopy_list_subclass(self):
644
self.assertEqual(list(x), list(y))
645
self.assertEqual(x.foo, y.foo)
646
self.assert_(x[0] is not y[0])
647
self.assert_(x.foo is not y.foo)
649
def test_copy_tuple_subclass(self):
653
self.assertEqual(tuple(x), (1, 2, 3))
655
self.assertEqual(tuple(y), (1, 2, 3))
657
def test_deepcopy_tuple_subclass(self):
661
self.assertEqual(tuple(x), ([1, 2], 3))
663
self.assertEqual(tuple(y), ([1, 2], 3))
664
self.assert_(x is not y)
665
self.assert_(x[0] is not y[0])
667
def test_getstate_exc(self):
668
class EvilState(object):
669
def __getstate__(self):
670
raise ValueError, "ain't got no stickin' state"
671
self.assertRaises(ValueError, copy.copy, EvilState())
674
test_support.run_unittest(TestCopy)
676
if __name__ == "__main__":