Skip to content

Commit b27eebd

Browse files
roman-y-wuloicdiridolloucmp0xff
authored
TYP: Add variance checks to aggregation tests and type assertions (#1546)
* Add variance checks to aggregation tests and type assertions - Updated aggregation tests in `test_agg.py` to include checks for the `var()` method across different data types (float, bool, int, and complex). - Added a warning check for complex series when calculating variance to handle potential loss of imaginary parts. - Enhanced type assertions in `test_series.py` for the `var()` method to ensure it returns a float type. * Undo the tests/_typing.py change * TYP: Fix Series.var() return type annotations: - Fix `Series[complex].var()` return type from `np.float64` to `float` - Add `Series[Timedelta].var()` overload returning `Never` (invalid operation) - Add upper bound `upper="2.3.99"` for complex variance warning test - Add Timedelta var() invalid usage test * GH1546 PR Feedback * Update tests/series/test_agg.py Co-authored-by: Yi-Fan Wang <[email protected]> * Fix type checking for series variance function --------- Co-authored-by: Loïc Diridollou <[email protected]> Co-authored-by: Yi-Fan Wang <[email protected]>
1 parent 694b1a6 commit b27eebd

File tree

3 files changed

+58
-6
lines changed

3 files changed

+58
-6
lines changed

pandas-stubs/core/series.pyi

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4636,14 +4636,42 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame):
46364636
**kwargs: Any,
46374637
) -> np_1darray: ...
46384638
def tolist(self) -> list[S1]: ...
4639+
@overload
46394640
def var(
4640-
self,
4641+
self: Series[Never],
46414642
axis: AxisIndex | None = 0,
46424643
skipna: _bool | None = True,
46434644
ddof: int = 1,
46444645
numeric_only: _bool = False,
46454646
**kwargs: Any,
4646-
) -> Scalar: ...
4647+
) -> float: ...
4648+
@overload
4649+
def var(
4650+
self: Series[Timedelta] | Series[Timestamp],
4651+
axis: AxisIndex | None = 0,
4652+
skipna: _bool | None = True,
4653+
ddof: int = 1,
4654+
numeric_only: _bool = False,
4655+
**kwargs: Any,
4656+
) -> Never: ...
4657+
@overload
4658+
def var(
4659+
self: Series[complex],
4660+
axis: AxisIndex | None = 0,
4661+
skipna: _bool | None = True,
4662+
ddof: int = 1,
4663+
numeric_only: _bool = False,
4664+
**kwargs: Any,
4665+
) -> float: ...
4666+
@overload
4667+
def var(
4668+
self: SupportsGetItem[Scalar, SupportsTruedivInt[S2]],
4669+
axis: AxisIndex | None = 0,
4670+
skipna: _bool | None = True,
4671+
ddof: int = 1,
4672+
numeric_only: _bool = False,
4673+
**kwargs: Any,
4674+
) -> S2: ...
46474675
# Rename axis with `mapper`, `axis`, and `inplace=True`
46484676
@overload
46494677
def rename_axis(

tests/series/test_agg.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import numpy as np
22
import pandas as pd
3-
from typing_extensions import assert_type
3+
from typing_extensions import (
4+
Never,
5+
assert_type,
6+
)
47

58
from tests import (
69
TYPE_CHECKING_INVALID_USAGE,
@@ -14,27 +17,31 @@ def test_agg_any_float() -> None:
1417
check(assert_type(series.mean(), float), np.float64)
1518
check(assert_type(series.median(), float), np.float64)
1619
check(assert_type(series.std(), float), np.float64)
20+
check(assert_type(series.var(), float), np.float64)
1721

1822

1923
def test_agg_bool() -> None:
2024
series = pd.Series([True, False, True])
2125
check(assert_type(series.mean(), float), np.float64)
2226
check(assert_type(series.median(), float), np.float64)
2327
check(assert_type(series.std(), float), np.float64)
28+
check(assert_type(series.var(), float), np.float64)
2429

2530

2631
def test_agg_int() -> None:
2732
series = pd.Series([3, 1, 2])
2833
check(assert_type(series.mean(), float), np.float64)
2934
check(assert_type(series.median(), float), np.float64)
3035
check(assert_type(series.std(), float), np.float64)
36+
check(assert_type(series.var(), float), np.float64)
3137

3238

3339
def test_agg_float() -> None:
3440
series = pd.Series([3.0, float("nan"), 2.0])
3541
check(assert_type(series.mean(), float), np.float64)
3642
check(assert_type(series.median(), float), np.float64)
3743
check(assert_type(series.std(), float), np.float64)
44+
check(assert_type(series.var(), float), np.float64)
3845

3946

4047
def test_agg_complex() -> None:
@@ -57,6 +64,12 @@ def test_agg_complex() -> None:
5764
),
5865
):
5966
check(assert_type(series.std(), np.float64), np.float64)
67+
with pytest_warns_bounded(
68+
np.exceptions.ComplexWarning,
69+
r"Casting complex values to real discards the imaginary part",
70+
upper="2.3.99",
71+
):
72+
check(assert_type(series.var(), float), np.float64)
6073

6174

6275
def test_agg_str() -> None:
@@ -65,6 +78,7 @@ def test_agg_str() -> None:
6578
series.mean() # type: ignore[misc] # pyright: ignore[reportAttributeAccessIssue]
6679
series.median() # type: ignore[misc] # pyright: ignore[reportAttributeAccessIssue]
6780
series.std() # type: ignore[misc] # pyright: ignore[reportAttributeAccessIssue]
81+
series.var() # type: ignore[misc] # pyright: ignore[reportAttributeAccessIssue]
6882

6983

7084
def test_agg_ts() -> None:
@@ -75,6 +89,11 @@ def test_agg_ts() -> None:
7589
check(assert_type(series.median(), pd.Timestamp), pd.Timestamp)
7690
check(assert_type(series.std(), pd.Timedelta), pd.Timedelta)
7791

92+
if TYPE_CHECKING_INVALID_USAGE:
93+
94+
def _0() -> None: # pyright: ignore[reportUnusedFunction]
95+
assert_type(series.var(), Never)
96+
7897

7998
def test_agg_td() -> None:
8099
series = pd.Series(pd.to_timedelta(["1 days", "2 days", "3 days"]))
@@ -83,3 +102,8 @@ def test_agg_td() -> None:
83102
check(assert_type(series.mean(), pd.Timedelta), pd.Timedelta)
84103
check(assert_type(series.median(), pd.Timedelta), pd.Timedelta)
85104
check(assert_type(series.std(), pd.Timedelta), pd.Timedelta)
105+
106+
if TYPE_CHECKING_INVALID_USAGE:
107+
108+
def _0() -> None: # pyright: ignore[reportUnusedFunction]
109+
assert_type(series.var(), Never)

tests/series/test_series.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -780,9 +780,9 @@ def test_types_abs() -> None:
780780

781781
def test_types_var() -> None:
782782
s = pd.Series([-10, 2, 3, 10])
783-
s.var()
784-
s.var(axis=0, ddof=1)
785-
s.var(skipna=True, numeric_only=False)
783+
check(assert_type(s.var(), float), np.float64)
784+
check(assert_type(s.var(axis=0, ddof=1), float), np.float64)
785+
check(assert_type(s.var(skipna=True, numeric_only=False), float), np.float64)
786786

787787

788788
def test_types_std() -> None:

0 commit comments

Comments
 (0)