Skip to content

Commit 6957ad1

Browse files
authored
Type RangeIndex (pandas-dev#1453)
* type rangeindex * add tests * get_indexer * argsort * type join * update roof * consistency * type default
1 parent 0875046 commit 6957ad1

File tree

5 files changed

+120
-40
lines changed

5 files changed

+120
-40
lines changed

pandas-stubs/core/indexes/base.pyi

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ from pandas._typing import (
6666
S2_NSDT,
6767
T_COMPLEX,
6868
AnyAll,
69+
AnyArrayLike,
6970
ArrayLike,
7071
AxesData,
7172
CategoryDtypeArg,
@@ -78,6 +79,7 @@ from pandas._typing import (
7879
GenericT_co,
7980
HashableT,
8081
IgnoreRaise,
82+
JoinHow,
8183
Just,
8284
Label,
8385
Level,
@@ -418,8 +420,12 @@ class Index(IndexOpsMixin[S1], ElementOpsMixin[S1]):
418420
) -> Self: ...
419421
def get_loc(self, key: Label) -> int | slice | np_1darray[np.bool]: ...
420422
def get_indexer(
421-
self, target, method: ReindexMethod | None = ..., limit=..., tolerance=...
422-
): ...
423+
self,
424+
target: Index,
425+
method: ReindexMethod | None = None,
426+
limit: int | None = None,
427+
tolerance: Scalar | AnyArrayLike | Sequence[Scalar] | None = None,
428+
) -> np_1darray[np.intp]: ...
423429
def reindex(
424430
self,
425431
target,
@@ -428,15 +434,26 @@ class Index(IndexOpsMixin[S1], ElementOpsMixin[S1]):
428434
limit=...,
429435
tolerance=...,
430436
): ...
437+
@overload
431438
def join(
432439
self,
433-
other,
440+
other: Index,
434441
*,
435-
how: _str = ...,
436-
level=...,
437-
return_indexers: bool = ...,
438-
sort: bool = ...,
439-
): ...
442+
how: JoinHow = "left",
443+
level: Level | None = None,
444+
return_indexers: Literal[True],
445+
sort: bool = False,
446+
) -> tuple[Index, np_1darray[np.intp] | None, np_1darray[np.intp] | None]: ...
447+
@overload
448+
def join(
449+
self,
450+
other: Index,
451+
*,
452+
how: JoinHow = "left",
453+
level: Level | None = None,
454+
return_indexers: Literal[False] = False,
455+
sort: bool = False,
456+
) -> Index: ...
440457
@property
441458
def values(self) -> np_1darray: ...
442459
def memory_usage(self, deep: bool = False): ...
@@ -474,7 +491,7 @@ class Index(IndexOpsMixin[S1], ElementOpsMixin[S1]):
474491
): ...
475492
@final
476493
def sort(self, *args: Any, **kwargs: Any) -> None: ...
477-
def argsort(self, *args: Any, **kwargs: Any): ...
494+
def argsort(self, *args: Any, **kwargs: Any) -> np_1darray[np.intp]: ...
478495
def get_indexer_non_unique(self, target): ...
479496
@final
480497
def get_indexer_for(self, target, **kwargs: Any): ...

pandas-stubs/core/indexes/interval.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ class IntervalIndex(ExtensionIndex[IntervalT, np.object_], IntervalMixin):
226226
method: FillnaOptions | Literal["nearest"] | None = ...,
227227
limit: int | None = ...,
228228
tolerance=...,
229-
) -> npt.NDArray[np.intp]: ...
229+
) -> np_1darray[np.intp]: ...
230230
def get_indexer_non_unique(
231231
self, target: Index
232232
) -> tuple[npt.NDArray[np.intp], npt.NDArray[np.intp]]: ...

pandas-stubs/core/indexes/range.pyi

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ from pandas.core.indexes.base import (
1616
from typing_extensions import Self
1717

1818
from pandas._typing import (
19+
Dtype,
1920
HashableT,
2021
MaskType,
2122
np_1darray,
@@ -25,16 +26,17 @@ from pandas._typing import (
2526
class RangeIndex(_IndexSubclassBase[int, np.int64]):
2627
def __new__(
2728
cls,
28-
start: int | RangeIndex | range = ...,
29-
stop: int = ...,
30-
step: int = ...,
31-
dtype=...,
32-
copy: bool = ...,
33-
name: Hashable = ...,
29+
start: int | RangeIndex | range | None = None,
30+
stop: int | None = None,
31+
step: int | None = None,
32+
dtype: Dtype | None = None,
33+
copy: bool = False,
34+
name: Hashable | None = None,
3435
): ...
3536
@classmethod
36-
def from_range(cls, data, name: Hashable = ..., dtype=...) -> Self: ...
37-
def __reduce__(self): ...
37+
def from_range(
38+
cls, data: range, name: Hashable | None = None, dtype: Dtype | None = None
39+
) -> Self: ...
3840
@property
3941
def start(self) -> int: ...
4042
@property
@@ -55,29 +57,15 @@ class RangeIndex(_IndexSubclassBase[int, np.int64]):
5557
@property
5658
def has_duplicates(self) -> bool: ...
5759
def __contains__(self, key: int | np.integer) -> bool: ...
58-
@final
59-
def get_indexer(self, target, method=..., limit=..., tolerance=...): ...
60-
def tolist(self): ...
61-
def min(self, axis=..., skipna: bool = ..., *args: Any, **kwargs: Any): ...
62-
def max(self, axis=..., skipna: bool = ..., *args: Any, **kwargs: Any): ...
63-
def argsort(self, *args: Any, **kwargs: Any): ...
6460
def factorize(
6561
self, sort: bool = False, use_na_sentinel: bool = True
6662
) -> tuple[np_1darray[np.intp], RangeIndex]: ...
67-
def equals(self, other): ...
68-
@final
69-
def join(
70-
self,
71-
other,
72-
*,
73-
how: str = ...,
74-
level=...,
75-
return_indexers: bool = ...,
76-
sort: bool = ...,
77-
): ...
7863
@property
7964
def size(self) -> int: ...
80-
def __floordiv__(self, other): ...
65+
# Base class returns `Self`, but for `RangeIndex` that's not true.
66+
def __floordiv__( # type: ignore[override]
67+
self, other: float | Sequence[float] | Index[int] | Index[float]
68+
) -> Index[int]: ...
8169
def all(self, *args: Any, **kwargs: Any) -> bool: ...
8270
def any(self, *args: Any, **kwargs: Any) -> bool: ...
8371
@final

pyproject.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,6 @@ ignore = [
204204
"PYI042", # https://docs.astral.sh/ruff/rules/snake-case-type-alias/
205205
"ERA001", "PLR0402", "PLC0105"
206206
]
207-
"*range.pyi" = [
208-
# TODO: remove when pandas-dev/pandas-stubs#1442 is resolved
209-
"ANN001", "ANN201", "ANN204", "ANN206",
210-
]
211207
"*category.pyi" = [
212208
# TODO: remove when pandas-dev/pandas-stubs#1443 is resolved
213209
"ANN001", "ANN201", "ANN204", "ANN206",

tests/indexes/test_rangeindex.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
from __future__ import annotations
2+
3+
import numpy as np
4+
import pandas as pd
5+
from typing_extensions import (
6+
assert_type,
7+
)
8+
9+
from tests import (
10+
check,
11+
np_1darray,
12+
)
13+
14+
15+
def test_rangeindex_floordiv() -> None:
16+
ri = pd.RangeIndex(3)
17+
check(
18+
assert_type(ri // 2, "pd.Index[int]"),
19+
pd.Index,
20+
)
21+
22+
23+
def test_rangeindex_min_max() -> None:
24+
ri = pd.RangeIndex(3)
25+
check(
26+
assert_type(ri.min(), int),
27+
int,
28+
)
29+
check(
30+
assert_type(ri.max(axis=0), int),
31+
int,
32+
)
33+
34+
35+
def test_rangeindex_equals() -> None:
36+
ri = pd.RangeIndex(3)
37+
check(
38+
assert_type(ri.equals(ri), bool),
39+
bool,
40+
)
41+
42+
43+
def test_rangeindex_tolist() -> None:
44+
ri = pd.RangeIndex.from_range(range(3))
45+
check(
46+
assert_type(ri.tolist(), list[int]),
47+
list[int],
48+
)
49+
50+
51+
def test_rangeindex_get_indexer() -> None:
52+
ri = pd.RangeIndex.from_range(range(3))
53+
check(
54+
assert_type(ri.get_indexer(ri), np_1darray[np.intp]),
55+
np_1darray[np.intp],
56+
)
57+
58+
59+
def test_rangeindex_argsort() -> None:
60+
ri = pd.RangeIndex.from_range(range(3))
61+
check(
62+
assert_type(ri.argsort(), np_1darray[np.intp]),
63+
np_1darray[np.intp],
64+
)
65+
66+
67+
def test_rangeindex_join() -> None:
68+
ri = pd.RangeIndex.from_range(range(3))
69+
check(
70+
assert_type(ri.join(ri), pd.Index),
71+
pd.Index,
72+
)
73+
check(
74+
assert_type(
75+
ri.join(ri, return_indexers=True),
76+
tuple[pd.Index, np_1darray[np.intp] | None, np_1darray[np.intp] | None],
77+
),
78+
tuple[pd.Index, np_1darray[np.intp] | None, np_1darray[np.intp] | None],
79+
)

0 commit comments

Comments
 (0)