]> granicus.if.org Git - python/commitdiff
Update to typing: treat subscripted generics as proxies (#265)
authorIvan Levkivskyi <levkivskyi@gmail.com>
Fri, 24 Feb 2017 03:03:28 +0000 (04:03 +0100)
committerMariatta <Mariatta@users.noreply.github.com>
Fri, 24 Feb 2017 03:03:28 +0000 (19:03 -0800)
Lib/test/test_typing.py
Lib/typing.py

index 64d8276658ee7f9783c0bde3e956f83b78c25d09..3a82b595da5950aaf25c4a32d94578f8b55f1a5d 100644 (file)
@@ -674,6 +674,33 @@ class GenericTests(BaseTestCase):
         c.bar = 'abc'
         self.assertEqual(c.__dict__, {'bar': 'abc'})
 
+    def test_subscripted_generics_as_proxies(self):
+        T = TypeVar('T')
+        class C(Generic[T]):
+            x = 'def'
+        self.assertEqual(C[int].x, 'def')
+        self.assertEqual(C[C[int]].x, 'def')
+        C[C[int]].x = 'changed'
+        self.assertEqual(C.x, 'changed')
+        self.assertEqual(C[str].x, 'changed')
+        C[List[str]].z = 'new'
+        self.assertEqual(C.z, 'new')
+        self.assertEqual(C[Tuple[int]].z, 'new')
+
+        self.assertEqual(C().x, 'changed')
+        self.assertEqual(C[Tuple[str]]().z, 'new')
+
+        class D(C[T]):
+            pass
+        self.assertEqual(D[int].x, 'changed')
+        self.assertEqual(D.z, 'new')
+        D.z = 'from derived z'
+        D[int].x = 'from derived x'
+        self.assertEqual(C.x, 'changed')
+        self.assertEqual(C[int].z, 'new')
+        self.assertEqual(D.x, 'from derived x')
+        self.assertEqual(D[str].z, 'from derived z')
+
     def test_false_subclasses(self):
         class MyMapping(MutableMapping[str, str]): pass
         self.assertNotIsInstance({}, MyMapping)
index efe358faf20988b0e2e3a315b7447b14d81c7109..fc2ed94cffd656306c2ede82710d3580fa4cf088 100644 (file)
@@ -1158,6 +1158,13 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
                               self.__parameters__, self.__args__, self.__origin__,
                               self.__extra__, self.__orig_bases__)
 
+    def __setattr__(self, attr, value):
+        # We consider all the subscripted genrics as proxies for original class
+        if attr.startswith('__') and attr.endswith('__'):
+            super(GenericMeta, self).__setattr__(attr, value)
+        else:
+            super(GenericMeta, _gorg(self)).__setattr__(attr, value)
+
 
 # Prevent checks for Generic to crash when defining Generic.
 Generic = None