diff -r 858cb1538531 Doc/library/collections.rst --- a/Doc/library/collections.rst Sat Nov 14 15:14:58 2015 -0800 +++ b/Doc/library/collections.rst Sun Nov 15 22:23:25 2015 +0200 @@ -792,6 +792,10 @@ they add the ability to access fields by .. versionchanged:: 3.1 Added support for *rename*. + .. deprecated:: 3.6 + Passing *verbose* and *rename* parameters as positional argument is + deprecated. Use keyword arguments. + .. doctest:: :options: +NORMALIZE_WHITESPACE diff -r 858cb1538531 Lib/collections/__init__.py --- a/Lib/collections/__init__.py Sat Nov 14 15:14:58 2015 -0800 +++ b/Lib/collections/__init__.py Sun Nov 15 22:23:25 2015 +0200 @@ -337,7 +337,7 @@ class {typename}(tuple): {name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}') ''' -def namedtuple(typename, field_names, verbose=False, rename=False): +def _namedtuple(typename, field_names, verbose=False, rename=False): """Returns a new subclass of tuple with named fields. >>> Point = namedtuple('Point', ['x', 'y']) @@ -420,12 +420,22 @@ def namedtuple(typename, field_names, ve # sys._getframe is not defined (Jython for example) or sys._getframe is not # defined for arguments greater than 0 (IronPython). try: - result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__') + result.__module__ = _sys._getframe(2).f_globals.get('__name__', '__main__') except (AttributeError, ValueError): pass return result +def namedtuple(typename, field_names, *args, **kwargs): + if args: + import warnings + warnings.warn("Passing 'verbose' as positional argument is deprecated", + DeprecationWarning, stacklevel=2) + if len(args) > 1: + warnings.warn("Passing 'rename' as positional argument is deprecated", + DeprecationWarning, stacklevel=2) + return _namedtuple(typename, field_names, *args, **kwargs) + ######################################################################## ### Counter diff -r 858cb1538531 Lib/test/test_collections.py --- a/Lib/test/test_collections.py Sat Nov 14 15:14:58 2015 -0800 +++ b/Lib/test/test_collections.py Sun Nov 15 22:23:25 2015 +0200 @@ -421,6 +421,32 @@ class TestNamedTuple(unittest.TestCase): a.w = 5 self.assertEqual(a.__dict__, {'w': 5}) + def test_bad_arguments(self): + with self.assertWarnsRegex(DeprecationWarning, + "Passing 'verbose' as positional argument is deprecated"): + namedtuple('Point', 'x y', False) + with self.assertWarnsRegex(DeprecationWarning, + "Passing 'verbose' as positional argument is deprecated"): + namedtuple('Point', 'x y', False, False) + with self.assertWarnsRegex(DeprecationWarning, + "Passing 'rename' as positional argument is deprecated"): + namedtuple('Point', 'x y', False, False) + + with support.check_warnings(('', DeprecationWarning)), \ + self.assertRaisesRegex(TypeError, + 'takes from 2 to 4 positional arguments but 5 were given'): + namedtuple('Point', 'x y', False, False, False) + with support.check_warnings(('', DeprecationWarning)), \ + self.assertRaisesRegex(TypeError, + "got multiple values for argument 'verbose'"): + namedtuple('Point', 'x y', False, False, verbose=False) + with support.check_warnings(('', DeprecationWarning)), \ + self.assertRaisesRegex(TypeError, + "got multiple values for argument 'rename'"): + namedtuple('Point', 'x y', False, False, rename=False) + with self.assertRaisesRegex(TypeError, + "got an unexpected keyword argument 'spam'"): + namedtuple('Point', 'x y', spam=False) ################################################################################ ### Abstract Base Classes