Skip to content

Commit 54ccef8

Browse files
committed
type Index methods: putmask, asof, asof_locs, sort_values, get_indexer_non_unique, get_indexer_for, map, get_slice_bound
1 parent dc3304b commit 54ccef8

File tree

2 files changed

+102
-16
lines changed

2 files changed

+102
-16
lines changed

pandas-stubs/core/indexes/base.pyi

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ from _typeshed import (
2828
_T_contra,
2929
)
3030
import numpy as np
31+
import numpy.typing as npt
3132
from pandas.core.arrays.boolean import BooleanArray
3233
from pandas.core.base import (
3334
ArrayIndexTimedeltaNoSeq,
@@ -99,6 +100,7 @@ from pandas._typing import (
99100
MaskType,
100101
NaPosition,
101102
ReindexMethod,
103+
Renamer,
102104
S2_contra,
103105
Scalar,
104106
SequenceNotStr,
@@ -513,39 +515,59 @@ class Index(IndexOpsMixin[S1], ElementOpsMixin[S1]):
513515
) -> Index[C2]: ...
514516
@overload
515517
def append(self, other: Index | Sequence[Index]) -> Index: ...
516-
def putmask(self, mask, value): ...
518+
def putmask(
519+
self,
520+
mask: Sequence[bool] | np_ndarray_bool | BooleanArray | IndexOpsMixin[bool],
521+
value: Scalar,
522+
) -> Index: ...
517523
def equals(self, other: Any) -> bool: ...
518524
@final
519525
def identical(self, other: Any) -> bool: ...
520526
@final
521-
def asof(self, label): ...
522-
def asof_locs(self, where, mask): ...
527+
def asof(self, label: Scalar) -> Scalar: ...
528+
def asof_locs(
529+
self, where: DatetimeIndex, mask: npt.NDArray[np.bool_]
530+
) -> np_1darray_intp: ...
531+
@overload
523532
def sort_values(
524533
self,
525534
*,
526-
return_indexer: bool = ...,
527-
ascending: bool = ...,
528-
na_position: NaPosition = ...,
535+
return_indexer: Literal[False] = False,
536+
ascending: bool = True,
537+
na_position: NaPosition = "last",
529538
key: Callable[[Index], Index] | None = None,
530-
): ...
539+
) -> Self: ...
540+
@overload
541+
def sort_values(
542+
self,
543+
*,
544+
return_indexer: Literal[True],
545+
ascending: bool = True,
546+
na_position: NaPosition = "last",
547+
key: Callable[[Index], Index] | None = None,
548+
) -> tuple[Self, np_1darray_intp]: ...
531549
@final
532550
def sort(self, *args: Any, **kwargs: Any) -> None: ...
533551
def argsort(self, *args: Any, **kwargs: Any) -> np_1darray_intp: ...
534-
def get_indexer_non_unique(self, target): ...
552+
def get_indexer_non_unique(
553+
self, target: Index
554+
) -> tuple[np_1darray_intp, np_1darray_intp]: ...
535555
@final
536-
def get_indexer_for(self, target, **kwargs: Any): ...
537-
def map(self, mapper, na_action=...) -> Index: ...
556+
def get_indexer_for(self, target: Index) -> np_1darray_intp: ...
557+
def map(
558+
self, mapper: Renamer, na_action: Literal["ignore"] | None = None
559+
) -> Index: ...
538560
def isin(self, values, level=...) -> np_1darray_bool: ...
539561
def slice_indexer(
540562
self,
541563
start: Label | None = None,
542564
end: Label | None = None,
543565
step: int | None = None,
544-
): ...
545-
def get_slice_bound(self, label, side): ...
566+
) -> slice: ...
567+
def get_slice_bound(self, label: Scalar, side: Literal["left", "right"]) -> int: ...
546568
def slice_locs(
547569
self, start: SliceType = None, end: SliceType = None, step: int | None = None
548-
): ...
570+
) -> tuple[np.integer, int]: ...
549571
def delete(
550572
self, loc: np.integer | int | AnyArrayLikeInt | Sequence[int]
551573
) -> Self: ...

tests/indexes/test_indexes.py

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
assert_type,
2424
)
2525

26+
from pandas._typing import Scalar # noqa: F401
27+
2628
from tests import (
2729
PD_LTE_23,
2830
TYPE_CHECKING_INVALID_USAGE,
@@ -1578,7 +1580,69 @@ def test_index_droplevel() -> None:
15781580
check(assert_type(mi.droplevel(0), pd.MultiIndex | pd.Index), pd.Index)
15791581

15801582

1581-
def test_index_setitem() -> None:
1583+
def test_index_putmask() -> None:
15821584
idx = pd.Index([1, 2])
1583-
if TYPE_CHECKING_INVALID_USAGE:
1584-
idx[0] = 999 # type: ignore[index] # pyright: ignore[reportIndexIssue]
1585+
check(assert_type(idx.putmask([True, False], 11.4), "pd.Index"), pd.Index)
1586+
1587+
1588+
def test_index_asof() -> None:
1589+
idx = pd.Index([1, 2])
1590+
check(assert_type(idx.asof(1), "Scalar"), np.integer)
1591+
1592+
1593+
def test_index_asof_locs() -> None:
1594+
idx = pd.DatetimeIndex(["2020-01-01", "2020-01-02", "2020-01-03"])
1595+
check(
1596+
assert_type(
1597+
idx.asof_locs(
1598+
pd.DatetimeIndex(["2020-01-01 11:00"]), np.array([True, True, True])
1599+
),
1600+
np_1darray_intp,
1601+
),
1602+
np_1darray_intp,
1603+
)
1604+
1605+
1606+
def test_index_sort_values() -> None:
1607+
idx = pd.DatetimeIndex(["2020-01-01", "2020-01-02", "2020-01-03"])
1608+
check(assert_type(idx.sort_values(), pd.DatetimeIndex), pd.DatetimeIndex)
1609+
sorted_ = idx.sort_values(return_indexer=True)
1610+
check(assert_type(sorted_[0], pd.DatetimeIndex), pd.DatetimeIndex)
1611+
check(assert_type(sorted_[1], np_1darray_intp), np_1darray_intp)
1612+
1613+
1614+
def test_index_get_indexer_non_unique() -> None:
1615+
idx = pd.Index([1, 3])
1616+
res = idx.get_indexer_non_unique(pd.Index([3]))
1617+
check(assert_type(res[0], np_1darray_intp), np_1darray_intp)
1618+
check(assert_type(res[1], np_1darray_intp), np_1darray_intp)
1619+
1620+
1621+
def test_index_get_indexer_for() -> None:
1622+
idx = pd.Index([1, 3])
1623+
check(
1624+
assert_type(idx.get_indexer_for(pd.Index([3])), np_1darray_intp),
1625+
np_1darray_intp,
1626+
)
1627+
1628+
1629+
def test_index_map() -> None:
1630+
idx = pd.Index([1, 3])
1631+
check(assert_type(idx.map(lambda x: str(x)), pd.Index), pd.Index)
1632+
1633+
1634+
def test_index_slice_indexer() -> None:
1635+
idx = pd.Index([1, 3])
1636+
check(assert_type(idx.slice_indexer(0, 1), slice), slice)
1637+
1638+
1639+
def test_index_get_slice_bound() -> None:
1640+
idx = pd.Index([1, 3])
1641+
check(assert_type(idx.get_slice_bound(1, side="left"), int), int)
1642+
1643+
1644+
def test_index_slice_locs() -> None:
1645+
idx = pd.Index([1, 3])
1646+
res = idx.slice_locs(0, 1)
1647+
check(assert_type(res[0], np.integer), np.integer)
1648+
check(assert_type(res[1], int), int)

0 commit comments

Comments
 (0)