|
37 | 37 | from test import mod_generics_cache |
38 | 38 |
|
39 | 39 |
|
| 40 | +PY36 = sys.version_info[:2] >= (3, 6) |
| 41 | + |
| 42 | + |
40 | 43 | class BaseTestCase(TestCase): |
41 | 44 |
|
42 | 45 | def assertIsSubclass(self, cls, class_or_tuple, msg=None): |
@@ -633,6 +636,27 @@ def test_init(self): |
633 | 636 | with self.assertRaises(TypeError): |
634 | 637 | Generic[T, S, T] |
635 | 638 |
|
| 639 | + @skipUnless(PY36, "__init_subclass__ support required") |
| 640 | + def test_init_subclass(self): |
| 641 | + class X(typing.Generic[T]): |
| 642 | + def __init_subclass__(cls, **kwargs): |
| 643 | + super().__init_subclass__(**kwargs) |
| 644 | + cls.attr = 42 |
| 645 | + class Y(X): |
| 646 | + pass |
| 647 | + self.assertEqual(Y.attr, 42) |
| 648 | + with self.assertRaises(AttributeError): |
| 649 | + X.attr |
| 650 | + X.attr = 1 |
| 651 | + Y.attr = 2 |
| 652 | + class Z(Y): |
| 653 | + pass |
| 654 | + class W(X[int]): |
| 655 | + pass |
| 656 | + self.assertEqual(Y.attr, 2) |
| 657 | + self.assertEqual(Z.attr, 42) |
| 658 | + self.assertEqual(W.attr, 42) |
| 659 | + |
636 | 660 | def test_repr(self): |
637 | 661 | self.assertEqual(repr(SimpleMapping), |
638 | 662 | __name__ + '.' + 'SimpleMapping') |
@@ -1080,6 +1104,30 @@ class Node(Generic[T]): ... |
1080 | 1104 | self.assertTrue(t is copy(t)) |
1081 | 1105 | self.assertTrue(t is deepcopy(t)) |
1082 | 1106 |
|
| 1107 | + def test_copy_generic_instances(self): |
| 1108 | + T = TypeVar('T') |
| 1109 | + class C(Generic[T]): |
| 1110 | + def __init__(self, attr: T) -> None: |
| 1111 | + self.attr = attr |
| 1112 | + |
| 1113 | + c = C(42) |
| 1114 | + self.assertEqual(copy(c).attr, 42) |
| 1115 | + self.assertEqual(deepcopy(c).attr, 42) |
| 1116 | + self.assertIsNot(copy(c), c) |
| 1117 | + self.assertIsNot(deepcopy(c), c) |
| 1118 | + c.attr = 1 |
| 1119 | + self.assertEqual(copy(c).attr, 1) |
| 1120 | + self.assertEqual(deepcopy(c).attr, 1) |
| 1121 | + ci = C[int](42) |
| 1122 | + self.assertEqual(copy(ci).attr, 42) |
| 1123 | + self.assertEqual(deepcopy(ci).attr, 42) |
| 1124 | + self.assertIsNot(copy(ci), ci) |
| 1125 | + self.assertIsNot(deepcopy(ci), ci) |
| 1126 | + ci.attr = 1 |
| 1127 | + self.assertEqual(copy(ci).attr, 1) |
| 1128 | + self.assertEqual(deepcopy(ci).attr, 1) |
| 1129 | + self.assertEqual(ci.__orig_class__, C[int]) |
| 1130 | + |
1083 | 1131 | def test_weakref_all(self): |
1084 | 1132 | T = TypeVar('T') |
1085 | 1133 | things = [Any, Union[T, int], Callable[..., T], Tuple[Any, Any], |
@@ -1580,8 +1628,6 @@ async def __aexit__(self, etype, eval, tb): |
1580 | 1628 | asyncio = None |
1581 | 1629 | AwaitableWrapper = AsyncIteratorWrapper = ACM = object |
1582 | 1630 |
|
1583 | | -PY36 = sys.version_info[:2] >= (3, 6) |
1584 | | - |
1585 | 1631 | PY36_TESTS = """ |
1586 | 1632 | from test import ann_module, ann_module2, ann_module3 |
1587 | 1633 | from typing import AsyncContextManager |
|
0 commit comments