[Python-checkins] bpo-38191: Turn warnings into errors in NamedTuple() and TypedDict(). (GH-16238)

Serhiy Storchaka webhook-mailer at python.org
Tue Sep 17 15:42:00 EDT 2019


https://github.com/python/cpython/commit/8fc5839a9def34c13b6025c291434ba5fb5d6442
commit: 8fc5839a9def34c13b6025c291434ba5fb5d6442
branch: master
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2019-09-17T22:41:55+03:00
summary:

bpo-38191: Turn warnings into errors in NamedTuple() and TypedDict(). (GH-16238)

files:
M Lib/test/test_typing.py
M Lib/typing.py
M Misc/NEWS.d/next/Library/2019-09-17-12-28-27.bpo-38191.1TU0HV.rst

diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 5914f314db0a..97e6d88ebf70 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -3582,16 +3582,10 @@ def test_namedtuple_errors(self):
             NamedTuple('Emp', [('name', str)], None)
         with self.assertRaises(ValueError):
             NamedTuple('Emp', [('_name', str)])
-
-        with self.assertWarns(DeprecationWarning):
-            Emp = NamedTuple(typename='Emp', name=str, id=int)
-        self.assertEqual(Emp.__name__, 'Emp')
-        self.assertEqual(Emp._fields, ('name', 'id'))
-
-        with self.assertWarns(DeprecationWarning):
-            Emp = NamedTuple('Emp', fields=[('name', str), ('id', int)])
-        self.assertEqual(Emp.__name__, 'Emp')
-        self.assertEqual(Emp._fields, ('name', 'id'))
+        with self.assertRaises(TypeError):
+            NamedTuple(typename='Emp', name=str, id=int)
+        with self.assertRaises(TypeError):
+            NamedTuple('Emp', fields=[('name', str), ('id', int)])
 
     def test_pickle(self):
         global Emp  # pickle wants to reference the class by name
@@ -3654,15 +3648,10 @@ def test_typeddict_create_errors(self):
         with self.assertRaises(TypeError):
             TypedDict('Emp', [('name', str)], None)
 
-        with self.assertWarns(DeprecationWarning):
-            Emp = TypedDict(_typename='Emp', name=str, id=int)
-        self.assertEqual(Emp.__name__, 'Emp')
-        self.assertEqual(Emp.__annotations__, {'name': str, 'id': int})
-
-        with self.assertWarns(DeprecationWarning):
-            Emp = TypedDict('Emp', _fields={'name': str, 'id': int})
-        self.assertEqual(Emp.__name__, 'Emp')
-        self.assertEqual(Emp.__annotations__, {'name': str, 'id': int})
+        with self.assertRaises(TypeError):
+            TypedDict(_typename='Emp', name=str, id=int)
+        with self.assertRaises(TypeError):
+            TypedDict('Emp', _fields={'name': str, 'id': int})
 
     def test_typeddict_errors(self):
         Emp = TypedDict('Emp', {'name': str, 'id': int})
diff --git a/Lib/typing.py b/Lib/typing.py
index 43486a7c8ba8..b1ac33e00e70 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -1653,81 +1653,20 @@ class Employee(NamedTuple):
     """
     _root = True
 
-    def __new__(*args, **kwargs):
-        if not args:
-            raise TypeError('NamedTuple.__new__(): not enough arguments')
-        cls, *args = args  # allow the "cls" keyword be passed
-        if args:
-            typename, *args = args # allow the "typename" keyword be passed
-        elif 'typename' in kwargs:
-            typename = kwargs.pop('typename')
-            import warnings
-            warnings.warn("Passing 'typename' as keyword argument is deprecated",
-                          DeprecationWarning, stacklevel=2)
-        else:
-            raise TypeError("NamedTuple.__new__() missing 1 required positional "
-                            "argument: 'typename'")
-        if args:
-            try:
-                fields, = args # allow the "fields" keyword be passed
-            except ValueError:
-                raise TypeError(f'NamedTuple.__new__() takes from 2 to 3 '
-                                f'positional arguments but {len(args) + 2} '
-                                f'were given') from None
-        elif 'fields' in kwargs and len(kwargs) == 1:
-            fields = kwargs.pop('fields')
-            import warnings
-            warnings.warn("Passing 'fields' as keyword argument is deprecated",
-                          DeprecationWarning, stacklevel=2)
-        else:
-            fields = None
-
+    def __new__(cls, typename, fields=None, /, **kwargs):
         if fields is None:
             fields = kwargs.items()
         elif kwargs:
             raise TypeError("Either list of fields or keywords"
                             " can be provided to NamedTuple, not both")
         return _make_nmtuple(typename, fields)
-    __new__.__text_signature__ = '($cls, typename, fields=None, /, **kwargs)'
 
 
-def _dict_new(*args, **kwargs):
-    if not args:
-        raise TypeError('TypedDict.__new__(): not enough arguments')
-    cls, *args = args  # allow the "cls" keyword be passed
+def _dict_new(cls, /, *args, **kwargs):
     return dict(*args, **kwargs)
-_dict_new.__text_signature__ = '($cls, _typename, _fields=None, /, **kwargs)'
-
-
-def _typeddict_new(*args, total=True, **kwargs):
-    if not args:
-        raise TypeError('TypedDict.__new__(): not enough arguments')
-    cls, *args = args  # allow the "cls" keyword be passed
-    if args:
-        typename, *args = args # allow the "_typename" keyword be passed
-    elif '_typename' in kwargs:
-        typename = kwargs.pop('_typename')
-        import warnings
-        warnings.warn("Passing '_typename' as keyword argument is deprecated",
-                      DeprecationWarning, stacklevel=2)
-    else:
-        raise TypeError("TypedDict.__new__() missing 1 required positional "
-                        "argument: '_typename'")
-    if args:
-        try:
-            fields, = args # allow the "_fields" keyword be passed
-        except ValueError:
-            raise TypeError(f'TypedDict.__new__() takes from 2 to 3 '
-                            f'positional arguments but {len(args) + 2} '
-                            f'were given') from None
-    elif '_fields' in kwargs and len(kwargs) == 1:
-        fields = kwargs.pop('_fields')
-        import warnings
-        warnings.warn("Passing '_fields' as keyword argument is deprecated",
-                      DeprecationWarning, stacklevel=2)
-    else:
-        fields = None
 
+
+def _typeddict_new(cls, typename, fields=None, /, *, total=True, **kwargs):
     if fields is None:
         fields = kwargs
     elif kwargs:
@@ -1742,7 +1681,6 @@ def _typeddict_new(*args, total=True, **kwargs):
         pass
 
     return _TypedDictMeta(typename, (), ns)
-_typeddict_new.__text_signature__ = '($cls, _typename, _fields=None, /, *, total=True, **kwargs)'
 
 
 def _check_fails(cls, other):
diff --git a/Misc/NEWS.d/next/Library/2019-09-17-12-28-27.bpo-38191.1TU0HV.rst b/Misc/NEWS.d/next/Library/2019-09-17-12-28-27.bpo-38191.1TU0HV.rst
index 1a6de60e46c1..05c7daaeafbe 100644
--- a/Misc/NEWS.d/next/Library/2019-09-17-12-28-27.bpo-38191.1TU0HV.rst
+++ b/Misc/NEWS.d/next/Library/2019-09-17-12-28-27.bpo-38191.1TU0HV.rst
@@ -1,4 +1,3 @@
 Constructors of :class:`~typing.NamedTuple` and :class:`~typing.TypedDict`
 types now accept arbitrary keyword argument names, including "cls", "self",
-"typename", "_typename", "fields" and "_fields".  Passing positional
-arguments by keyword is deprecated.
+"typename", "_typename", "fields" and "_fields".



More information about the Python-checkins mailing list