mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
gh-133817: remove keyword arguments syntax for NamedTuple
(#133822)
This commit is contained in:
parent
92337f666e
commit
c5e1775825
4 changed files with 32 additions and 116 deletions
|
@ -8080,78 +8080,13 @@ class NamedTupleTests(BaseTestCase):
|
|||
self.assertIs(type(a), Group)
|
||||
self.assertEqual(a, (1, [2]))
|
||||
|
||||
def test_namedtuple_keyword_usage(self):
|
||||
with self.assertWarnsRegex(
|
||||
DeprecationWarning,
|
||||
"Creating NamedTuple classes using keyword arguments is deprecated"
|
||||
):
|
||||
LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int)
|
||||
|
||||
nick = LocalEmployee('Nick', 25)
|
||||
self.assertIsInstance(nick, tuple)
|
||||
self.assertEqual(nick.name, 'Nick')
|
||||
self.assertEqual(LocalEmployee.__name__, 'LocalEmployee')
|
||||
self.assertEqual(LocalEmployee._fields, ('name', 'age'))
|
||||
self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int))
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
"Either list of fields or keywords can be provided to NamedTuple, not both"
|
||||
):
|
||||
NamedTuple('Name', [('x', int)], y=str)
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
"Either list of fields or keywords can be provided to NamedTuple, not both"
|
||||
):
|
||||
NamedTuple('Name', [], y=str)
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
(
|
||||
r"Cannot pass `None` as the 'fields' parameter "
|
||||
r"and also specify fields using keyword arguments"
|
||||
)
|
||||
):
|
||||
NamedTuple('Name', None, x=int)
|
||||
|
||||
def test_namedtuple_special_keyword_names(self):
|
||||
with self.assertWarnsRegex(
|
||||
DeprecationWarning,
|
||||
"Creating NamedTuple classes using keyword arguments is deprecated"
|
||||
):
|
||||
NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list)
|
||||
|
||||
self.assertEqual(NT.__name__, 'NT')
|
||||
self.assertEqual(NT._fields, ('cls', 'self', 'typename', 'fields'))
|
||||
a = NT(cls=str, self=42, typename='foo', fields=[('bar', tuple)])
|
||||
self.assertEqual(a.cls, str)
|
||||
self.assertEqual(a.self, 42)
|
||||
self.assertEqual(a.typename, 'foo')
|
||||
self.assertEqual(a.fields, [('bar', tuple)])
|
||||
|
||||
def test_empty_namedtuple(self):
|
||||
expected_warning = re.escape(
|
||||
"Failing to pass a value for the 'fields' parameter is deprecated "
|
||||
"and will be disallowed in Python 3.15. "
|
||||
"To create a NamedTuple class with 0 fields "
|
||||
"using the functional syntax, "
|
||||
"pass an empty list, e.g. `NT1 = NamedTuple('NT1', [])`."
|
||||
)
|
||||
with self.assertWarnsRegex(DeprecationWarning, fr"^{expected_warning}$"):
|
||||
NT1 = NamedTuple('NT1')
|
||||
with self.assertRaisesRegex(TypeError, "missing.*required.*argument"):
|
||||
BAD = NamedTuple('BAD')
|
||||
|
||||
expected_warning = re.escape(
|
||||
"Passing `None` as the 'fields' parameter is deprecated "
|
||||
"and will be disallowed in Python 3.15. "
|
||||
"To create a NamedTuple class with 0 fields "
|
||||
"using the functional syntax, "
|
||||
"pass an empty list, e.g. `NT2 = NamedTuple('NT2', [])`."
|
||||
)
|
||||
with self.assertWarnsRegex(DeprecationWarning, fr"^{expected_warning}$"):
|
||||
NT2 = NamedTuple('NT2', None)
|
||||
|
||||
NT3 = NamedTuple('NT2', [])
|
||||
NT1 = NamedTuple('NT1', {})
|
||||
NT2 = NamedTuple('NT2', ())
|
||||
NT3 = NamedTuple('NT3', [])
|
||||
|
||||
class CNT(NamedTuple):
|
||||
pass # empty body
|
||||
|
@ -8166,16 +8101,18 @@ class NamedTupleTests(BaseTestCase):
|
|||
def test_namedtuple_errors(self):
|
||||
with self.assertRaises(TypeError):
|
||||
NamedTuple.__new__()
|
||||
with self.assertRaisesRegex(TypeError, "object is not iterable"):
|
||||
NamedTuple('Name', None)
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
"missing 1 required positional argument"
|
||||
"missing 2 required positional arguments"
|
||||
):
|
||||
NamedTuple()
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
"takes from 1 to 2 positional arguments but 3 were given"
|
||||
"takes 2 positional arguments but 3 were given"
|
||||
):
|
||||
NamedTuple('Emp', [('name', str)], None)
|
||||
|
||||
|
@ -8187,10 +8124,22 @@ class NamedTupleTests(BaseTestCase):
|
|||
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
"missing 1 required positional argument: 'typename'"
|
||||
"got some positional-only arguments passed as keyword arguments"
|
||||
):
|
||||
NamedTuple(typename='Emp', name=str, id=int)
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
"got an unexpected keyword argument"
|
||||
):
|
||||
NamedTuple('Name', [('x', int)], y=str)
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
"got an unexpected keyword argument"
|
||||
):
|
||||
NamedTuple('Name', [], y=str)
|
||||
|
||||
def test_copy_and_pickle(self):
|
||||
global Emp # pickle wants to reference the class by name
|
||||
Emp = NamedTuple('Emp', [('name', str), ('cool', int)])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue