2Tests NamedTuple definitions using the functional syntax.
5from collections import namedtuple
6from typing import NamedTuple
8# Specification: https://typing.readthedocs.io/en/latest/spec/namedtuples.html#defining-named-tuples
10# > A type checker may support the function syntax in its various forms::
13Point1 = namedtuple("Point1", ["x", "y"])
14p1_1 = Point1(x=1, y=1)
[missing-argument] No argument provided for required parameter `y`
18Point2 = namedtuple("Point2", ("x", "y"))
19p2_1 = Point2(x=1, y=1)
[missing-argument] No arguments provided for required parameters `x`, `y`
23Point3 = namedtuple("Point3", "x y")
24p3_1 = Point3(x=1, y=1)
26p3_3 = Point3(1, 2, 3) # E
[too-many-positional-arguments] Too many positional arguments: expected 3, got 4
28Point4 = namedtuple("Point4", "x, y")
29p4_1 = Point4(x=1, y=1)
31p4_3 = Point4(1, z=3) # E
[missing-argument] No argument provided for required parameter `y`
[unknown-argument] Argument `z` does not match any known parameter
33Point5 = NamedTuple("Point5", [("x", int), ("y", int)])
34p5_1 = Point5(x=1, y=1)
36p5_3 = Point5(2, "1") # E
[invalid-argument-type] Argument is incorrect: Expected `int`, found `Literal["1"]`
37p5_4 = Point5(1, 2, 3) # E
[too-many-positional-arguments] Too many positional arguments: expected 3, got 4
39Point6 = NamedTuple("Point6", (("x", int), ("y", int)))
40p6_1 = Point6(x=1, y=1)
42p6_3 = Point6(2, "1") # E
[invalid-argument-type] Argument is incorrect: Expected `int`, found `Literal["1"]`
43p6_4 = Point6(x=1.1, y=2) # E
[invalid-argument-type] Argument is incorrect: Expected `int`, found `float`
46# > At runtime, the ``namedtuple`` function disallows field names that begin with
47# > an underscore or are illegal Python identifiers, and either raises an exception
48# > or replaces these fields with a parameter name of the form ``_N``. The behavior
49# > depends on the value of the ``rename`` argument. Type checkers may replicate
50# > this behavior statically.
52NT1 = namedtuple("NT1", ["a", "a"]) # E?: duplicate field name
[invalid-named-tuple] Duplicate field name `a` in `namedtuple()`: Field `a` already defined; will raise `ValueError` at runtime
53NT2 = namedtuple("NT2", ["abc", "def"]) # E?: illegal field name
[invalid-named-tuple] Field name `def` in `namedtuple()` cannot be a Python keyword: Will raise `ValueError` at runtime
54NT3 = namedtuple("NT3", ["abc", "def"], rename=False) # E?: illegal field name
[invalid-named-tuple] Field name `def` in `namedtuple()` cannot be a Python keyword: Will raise `ValueError` at runtime
55NT4 = namedtuple("NT4", ["abc", "_d"], rename=False) # E?: illegal field name
[invalid-named-tuple] Field name `_d` in `namedtuple()` cannot start with an underscore: Will raise `ValueError` at runtime
57NT5 = namedtuple("NT5", ["abc", "def"], rename=True) # OK
58NT5(abc="", _1="") # OK
59NT6 = namedtuple("NT6", ["abc", "_d"], rename=True) # OK
60NT6(abc="", _1="") # OK
63# > The ``namedtuple`` function also supports a ``defaults`` keyword argument that
64# > specifies default values for the fields. Type checkers may support this.
66NT7 = namedtuple("NT7", "a b c", defaults=(1, 2))
69NT7() # E: too few arguments
[missing-argument] No argument provided for required parameter `a`