-
Notifications
You must be signed in to change notification settings - Fork 297
Expand file tree
/
Copy pathnamedtuples_define_class.py
More file actions
133 lines (85 loc) · 2.83 KB
/
namedtuples_define_class.py
File metadata and controls
133 lines (85 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"""
Tests NamedTuple definitions using the class syntax.
"""
# Specification: https://typing.readthedocs.io/en/latest/spec/namedtuples.html#defining-named-tuples
# > Type checkers should support the class syntax
from typing import Generic, NamedTuple, TypeVar, assert_type
class Point(NamedTuple):
x: int
y: int
units: str = "meters"
# > Type checkers should synthesize a ``__new__`` method based on
# > the named tuple fields.
p1 = Point(1, 2)
assert_type(p1, Point)
assert_type(p1[0], int)
assert_type(p1[1], int)
assert_type(p1[2], str)
assert_type(p1[-1], str)
assert_type(p1[-2], int)
assert_type(p1[-3], int)
assert_type(p1[0:2], tuple[int, int])
assert_type(p1[0:], tuple[int, int, str])
print(p1[3]) # E
print(p1[-4]) # E
p2 = Point(1, 2, "")
assert_type(p2, Point)
p3 = Point(x=1, y=2)
assert_type(p3, Point)
p4 = Point(x=1, y=2, units="")
assert_type(p4, Point)
p5 = Point(1) # E
p6 = Point(x=1) # E
p7 = Point(1, "") # E
p8 = Point(1, 2, units=3) # E
p9 = Point(1, 2, "", "") # E
p10 = Point(1, 2, "", other="") # E
# > Fields must be annotated attributes - methods and un-annotated attributes are not
# > considered fields.
class Point2(NamedTuple):
x: int
y: int
units = "meters" # Not a field
def is_origin(self) -> int: # Not a field
return self.x == 0 and self.y == 0
p11 = Point2(1, 2)
assert_type(p11, Point2)
x, y = p11
p12 = Point2(1, 2, "") # E
# > Field names may not start with an underscore.
class Point3(NamedTuple):
x: int
_y: int # E: illegal field name
# > The runtime implementation of ``NamedTuple`` enforces that fields with default
# > values must come after fields without default values. Type checkers should
# > likewise enforce this restriction::
class Location(NamedTuple):
altitude: float = 0.0
latitude: float # E: previous field has a default value
# > A named tuple class can be subclassed, but any fields added by the subclass
# > are not considered part of the named tuple type. Type checkers should enforce
# > that these newly-added fields do not conflict with the named tuple fields
# > in the base class.
class PointWithName(Point):
name: str = "" # OK
pn1 = PointWithName(1, 2, "")
pnt1: tuple[int, int, str] = pn1
assert_type(pn1.name, str)
class BadPointWithName(Point):
name: str = "" # OK
x: int = 0 # E
# > In Python 3.11 and newer, the class syntax supports generic named tuple classes.
# > Type checkers should support this.
T = TypeVar("T")
class Property(NamedTuple, Generic[T]):
name: str
value: T
pr1 = Property("", 3.4)
assert_type(pr1, Property[float])
assert_type(pr1[1], float)
assert_type(pr1.value, float)
Property[str]("", 3.1) # E
# > ``NamedTuple`` does not support multiple inheritance. Type checkers should
# > enforce this limitation.
class Unit(NamedTuple, object): # E
name: str