diff --git a/pyproject.toml b/pyproject.toml index 62c63b03..7d23029d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,11 +35,11 @@ types-pytz = ">= 2022.1.1" numpy = { version = ">=1.26.0", python = "<3.13" } [tool.poetry.group.dev.dependencies] -mypy = "1.9.0" -pandas = "2.2.1" +mypy = "1.10.0" +pandas = "2.2.2" pyarrow = ">=10.0.1" pytest = ">=7.1.2" -pyright = ">=1.1.354" +pyright = ">=1.1.362" poethepoet = ">=0.16.5" loguru = ">=0.6.0" typing-extensions = ">=4.4.0" diff --git a/tests/test_frame.py b/tests/test_frame.py index ed42dad8..dc004069 100644 --- a/tests/test_frame.py +++ b/tests/test_frame.py @@ -1953,44 +1953,60 @@ class ReadCsvKwargs(TypedDict): ), pd.DataFrame, ) - parse_dates_2 = {"combined_date": ["Year", "Month", "Day"]} - with pytest_warns_bounded( - FutureWarning, "Support for nested sequences", lower="2.1.99" - ): - check( - assert_type(pd.read_csv(path, parse_dates=parse_dates_2), pd.DataFrame), - pd.DataFrame, - ) - parse_dates_3 = {"combined_date": [1, 2, 3]} - with pytest_warns_bounded( - FutureWarning, "Support for nested sequences", lower="2.1.99" - ): - check( - assert_type(pd.read_csv(path, parse_dates=parse_dates_3), pd.DataFrame), - pd.DataFrame, - ) - # MyPy calls this Dict[str, object] by default which necessitates the explicit annotation (Pyright does not) - parse_dates_4: dict[str, list[str | int]] = {"combined_date": [1, "Month", 3]} - with pytest_warns_bounded( - FutureWarning, "Support for nested sequences", lower="2.1.99" - ): - check( - assert_type(pd.read_csv(path, parse_dates=parse_dates_4), pd.DataFrame), - pd.DataFrame, - ) + if PD_LTE_22: + parse_dates_2 = {"combined_date": ["Year", "Month", "Day"]} + with pytest_warns_bounded( + FutureWarning, + "Support for nested sequences", + lower="2.1.99", + ): + check( + assert_type( + pd.read_csv(path, parse_dates=parse_dates_2), pd.DataFrame + ), + pd.DataFrame, + ) + parse_dates_3 = {"combined_date": [1, 2, 3]} + with pytest_warns_bounded( + FutureWarning, "Support for nested sequences", lower="2.1.99" + ): + check( + assert_type( + pd.read_csv(path, parse_dates=parse_dates_3), pd.DataFrame + ), + pd.DataFrame, + ) + # MyPy calls this Dict[str, object] by default which necessitates the explicit annotation (Pyright does not) + parse_dates_4: dict[str, list[str | int]] = { + "combined_date": [1, "Month", 3] + } + with pytest_warns_bounded( + FutureWarning, "Support for nested sequences", lower="2.1.99" + ): + check( + assert_type( + pd.read_csv(path, parse_dates=parse_dates_4), pd.DataFrame + ), + pd.DataFrame, + ) + + parse_dates_6 = [[1, 2, 3]] + with pytest_warns_bounded( + FutureWarning, + "Support for nested sequences", + lower="2.1.99", + ): + check( + assert_type( + pd.read_csv(path, parse_dates=parse_dates_6), pd.DataFrame + ), + pd.DataFrame, + ) parse_dates_5 = [0] check( assert_type(pd.read_csv(path, parse_dates=parse_dates_5), pd.DataFrame), pd.DataFrame, ) - parse_dates_6 = [[1, 2, 3]] - with pytest_warns_bounded( - FutureWarning, "Support for nested sequences", lower="2.1.99" - ): - check( - assert_type(pd.read_csv(path, parse_dates=parse_dates_6), pd.DataFrame), - pd.DataFrame, - ) def test_groupby_series_methods() -> None: diff --git a/tests/test_groupby.py b/tests/test_groupby.py index dc191b88..fd0dae4b 100644 --- a/tests/test_groupby.py +++ b/tests/test_groupby.py @@ -246,15 +246,44 @@ def df2scalar(val: DataFrame) -> float: ) # interpolate - check(assert_type(GB_DF.resample("ME").interpolate(), DataFrame), DataFrame) - check( - assert_type(GB_DF.resample("ME").interpolate(method="linear"), DataFrame), - DataFrame, - ) - check( - assert_type(GB_DF.resample("ME").interpolate(inplace=True), None), - type(None), - ) + if PD_LTE_22: + check(assert_type(GB_DF.resample("ME").interpolate(), DataFrame), DataFrame) + check( + assert_type( + GB_DF.resample("ME").interpolate(method="linear"), DataFrame + ), + DataFrame, + ) + check( + assert_type(GB_DF.resample("ME").interpolate(inplace=True), None), + type(None), + ) + else: + + def resample_interpolate(x: DataFrame) -> DataFrame: + return x.resample("ME").interpolate() + + check( + assert_type( + GB_DF.apply(resample_interpolate, include_groups=False), + DataFrame, + ), + DataFrame, + ) + + def resample_interpolate_linear(x: DataFrame) -> DataFrame: + return x.resample("ME").interpolate(method="linear") + + check( + assert_type( + GB_DF.apply( + resample_interpolate_linear, + include_groups=False, + ), + DataFrame, + ), + DataFrame, + ) # pipe def g(val: Resampler[DataFrame]) -> DataFrame: @@ -393,10 +422,31 @@ def f(val: Series) -> float: check(assert_type(GB_S.resample("ME").asfreq(-1.0), "Series[float]"), Series, float) # interpolate - check( - assert_type(GB_S.resample("ME").interpolate(), "Series[float]"), Series, float - ) - check(assert_type(GB_S.resample("ME").interpolate(inplace=True), None), type(None)) + if PD_LTE_22: + check( + assert_type(GB_S.resample("ME").interpolate(), "Series[float]"), + Series, + float, + ) + check( + assert_type(GB_S.resample("ME").interpolate(inplace=True), None), type(None) + ) + else: + check( + assert_type( + GB_S.apply(lambda x: x.resample("ME").interpolate()), "Series[float]" + ), + Series, + float, + ) + # This fails typing checks, and should work in 3.0, but is a bug in main + # https://github.com/pandas-dev/pandas/issues/58690 + # check( + # assert_type( + # GB_S.apply(lambda x: x.resample("ME").interpolate(inplace=True)), None + # ), + # type(None), + # ) # pipe def g(val: Resampler[Series]) -> float: @@ -854,62 +904,63 @@ def test_frame_groupby_ewm() -> None: check(assert_type(GB_DF.ewm(1).var(), DataFrame), DataFrame) # aggregate - with pytest_warns_bounded( - FutureWarning, - r"The provided callable is currently using ", - upper="2.2.99", - ): - check(assert_type(GB_DF.ewm(1).aggregate(np.sum), DataFrame), DataFrame) - check(assert_type(GB_DF.ewm(1).agg(np.sum), DataFrame), DataFrame) - check( - assert_type(GB_DF.ewm(1).aggregate([np.sum, np.mean]), DataFrame), - DataFrame, - ) - check( - assert_type(GB_DF.ewm(1).aggregate(["sum", np.mean]), DataFrame), - DataFrame, - ) - check( - assert_type( - GB_DF.ewm(1).aggregate({"col1": "sum", "col2": np.mean}), + if PD_LTE_22: + with pytest_warns_bounded( + FutureWarning, + r"The provided callable is currently using ", + upper="2.2.99", + ): + check(assert_type(GB_DF.ewm(1).aggregate(np.sum), DataFrame), DataFrame) + check(assert_type(GB_DF.ewm(1).agg(np.sum), DataFrame), DataFrame) + check( + assert_type(GB_DF.ewm(1).aggregate([np.sum, np.mean]), DataFrame), DataFrame, - ), - DataFrame, - ) - check( - assert_type( - GB_DF.ewm(1).aggregate({"col1": ["sum", np.mean], "col2": np.mean}), + ) + check( + assert_type(GB_DF.ewm(1).aggregate(["sum", np.mean]), DataFrame), DataFrame, - ), - DataFrame, - ) + ) + check( + assert_type( + GB_DF.ewm(1).aggregate({"col1": "sum", "col2": np.mean}), + DataFrame, + ), + DataFrame, + ) + check( + assert_type( + GB_DF.ewm(1).aggregate({"col1": ["sum", np.mean], "col2": np.mean}), + DataFrame, + ), + DataFrame, + ) - # aggregate combinations - with pytest_warns_bounded( - FutureWarning, - r"The provided callable is currently using ", - upper="2.2.99", - ): - check(GB_DF.ewm(1).aggregate(np.sum), DataFrame) - check(GB_DF.ewm(1).aggregate([np.mean]), DataFrame) - check(GB_DF.ewm(1).aggregate(["sum", np.mean]), DataFrame) - check(GB_DF.ewm(1).aggregate({"col1": np.sum}), DataFrame) - check( - GB_DF.ewm(1).aggregate({"col1": np.sum, "col2": np.mean}), - DataFrame, - ) - check( - GB_DF.ewm(1).aggregate({"col1": [np.sum], "col2": ["sum", np.mean]}), - DataFrame, - ) - check( - GB_DF.ewm(1).aggregate({"col1": np.sum, "col2": ["sum", np.mean]}), - DataFrame, - ) - check( - GB_DF.ewm(1).aggregate({"col1": "sum", "col2": [np.mean]}), - DataFrame, - ) + # aggregate combinations + with pytest_warns_bounded( + FutureWarning, + r"The provided callable is currently using ", + upper="2.2.99", + ): + check(GB_DF.ewm(1).aggregate(np.sum), DataFrame) + check(GB_DF.ewm(1).aggregate([np.mean]), DataFrame) + check(GB_DF.ewm(1).aggregate(["sum", np.mean]), DataFrame) + check(GB_DF.ewm(1).aggregate({"col1": np.sum}), DataFrame) + check( + GB_DF.ewm(1).aggregate({"col1": np.sum, "col2": np.mean}), + DataFrame, + ) + check( + GB_DF.ewm(1).aggregate({"col1": [np.sum], "col2": ["sum", np.mean]}), + DataFrame, + ) + check( + GB_DF.ewm(1).aggregate({"col1": np.sum, "col2": ["sum", np.mean]}), + DataFrame, + ) + check( + GB_DF.ewm(1).aggregate({"col1": "sum", "col2": [np.mean]}), + DataFrame, + ) check(GB_DF.ewm(1).aggregate("sum"), DataFrame) # getattr @@ -964,22 +1015,23 @@ def test_series_groupby_ewm() -> None: upper="2.2.99", ): check(assert_type(GB_S.ewm(1).aggregate("sum"), Series), Series) - check(assert_type(GB_S.ewm(1).aggregate(np.sum), Series), Series) - check(assert_type(GB_S.ewm(1).agg(np.sum), Series), Series) - check( - assert_type(GB_S.ewm(1).aggregate([np.sum, np.mean]), DataFrame), - DataFrame, - ) - check( - assert_type(GB_S.ewm(1).aggregate(["sum", np.mean]), DataFrame), - DataFrame, - ) - check( - assert_type( - GB_S.ewm(1).aggregate({"col1": "sum", "col2": np.mean}), DataFrame - ), - DataFrame, - ) + if PD_LTE_22: + check(assert_type(GB_S.ewm(1).aggregate(np.sum), Series), Series) + check(assert_type(GB_S.ewm(1).agg(np.sum), Series), Series) + check( + assert_type(GB_S.ewm(1).aggregate([np.sum, np.mean]), DataFrame), + DataFrame, + ) + check( + assert_type(GB_S.ewm(1).aggregate(["sum", np.mean]), DataFrame), + DataFrame, + ) + check( + assert_type( + GB_S.ewm(1).aggregate({"col1": "sum", "col2": np.mean}), DataFrame + ), + DataFrame, + ) # iter iterator = iter(GB_S.ewm(1)) diff --git a/tests/test_resampler.py b/tests/test_resampler.py index 27828406..70e36f05 100644 --- a/tests/test_resampler.py +++ b/tests/test_resampler.py @@ -21,6 +21,7 @@ from typing_extensions import assert_type from tests import ( + PD_LTE_22, TYPE_CHECKING_INVALID_USAGE, check, pytest_warns_bounded, @@ -148,7 +149,11 @@ def test_interpolate() -> None: def test_interpolate_inplace() -> None: - check(assert_type(DF.resample("ME").interpolate(inplace=True), None), type(None)) + if PD_LTE_22: + # Bug in main see https://github.com/pandas-dev/pandas/issues/58690 + check( + assert_type(DF.resample("ME").interpolate(inplace=True), None), type(None) + ) def test_pipe() -> None: @@ -360,7 +365,9 @@ def test_interpolate_series() -> None: def test_interpolate_inplace_series() -> None: - check(assert_type(S.resample("ME").interpolate(inplace=True), None), type(None)) + if PD_LTE_22: + # Bug in main see https://github.com/pandas-dev/pandas/issues/58690 + check(assert_type(S.resample("ME").interpolate(inplace=True), None), type(None)) def test_pipe_series() -> None: diff --git a/tests/test_series.py b/tests/test_series.py index d2a8af78..efd368f8 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -145,13 +145,15 @@ def test_types_copy() -> None: def test_types_select() -> None: s = pd.Series(data={"row1": 1, "row2": 2}) - with pytest_warns_bounded( - FutureWarning, - "Series.__getitem__ treating keys as positions is deprecated", - lower="2.0.99", - ): - s[0] - s[1:] + if PD_LTE_22: + # Not valid in 3.0 + with pytest_warns_bounded( + FutureWarning, + "Series.__getitem__ treating keys as positions is deprecated", + lower="2.0.99", + ): + s[0] + s[1:] def test_types_iloc_iat() -> None: @@ -1710,20 +1712,21 @@ def test_bitwise_operators() -> None: check(assert_type(s ^ s2, "pd.Series[int]"), pd.Series, np.integer) check(assert_type(s2 ^ s, "pd.Series[int]"), pd.Series, np.integer) - with pytest_warns_bounded( - FutureWarning, - r"Logical ops \(and, or, xor\) between Pandas objects and dtype-less sequences " - r"\(e.g. list, tuple\) are deprecated", - lower="2.0.99", - ): - check(assert_type(s & [1, 2, 3, 4], "pd.Series[bool]"), pd.Series, np.bool_) - check(assert_type([1, 2, 3, 4] & s, "pd.Series[bool]"), pd.Series, np.bool_) + if PD_LTE_22: + with pytest_warns_bounded( + FutureWarning, + r"Logical ops \(and, or, xor\) between Pandas objects and dtype-less sequences " + r"\(e.g. list, tuple\) are deprecated", + lower="2.0.99", + ): + check(assert_type(s & [1, 2, 3, 4], "pd.Series[bool]"), pd.Series, np.bool_) + check(assert_type([1, 2, 3, 4] & s, "pd.Series[bool]"), pd.Series, np.bool_) - check(assert_type(s | [1, 2, 3, 4], "pd.Series[bool]"), pd.Series, np.bool_) - check(assert_type([1, 2, 3, 4] | s, "pd.Series[bool]"), pd.Series, np.bool_) + check(assert_type(s | [1, 2, 3, 4], "pd.Series[bool]"), pd.Series, np.bool_) + check(assert_type([1, 2, 3, 4] | s, "pd.Series[bool]"), pd.Series, np.bool_) - check(assert_type(s ^ [1, 2, 3, 4], "pd.Series[bool]"), pd.Series, np.bool_) - check(assert_type([1, 2, 3, 4] ^ s, "pd.Series[bool]"), pd.Series, np.bool_) + check(assert_type(s ^ [1, 2, 3, 4], "pd.Series[bool]"), pd.Series, np.bool_) + check(assert_type([1, 2, 3, 4] ^ s, "pd.Series[bool]"), pd.Series, np.bool_) def test_logical_operators() -> None: @@ -1757,42 +1760,43 @@ def test_logical_operators() -> None: check(assert_type(True ^ (df["a"] >= 2), "pd.Series[bool]"), pd.Series, np.bool_) - with pytest_warns_bounded( - FutureWarning, - r"Logical ops \(and, or, xor\) between Pandas objects and dtype-less sequences " - r"\(e.g. list, tuple\) are deprecated", - lower="2.0.99", - ): - check( - assert_type((df["a"] >= 2) ^ [True, False, True], "pd.Series[bool]"), - pd.Series, - np.bool_, - ) - check( - assert_type((df["a"] >= 2) & [True, False, True], "pd.Series[bool]"), - pd.Series, - np.bool_, - ) - check( - assert_type((df["a"] >= 2) | [True, False, True], "pd.Series[bool]"), - pd.Series, - np.bool_, - ) - check( - assert_type([True, False, True] & (df["a"] >= 2), "pd.Series[bool]"), - pd.Series, - np.bool_, - ) - check( - assert_type([True, False, True] | (df["a"] >= 2), "pd.Series[bool]"), - pd.Series, - np.bool_, - ) - check( - assert_type([True, False, True] ^ (df["a"] >= 2), "pd.Series[bool]"), - pd.Series, - np.bool_, - ) + if PD_LTE_22: + with pytest_warns_bounded( + FutureWarning, + r"Logical ops \(and, or, xor\) between Pandas objects and dtype-less sequences " + r"\(e.g. list, tuple\) are deprecated", + lower="2.0.99", + ): + check( + assert_type((df["a"] >= 2) ^ [True, False, True], "pd.Series[bool]"), + pd.Series, + np.bool_, + ) + check( + assert_type((df["a"] >= 2) & [True, False, True], "pd.Series[bool]"), + pd.Series, + np.bool_, + ) + check( + assert_type((df["a"] >= 2) | [True, False, True], "pd.Series[bool]"), + pd.Series, + np.bool_, + ) + check( + assert_type([True, False, True] & (df["a"] >= 2), "pd.Series[bool]"), + pd.Series, + np.bool_, + ) + check( + assert_type([True, False, True] | (df["a"] >= 2), "pd.Series[bool]"), + pd.Series, + np.bool_, + ) + check( + assert_type([True, False, True] ^ (df["a"] >= 2), "pd.Series[bool]"), + pd.Series, + np.bool_, + ) def test_AnyArrayLike_and_clip() -> None: diff --git a/tests/test_timefuncs.py b/tests/test_timefuncs.py index 173a4a41..e3dcb9a8 100644 --- a/tests/test_timefuncs.py +++ b/tests/test_timefuncs.py @@ -459,7 +459,12 @@ def test_series_dt_accessors() -> None: check(assert_type(s2.dt.microseconds, "pd.Series[int]"), pd.Series, np.integer) check(assert_type(s2.dt.nanoseconds, "pd.Series[int]"), pd.Series, np.integer) check(assert_type(s2.dt.components, pd.DataFrame), pd.DataFrame) - check(assert_type(s2.dt.to_pytimedelta(), np.ndarray), np.ndarray) + with pytest_warns_bounded( + FutureWarning, + "The behavior of TimedeltaProperties.to_pytimedelta is deprecated", + lower="2.2.99", + ): + check(assert_type(s2.dt.to_pytimedelta(), np.ndarray), np.ndarray) check(assert_type(s2.dt.total_seconds(), "pd.Series[float]"), pd.Series, float) check(assert_type(s2.dt.unit, TimeUnit), str) check(assert_type(s2.dt.as_unit("s"), "TimedeltaSeries"), pd.Series, pd.Timedelta) diff --git a/tests/test_windowing.py b/tests/test_windowing.py index db935c31..3186415c 100644 --- a/tests/test_windowing.py +++ b/tests/test_windowing.py @@ -15,6 +15,7 @@ from typing_extensions import assert_type from tests import ( + PD_LTE_22, check, pytest_warns_bounded, ) @@ -339,22 +340,24 @@ def test_ewm_basic_math() -> None: def test_ewm_aggregate() -> None: - with pytest_warns_bounded( - FutureWarning, - r"The provided callable is currently using ", - upper="2.2.99", - ): - check(assert_type(DF.ewm(span=10).aggregate(np.mean), DataFrame), DataFrame) - check( - assert_type(DF.ewm(span=10).aggregate(["mean", np.mean]), DataFrame), - DataFrame, - ) - check( - assert_type( - DF.ewm(span=10).aggregate({"col1": "mean", "col2": np.mean}), DataFrame - ), - DataFrame, - ) + if PD_LTE_22: + with pytest_warns_bounded( + FutureWarning, + r"The provided callable is currently using ", + upper="2.2.99", + ): + check(assert_type(DF.ewm(span=10).aggregate(np.mean), DataFrame), DataFrame) + check( + assert_type(DF.ewm(span=10).aggregate(["mean", np.mean]), DataFrame), + DataFrame, + ) + check( + assert_type( + DF.ewm(span=10).aggregate({"col1": "mean", "col2": np.mean}), + DataFrame, + ), + DataFrame, + ) check(assert_type(DF.ewm(span=10).agg("sum"), DataFrame), DataFrame) @@ -368,22 +371,24 @@ def test_ewm_basic_math_series() -> None: def test_ewm_aggregate_series() -> None: - with pytest_warns_bounded( - FutureWarning, - r"The provided callable is currently using ", - upper="2.2.99", - ): - check(assert_type(S.ewm(span=10).aggregate(np.mean), Series), Series) - check( - assert_type(S.ewm(span=10).aggregate(["mean", np.mean]), DataFrame), - DataFrame, - ) - check( - assert_type( - S.ewm(span=10).aggregate({"col1": "mean", "col2": np.mean}), DataFrame - ), - DataFrame, - ) + if PD_LTE_22: + with pytest_warns_bounded( + FutureWarning, + r"The provided callable is currently using ", + upper="2.2.99", + ): + check(assert_type(S.ewm(span=10).aggregate(np.mean), Series), Series) + check( + assert_type(S.ewm(span=10).aggregate(["mean", np.mean]), DataFrame), + DataFrame, + ) + check( + assert_type( + S.ewm(span=10).aggregate({"col1": "mean", "col2": np.mean}), + DataFrame, + ), + DataFrame, + ) check(assert_type(S.ewm(span=10).agg("sum"), Series), Series)