Skip to content

Commit 479a7f6

Browse files
authored
TYP: indexes/base.py (pandas-dev#39897)
1 parent 6e243b6 commit 479a7f6

File tree

7 files changed

+55
-42
lines changed

7 files changed

+55
-42
lines changed

pandas/core/algorithms.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,7 @@ def value_counts_arraylike(values, dropna: bool):
911911
return keys, counts
912912

913913

914-
def duplicated(values: ArrayLike, keep: str = "first") -> np.ndarray:
914+
def duplicated(values: ArrayLike, keep: Union[str, bool] = "first") -> np.ndarray:
915915
"""
916916
Return boolean ndarray denoting duplicate values.
917917

pandas/core/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1316,5 +1316,5 @@ def drop_duplicates(self, keep="first"):
13161316
# error: Value of type "IndexOpsMixin" is not indexable
13171317
return self[~duplicated] # type: ignore[index]
13181318

1319-
def duplicated(self, keep="first"):
1319+
def duplicated(self, keep: Union[str, bool] = "first") -> np.ndarray:
13201320
return duplicated(self._values, keep=keep)

pandas/core/indexes/base.py

+48-36
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
Sequence,
1818
Set,
1919
Tuple,
20+
Type,
2021
TypeVar,
2122
Union,
2223
cast,
@@ -47,6 +48,7 @@
4748
Dtype,
4849
DtypeObj,
4950
Shape,
51+
T,
5052
final,
5153
)
5254
from pandas.compat.numpy import function as nv
@@ -161,6 +163,7 @@
161163
if TYPE_CHECKING:
162164
from pandas import (
163165
CategoricalIndex,
166+
DataFrame,
164167
IntervalIndex,
165168
MultiIndex,
166169
RangeIndex,
@@ -278,16 +281,22 @@ class Index(IndexOpsMixin, PandasObject):
278281
# for why we need to wrap these instead of making them class attributes
279282
# Moreover, cython will choose the appropriate-dtyped sub-function
280283
# given the dtypes of the passed arguments
281-
def _left_indexer_unique(self, left, right):
284+
def _left_indexer_unique(self, left: np.ndarray, right: np.ndarray) -> np.ndarray:
282285
return libjoin.left_join_indexer_unique(left, right)
283286

284-
def _left_indexer(self, left, right):
287+
def _left_indexer(
288+
self, left: np.ndarray, right: np.ndarray
289+
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
285290
return libjoin.left_join_indexer(left, right)
286291

287-
def _inner_indexer(self, left, right):
292+
def _inner_indexer(
293+
self, left: np.ndarray, right: np.ndarray
294+
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
288295
return libjoin.inner_join_indexer(left, right)
289296

290-
def _outer_indexer(self, left, right):
297+
def _outer_indexer(
298+
self, left: np.ndarray, right: np.ndarray
299+
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
291300
return libjoin.outer_join_indexer(left, right)
292301

293302
_typ = "index"
@@ -548,7 +557,7 @@ def asi8(self):
548557
return None
549558

550559
@classmethod
551-
def _simple_new(cls, values, name: Hashable = None):
560+
def _simple_new(cls: Type[_IndexT], values, name: Hashable = None) -> _IndexT:
552561
"""
553562
We require that we have a dtype compat for the values. If we are passed
554563
a non-dtype compat, then coerce using the constructor.
@@ -571,11 +580,11 @@ def _simple_new(cls, values, name: Hashable = None):
571580
return result
572581

573582
@cache_readonly
574-
def _constructor(self):
583+
def _constructor(self: _IndexT) -> Type[_IndexT]:
575584
return type(self)
576585

577586
@final
578-
def _maybe_check_unique(self):
587+
def _maybe_check_unique(self) -> None:
579588
"""
580589
Check that an Index has no duplicates.
581590
@@ -626,13 +635,13 @@ def _format_duplicate_message(self):
626635
# Index Internals Methods
627636

628637
@final
629-
def _get_attributes_dict(self):
638+
def _get_attributes_dict(self) -> Dict[str_t, Any]:
630639
"""
631640
Return an attributes dict for my class.
632641
"""
633642
return {k: getattr(self, k, None) for k in self._attributes}
634643

635-
def _shallow_copy(self, values, name: Hashable = no_default):
644+
def _shallow_copy(self: _IndexT, values, name: Hashable = no_default) -> _IndexT:
636645
"""
637646
Create a new Index with the same class as the caller, don't copy the
638647
data, use the same object attributes with passed in attributes taking
@@ -706,11 +715,11 @@ def _reset_identity(self) -> None:
706715
self._id = _Identity(object())
707716

708717
@final
709-
def _cleanup(self):
718+
def _cleanup(self) -> None:
710719
self._engine.clear_mapping()
711720

712721
@cache_readonly
713-
def _engine(self):
722+
def _engine(self) -> libindex.ObjectEngine:
714723
# property, for now, slow to look up
715724

716725
# to avoid a reference cycle, bind `target_values` to a local variable, so
@@ -1260,7 +1269,7 @@ def to_flat_index(self):
12601269
"""
12611270
return self
12621271

1263-
def to_series(self, index=None, name=None):
1272+
def to_series(self, index=None, name: Hashable = None) -> Series:
12641273
"""
12651274
Create a Series with both index and values equal to the index keys.
12661275
@@ -1323,7 +1332,7 @@ def to_series(self, index=None, name=None):
13231332

13241333
return Series(self._values.copy(), index=index, name=name)
13251334

1326-
def to_frame(self, index: bool = True, name=None):
1335+
def to_frame(self, index: bool = True, name=None) -> DataFrame:
13271336
"""
13281337
Create a DataFrame with a column containing the Index.
13291338
@@ -1438,10 +1447,10 @@ def _validate_names(
14381447

14391448
return new_names
14401449

1441-
def _get_names(self):
1450+
def _get_names(self) -> FrozenList:
14421451
return FrozenList((self.name,))
14431452

1444-
def _set_names(self, values, level=None):
1453+
def _set_names(self, values, level=None) -> None:
14451454
"""
14461455
Set new names on index. Each name has to be a hashable type.
14471456
@@ -1642,14 +1651,14 @@ def nlevels(self) -> int:
16421651
"""
16431652
return 1
16441653

1645-
def _sort_levels_monotonic(self):
1654+
def _sort_levels_monotonic(self: _IndexT) -> _IndexT:
16461655
"""
16471656
Compat with MultiIndex.
16481657
"""
16491658
return self
16501659

16511660
@final
1652-
def _validate_index_level(self, level):
1661+
def _validate_index_level(self, level) -> None:
16531662
"""
16541663
Validate index level.
16551664
@@ -2386,7 +2395,7 @@ def hasnans(self) -> bool:
23862395
return False
23872396

23882397
@final
2389-
def isna(self):
2398+
def isna(self) -> np.ndarray:
23902399
"""
23912400
Detect missing values.
23922401
@@ -2444,7 +2453,7 @@ def isna(self):
24442453
isnull = isna
24452454

24462455
@final
2447-
def notna(self):
2456+
def notna(self) -> np.ndarray:
24482457
"""
24492458
Detect existing (non-missing) values.
24502459
@@ -2522,7 +2531,7 @@ def fillna(self, value=None, downcast=None):
25222531
return Index(result, name=self.name)
25232532
return self._view()
25242533

2525-
def dropna(self, how="any"):
2534+
def dropna(self: _IndexT, how: str_t = "any") -> _IndexT:
25262535
"""
25272536
Return Index without NA/NaN values.
25282537
@@ -2547,20 +2556,21 @@ def dropna(self, how="any"):
25472556
# --------------------------------------------------------------------
25482557
# Uniqueness Methods
25492558

2550-
def unique(self, level=None):
2559+
def unique(self: _IndexT, level: Optional[Hashable] = None) -> _IndexT:
25512560
"""
25522561
Return unique values in the index.
25532562
25542563
Unique values are returned in order of appearance, this does NOT sort.
25552564
25562565
Parameters
25572566
----------
2558-
level : int or str, optional, default None
2567+
level : int or hashable, optional
25592568
Only return values from specified level (for MultiIndex).
2569+
If int, gets the level by integer position, else by level name.
25602570
25612571
Returns
25622572
-------
2563-
Index without duplicates
2573+
Index
25642574
25652575
See Also
25662576
--------
@@ -2577,7 +2587,7 @@ def unique(self, level=None):
25772587
return self._shallow_copy(result)
25782588

25792589
@final
2580-
def drop_duplicates(self, keep="first"):
2590+
def drop_duplicates(self: _IndexT, keep: Union[str_t, bool] = "first") -> _IndexT:
25812591
"""
25822592
Return Index with duplicate values removed.
25832593
@@ -2628,7 +2638,7 @@ def drop_duplicates(self, keep="first"):
26282638

26292639
return super().drop_duplicates(keep=keep)
26302640

2631-
def duplicated(self, keep="first"):
2641+
def duplicated(self, keep: Union[str_t, bool] = "first") -> np.ndarray:
26322642
"""
26332643
Indicate duplicate index values.
26342644
@@ -3214,12 +3224,12 @@ def symmetric_difference(self, other, result_name=None, sort=None):
32143224
return Index(the_diff, name=result_name)
32153225

32163226
@final
3217-
def _assert_can_do_setop(self, other):
3227+
def _assert_can_do_setop(self, other) -> bool:
32183228
if not is_list_like(other):
32193229
raise TypeError("Input must be Index or array-like")
32203230
return True
32213231

3222-
def _convert_can_do_setop(self, other):
3232+
def _convert_can_do_setop(self, other) -> Tuple[Index, Hashable]:
32233233
if not isinstance(other, Index):
32243234
other = Index(other, name=self.name)
32253235
result_name = self.name
@@ -3402,7 +3412,7 @@ def _get_indexer(
34023412
return ensure_platform_int(indexer)
34033413

34043414
@final
3405-
def _check_indexing_method(self, method):
3415+
def _check_indexing_method(self, method: Optional[str_t]) -> None:
34063416
"""
34073417
Raise if we have a get_indexer `method` that is not supported or valid.
34083418
"""
@@ -3420,7 +3430,9 @@ def _check_indexing_method(self, method):
34203430

34213431
raise ValueError("Invalid fill method")
34223432

3423-
def _convert_tolerance(self, tolerance, target):
3433+
def _convert_tolerance(
3434+
self, tolerance, target: Union[np.ndarray, Index]
3435+
) -> np.ndarray:
34243436
# override this method on subclasses
34253437
tolerance = np.asarray(tolerance)
34263438
if target.size != tolerance.size and tolerance.size > 1:
@@ -3523,7 +3535,7 @@ def _filter_indexer_tolerance(
35233535
# --------------------------------------------------------------------
35243536
# Indexer Conversion Methods
35253537

3526-
def _get_partial_string_timestamp_match_key(self, key):
3538+
def _get_partial_string_timestamp_match_key(self, key: T) -> T:
35273539
"""
35283540
Translate any partial string timestamp matches in key, returning the
35293541
new key.
@@ -3534,7 +3546,7 @@ def _get_partial_string_timestamp_match_key(self, key):
35343546
return key
35353547

35363548
@final
3537-
def _validate_positional_slice(self, key: slice):
3549+
def _validate_positional_slice(self, key: slice) -> None:
35383550
"""
35393551
For positional indexing, a slice must have either int or None
35403552
for each of start, stop, and step.
@@ -3635,7 +3647,7 @@ def _convert_listlike_indexer(self, keyarr):
36353647
indexer = self._convert_list_indexer(keyarr)
36363648
return indexer, keyarr
36373649

3638-
def _convert_arr_indexer(self, keyarr):
3650+
def _convert_arr_indexer(self, keyarr) -> np.ndarray:
36393651
"""
36403652
Convert an array-like indexer to the appropriate dtype.
36413653
@@ -3680,13 +3692,13 @@ def _invalid_indexer(self, form: str_t, key) -> TypeError:
36803692
# Reindex Methods
36813693

36823694
@final
3683-
def _can_reindex(self, indexer):
3695+
def _validate_can_reindex(self, indexer: np.ndarray) -> None:
36843696
"""
36853697
Check if we are allowing reindexing with this particular indexer.
36863698
36873699
Parameters
36883700
----------
3689-
indexer : an integer indexer
3701+
indexer : an integer ndarray
36903702
36913703
Raises
36923704
------
@@ -6209,7 +6221,7 @@ def trim_front(strings: List[str]) -> List[str]:
62096221
return strings
62106222

62116223

6212-
def _validate_join_method(method: str):
6224+
def _validate_join_method(method: str) -> None:
62136225
if method not in ["left", "right", "inner", "outer"]:
62146226
raise ValueError(f"do not recognize join method {method}")
62156227

@@ -6421,7 +6433,7 @@ def get_unanimous_names(*indexes: Index) -> Tuple[Hashable, ...]:
64216433
return names
64226434

64236435

6424-
def unpack_nested_dtype(other: Index) -> Index:
6436+
def unpack_nested_dtype(other: _IndexT) -> _IndexT:
64256437
"""
64266438
When checking if our dtype is comparable with another, we need
64276439
to unpack CategoricalDtype to look at its categories.dtype.

pandas/core/indexes/multi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,7 @@ def _engine(self):
11091109
return MultiIndexUIntEngine(self.levels, self.codes, offsets)
11101110

11111111
@property
1112-
def _constructor(self):
1112+
def _constructor(self) -> Callable[..., MultiIndex]:
11131113
return type(self).from_tuples
11141114

11151115
@doc(Index._shallow_copy)

pandas/core/indexes/range.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
List,
1111
Optional,
1212
Tuple,
13+
Type,
1314
)
1415
import warnings
1516

@@ -171,7 +172,7 @@ def _simple_new(cls, values: range, name: Hashable = None) -> RangeIndex:
171172
# --------------------------------------------------------------------
172173

173174
@cache_readonly
174-
def _constructor(self):
175+
def _constructor(self) -> Type[Int64Index]:
175176
""" return the class to use for construction """
176177
return Int64Index
177178

pandas/core/internals/array_manager.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,7 @@ def _reindex_indexer(
802802

803803
# some axes don't allow reindexing with dups
804804
if not allow_dups:
805-
self._axes[axis]._can_reindex(indexer)
805+
self._axes[axis]._validate_can_reindex(indexer)
806806

807807
# if axis >= self.ndim:
808808
# raise IndexError("Requested axis not found in manager")

pandas/core/internals/managers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,7 @@ def reindex_indexer(
12411241

12421242
# some axes don't allow reindexing with dups
12431243
if not allow_dups:
1244-
self.axes[axis]._can_reindex(indexer)
1244+
self.axes[axis]._validate_can_reindex(indexer)
12451245

12461246
if axis >= self.ndim:
12471247
raise IndexError("Requested axis not found in manager")

0 commit comments

Comments
 (0)