Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bea9d2f

Browse files
authored
[3.6] bpo-28556: Update to typing: treat subscripted generics as proxies (GH-265) (GH-268)
(cherry picked from commit abb3b8a) (cherry picked from commit 365cb5b)
1 parent f28db60 commit bea9d2f

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

Lib/test/test_typing.py

+35
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,41 @@ class C(B[int]):
674674
c.bar = 'abc'
675675
self.assertEqual(c.__dict__, {'bar': 'abc'})
676676

677+
def test_subscripted_generics_as_proxies(self):
678+
T = TypeVar('T')
679+
class C(Generic[T]):
680+
x = 'def'
681+
self.assertEqual(C[int].x, 'def')
682+
self.assertEqual(C[C[int]].x, 'def')
683+
C[C[int]].x = 'changed'
684+
self.assertEqual(C.x, 'changed')
685+
self.assertEqual(C[str].x, 'changed')
686+
C[List[str]].z = 'new'
687+
self.assertEqual(C.z, 'new')
688+
self.assertEqual(C[Tuple[int]].z, 'new')
689+
690+
self.assertEqual(C().x, 'changed')
691+
self.assertEqual(C[Tuple[str]]().z, 'new')
692+
693+
class D(C[T]):
694+
pass
695+
self.assertEqual(D[int].x, 'changed')
696+
self.assertEqual(D.z, 'new')
697+
D.z = 'from derived z'
698+
D[int].x = 'from derived x'
699+
self.assertEqual(C.x, 'changed')
700+
self.assertEqual(C[int].z, 'new')
701+
self.assertEqual(D.x, 'from derived x')
702+
self.assertEqual(D[str].z, 'from derived z')
703+
704+
def test_abc_registry_kept(self):
705+
T = TypeVar('T')
706+
class C(Generic[T]): ...
707+
C.register(int)
708+
self.assertIsInstance(1, C)
709+
C[int]
710+
self.assertIsInstance(1, C)
711+
677712
def test_false_subclasses(self):
678713
class MyMapping(MutableMapping[str, str]): pass
679714
self.assertNotIsInstance({}, MyMapping)

Lib/typing.py

+10
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,16 @@ def __copy__(self):
11581158
self.__parameters__, self.__args__, self.__origin__,
11591159
self.__extra__, self.__orig_bases__)
11601160

1161+
def __setattr__(self, attr, value):
1162+
# We consider all the subscripted genrics as proxies for original class
1163+
if (
1164+
attr.startswith('__') and attr.endswith('__') or
1165+
attr.startswith('_abc_')
1166+
):
1167+
super(GenericMeta, self).__setattr__(attr, value)
1168+
else:
1169+
super(GenericMeta, _gorg(self)).__setattr__(attr, value)
1170+
11611171

11621172
# Prevent checks for Generic to crash when defining Generic.
11631173
Generic = None

0 commit comments

Comments
 (0)