Skip to content

Commit 9b16a88

Browse files
committed
type indexing.pyi
1 parent d54943e commit 9b16a88

File tree

5 files changed

+50
-47
lines changed

5 files changed

+50
-47
lines changed

pandas-stubs/core/frame.pyi

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -323,42 +323,21 @@ class _LocIndexerFrame(_LocIndexer, Generic[_T]):
323323
) -> None: ...
324324

325325
class _iAtIndexerFrame(_iAtIndexer):
326-
def __getitem__(self, key: tuple[int, int]) -> Scalar: ...
327-
def __setitem__(
326+
def __getitem__(self, key: tuple[int, int]) -> Scalar: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
327+
def __setitem__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
328328
self,
329329
key: tuple[int, int],
330330
value: Scalar | NAType | NaTType | None,
331331
) -> None: ...
332332

333333
class _AtIndexerFrame(_AtIndexer):
334-
def __getitem__(
335-
self,
336-
key: tuple[
337-
int
338-
| StrLike
339-
| Timestamp
340-
| tuple[Scalar, ...]
341-
| Callable[[DataFrame], ScalarT],
342-
int | StrLike | tuple[Scalar, ...],
343-
],
334+
def __getitem__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
335+
self, key: tuple[Hashable, Hashable]
344336
) -> Scalar: ...
345-
def __setitem__(
337+
def __setitem__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
346338
self,
347-
key: (
348-
MaskType | StrLike | _IndexSliceTuple | list[ScalarT] | IndexingInt | slice
349-
),
350-
value: (
351-
Scalar
352-
| NAType
353-
| NaTType
354-
| ArrayLike
355-
| IndexOpsMixin
356-
| DataFrame
357-
| Sequence[Scalar]
358-
| Sequence[Sequence[Scalar]]
359-
| Mapping[Hashable, Scalar | NAType | NaTType]
360-
| None
361-
),
339+
key: tuple[Hashable, Hashable],
340+
value: Scalar | NAType | NaTType | None,
362341
) -> None: ...
363342

364343
# With mypy 1.14.1 and python 3.12, the second overload needs a type-ignore statement

pandas-stubs/core/indexing.pyi

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
1-
from collections.abc import Sequence
1+
from collections.abc import (
2+
Hashable,
3+
Sequence,
4+
)
25
from typing import (
36
TypeAlias,
47
TypeVar,
58
)
69

710
from pandas.core.base import IndexOpsMixin
11+
from typing_extensions import Self
812

913
from pandas._libs.indexing import _NDFrameIndexerBase
14+
from pandas._libs.missing import NAType
15+
from pandas._libs.tslibs.nattype import NaTType
1016
from pandas._typing import (
17+
Axis,
18+
AxisInt,
1119
MaskType,
1220
Scalar,
1321
)
@@ -38,20 +46,20 @@ class IndexingMixin:
3846
def iat(self) -> _iAtIndexer: ...
3947

4048
class _NDFrameIndexer(_NDFrameIndexerBase):
41-
axis = ...
42-
def __call__(self, axis=...): ...
43-
def __getitem__(self, key): ...
44-
def __setitem__(self, key, value) -> None: ...
45-
46-
class _LocationIndexer(_NDFrameIndexer):
47-
def __getitem__(self, key): ...
49+
axis: AxisInt | None = None
50+
def __call__(self, axis: Axis | None = None) -> Self: ...
4851

49-
class _LocIndexer(_LocationIndexer): ...
50-
class _iLocIndexer(_LocationIndexer): ...
52+
class _LocIndexer(_NDFrameIndexer): ...
53+
class _iLocIndexer(_NDFrameIndexer): ...
5154

52-
class _ScalarAccessIndexer(_NDFrameIndexerBase):
53-
def __getitem__(self, key): ...
54-
def __setitem__(self, key, value) -> None: ...
55+
class _AtIndexer(_NDFrameIndexerBase):
56+
def __getitem__(self, key: Hashable) -> Scalar: ...
57+
def __setitem__(
58+
self, key: Hashable, value: Scalar | NAType | NaTType | None
59+
) -> None: ...
5560

56-
class _AtIndexer(_ScalarAccessIndexer): ...
57-
class _iAtIndexer(_ScalarAccessIndexer): ...
61+
class _iAtIndexer(_NDFrameIndexerBase):
62+
def __getitem__(self, key: int) -> Scalar: ...
63+
def __setitem__(
64+
self, key: int, value: Scalar | NAType | NaTType | None
65+
) -> None: ...

pyproject.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,6 @@ ignore = [
205205
"PYI042", # https://docs.astral.sh/ruff/rules/snake-case-type-alias/
206206
"ERA001", "PLR0402", "PLC0105"
207207
]
208-
"indexing.pyi" = [
209-
# TODO: remove when indexing.pyi is fully typed
210-
"ANN001", "ANN201", "ANN204", "ANN206",
211-
]
212208
"*computation*" = [
213209
# TODO: remove when computations are fully typed
214210
"ANN001", "ANN201", "ANN204", "ANN206",

tests/frame/test_frame.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3959,3 +3959,19 @@ def test_frame_index_setter() -> None:
39593959
check(assert_type(df.index, pd.Index), pd.Index)
39603960
df.index = [2, 3]
39613961
check(assert_type(df.index, pd.Index), pd.Index)
3962+
3963+
3964+
def test_frame_at() -> None:
3965+
df = pd.DataFrame(data={"col1": [1.6, 2], "col2": [3, 4]})
3966+
3967+
check(assert_type(df.at[0, "col1"], Scalar), float)
3968+
df.at[0, "col1"] = 999
3969+
df.at[0, "col1"] = float("nan")
3970+
3971+
3972+
def test_frame_iat() -> None:
3973+
df = pd.DataFrame(data={"col1": [1, 2], "col2": [3, 4]})
3974+
3975+
check(assert_type(df.iat[0, 0], Scalar), np.integer)
3976+
df.iat[0, 0] = 999
3977+
df.iat[0, 0] = float("nan")

tests/series/test_indexing.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,21 @@ def test_types_iloc_iat() -> None:
3131
s2 = pd.Series(data=[1, 2])
3232
s.loc["row1"]
3333
s.iat[0]
34+
s.iat[0] = 999
3435
s2.loc[0]
3536
s2.iat[0]
37+
s2.iat[0] = None
3638

3739

3840
def test_types_loc_at() -> None:
3941
s = pd.Series(data={"row1": 1, "row2": 2})
4042
s2 = pd.Series(data=[1, 2])
4143
s.loc["row1"]
4244
s.at["row1"]
45+
s.at["row1"] = 9
4346
s2.loc[1]
4447
s2.at[1]
48+
s2.at[1] = 99
4549

4650

4751
def test_types_getitem() -> None:

0 commit comments

Comments
 (0)