1"""Unit tests for the copy module.""" 2 3import copy 4import copyreg 5import weakref 6import abc 7from operator import le, lt, ge, gt, eq, ne 8 9import unittest 10from test import support 11 12order_comparisons = le, lt, ge, gt 13equality_comparisons = eq, ne 14comparisons = order_comparisons + equality_comparisons 15 16class TestCopy(unittest.TestCase): 17 18 # Attempt full line coverage of copy.py from top to bottom 19 20 def test_exceptions(self): 21 self.assertIs(copy.Error, copy.error) 22 self.assertTrue(issubclass(copy.Error, Exception)) 23 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 42 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) 52 copyreg.pickle(C, pickle_C, C) 53 y = copy.copy(x) 54 self.assertIsNot(x, y) 55 self.assertEqual(type(y), C) 56 self.assertEqual(y.foo, x.foo) 57 58 def test_copy_reduce_ex(self): 59 class C(object): 60 def __reduce_ex__(self, proto): 61 c.append(1) 62 return "" 63 def __reduce__(self): 64 self.fail("shouldn't call this") 65 c = [] 66 x = C() 67 y = copy.copy(x) 68 self.assertIs(y, x) 69 self.assertEqual(c, [1]) 70 71 def test_copy_reduce(self): 72 class C(object): 73 def __reduce__(self): 74 c.append(1) 75 return "" 76 c = [] 77 x = C() 78 y = copy.copy(x) 79 self.assertIs(y, x) 80 self.assertEqual(c, [1]) 81 82 def test_copy_cant(self): 83 class C(object): 84 def __getattribute__(self, name): 85 if name.startswith("__reduce"): 86 raise AttributeError(name) 87 return object.__getattribute__(self, name) 88 x = C() 89 self.assertRaises(copy.Error, copy.copy, x) 90 91 # Type-specific _copy_xxx() methods 92 93 def test_copy_atomic(self): 94 class Classic: 95 pass 96 class NewStyle(object): 97 pass 98 def f(): 99 pass 100 class WithMetaclass(metaclass=abc.ABCMeta): 101 pass 102 tests = [None, ..., NotImplemented, 103 42, 2**100, 3.14, True, False, 1j, 104 "hello", "hello\u1234", f.__code__, 105 b"world", bytes(range(256)), range(10), slice(1, 10, 2), 106 NewStyle, Classic, max, WithMetaclass, property()] 107 for x in tests: 108 self.assertIs(copy.copy(x), x) 109 110 def test_copy_list(self): 111 x = [1, 2, 3] 112 y = copy.copy(x) 113 self.assertEqual(y, x) 114 self.assertIsNot(y, x) 115 x = [] 116 y = copy.copy(x) 117 self.assertEqual(y, x) 118 self.assertIsNot(y, x) 119 120 def test_copy_tuple(self): 121 x = (1, 2, 3) 122 self.assertIs(copy.copy(x), x) 123 x = () 124 self.assertIs(copy.copy(x), x) 125 x = (1, 2, 3, []) 126 self.assertIs(copy.copy(x), x) 127 128 def test_copy_dict(self): 129 x = {"foo": 1, "bar": 2} 130 y = copy.copy(x) 131 self.assertEqual(y, x) 132 self.assertIsNot(y, x) 133 x = {} 134 y = copy.copy(x) 135 self.assertEqual(y, x) 136 self.assertIsNot(y, x) 137 138 def test_copy_set(self): 139 x = {1, 2, 3} 140 y = copy.copy(x) 141 self.assertEqual(y, x) 142 self.assertIsNot(y, x) 143 x = set() 144 y = copy.copy(x) 145 self.assertEqual(y, x) 146 self.assertIsNot(y, x) 147 148 def test_copy_frozenset(self): 149 x = frozenset({1, 2, 3}) 150 self.assertIs(copy.copy(x), x) 151 x = frozenset() 152 self.assertIs(copy.copy(x), x) 153 154 def test_copy_bytearray(self): 155 x = bytearray(b'abc') 156 y = copy.copy(x) 157 self.assertEqual(y, x) 158 self.assertIsNot(y, x) 159 x = bytearray() 160 y = copy.copy(x) 161 self.assertEqual(y, x) 162 self.assertIsNot(y, x) 163 164 def test_copy_inst_vanilla(self): 165 class C: 166 def __init__(self, foo): 167 self.foo = foo 168 def __eq__(self, other): 169 return self.foo == other.foo 170 x = C(42) 171 self.assertEqual(copy.copy(x), x) 172 173 def test_copy_inst_copy(self): 174 class C: 175 def __init__(self, foo): 176 self.foo = foo 177 def __copy__(self): 178 return C(self.foo) 179 def __eq__(self, other): 180 return self.foo == other.foo 181 x = C(42) 182 self.assertEqual(copy.copy(x), x) 183 184 def test_copy_inst_getinitargs(self): 185 class C: 186 def __init__(self, foo): 187 self.foo = foo 188 def __getinitargs__(self): 189 return (self.foo,) 190 def __eq__(self, other): 191 return self.foo == other.foo 192 x = C(42) 193 self.assertEqual(copy.copy(x), x) 194 195 def test_copy_inst_getnewargs(self): 196 class C(int): 197 def __new__(cls, foo): 198 self = int.__new__(cls) 199 self.foo = foo 200 return self 201 def __getnewargs__(self): 202 return self.foo, 203 def __eq__(self, other): 204 return self.foo == other.foo 205 x = C(42) 206 y = copy.copy(x) 207 self.assertIsInstance(y, C) 208 self.assertEqual(y, x) 209 self.assertIsNot(y, x) 210 self.assertEqual(y.foo, x.foo) 211 212 def test_copy_inst_getnewargs_ex(self): 213 class C(int): 214 def __new__(cls, *, foo): 215 self = int.__new__(cls) 216 self.foo = foo 217 return self 218 def __getnewargs_ex__(self): 219 return (), {'foo': self.foo} 220 def __eq__(self, other): 221 return self.foo == other.foo 222 x = C(foo=42) 223 y = copy.copy(x) 224 self.assertIsInstance(y, C) 225 self.assertEqual(y, x) 226 self.assertIsNot(y, x) 227 self.assertEqual(y.foo, x.foo) 228 229 def test_copy_inst_getstate(self): 230 class C: 231 def __init__(self, foo): 232 self.foo = foo 233 def __getstate__(self): 234 return {"foo": self.foo} 235 def __eq__(self, other): 236 return self.foo == other.foo 237 x = C(42) 238 self.assertEqual(copy.copy(x), x) 239 240 def test_copy_inst_setstate(self): 241 class C: 242 def __init__(self, foo): 243 self.foo = foo 244 def __setstate__(self, state): 245 self.foo = state["foo"] 246 def __eq__(self, other): 247 return self.foo == other.foo 248 x = C(42) 249 self.assertEqual(copy.copy(x), x) 250 251 def test_copy_inst_getstate_setstate(self): 252 class C: 253 def __init__(self, foo): 254 self.foo = foo 255 def __getstate__(self): 256 return self.foo 257 def __setstate__(self, state): 258 self.foo = state 259 def __eq__(self, other): 260 return self.foo == other.foo 261 x = C(42) 262 self.assertEqual(copy.copy(x), x) 263 # State with boolean value is false (issue #25718) 264 x = C(0.0) 265 self.assertEqual(copy.copy(x), x) 266 267 # The deepcopy() method 268 269 def test_deepcopy_basic(self): 270 x = 42 271 y = copy.deepcopy(x) 272 self.assertEqual(y, x) 273 274 def test_deepcopy_memo(self): 275 # Tests of reflexive objects are under type-specific sections below. 276 # This tests only repetitions of objects. 277 x = [] 278 x = [x, x] 279 y = copy.deepcopy(x) 280 self.assertEqual(y, x) 281 self.assertIsNot(y, x) 282 self.assertIsNot(y[0], x[0]) 283 self.assertIs(y[0], y[1]) 284 285 def test_deepcopy_issubclass(self): 286 # XXX Note: there's no way to test the TypeError coming out of 287 # issubclass() -- this can only happen when an extension 288 # module defines a "type" that doesn't formally inherit from 289 # type. 290 class Meta(type): 291 pass 292 class C(metaclass=Meta): 293 pass 294 self.assertEqual(copy.deepcopy(C), C) 295 296 def test_deepcopy_deepcopy(self): 297 class C(object): 298 def __init__(self, foo): 299 self.foo = foo 300 def __deepcopy__(self, memo=None): 301 return C(self.foo) 302 x = C(42) 303 y = copy.deepcopy(x) 304 self.assertEqual(y.__class__, x.__class__) 305 self.assertEqual(y.foo, x.foo) 306 307 def test_deepcopy_registry(self): 308 class C(object): 309 def __new__(cls, foo): 310 obj = object.__new__(cls) 311 obj.foo = foo 312 return obj 313 def pickle_C(obj): 314 return (C, (obj.foo,)) 315 x = C(42) 316 self.assertRaises(TypeError, copy.deepcopy, x) 317 copyreg.pickle(C, pickle_C, C) 318 y = copy.deepcopy(x) 319 self.assertIsNot(x, y) 320 self.assertEqual(type(y), C) 321 self.assertEqual(y.foo, x.foo) 322 323 def test_deepcopy_reduce_ex(self): 324 class C(object): 325 def __reduce_ex__(self, proto): 326 c.append(1) 327 return "" 328 def __reduce__(self): 329 self.fail("shouldn't call this") 330 c = [] 331 x = C() 332 y = copy.deepcopy(x) 333 self.assertIs(y, x) 334 self.assertEqual(c, [1]) 335 336 def test_deepcopy_reduce(self): 337 class C(object): 338 def __reduce__(self): 339 c.append(1) 340 return "" 341 c = [] 342 x = C() 343 y = copy.deepcopy(x) 344 self.assertIs(y, x) 345 self.assertEqual(c, [1]) 346 347 def test_deepcopy_cant(self): 348 class C(object): 349 def __getattribute__(self, name): 350 if name.startswith("__reduce"): 351 raise AttributeError(name) 352 return object.__getattribute__(self, name) 353 x = C() 354 self.assertRaises(copy.Error, copy.deepcopy, x) 355 356 # Type-specific _deepcopy_xxx() methods 357 358 def test_deepcopy_atomic(self): 359 class Classic: 360 pass 361 class NewStyle(object): 362 pass 363 def f(): 364 pass 365 tests = [None, ..., NotImplemented, 42, 2**100, 3.14, True, False, 1j, 366 b"bytes", "hello", "hello\u1234", f.__code__, 367 NewStyle, range(10), Classic, max, property()] 368 for x in tests: 369 self.assertIs(copy.deepcopy(x), x) 370 371 def test_deepcopy_list(self): 372 x = [[1, 2], 3] 373 y = copy.deepcopy(x) 374 self.assertEqual(y, x) 375 self.assertIsNot(x, y) 376 self.assertIsNot(x[0], y[0]) 377 378 def test_deepcopy_reflexive_list(self): 379 x = [] 380 x.append(x) 381 y = copy.deepcopy(x) 382 for op in comparisons: 383 self.assertRaises(RecursionError, op, y, x) 384 self.assertIsNot(y, x) 385 self.assertIs(y[0], y) 386 self.assertEqual(len(y), 1) 387 388 def test_deepcopy_empty_tuple(self): 389 x = () 390 y = copy.deepcopy(x) 391 self.assertIs(x, y) 392 393 def test_deepcopy_tuple(self): 394 x = ([1, 2], 3) 395 y = copy.deepcopy(x) 396 self.assertEqual(y, x) 397 self.assertIsNot(x, y) 398 self.assertIsNot(x[0], y[0]) 399 400 def test_deepcopy_tuple_of_immutables(self): 401 x = ((1, 2), 3) 402 y = copy.deepcopy(x) 403 self.assertIs(x, y) 404 405 def test_deepcopy_reflexive_tuple(self): 406 x = ([],) 407 x[0].append(x) 408 y = copy.deepcopy(x) 409 for op in comparisons: 410 self.assertRaises(RecursionError, op, y, x) 411 self.assertIsNot(y, x) 412 self.assertIsNot(y[0], x[0]) 413 self.assertIs(y[0][0], y) 414 415 def test_deepcopy_dict(self): 416 x = {"foo": [1, 2], "bar": 3} 417 y = copy.deepcopy(x) 418 self.assertEqual(y, x) 419 self.assertIsNot(x, y) 420 self.assertIsNot(x["foo"], y["foo"]) 421 422 def test_deepcopy_reflexive_dict(self): 423 x = {} 424 x['foo'] = x 425 y = copy.deepcopy(x) 426 for op in order_comparisons: 427 self.assertRaises(TypeError, op, y, x) 428 for op in equality_comparisons: 429 self.assertRaises(RecursionError, op, y, x) 430 self.assertIsNot(y, x) 431 self.assertIs(y['foo'], y) 432 self.assertEqual(len(y), 1) 433 434 def test_deepcopy_keepalive(self): 435 memo = {} 436 x = [] 437 y = copy.deepcopy(x, memo) 438 self.assertIs(memo[id(memo)][0], x) 439 440 def test_deepcopy_dont_memo_immutable(self): 441 memo = {} 442 x = [1, 2, 3, 4] 443 y = copy.deepcopy(x, memo) 444 self.assertEqual(y, x) 445 # There's the entry for the new list, and the keep alive. 446 self.assertEqual(len(memo), 2) 447 448 memo = {} 449 x = [(1, 2)] 450 y = copy.deepcopy(x, memo) 451 self.assertEqual(y, x) 452 # Tuples with immutable contents are immutable for deepcopy. 453 self.assertEqual(len(memo), 2) 454 455 def test_deepcopy_inst_vanilla(self): 456 class C: 457 def __init__(self, foo): 458 self.foo = foo 459 def __eq__(self, other): 460 return self.foo == other.foo 461 x = C([42]) 462 y = copy.deepcopy(x) 463 self.assertEqual(y, x) 464 self.assertIsNot(y.foo, x.foo) 465 466 def test_deepcopy_inst_deepcopy(self): 467 class C: 468 def __init__(self, foo): 469 self.foo = foo 470 def __deepcopy__(self, memo): 471 return C(copy.deepcopy(self.foo, memo)) 472 def __eq__(self, other): 473 return self.foo == other.foo 474 x = C([42]) 475 y = copy.deepcopy(x) 476 self.assertEqual(y, x) 477 self.assertIsNot(y, x) 478 self.assertIsNot(y.foo, x.foo) 479 480 def test_deepcopy_inst_getinitargs(self): 481 class C: 482 def __init__(self, foo): 483 self.foo = foo 484 def __getinitargs__(self): 485 return (self.foo,) 486 def __eq__(self, other): 487 return self.foo == other.foo 488 x = C([42]) 489 y = copy.deepcopy(x) 490 self.assertEqual(y, x) 491 self.assertIsNot(y, x) 492 self.assertIsNot(y.foo, x.foo) 493 494 def test_deepcopy_inst_getnewargs(self): 495 class C(int): 496 def __new__(cls, foo): 497 self = int.__new__(cls) 498 self.foo = foo 499 return self 500 def __getnewargs__(self): 501 return self.foo, 502 def __eq__(self, other): 503 return self.foo == other.foo 504 x = C([42]) 505 y = copy.deepcopy(x) 506 self.assertIsInstance(y, C) 507 self.assertEqual(y, x) 508 self.assertIsNot(y, x) 509 self.assertEqual(y.foo, x.foo) 510 self.assertIsNot(y.foo, x.foo) 511 512 def test_deepcopy_inst_getnewargs_ex(self): 513 class C(int): 514 def __new__(cls, *, foo): 515 self = int.__new__(cls) 516 self.foo = foo 517 return self 518 def __getnewargs_ex__(self): 519 return (), {'foo': self.foo} 520 def __eq__(self, other): 521 return self.foo == other.foo 522 x = C(foo=[42]) 523 y = copy.deepcopy(x) 524 self.assertIsInstance(y, C) 525 self.assertEqual(y, x) 526 self.assertIsNot(y, x) 527 self.assertEqual(y.foo, x.foo) 528 self.assertIsNot(y.foo, x.foo) 529 530 def test_deepcopy_inst_getstate(self): 531 class C: 532 def __init__(self, foo): 533 self.foo = foo 534 def __getstate__(self): 535 return {"foo": self.foo} 536 def __eq__(self, other): 537 return self.foo == other.foo 538 x = C([42]) 539 y = copy.deepcopy(x) 540 self.assertEqual(y, x) 541 self.assertIsNot(y, x) 542 self.assertIsNot(y.foo, x.foo) 543 544 def test_deepcopy_inst_setstate(self): 545 class C: 546 def __init__(self, foo): 547 self.foo = foo 548 def __setstate__(self, state): 549 self.foo = state["foo"] 550 def __eq__(self, other): 551 return self.foo == other.foo 552 x = C([42]) 553 y = copy.deepcopy(x) 554 self.assertEqual(y, x) 555 self.assertIsNot(y, x) 556 self.assertIsNot(y.foo, x.foo) 557 558 def test_deepcopy_inst_getstate_setstate(self): 559 class C: 560 def __init__(self, foo): 561 self.foo = foo 562 def __getstate__(self): 563 return self.foo 564 def __setstate__(self, state): 565 self.foo = state 566 def __eq__(self, other): 567 return self.foo == other.foo 568 x = C([42]) 569 y = copy.deepcopy(x) 570 self.assertEqual(y, x) 571 self.assertIsNot(y, x) 572 self.assertIsNot(y.foo, x.foo) 573 # State with boolean value is false (issue #25718) 574 x = C([]) 575 y = copy.deepcopy(x) 576 self.assertEqual(y, x) 577 self.assertIsNot(y, x) 578 self.assertIsNot(y.foo, x.foo) 579 580 def test_deepcopy_reflexive_inst(self): 581 class C: 582 pass 583 x = C() 584 x.foo = x 585 y = copy.deepcopy(x) 586 self.assertIsNot(y, x) 587 self.assertIs(y.foo, y) 588 589 # _reconstruct() 590 591 def test_reconstruct_string(self): 592 class C(object): 593 def __reduce__(self): 594 return "" 595 x = C() 596 y = copy.copy(x) 597 self.assertIs(y, x) 598 y = copy.deepcopy(x) 599 self.assertIs(y, x) 600 601 def test_reconstruct_nostate(self): 602 class C(object): 603 def __reduce__(self): 604 return (C, ()) 605 x = C() 606 x.foo = 42 607 y = copy.copy(x) 608 self.assertIs(y.__class__, x.__class__) 609 y = copy.deepcopy(x) 610 self.assertIs(y.__class__, x.__class__) 611 612 def test_reconstruct_state(self): 613 class C(object): 614 def __reduce__(self): 615 return (C, (), self.__dict__) 616 def __eq__(self, other): 617 return self.__dict__ == other.__dict__ 618 x = C() 619 x.foo = [42] 620 y = copy.copy(x) 621 self.assertEqual(y, x) 622 y = copy.deepcopy(x) 623 self.assertEqual(y, x) 624 self.assertIsNot(y.foo, x.foo) 625 626 def test_reconstruct_state_setstate(self): 627 class C(object): 628 def __reduce__(self): 629 return (C, (), self.__dict__) 630 def __setstate__(self, state): 631 self.__dict__.update(state) 632 def __eq__(self, other): 633 return self.__dict__ == other.__dict__ 634 x = C() 635 x.foo = [42] 636 y = copy.copy(x) 637 self.assertEqual(y, x) 638 y = copy.deepcopy(x) 639 self.assertEqual(y, x) 640 self.assertIsNot(y.foo, x.foo) 641 642 def test_reconstruct_reflexive(self): 643 class C(object): 644 pass 645 x = C() 646 x.foo = x 647 y = copy.deepcopy(x) 648 self.assertIsNot(y, x) 649 self.assertIs(y.foo, y) 650 651 # Additions for Python 2.3 and pickle protocol 2 652 653 def test_reduce_4tuple(self): 654 class C(list): 655 def __reduce__(self): 656 return (C, (), self.__dict__, iter(self)) 657 def __eq__(self, other): 658 return (list(self) == list(other) and 659 self.__dict__ == other.__dict__) 660 x = C([[1, 2], 3]) 661 y = copy.copy(x) 662 self.assertEqual(x, y) 663 self.assertIsNot(x, y) 664 self.assertIs(x[0], y[0]) 665 y = copy.deepcopy(x) 666 self.assertEqual(x, y) 667 self.assertIsNot(x, y) 668 self.assertIsNot(x[0], y[0]) 669 670 def test_reduce_5tuple(self): 671 class C(dict): 672 def __reduce__(self): 673 return (C, (), self.__dict__, None, self.items()) 674 def __eq__(self, other): 675 return (dict(self) == dict(other) and 676 self.__dict__ == other.__dict__) 677 x = C([("foo", [1, 2]), ("bar", 3)]) 678 y = copy.copy(x) 679 self.assertEqual(x, y) 680 self.assertIsNot(x, y) 681 self.assertIs(x["foo"], y["foo"]) 682 y = copy.deepcopy(x) 683 self.assertEqual(x, y) 684 self.assertIsNot(x, y) 685 self.assertIsNot(x["foo"], y["foo"]) 686 687 def test_reduce_6tuple(self): 688 def state_setter(*args, **kwargs): 689 self.fail("shouldn't call this") 690 class C: 691 def __reduce__(self): 692 return C, (), self.__dict__, None, None, state_setter 693 x = C() 694 with self.assertRaises(TypeError): 695 copy.copy(x) 696 with self.assertRaises(TypeError): 697 copy.deepcopy(x) 698 699 def test_reduce_6tuple_none(self): 700 class C: 701 def __reduce__(self): 702 return C, (), self.__dict__, None, None, None 703 x = C() 704 with self.assertRaises(TypeError): 705 copy.copy(x) 706 with self.assertRaises(TypeError): 707 copy.deepcopy(x) 708 709 def test_copy_slots(self): 710 class C(object): 711 __slots__ = ["foo"] 712 x = C() 713 x.foo = [42] 714 y = copy.copy(x) 715 self.assertIs(x.foo, y.foo) 716 717 def test_deepcopy_slots(self): 718 class C(object): 719 __slots__ = ["foo"] 720 x = C() 721 x.foo = [42] 722 y = copy.deepcopy(x) 723 self.assertEqual(x.foo, y.foo) 724 self.assertIsNot(x.foo, y.foo) 725 726 def test_deepcopy_dict_subclass(self): 727 class C(dict): 728 def __init__(self, d=None): 729 if not d: 730 d = {} 731 self._keys = list(d.keys()) 732 super().__init__(d) 733 def __setitem__(self, key, item): 734 super().__setitem__(key, item) 735 if key not in self._keys: 736 self._keys.append(key) 737 x = C(d={'foo':0}) 738 y = copy.deepcopy(x) 739 self.assertEqual(x, y) 740 self.assertEqual(x._keys, y._keys) 741 self.assertIsNot(x, y) 742 x['bar'] = 1 743 self.assertNotEqual(x, y) 744 self.assertNotEqual(x._keys, y._keys) 745 746 def test_copy_list_subclass(self): 747 class C(list): 748 pass 749 x = C([[1, 2], 3]) 750 x.foo = [4, 5] 751 y = copy.copy(x) 752 self.assertEqual(list(x), list(y)) 753 self.assertEqual(x.foo, y.foo) 754 self.assertIs(x[0], y[0]) 755 self.assertIs(x.foo, y.foo) 756 757 def test_deepcopy_list_subclass(self): 758 class C(list): 759 pass 760 x = C([[1, 2], 3]) 761 x.foo = [4, 5] 762 y = copy.deepcopy(x) 763 self.assertEqual(list(x), list(y)) 764 self.assertEqual(x.foo, y.foo) 765 self.assertIsNot(x[0], y[0]) 766 self.assertIsNot(x.foo, y.foo) 767 768 def test_copy_tuple_subclass(self): 769 class C(tuple): 770 pass 771 x = C([1, 2, 3]) 772 self.assertEqual(tuple(x), (1, 2, 3)) 773 y = copy.copy(x) 774 self.assertEqual(tuple(y), (1, 2, 3)) 775 776 def test_deepcopy_tuple_subclass(self): 777 class C(tuple): 778 pass 779 x = C([[1, 2], 3]) 780 self.assertEqual(tuple(x), ([1, 2], 3)) 781 y = copy.deepcopy(x) 782 self.assertEqual(tuple(y), ([1, 2], 3)) 783 self.assertIsNot(x, y) 784 self.assertIsNot(x[0], y[0]) 785 786 def test_getstate_exc(self): 787 class EvilState(object): 788 def __getstate__(self): 789 raise ValueError("ain't got no stickin' state") 790 self.assertRaises(ValueError, copy.copy, EvilState()) 791 792 def test_copy_function(self): 793 self.assertEqual(copy.copy(global_foo), global_foo) 794 def foo(x, y): return x+y 795 self.assertEqual(copy.copy(foo), foo) 796 bar = lambda: None 797 self.assertEqual(copy.copy(bar), bar) 798 799 def test_deepcopy_function(self): 800 self.assertEqual(copy.deepcopy(global_foo), global_foo) 801 def foo(x, y): return x+y 802 self.assertEqual(copy.deepcopy(foo), foo) 803 bar = lambda: None 804 self.assertEqual(copy.deepcopy(bar), bar) 805 806 def _check_weakref(self, _copy): 807 class C(object): 808 pass 809 obj = C() 810 x = weakref.ref(obj) 811 y = _copy(x) 812 self.assertIs(y, x) 813 del obj 814 y = _copy(x) 815 self.assertIs(y, x) 816 817 def test_copy_weakref(self): 818 self._check_weakref(copy.copy) 819 820 def test_deepcopy_weakref(self): 821 self._check_weakref(copy.deepcopy) 822 823 def _check_copy_weakdict(self, _dicttype): 824 class C(object): 825 pass 826 a, b, c, d = [C() for i in range(4)] 827 u = _dicttype() 828 u[a] = b 829 u[c] = d 830 v = copy.copy(u) 831 self.assertIsNot(v, u) 832 self.assertEqual(v, u) 833 self.assertEqual(v[a], b) 834 self.assertEqual(v[c], d) 835 self.assertEqual(len(v), 2) 836 del c, d 837 support.gc_collect() # For PyPy or other GCs. 838 self.assertEqual(len(v), 1) 839 x, y = C(), C() 840 # The underlying containers are decoupled 841 v[x] = y 842 self.assertNotIn(x, u) 843 844 def test_copy_weakkeydict(self): 845 self._check_copy_weakdict(weakref.WeakKeyDictionary) 846 847 def test_copy_weakvaluedict(self): 848 self._check_copy_weakdict(weakref.WeakValueDictionary) 849 850 def test_deepcopy_weakkeydict(self): 851 class C(object): 852 def __init__(self, i): 853 self.i = i 854 a, b, c, d = [C(i) for i in range(4)] 855 u = weakref.WeakKeyDictionary() 856 u[a] = b 857 u[c] = d 858 # Keys aren't copied, values are 859 v = copy.deepcopy(u) 860 self.assertNotEqual(v, u) 861 self.assertEqual(len(v), 2) 862 self.assertIsNot(v[a], b) 863 self.assertIsNot(v[c], d) 864 self.assertEqual(v[a].i, b.i) 865 self.assertEqual(v[c].i, d.i) 866 del c 867 support.gc_collect() # For PyPy or other GCs. 868 self.assertEqual(len(v), 1) 869 870 def test_deepcopy_weakvaluedict(self): 871 class C(object): 872 def __init__(self, i): 873 self.i = i 874 a, b, c, d = [C(i) for i in range(4)] 875 u = weakref.WeakValueDictionary() 876 u[a] = b 877 u[c] = d 878 # Keys are copied, values aren't 879 v = copy.deepcopy(u) 880 self.assertNotEqual(v, u) 881 self.assertEqual(len(v), 2) 882 (x, y), (z, t) = sorted(v.items(), key=lambda pair: pair[0].i) 883 self.assertIsNot(x, a) 884 self.assertEqual(x.i, a.i) 885 self.assertIs(y, b) 886 self.assertIsNot(z, c) 887 self.assertEqual(z.i, c.i) 888 self.assertIs(t, d) 889 del x, y, z, t 890 del d 891 support.gc_collect() # For PyPy or other GCs. 892 self.assertEqual(len(v), 1) 893 894 def test_deepcopy_bound_method(self): 895 class Foo(object): 896 def m(self): 897 pass 898 f = Foo() 899 f.b = f.m 900 g = copy.deepcopy(f) 901 self.assertEqual(g.m, g.b) 902 self.assertIs(g.b.__self__, g) 903 g.b() 904 905 906def global_foo(x, y): return x+y 907 908if __name__ == "__main__": 909 unittest.main() 910