summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Levkivskyi <levkivskyi@gmail.com>2018-05-11 03:15:14 (GMT)
committerGitHub <noreply@github.com>2018-05-11 03:15:14 (GMT)
commit308dbe03887a60a192860bc533af15e7520169a6 (patch)
tree70a2ed099408f8301506b2f598c51291e016eba0
parent7488c79b600cd173b0ccea13adb567d078e7b835 (diff)
downloadcpython-308dbe03887a60a192860bc533af15e7520169a6.zip
cpython-308dbe03887a60a192860bc533af15e7520169a6.tar.gz
cpython-308dbe03887a60a192860bc533af15e7520169a6.tar.bz2
Backport recent typing updates (GH-6759)
-rw-r--r--Lib/test/test_typing.py70
-rw-r--r--Lib/typing.py13
-rw-r--r--Misc/NEWS.d/next/Library/2018-05-10-14-51-19.bpo-28556.y3zK6I.rst3
3 files changed, 84 insertions, 2 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index fe5247c..4843d6f 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -1310,6 +1310,74 @@ 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
+
+ with self.assertRaises(TypeError):
+ A('foo')
+
+ 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):
@@ -1739,6 +1807,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 b5564cc..f2b6aaf 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -1181,10 +1181,18 @@ def _generic_new(base_cls, cls, *args, **kwds):
# Assure type is erased on instantiation,
# but attempt to store it in __orig_class__
if cls.__origin__ is None:
- return base_cls.__new__(cls)
+ if (base_cls.__new__ is object.__new__ and
+ cls.__init__ is not object.__init__):
+ return base_cls.__new__(cls)
+ else:
+ return base_cls.__new__(cls, *args, **kwds)
else:
origin = cls._gorg
- obj = base_cls.__new__(origin)
+ if (base_cls.__new__ is object.__new__ and
+ cls.__init__ is not object.__init__):
+ obj = base_cls.__new__(origin)
+ else:
+ obj = base_cls.__new__(origin, *args, **kwds)
try:
obj.__orig_class__ = cls
except AttributeError:
@@ -2146,6 +2154,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-10-14-51-19.bpo-28556.y3zK6I.rst b/Misc/NEWS.d/next/Library/2018-05-10-14-51-19.bpo-28556.y3zK6I.rst
new file mode 100644
index 0000000..8ed4658
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-05-10-14-51-19.bpo-28556.y3zK6I.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.