2Tests NamedTuple definitions using the class syntax.
5# Specification: https://typing.readthedocs.io/en/latest/spec/namedtuples.html#defining-named-tuples
7# > Type checkers should support the class syntax
9from typing import Generic, NamedTuple, TypeVar, assert_type
12class Point(NamedTuple):
18# > Type checkers should synthesize a ``__new__`` method based on
19# > the named tuple fields.
23assert_type(p1[0], int)
24assert_type(p1[1], int)
25assert_type(p1[2], str)
26assert_type(p1[-1], str)
27assert_type(p1[-2], int)
28assert_type(p1[-3], int)
29assert_type(p1[0:2], tuple[int, int])
30assert_type(p1[0:], tuple[int, int, str])
[index-out-of-bounds] Index 3 is out of bounds for tuple `Point` with length 3
[index-out-of-bounds] Index -4 is out of bounds for tuple `Point` with length 3
41p4 = Point(x=1, y=2, units="")
[missing-argument] No argument provided for required parameter `y`
[missing-argument] No argument provided for required parameter `y`
[invalid-argument-type] Argument is incorrect: Expected `int`, found `Literal[""]`
47p8 = Point(1, 2, units=3) # E
[invalid-argument-type] Argument is incorrect: Expected `str`, found `Literal[3]`
48p9 = Point(1, 2, "", "") # E
[too-many-positional-arguments] Too many positional arguments: expected 4, got 5
49p10 = Point(1, 2, "", other="") # E
[unknown-argument] Argument `other` does not match any known parameter
52# > Fields must be annotated attributes - methods and un-annotated attributes are not
56class Point2(NamedTuple):
59 units = "meters" # Not a field
61 def is_origin(self) -> int: # Not a field
62 return self.x == 0 and self.y == 0
66assert_type(p11, Point2)
69p12 = Point2(1, 2, "") # E
[too-many-positional-arguments] Too many positional arguments: expected 3, got 4
72# > Field names may not start with an underscore.
74class Point3(NamedTuple):
76 _y: int # E: illegal field name
[invalid-named-tuple] NamedTuple field `_y` cannot start with an underscore
79# > The runtime implementation of ``NamedTuple`` enforces that fields with default
80# > values must come after fields without default values. Type checkers should
81# > likewise enforce this restriction::
84class Location(NamedTuple):
86 latitude: float # E: previous field has a default value
[invalid-named-tuple] NamedTuple field without default value cannot follow field(s) with default value(s): Field `latitude` defined here without a default value
89# > A named tuple class can be subclassed, but any fields added by the subclass
90# > are not considered part of the named tuple type. Type checkers should enforce
91# > that these newly-added fields do not conflict with the named tuple fields
95class PointWithName(Point):
99pn1 = PointWithName(1, 2, "")
100pnt1: tuple[int, int, str] = pn1
101assert_type(pn1.name, str)
104class BadPointWithName(Point):
Expected a ty diagnostic for this line
109# > In Python 3.11 and newer, the class syntax supports generic named tuple classes.
110# > Type checkers should support this.
115class Property(NamedTuple, Generic[T]):
120pr1 = Property("", 3.4)
121assert_type(pr1, Property[float])
122assert_type(pr1[1], float)
123assert_type(pr1.value, float)
125Property[str]("", 3.1) # E
[invalid-argument-type] Argument is incorrect: Expected `str`, found `float`
128# > ``NamedTuple`` does not support multiple inheritance. Type checkers should
129# > enforce this limitation.
132class Unit(NamedTuple, object): # E
[invalid-named-tuple] NamedTuple class `Unit` cannot use multiple inheritance except with `Generic[]`