Skip to content

Commit 709d745

Browse files
authored
Use default in TypeVar so Series defaults to Series[Any], and Index to Index[Any] (#1232)
* default Series to Series[Any] * remove UnknownSeries * replace one UnknownIndex * replace one more UnknownIndex * replace Series[Any] with Series * replace Index[Any] with Index * go back to S1 in groupby, set defaults for ByT and _TT * use S2 python/mypy#19182 * Revert "use S2 python/mypy#19182" This reverts commit 1c0f351. * Revert "go back to S1 in groupby, set defaults for ByT and _TT" This reverts commit 76ee8bb. * simplify * unquote pd.Series in tests * update philosophy * add comment about why one UnknownIndex needs to stay (!)
1 parent f745945 commit 709d745

File tree

14 files changed

+149
-192
lines changed

14 files changed

+149
-192
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ mypy round.py
4545
we get the following error message:
4646

4747
```text
48-
round.py:6: error: Argument "decimals" to "round" of "DataFrame" has incompatible type "DataFrame"; expected "Union[int, Dict[Any, Any], Series[Any]]" [arg-type]
48+
round.py:6: error: Argument "decimals" to "round" of "DataFrame" has incompatible type "DataFrame"; expected "Union[int, Dict[Any, Any], Series]" [arg-type]
4949
Found 1 error in 1 file (checked 1 source file)
5050
```
5151

docs/philosophy.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ lt = s < 3
2929

3030
In the pandas source, `lt` is a `Series` with a `dtype` of `bool`. In the pandas-stubs,
3131
the type of `lt` is `Series[bool]`. This allows further type checking to occur in other
32-
pandas methods. Note that in the above example, `s` is typed as `Series[Any]` because
33-
its type cannot be statically inferred.
32+
pandas methods. Note that in the above example, `s` is just typed as `Series` (which
33+
defaults to `Series[Any]`) because its type cannot be statically inferred.
3434

3535
This also allows type checking for operations on series that contain date/time data. Consider
3636
the following example that creates two series of datetimes with corresponding arithmetic.

pandas-stubs/_libs/tslibs/timestamps.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ from typing import (
1919
import numpy as np
2020
from pandas import (
2121
DatetimeIndex,
22+
Index,
2223
TimedeltaIndex,
2324
)
24-
from pandas.core.indexes.base import UnknownIndex
2525
from pandas.core.series import (
2626
Series,
2727
TimedeltaSeries,
@@ -236,15 +236,15 @@ class Timestamp(datetime, SupportsIndex):
236236
@overload
237237
def __eq__(self, other: TimestampSeries) -> Series[bool]: ... # type: ignore[overload-overlap]
238238
@overload
239-
def __eq__(self, other: npt.NDArray[np.datetime64] | UnknownIndex) -> np_ndarray_bool: ... # type: ignore[overload-overlap]
239+
def __eq__(self, other: npt.NDArray[np.datetime64] | Index) -> np_ndarray_bool: ... # type: ignore[overload-overlap]
240240
@overload
241241
def __eq__(self, other: object) -> Literal[False]: ...
242242
@overload
243243
def __ne__(self, other: Timestamp | datetime | np.datetime64) -> bool: ... # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
244244
@overload
245245
def __ne__(self, other: TimestampSeries) -> Series[bool]: ... # type: ignore[overload-overlap]
246246
@overload
247-
def __ne__(self, other: npt.NDArray[np.datetime64] | UnknownIndex) -> np_ndarray_bool: ... # type: ignore[overload-overlap]
247+
def __ne__(self, other: npt.NDArray[np.datetime64] | Index) -> np_ndarray_bool: ... # type: ignore[overload-overlap]
248248
@overload
249249
def __ne__(self, other: object) -> Literal[True]: ...
250250
def __hash__(self) -> int: ...

pandas-stubs/_typing.pyi

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ from typing import (
1818
Protocol,
1919
SupportsIndex,
2020
TypedDict,
21-
TypeVar,
2221
Union,
2322
overload,
2423
)
@@ -36,6 +35,7 @@ from pandas.core.tools.datetimes import FulldatetimeDict
3635
from typing_extensions import (
3736
ParamSpec,
3837
TypeAlias,
38+
TypeVar,
3939
)
4040

4141
from pandas._libs.interval import Interval
@@ -66,7 +66,7 @@ HashableT5 = TypeVar("HashableT5", bound=Hashable)
6666
# array-like
6767

6868
ArrayLike: TypeAlias = ExtensionArray | np.ndarray
69-
AnyArrayLike: TypeAlias = ArrayLike | Index[Any] | Series[Any]
69+
AnyArrayLike: TypeAlias = ArrayLike | Index | Series
7070

7171
# list-like
7272

@@ -803,7 +803,7 @@ DtypeNp = TypeVar("DtypeNp", bound=np.dtype[np.generic])
803803
KeysArgType: TypeAlias = Any
804804
ListLikeT = TypeVar("ListLikeT", bound=ListLike)
805805
ListLikeExceptSeriesAndStr: TypeAlias = (
806-
MutableSequence[Any] | np.ndarray | tuple[Any, ...] | Index[Any]
806+
MutableSequence[Any] | np.ndarray | tuple[Any, ...] | Index
807807
)
808808
ListLikeU: TypeAlias = Sequence | np.ndarray | Series | Index
809809
ListLikeHashable: TypeAlias = (
@@ -826,29 +826,8 @@ MaskType: TypeAlias = Series[bool] | np_ndarray_bool | list[bool]
826826

827827
# Scratch types for generics
828828

829-
S1 = TypeVar(
830-
"S1",
831-
bound=str
832-
| bytes
833-
| datetime.date
834-
| datetime.time
835-
| bool
836-
| int
837-
| float
838-
| complex
839-
| Dtype
840-
| datetime.datetime # includes pd.Timestamp
841-
| datetime.timedelta # includes pd.Timedelta
842-
| Period
843-
| Interval
844-
| CategoricalDtype
845-
| BaseOffset
846-
| list[str],
847-
)
848-
849-
S2 = TypeVar(
850-
"S2",
851-
bound=str
829+
SeriesDType: TypeAlias = (
830+
str
852831
| bytes
853832
| datetime.date
854833
| datetime.time
@@ -863,8 +842,12 @@ S2 = TypeVar(
863842
| Interval
864843
| CategoricalDtype
865844
| BaseOffset
866-
| list[str],
845+
| list[str]
867846
)
847+
S1 = TypeVar("S1", bound=SeriesDType, default=Any)
848+
# Like S1, but without `default=Any`.
849+
S2 = TypeVar("S2", bound=SeriesDType)
850+
S3 = TypeVar("S3", bound=SeriesDType)
868851

869852
IndexingInt: TypeAlias = (
870853
int | np.int_ | np.integer | np.unsignedinteger | np.signedinteger | np.int8
@@ -951,7 +934,7 @@ ReplaceValue: TypeAlias = (
951934
| NAType
952935
| Sequence[Scalar | Pattern]
953936
| Mapping[HashableT, ScalarT]
954-
| Series[Any]
937+
| Series
955938
| None
956939
)
957940

pandas-stubs/core/dtypes/missing.pyi

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ isneginf_scalar = ...
2626
@overload
2727
def isna(obj: DataFrame) -> DataFrame: ...
2828
@overload
29-
def isna(obj: Series[Any]) -> Series[bool]: ...
29+
def isna(obj: Series) -> Series[bool]: ...
3030
@overload
31-
def isna(obj: Index[Any] | list[Any] | ArrayLike) -> npt.NDArray[np.bool_]: ...
31+
def isna(obj: Index | list[Any] | ArrayLike) -> npt.NDArray[np.bool_]: ...
3232
@overload
3333
def isna(
3434
obj: Scalar | NaTType | NAType | None,
@@ -39,9 +39,9 @@ isnull = isna
3939
@overload
4040
def notna(obj: DataFrame) -> DataFrame: ...
4141
@overload
42-
def notna(obj: Series[Any]) -> Series[bool]: ...
42+
def notna(obj: Series) -> Series[bool]: ...
4343
@overload
44-
def notna(obj: Index[Any] | list[Any] | ArrayLike) -> npt.NDArray[np.bool_]: ...
44+
def notna(obj: Index | list[Any] | ArrayLike) -> npt.NDArray[np.bool_]: ...
4545
@overload
4646
def notna(obj: ScalarT | NaTType | NAType | None) -> TypeIs[ScalarT]: ...
4747

pandas-stubs/core/frame.pyi

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ from pandas.core.reshape.pivot import (
5656
)
5757
from pandas.core.series import (
5858
Series,
59-
UnknownSeries,
6059
)
6160
from pandas.core.window import (
6261
Expanding,
@@ -79,7 +78,7 @@ from pandas._libs.tslibs import BaseOffset
7978
from pandas._libs.tslibs.nattype import NaTType
8079
from pandas._libs.tslibs.offsets import DateOffset
8180
from pandas._typing import (
82-
S1,
81+
S2,
8382
AggFuncTypeBase,
8483
AggFuncTypeDictFrame,
8584
AggFuncTypeDictSeries,
@@ -1319,11 +1318,11 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
13191318
@overload
13201319
def stack(
13211320
self, level: Level | list[Level] = ..., dropna: _bool = ..., sort: _bool = ...
1322-
) -> Self | Series[Any]: ...
1321+
) -> Self | Series: ...
13231322
@overload
13241323
def stack(
13251324
self, level: Level | list[Level] = ..., future_stack: _bool = ...
1326-
) -> Self | Series[Any]: ...
1325+
) -> Self | Series: ...
13271326
def explode(
13281327
self, column: Sequence[Hashable], ignore_index: _bool = ...
13291328
) -> Self: ...
@@ -1383,7 +1382,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
13831382
@overload
13841383
def apply(
13851384
self,
1386-
f: Callable[..., ListLikeExceptSeriesAndStr | Series[Any]],
1385+
f: Callable[..., ListLikeExceptSeriesAndStr | Series],
13871386
axis: AxisIndex = ...,
13881387
raw: _bool = ...,
13891388
result_type: None = ...,
@@ -1393,13 +1392,14 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
13931392
@overload
13941393
def apply(
13951394
self,
1396-
f: Callable[..., S1 | NAType],
1395+
# Use S2 (TypeVar without `default=Any`) instead of S1 due to https://github.com/python/mypy/issues/19182.
1396+
f: Callable[..., S2 | NAType],
13971397
axis: AxisIndex = ...,
13981398
raw: _bool = ...,
13991399
result_type: None = ...,
14001400
args: Any = ...,
14011401
**kwargs: Any,
1402-
) -> Series[S1]: ...
1402+
) -> Series[S2]: ...
14031403
# Since non-scalar type T is not supported in Series[T],
14041404
# we separate this overload from the above one
14051405
@overload
@@ -1411,24 +1411,25 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
14111411
result_type: None = ...,
14121412
args: Any = ...,
14131413
**kwargs: Any,
1414-
) -> Series[Any]: ...
1414+
) -> Series: ...
14151415

14161416
# apply() overloads with keyword result_type, and axis does not matter
14171417
@overload
14181418
def apply(
14191419
self,
1420-
f: Callable[..., S1 | NAType],
1420+
# Use S2 (TypeVar without `default=Any`) instead of S1 due to https://github.com/python/mypy/issues/19182.
1421+
f: Callable[..., S2 | NAType],
14211422
axis: Axis = ...,
14221423
raw: _bool = ...,
14231424
args: Any = ...,
14241425
*,
14251426
result_type: Literal["expand", "reduce"],
14261427
**kwargs: Any,
1427-
) -> Series[S1]: ...
1428+
) -> Series[S2]: ...
14281429
@overload
14291430
def apply(
14301431
self,
1431-
f: Callable[..., ListLikeExceptSeriesAndStr | Series[Any] | Mapping[Any, Any]],
1432+
f: Callable[..., ListLikeExceptSeriesAndStr | Series | Mapping[Any, Any]],
14321433
axis: Axis = ...,
14331434
raw: _bool = ...,
14341435
args: Any = ...,
@@ -1446,12 +1447,12 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
14461447
*,
14471448
result_type: Literal["reduce"],
14481449
**kwargs: Any,
1449-
) -> Series[Any]: ...
1450+
) -> Series: ...
14501451
@overload
14511452
def apply(
14521453
self,
14531454
f: Callable[
1454-
..., ListLikeExceptSeriesAndStr | Series[Any] | Scalar | Mapping[Any, Any]
1455+
..., ListLikeExceptSeriesAndStr | Series | Scalar | Mapping[Any, Any]
14551456
],
14561457
axis: Axis = ...,
14571458
raw: _bool = ...,
@@ -1465,27 +1466,28 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
14651466
@overload
14661467
def apply(
14671468
self,
1468-
f: Callable[..., Series[Any]],
1469+
f: Callable[..., Series],
14691470
axis: AxisIndex = ...,
14701471
raw: _bool = ...,
14711472
args: Any = ...,
14721473
*,
14731474
result_type: Literal["reduce"],
14741475
**kwargs: Any,
1475-
) -> Series[Any]: ...
1476+
) -> Series: ...
14761477

14771478
# apply() overloads with default result_type of None, and keyword axis=1 matters
14781479
@overload
14791480
def apply(
14801481
self,
1481-
f: Callable[..., S1 | NAType],
1482+
# Use S2 (TypeVar without `default=Any`) instead of S1 due to https://github.com/python/mypy/issues/19182.
1483+
f: Callable[..., S2 | NAType],
14821484
raw: _bool = ...,
14831485
result_type: None = ...,
14841486
args: Any = ...,
14851487
*,
14861488
axis: AxisColumn,
14871489
**kwargs: Any,
1488-
) -> Series[S1]: ...
1490+
) -> Series[S2]: ...
14891491
@overload
14901492
def apply(
14911493
self,
@@ -1496,11 +1498,11 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
14961498
*,
14971499
axis: AxisColumn,
14981500
**kwargs: Any,
1499-
) -> Series[Any]: ...
1501+
) -> Series: ...
15001502
@overload
15011503
def apply(
15021504
self,
1503-
f: Callable[..., Series[Any]],
1505+
f: Callable[..., Series],
15041506
raw: _bool = ...,
15051507
result_type: None = ...,
15061508
args: Any = ...,
@@ -1513,7 +1515,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
15131515
@overload
15141516
def apply(
15151517
self,
1516-
f: Callable[..., Series[Any]],
1518+
f: Callable[..., Series],
15171519
raw: _bool = ...,
15181520
args: Any = ...,
15191521
*,
@@ -1538,7 +1540,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
15381540
) -> Self: ...
15391541
def merge(
15401542
self,
1541-
right: DataFrame | Series[Any],
1543+
right: DataFrame | Series,
15421544
how: MergeHow = ...,
15431545
on: IndexLabel | AnyArrayLike | None = ...,
15441546
left_on: IndexLabel | AnyArrayLike | None = ...,
@@ -1684,6 +1686,8 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
16841686
@property
16851687
def iloc(self) -> _iLocIndexerFrame[Self]: ...
16861688
@property
1689+
# mypy complains if we use Index[Any] instead of UnknownIndex here, even though
1690+
# the latter is aliased to the former ¯\_(ツ)_/¯.
16871691
def index(self) -> UnknownIndex: ...
16881692
@index.setter
16891693
def index(self, idx: Index) -> None: ...
@@ -2012,7 +2016,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
20122016
| Callable[[DataFrame], DataFrame]
20132017
| Callable[[Any], _bool]
20142018
),
2015-
other: Scalar | UnknownSeries | DataFrame | Callable | NAType | None = ...,
2019+
other: Scalar | Series | DataFrame | Callable | NAType | None = ...,
20162020
*,
20172021
inplace: Literal[True],
20182022
axis: Axis | None = ...,
@@ -2028,7 +2032,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack):
20282032
| Callable[[DataFrame], DataFrame]
20292033
| Callable[[Any], _bool]
20302034
),
2031-
other: Scalar | UnknownSeries | DataFrame | Callable | NAType | None = ...,
2035+
other: Scalar | Series | DataFrame | Callable | NAType | None = ...,
20322036
*,
20332037
inplace: Literal[False] = ...,
20342038
axis: Axis | None = ...,

0 commit comments

Comments
 (0)