bpo-28556: Minor fixes for typing module (GH-6732)


This also fixes https://bugs.python.org/issue33420
(cherry picked from commit 43d12a6bd82bd09ac189069fe1eb40cdbc10a58c)

Co-authored-by: Ivan Levkivskyi <levkivskyi@gmail.com>
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 390fe60..46bab5e 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -1324,6 +1324,72 @@
         with self.assertRaises(Exception):
             D[T]
 
+    def test_new_with_args(self):
+
+        class A(Generic[T]):
+            pass
+
+        class B:
+            def __new__(cls, arg):
+                # call object
+                obj = super().__new__(cls)
+                obj.arg = arg
+                return obj
+
+        # mro: C, A, Generic, B, object
+        class C(A, B):
+            pass
+
+        c = C('foo')
+        self.assertEqual(c.arg, 'foo')
+
+    def test_new_with_args2(self):
+
+        class A:
+            def __init__(self, arg):
+                self.from_a = arg
+                # call object
+                super().__init__()
+
+        # mro: C, Generic, A, object
+        class C(Generic[T], A):
+            def __init__(self, arg):
+                self.from_c = arg
+                # call Generic
+                super().__init__(arg)
+
+        c = C('foo')
+        self.assertEqual(c.from_a, 'foo')
+        self.assertEqual(c.from_c, 'foo')
+
+    def test_new_no_args(self):
+
+        class A(Generic[T]):
+            pass
+
+        class B:
+            def __new__(cls):
+                # call object
+                obj = super().__new__(cls)
+                obj.from_b = 'b'
+                return obj
+
+        # mro: C, A, Generic, B, object
+        class C(A, B):
+            def __init__(self, arg):
+                self.arg = arg
+
+            def __new__(cls, arg):
+                # call A
+                obj = super().__new__(cls)
+                obj.from_c = 'c'
+                return obj
+
+        c = C('foo')
+        self.assertEqual(c.arg, 'foo')
+        self.assertEqual(c.from_b, 'b')
+        self.assertEqual(c.from_c, 'c')
+
 
 class ClassVarTests(BaseTestCase):
 
@@ -1737,6 +1803,8 @@
         self.assertEqual(gth(HasForeignBaseClass),
                          {'some_xrepr': XRepr, 'other_a': mod_generics_cache.A,
                           'some_b': mod_generics_cache.B})
+        self.assertEqual(gth(XRepr.__new__),
+                         {'x': int, 'y': int})
         self.assertEqual(gth(mod_generics_cache.B),
                          {'my_inner_a1': mod_generics_cache.B.A,
                           'my_inner_a2': mod_generics_cache.B.A,
diff --git a/Lib/typing.py b/Lib/typing.py
index 8329607..89b73db 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -607,7 +607,8 @@
 # * __parameters__ is a tuple of unique free type parameters of a generic
 #   type, for example, Dict[T, T].__parameters__ == (T,);
 # * __origin__ keeps a reference to a type that was subscripted,
-#   e.g., Union[T, int].__origin__ == Union;
+#   e.g., Union[T, int].__origin__ == Union, or the non-generic version of
+#   the type.
 # * __args__ is a tuple of all arguments used in subscripting,
 #   e.g., Dict[T, int].__args__ == (T, int).
 
@@ -835,7 +836,11 @@
         if cls is Generic:
             raise TypeError("Type Generic cannot be instantiated; "
                             "it can be used only as a base class")
-        return super().__new__(cls)
+        if super().__new__ is object.__new__:
+            obj = super().__new__(cls)
+        else:
+            obj = super().__new__(cls, *args, **kwds)
+        return obj
 
     @_tp_cache
     def __class_getitem__(cls, params):
@@ -1385,6 +1390,7 @@
                                 "follow default field(s) {default_names}"
                                 .format(field_name=field_name,
                                         default_names=', '.join(defaults_dict.keys())))
+        nm_tpl.__new__.__annotations__ = collections.OrderedDict(types)
         nm_tpl.__new__.__defaults__ = tuple(defaults)
         nm_tpl._field_defaults = defaults_dict
         # update from user namespace without overriding special namedtuple attributes