-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Expand file tree
/
Copy pathcheck-unsafe-datetime.test
More file actions
143 lines (116 loc) · 4.43 KB
/
Copy pathcheck-unsafe-datetime.test
File metadata and controls
143 lines (116 loc) · 4.43 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
134
135
136
137
138
139
140
141
142
143
[case testUnsafeDatetime]
# flags: --show-error-codes --python-version 3.10
from datetime import date, datetime, timedelta
from typing import NewType, TypeVar
d: date
dt: datetime
if dt < d: # E: Unsupported operand types for < ("datetime" and "date") [operator]
pass
if d > dt: # E: Unsupported operand types for > ("date" and "datetime") [operator]
pass
if dt <= d: # E: Unsupported operand types for <= ("datetime" and "date") [operator]
pass
if d >= dt: # E: Unsupported operand types for >= ("date" and "datetime") [operator]
pass
d - dt # E: Unsupported operand types for - ("date" and "datetime") [operator]
# Equality and identity do not raise TypeError.
if dt == d:
pass
if d != dt:
pass
if dt is d:
pass
# Do not warn when both operands have the same static type.
d2: date
dt2: datetime
if d < d2:
pass
if dt < dt2:
pass
d - d2
dt - dt2
# Normal subtyping is preserved.
d = datetime.now()
def accept_date(value: date) -> None:
pass
accept_date(datetime.now())
# Narrowed optional operands and bounded type variables retain their precise type.
optional_dt: datetime | None
if optional_dt is not None and optional_dt < d2: # E: Unsupported operand types for < ("datetime" and "date") [operator]
pass
DT = TypeVar("DT", bound=datetime)
def compare(value: DT, other: date) -> bool:
return value < other # E: Unsupported operand types for < ("DT" and "date") [operator]
# Descendants with inherited date and datetime behavior are unsafe as well.
class DateSubclass(date):
pass
class DatetimeSubclass(datetime):
pass
sub_d: DateSubclass
sub_dt: DatetimeSubclass
# Before Python 3.13, a date subclass on the left is compared by date only.
sub_d < sub_dt
sub_dt < sub_d # E: Unsupported operand types for < ("DatetimeSubclass" and "DateSubclass") [operator]
sub_d - sub_dt # E: Unsupported operand types for - ("DateSubclass" and "DatetimeSubclass") [operator]
DateNewType = NewType("DateNewType", date)
DatetimeNewType = NewType("DatetimeNewType", datetime)
new_d: DateNewType
new_dt: DatetimeNewType
new_d < new_dt # E: Unsupported operand types for < ("DateNewType" and "DatetimeNewType") [operator]
new_d - new_dt # E: Unsupported operand types for - ("DateNewType" and "DatetimeNewType") [operator]
# Descendants from the same side of the date/datetime boundary are safe.
sub_d2: DateSubclass
sub_dt2: DatetimeSubclass
sub_d < sub_d2
sub_dt < sub_dt2
new_d < new_d
new_dt < new_dt
# Do not warn when a descendant overrides an operator to support mixed operands.
class ComparableDate(date):
def __lt__(self, other: date) -> bool: ...
def __sub__(self, other: date) -> timedelta: ...
class ComparableDatetime(datetime):
def __gt__(self, other: date) -> bool: ... # type: ignore[override]
comparable_d: ComparableDate
comparable_dt: ComparableDatetime
comparable_d < sub_dt
sub_d < comparable_dt
comparable_d - sub_dt
[builtins fixtures/classmethod.pyi]
[file datetime.pyi]
class timedelta: ...
class date:
@classmethod
def today(cls) -> date: ...
def __lt__(self, other: date) -> bool: ...
def __le__(self, other: date) -> bool: ...
def __gt__(self, other: date) -> bool: ...
def __ge__(self, other: date) -> bool: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __sub__(self, other: date) -> timedelta: ...
class datetime(date):
@classmethod
def now(cls) -> datetime: ...
def __lt__(self, other: datetime) -> bool: ... # type: ignore[override]
def __le__(self, other: datetime) -> bool: ... # type: ignore[override]
def __gt__(self, other: datetime) -> bool: ... # type: ignore[override]
def __ge__(self, other: datetime) -> bool: ... # type: ignore[override]
def __sub__(self, other: datetime) -> timedelta: ... # type: ignore[override]
[case testUnsafeDatetimeSubclassComparisonPython313]
# flags: --show-error-codes --python-version 3.13
from datetime import date, datetime
class DateSubclass(date):
pass
class DatetimeSubclass(datetime):
pass
d: DateSubclass
dt: DatetimeSubclass
d < dt # E: Unsupported operand types for < ("DateSubclass" and "DatetimeSubclass") [operator]
[file datetime.pyi]
class date:
def __lt__(self, other: date) -> bool: ...
def __gt__(self, other: date) -> bool: ...
class datetime(date):
def __lt__(self, other: datetime) -> bool: ... # type: ignore[override]
def __gt__(self, other: datetime) -> bool: ... # type: ignore[override]