diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2019-09-17 19:41:55 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-17 19:41:55 (GMT) |
commit | 8fc5839a9def34c13b6025c291434ba5fb5d6442 (patch) | |
tree | 8a60e3596333f581d1384a8205c08454c45f4e88 | |
parent | 2bf31ccab3d17f3f35b42dca97f99576dfe2fc7d (diff) | |
download | cpython-8fc5839a9def34c13b6025c291434ba5fb5d6442.zip cpython-8fc5839a9def34c13b6025c291434ba5fb5d6442.tar.gz cpython-8fc5839a9def34c13b6025c291434ba5fb5d6442.tar.bz2 |
bpo-38191: Turn warnings into errors in NamedTuple() and TypedDict(). (GH-16238)
-rw-r--r-- | Lib/test/test_typing.py | 27 | ||||
-rw-r--r-- | Lib/typing.py | 70 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2019-09-17-12-28-27.bpo-38191.1TU0HV.rst | 3 |
3 files changed, 13 insertions, 87 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 5914f31..97e6d88 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -3582,16 +3582,10 @@ class XMethBad2(NamedTuple): 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 @@ class TypedDictTests(BaseTestCase): 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 43486a7..b1ac33e 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1653,81 +1653,20 @@ class NamedTuple(metaclass=NamedTupleMeta): """ _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 1a6de60..05c7daa 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". |