Skip to content

Commit ca481c6

Browse files
authored
Type Series (#1467)
* Type `Series` * update pyproject * use IndexOpsMixin more * remove `_NoDefaultDoNotUse`
1 parent bb6d0f9 commit ca481c6

File tree

2 files changed

+78
-26
lines changed

2 files changed

+78
-26
lines changed

pandas-stubs/core/series.pyi

Lines changed: 78 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -239,21 +239,27 @@ class SupportsTruedivInt(Protocol[_T_co]):
239239

240240
class _iLocIndexerSeries(_iLocIndexer, Generic[S1]):
241241
# get item
242+
# Keep in sync with `Series.__getitem__`
242243
@overload
243244
def __getitem__(self, idx: IndexingInt) -> S1: ...
244245
@overload
245-
def __getitem__(self, idx: Index | slice | np_ndarray_anyint) -> Series[S1]: ...
246+
def __getitem__(
247+
self, idx: Index | Series | slice | np_ndarray_anyint
248+
) -> Series[S1]: ...
249+
246250
# set item
251+
# Keep in sync with `Series.__setitem__`
247252
@overload
248253
def __setitem__(self, idx: int, value: S1 | None) -> None: ...
249254
@overload
250255
def __setitem__(
251256
self,
252257
idx: Index | slice | np_ndarray_anyint | list[int],
253-
value: S1 | Series[S1] | None,
258+
value: S1 | IndexOpsMixin[S1] | None,
254259
) -> None: ...
255260

256261
class _LocIndexerSeries(_LocIndexer, Generic[S1]):
262+
# Keep in sync with `Series.__getitem__`
257263
# ignore needed because of mypy. Overlapping, but we want to distinguish
258264
# having a tuple of just scalars, versus tuples that include slices or Index
259265
@overload
@@ -268,6 +274,7 @@ class _LocIndexerSeries(_LocIndexer, Generic[S1]):
268274
idx: (
269275
MaskType
270276
| Index
277+
| Series
271278
| SequenceNotStr[float | _str | Timestamp]
272279
| slice
273280
| _IndexSliceTuple
@@ -277,11 +284,13 @@ class _LocIndexerSeries(_LocIndexer, Generic[S1]):
277284
# _IndexSliceTuple is when having a tuple that includes a slice. Could just
278285
# be s.loc[1, :], or s.loc[pd.IndexSlice[1, :]]
279286
) -> Series[S1]: ...
287+
288+
# Keep in sync with `Series.__setitem__`
280289
@overload
281290
def __setitem__(
282291
self,
283-
idx: Index | MaskType | slice,
284-
value: S1 | ArrayLike | Series[S1] | None,
292+
idx: IndexOpsMixin[S1] | MaskType | slice,
293+
value: S1 | ArrayLike | IndexOpsMixin[S1] | None,
285294
) -> None: ...
286295
@overload
287296
def __setitem__(
@@ -293,7 +302,7 @@ class _LocIndexerSeries(_LocIndexer, Generic[S1]):
293302
def __setitem__(
294303
self,
295304
idx: MaskType | StrLike | _IndexSliceTuple | list[ScalarT],
296-
value: S1 | ArrayLike | Series[S1] | None,
305+
value: S1 | ArrayLike | IndexOpsMixin[S1] | None,
297306
) -> None: ...
298307

299308
_DataLike: TypeAlias = ArrayLike | dict[str, np.ndarray] | SequenceNotStr[S1]
@@ -513,33 +522,78 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame):
513522
def values(self) -> ArrayLike: ...
514523
def ravel(self, order: _str = ...) -> np.ndarray: ...
515524
def __len__(self) -> int: ...
516-
def view(self, dtype=...) -> Series[S1]: ...
525+
def view(self, dtype: Dtype | None = None) -> Series[S1]: ...
517526
@final
518527
def __array_ufunc__(
519528
self, ufunc: Callable, method: _str, *inputs: Any, **kwargs: Any
520-
): ...
529+
) -> Any: ...
521530
def __array__(
522531
self, dtype: _str | np.dtype = ..., copy: bool | None = ...
523532
) -> np_1darray: ...
524533
@property
525534
def axes(self) -> list: ...
526535
@final
527536
def __getattr__(self, name: _str) -> S1: ...
537+
538+
# Keep in sync with `iLocIndexerSeries.__getitem__`
539+
@overload
540+
def __getitem__(self, idx: IndexingInt) -> S1: ...
541+
@overload
542+
def __getitem__(
543+
self, idx: Index | Series | slice | np_ndarray_anyint
544+
) -> Series[S1]: ...
545+
# Keep in sync with `LocIndexerSeries.__getitem__`
546+
@overload
547+
def __getitem__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
548+
self,
549+
idx: Scalar | tuple[Scalar, ...],
550+
# tuple case is for getting a specific element when using a MultiIndex
551+
) -> S1: ...
528552
@overload
529553
def __getitem__(
530554
self,
531555
idx: (
532-
list[_str]
556+
MaskType
533557
| Index
534-
| Series[S1]
558+
| Series
559+
| SequenceNotStr[float | _str | Timestamp]
535560
| slice
536-
| MaskType
537-
| tuple[Hashable | slice, ...]
561+
| _IndexSliceTuple
562+
| Sequence[_IndexSliceTuple]
563+
| Callable
538564
),
539-
) -> Self: ...
565+
# _IndexSliceTuple is when having a tuple that includes a slice. Could just
566+
# be s.loc[1, :], or s.loc[pd.IndexSlice[1, :]]
567+
) -> Series[S1]: ...
568+
569+
# Keep in sync with `_iLocIndexerSeries.__setitem__`
540570
@overload
541-
def __getitem__(self, idx: Scalar) -> S1: ...
542-
def __setitem__(self, key, value) -> None: ...
571+
def __setitem__(self, idx: int, value: S1 | None) -> None: ...
572+
@overload
573+
def __setitem__(
574+
self,
575+
idx: Index | slice | np_ndarray_anyint | list[int],
576+
value: S1 | IndexOpsMixin[S1] | None,
577+
) -> None: ...
578+
# Keep in sync with `_LocIndexerSeries.__setitem__`
579+
@overload
580+
def __setitem__(
581+
self,
582+
idx: Index | MaskType | slice,
583+
value: S1 | ArrayLike | IndexOpsMixin[S1] | None,
584+
) -> None: ...
585+
@overload
586+
def __setitem__(
587+
self,
588+
idx: _str,
589+
value: S1 | None,
590+
) -> None: ...
591+
@overload
592+
def __setitem__(
593+
self,
594+
idx: MaskType | StrLike | _IndexSliceTuple | list[ScalarT],
595+
value: S1 | ArrayLike | IndexOpsMixin[S1] | None,
596+
) -> None: ...
543597
@overload
544598
def get(self, key: Hashable, default: None = None) -> S1 | None: ...
545599
@overload
@@ -804,7 +858,7 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame):
804858
dropna: _bool = ...,
805859
) -> SeriesGroupBy[S1, Any]: ...
806860
def count(self) -> int: ...
807-
def mode(self, dropna=True) -> Series[S1]: ...
861+
def mode(self, dropna: bool = True) -> Series[S1]: ...
808862
@overload
809863
def unique(self: Series[Never]) -> np.ndarray: ... # type: ignore[overload-overlap]
810864
@overload
@@ -1527,10 +1581,6 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame):
15271581
axis: AxisIndex | None = 0,
15281582
) -> Series[S1]: ...
15291583
@final
1530-
def first(self, offset) -> Series[S1]: ...
1531-
@final
1532-
def last(self, offset) -> Series[S1]: ...
1533-
@final
15341584
def rank(
15351585
self,
15361586
axis: AxisIndex = 0,
@@ -1550,7 +1600,7 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame):
15501600
| Callable[[Series[S1]], Series[bool]]
15511601
| Callable[[S1], bool]
15521602
),
1553-
other=...,
1603+
other: S1 | Self | Callable[..., S1 | Self] = ...,
15541604
*,
15551605
inplace: Literal[True],
15561606
axis: AxisIndex | None = 0,
@@ -1566,7 +1616,7 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame):
15661616
| Callable[[Series[S1]], Series[bool]]
15671617
| Callable[[S1], bool]
15681618
),
1569-
other=...,
1619+
other: Scalar | Self | Callable[..., Scalar | Self] = ...,
15701620
*,
15711621
inplace: Literal[False] = False,
15721622
axis: AxisIndex | None = 0,
@@ -4603,7 +4653,13 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame):
46034653
copy: _bool = ...,
46044654
inplace: Literal[False] = False,
46054655
) -> Self: ...
4606-
def set_axis(self, labels, *, axis: Axis = ..., copy: _bool = ...) -> Self: ...
4656+
def set_axis(
4657+
self,
4658+
labels: AxesData,
4659+
*,
4660+
axis: Axis = 0,
4661+
copy: _bool | _NoDefaultDoNotUse = ...,
4662+
) -> Self: ...
46074663
@final
46084664
def xs(
46094665
self,

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-
"*series.pyi" = [
208-
# TODO: remove when pandas-dev/pandas-stubs#1444 is resolved
209-
"ANN001", "ANN201", "ANN204", "ANN206",
210-
]
211207
"*frame.pyi" = [
212208
# TODO: remove when pandas-dev/pandas-stubs#1446 is resolved
213209
"ANN001", "ANN201", "ANN204", "ANN206",

0 commit comments

Comments
 (0)