Skip to content

Commit 5099a1a

Browse files
authored
Type NAType (#1348)
* wip * maybe fix the overloads * wip tests * fixup test * appease mypy * wip * fixup * fixup * remove ndarray overloads as they dont really make sense for a nullable-only object * fixup * fixup * fixup * mypy fixup * remove `__bool__`, and comparisons (eq/ne/gt/lt/...) with `Series`/`Index` as they return `NotImplemented` * remove redundant annotation * comment cases which require other fixes * note pyright bug * update pyright * keep divmod(na, 1), ignore pyright, link to issue * uncomment some parts * remove more outdated commented-out tests * linting
1 parent 2106e8b commit 5099a1a

File tree

3 files changed

+423
-38
lines changed

3 files changed

+423
-38
lines changed

pandas-stubs/_libs/missing.pyi

Lines changed: 234 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,243 @@
1+
from typing import (
2+
Any,
3+
Callable,
4+
Literal,
5+
overload,
6+
)
7+
8+
from pandas import (
9+
Index,
10+
Series,
11+
)
12+
from pandas.core.arrays.boolean import BooleanArray
113
from typing_extensions import Self
214

315
class NAType:
4-
def __new__(cls, *args, **kwargs) -> Self: ...
16+
def __new__(cls, *args: Any, **kwargs: Any) -> Self: ...
517
def __format__(self, format_spec: str) -> str: ...
6-
def __bool__(self) -> None: ...
718
def __hash__(self) -> int: ...
819
def __reduce__(self) -> str: ...
9-
def __add__(self, other) -> NAType: ...
10-
def __radd__(self, other) -> NAType: ...
11-
def __sub__(self, other) -> NAType: ...
12-
def __rsub__(self, other) -> NAType: ...
13-
def __mul__(self, other) -> NAType: ...
14-
def __rmul__(self, other) -> NAType: ...
15-
def __matmul__(self, other) -> NAType: ...
16-
def __rmatmul__(self, other) -> NAType: ...
17-
def __truediv__(self, other) -> NAType: ...
18-
def __rtruediv__(self, other) -> NAType: ...
19-
def __floordiv__(self, other) -> NAType: ...
20-
def __rfloordiv__(self, other) -> NAType: ...
21-
def __mod__(self, other) -> NAType: ...
22-
def __rmod__(self, other) -> NAType: ...
23-
def __divmod__(self, other) -> NAType: ...
24-
def __rdivmod__(self, other) -> NAType: ...
25-
def __eq__(self, other) -> bool: ...
26-
def __ne__(self, other) -> bool: ...
27-
def __le__(self, other) -> bool: ...
28-
def __lt__(self, other) -> bool: ...
29-
def __gt__(self, other) -> bool: ...
30-
def __ge__(self, other) -> bool: ...
31-
def __neg__(self, other) -> NAType: ...
32-
def __pos__(self, other) -> NAType: ...
33-
def __abs__(self, other) -> NAType: ...
34-
def __invert__(self, other) -> NAType: ...
35-
def __pow__(self, other) -> NAType: ...
36-
def __rpow__(self, other) -> NAType: ...
37-
def __and__(self, other) -> NAType | None: ...
38-
__rand__ = __and__
39-
def __or__(self, other) -> bool | NAType: ...
40-
__ror__ = __or__
41-
def __xor__(self, other) -> NAType: ...
42-
__rxor__ = __xor__
20+
@overload
21+
def __add__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
22+
self, other: Series, /
23+
) -> Series: ...
24+
@overload
25+
def __add__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
26+
@overload
27+
def __add__(self, other: object, /) -> NAType: ...
28+
@overload
29+
def __radd__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
30+
self, other: Series, /
31+
) -> Series: ...
32+
@overload
33+
def __radd__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
34+
@overload
35+
def __radd__(self, other: object, /) -> NAType: ...
36+
@overload
37+
def __sub__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
38+
self, other: Series, /
39+
) -> Series: ...
40+
@overload
41+
def __sub__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
42+
@overload
43+
def __sub__(self, other: object, /) -> NAType: ...
44+
@overload
45+
def __rsub__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
46+
self, other: Series, /
47+
) -> Series: ...
48+
@overload
49+
def __rsub__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
50+
@overload
51+
def __rsub__(self, other: object, /) -> NAType: ...
52+
@overload
53+
def __mul__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
54+
self, other: Series, /
55+
) -> Series: ...
56+
@overload
57+
def __mul__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
58+
@overload
59+
def __mul__(self, other: object, /) -> NAType: ...
60+
@overload
61+
def __rmul__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
62+
self, other: Series, /
63+
) -> Series: ...
64+
@overload
65+
def __rmul__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
66+
@overload
67+
def __rmul__(self, other: object, /) -> NAType: ...
68+
def __matmul__(self, other: object, /) -> NAType: ...
69+
def __rmatmul__(self, other: object, /) -> NAType: ...
70+
@overload
71+
def __truediv__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
72+
self, other: Series, /
73+
) -> Series: ...
74+
@overload
75+
def __truediv__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
76+
@overload
77+
def __truediv__(self, other: object, /) -> NAType: ...
78+
@overload
79+
def __rtruediv__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
80+
self, other: Series, /
81+
) -> Series: ...
82+
@overload
83+
def __rtruediv__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
84+
@overload
85+
def __rtruediv__(self, other: object, /) -> NAType: ...
86+
@overload
87+
def __floordiv__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
88+
self, other: Series, /
89+
) -> Series: ...
90+
@overload
91+
def __floordiv__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
92+
@overload
93+
def __floordiv__(self, other: object, /) -> NAType: ...
94+
@overload
95+
def __rfloordiv__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
96+
self, other: Series, /
97+
) -> Series: ...
98+
@overload
99+
def __rfloordiv__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
100+
@overload
101+
def __rfloordiv__(self, other: object, /) -> NAType: ...
102+
@overload
103+
def __mod__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
104+
self, other: Series, /
105+
) -> Series: ...
106+
@overload
107+
def __mod__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
108+
@overload
109+
def __mod__(self, other: object, /) -> NAType: ...
110+
@overload
111+
def __rmod__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
112+
self, other: Series, /
113+
) -> Series: ...
114+
@overload
115+
def __rmod__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
116+
@overload
117+
def __rmod__(self, other: object, /) -> NAType: ...
118+
@overload
119+
def __divmod__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
120+
self, other: Series, /
121+
) -> tuple[Series, Series]: ...
122+
@overload
123+
def __divmod__(self, other: Index, /) -> tuple[Index, Index]: ... # type: ignore[overload-overlap]
124+
@overload
125+
def __divmod__(self, other: object, /) -> tuple[NAType, NAType]: ...
126+
@overload
127+
def __rdivmod__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
128+
self, other: Series, /
129+
) -> tuple[Series, Series]: ...
130+
@overload
131+
def __rdivmod__(self, other: Index, /) -> tuple[Index, Index]: ... # type: ignore[overload-overlap]
132+
@overload
133+
def __rdivmod__(self, other: object, /) -> tuple[NAType, NAType]: ...
134+
@overload # type: ignore[override]
135+
def __eq__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
136+
self, other: Series, /
137+
) -> Series[bool]: ...
138+
@overload
139+
def __eq__(self, other: Index, /) -> BooleanArray: ... # type: ignore[overload-overlap]
140+
@overload
141+
def __eq__( # pyright: ignore[reportIncompatibleMethodOverride]
142+
self, other: object, /
143+
) -> NAType: ...
144+
@overload # type: ignore[override]
145+
def __ne__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
146+
self, other: Series, /
147+
) -> Series[bool]: ...
148+
@overload
149+
def __ne__(self, other: Index, /) -> BooleanArray: ... # type: ignore[overload-overlap]
150+
@overload
151+
def __ne__( # pyright: ignore[reportIncompatibleMethodOverride]
152+
self, other: object, /
153+
) -> NAType: ...
154+
@overload
155+
def __le__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
156+
self, other: Series, /
157+
) -> Series[bool]: ...
158+
@overload
159+
def __le__(self, other: Index, /) -> BooleanArray: ... # type: ignore[overload-overlap]
160+
@overload
161+
def __le__(self, other: object, /) -> NAType: ...
162+
@overload
163+
def __lt__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
164+
self, other: Series, /
165+
) -> Series[bool]: ...
166+
@overload
167+
def __lt__(self, other: Index, /) -> BooleanArray: ... # type: ignore[overload-overlap]
168+
@overload
169+
def __lt__(self, other: object, /) -> NAType: ...
170+
@overload
171+
def __gt__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
172+
self, other: Series, /
173+
) -> Series[bool]: ...
174+
@overload
175+
def __gt__(self, other: Index, /) -> BooleanArray: ... # type: ignore[overload-overlap]
176+
@overload
177+
def __gt__(self, other: object, /) -> NAType: ...
178+
@overload
179+
def __ge__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
180+
self, other: Series, /
181+
) -> Series[bool]: ...
182+
@overload
183+
def __ge__(self, other: Index, /) -> BooleanArray: ... # type: ignore[overload-overlap]
184+
@overload
185+
def __ge__(self, other: object, /) -> NAType: ...
186+
def __neg__(self) -> NAType: ...
187+
def __pos__(self) -> NAType: ...
188+
def __abs__(self) -> NAType: ...
189+
def __invert__(self) -> NAType: ...
190+
@overload
191+
def __pow__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
192+
self, other: Series, /
193+
) -> Series: ...
194+
@overload
195+
def __pow__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
196+
@overload
197+
def __pow__(self, other: object, /) -> NAType: ...
198+
@overload
199+
def __rpow__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
200+
self, other: Series, /
201+
) -> Series: ...
202+
@overload
203+
def __rpow__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
204+
@overload
205+
def __rpow__(self, other: object, /) -> NAType: ...
206+
@overload
207+
def __and__(self, other: Literal[False], /) -> Literal[False]: ... # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
208+
@overload
209+
def __and__(self, other: bool | NAType, /) -> NAType: ...
210+
@overload
211+
def __rand__(self, other: Literal[False], /) -> Literal[False]: ... # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
212+
@overload
213+
def __rand__(self, other: bool, /) -> NAType: ...
214+
@overload
215+
def __or__(self, other: Literal[True], /) -> Literal[True]: ... # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
216+
@overload
217+
def __or__(self, other: bool | NAType, /) -> NAType: ...
218+
@overload
219+
def __ror__(self, other: Literal[True], /) -> Literal[True]: ... # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
220+
@overload
221+
def __ror__(self, other: bool | NAType, /) -> NAType: ...
222+
@overload
223+
def __xor__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
224+
self, other: Series, /
225+
) -> Series: ...
226+
@overload
227+
def __xor__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
228+
@overload
229+
def __xor__(self, other: object, /) -> NAType: ...
230+
@overload
231+
def __rxor__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
232+
self, other: Series, /
233+
) -> Series: ...
234+
@overload
235+
def __rxor__(self, other: Index, /) -> Index: ... # type: ignore[overload-overlap]
236+
@overload
237+
def __rxor__(self, other: object, /) -> NAType: ...
43238
__array_priority__: int
44-
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): ...
239+
def __array_ufunc__(
240+
self, ufunc: Callable[..., Any], method: str, *inputs: Any, **kwargs: Any
241+
) -> Any: ...
45242

46243
NA: NAType = ...

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ mypy = "1.17.1"
4040
pandas = "2.3.2"
4141
pyarrow = ">=10.0.1"
4242
pytest = ">=7.1.2"
43-
pyright = ">=1.1.404"
43+
pyright = ">=1.1.405"
4444
ty = "^0.0.1a9"
4545
pyrefly = "^0.21.0"
4646
poethepoet = ">=0.16.5"

0 commit comments

Comments
 (0)