bpo-36321: Fix misspelled attribute in namedtuple() (GH-12375) (GH-12395)

(cherry picked from commit 23581c018f)

Co-authored-by: Raymond Hettinger <rhettinger@users.noreply.github.com>
This commit is contained in:
Miss Islington (bot) 2019-03-18 00:48:02 -07:00 committed by Raymond Hettinger
parent 76ff715e03
commit bedfbc790e
4 changed files with 15 additions and 8 deletions

View file

@ -941,14 +941,14 @@ field names, the method and attribute names start with an underscore.
>>> Pixel(11, 22, 128, 255, 0)
Pixel(x=11, y=22, red=128, green=255, blue=0)
.. attribute:: somenamedtuple._fields_defaults
.. attribute:: somenamedtuple._field_defaults
Dictionary mapping field names to default values.
.. doctest::
>>> Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
>>> Account._fields_defaults
>>> Account._field_defaults
{'balance': 0}
>>> Account('premium')
Account(type='premium', balance=0)

View file

@ -443,6 +443,8 @@ def __getnewargs__(self):
'__doc__': f'{typename}({arg_list})',
'__slots__': (),
'_fields': field_names,
'_field_defaults': field_defaults,
# alternate spelling for backward compatiblity
'_fields_defaults': field_defaults,
'__new__': __new__,
'_make': _make,

View file

@ -249,18 +249,18 @@ def test_factory(self):
def test_defaults(self):
Point = namedtuple('Point', 'x y', defaults=(10, 20)) # 2 defaults
self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
self.assertEqual(Point(1, 2), (1, 2))
self.assertEqual(Point(1), (1, 20))
self.assertEqual(Point(), (10, 20))
Point = namedtuple('Point', 'x y', defaults=(20,)) # 1 default
self.assertEqual(Point._fields_defaults, {'y': 20})
self.assertEqual(Point._field_defaults, {'y': 20})
self.assertEqual(Point(1, 2), (1, 2))
self.assertEqual(Point(1), (1, 20))
Point = namedtuple('Point', 'x y', defaults=()) # 0 defaults
self.assertEqual(Point._fields_defaults, {})
self.assertEqual(Point._field_defaults, {})
self.assertEqual(Point(1, 2), (1, 2))
with self.assertRaises(TypeError):
Point(1)
@ -277,21 +277,21 @@ def test_defaults(self):
Point = namedtuple('Point', 'x y', defaults=False)
Point = namedtuple('Point', 'x y', defaults=None) # default is None
self.assertEqual(Point._fields_defaults, {})
self.assertEqual(Point._field_defaults, {})
self.assertIsNone(Point.__new__.__defaults__, None)
self.assertEqual(Point(10, 20), (10, 20))
with self.assertRaises(TypeError): # catch too few args
Point(10)
Point = namedtuple('Point', 'x y', defaults=[10, 20]) # allow non-tuple iterable
self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
self.assertEqual(Point.__new__.__defaults__, (10, 20))
self.assertEqual(Point(1, 2), (1, 2))
self.assertEqual(Point(1), (1, 20))
self.assertEqual(Point(), (10, 20))
Point = namedtuple('Point', 'x y', defaults=iter([10, 20])) # allow plain iterator
self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
self.assertEqual(Point.__new__.__defaults__, (10, 20))
self.assertEqual(Point(1, 2), (1, 2))
self.assertEqual(Point(1), (1, 20))

View file

@ -0,0 +1,5 @@
collections.namedtuple() misspelled the name of an attribute. To be
consistent with typing.NamedTuple, the attribute name should have been
"_field_defaults" instead of "_fields_defaults". For backwards
compatibility, both spellings are now created. The misspelled version may
be removed in the future.