From 43d12a6bd82bd09ac189069fe1eb40cdbc10a58c Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Wed, 9 May 2018 02:23:46 +0100 Subject: [PATCH] bpo-28556: Minor fixes for typing module (GH-6732) This also fixes https://bugs.python.org/issue33420 --- Lib/test/test_typing.py | 68 +++++++++++++++++++ Lib/typing.py | 10 ++- .../2018-05-08-16-43-42.bpo-28556._xr5mp.rst | 3 + 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 390fe60fcc..46bab5eba6 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1324,6 +1324,72 @@ class GenericTests(BaseTestCase): 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 @@ class GetTypeHintTests(BaseTestCase): 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 83296073b9..89b73db158 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -607,7 +607,8 @@ class TypeVar(_Final, _Immutable, _root=True): # * __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 @@ class Generic: 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 @@ class NamedTupleMeta(type): "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 diff --git a/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst b/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst new file mode 100644 index 0000000000..8ed4658211 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst @@ -0,0 +1,3 @@ +Minor fixes in typing module: add annotations to ``NamedTuple.__new__``, +pass ``*args`` and ``**kwds`` in ``Generic.__new__``. Original PRs by +Paulius Å arka and Chad Dombrova. -- 2.40.0