diff --git a/pandas-stubs/_libs/tslibs/offsets.pyi b/pandas-stubs/_libs/tslibs/offsets.pyi index 2bed61cf2..d22658831 100644 --- a/pandas-stubs/_libs/tslibs/offsets.pyi +++ b/pandas-stubs/_libs/tslibs/offsets.pyi @@ -125,7 +125,12 @@ class BusinessMixin(SingleConstructorOffset): self, n: int = ..., normalize: bool = ..., offset: timedelta = ... ) -> None: ... -class BusinessDay(BusinessMixin): ... +# Changed from implementation because it is not allowed for `PeriodDtype` +class BusinessDay(BaseOffset): + def __init__( + self, n: int = ..., normalize: bool = ..., offset: timedelta = ... + ) -> None: ... + def __reduce__(self): ... class BusinessHour(BusinessMixin): def __init__( diff --git a/pandas-stubs/core/dtypes/dtypes.pyi b/pandas-stubs/core/dtypes/dtypes.pyi index 7c075d8f5..009134866 100644 --- a/pandas-stubs/core/dtypes/dtypes.pyi +++ b/pandas-stubs/core/dtypes/dtypes.pyi @@ -11,6 +11,10 @@ from pandas.core.series import Series from pandas._libs import NaTType from pandas._libs.tslibs import BaseOffset +from pandas._libs.tslibs.offsets import ( + RelativeDeltaOffset, + SingleConstructorOffset, +) from pandas._typing import ( Ordered, npt, @@ -48,7 +52,9 @@ class DatetimeTZDtype(PandasExtensionDtype): def na_value(self) -> NaTType: ... class PeriodDtype(PandasExtensionDtype): - def __init__(self, freq: str | BaseOffset = ...) -> None: ... + def __init__( + self, freq: str | SingleConstructorOffset | RelativeDeltaOffset = ... + ) -> None: ... @property def freq(self) -> BaseOffset: ... @property diff --git a/pandas-stubs/core/frame.pyi b/pandas-stubs/core/frame.pyi index d2394cdf5..7af2fcbab 100644 --- a/pandas-stubs/core/frame.pyi +++ b/pandas-stubs/core/frame.pyi @@ -998,7 +998,7 @@ class DataFrame(NDFrame, OpsMixin): def groupby( self, by: Scalar, - axis: Axis = ..., + axis: AxisIndex = ..., level: Level | None = ..., as_index: _bool = ..., sort: _bool = ..., @@ -1011,7 +1011,7 @@ class DataFrame(NDFrame, OpsMixin): def groupby( self, by: DatetimeIndex, - axis: Axis = ..., + axis: AxisIndex = ..., level: Level | None = ..., as_index: _bool = ..., sort: _bool = ..., @@ -1024,7 +1024,7 @@ class DataFrame(NDFrame, OpsMixin): def groupby( self, by: TimedeltaIndex, - axis: Axis = ..., + axis: AxisIndex = ..., level: Level | None = ..., as_index: _bool = ..., sort: _bool = ..., @@ -1037,7 +1037,7 @@ class DataFrame(NDFrame, OpsMixin): def groupby( self, by: PeriodIndex, - axis: Axis = ..., + axis: AxisIndex = ..., level: Level | None = ..., as_index: _bool = ..., sort: _bool = ..., @@ -1050,7 +1050,7 @@ class DataFrame(NDFrame, OpsMixin): def groupby( self, by: IntervalIndex[IntervalT], - axis: Axis = ..., + axis: AxisIndex = ..., level: Level | None = ..., as_index: _bool = ..., sort: _bool = ..., @@ -1063,7 +1063,7 @@ class DataFrame(NDFrame, OpsMixin): def groupby( self, by: MultiIndex | GroupByObjectNonScalar | None = ..., - axis: Axis = ..., + axis: AxisIndex = ..., level: Level | None = ..., as_index: _bool = ..., sort: _bool = ..., @@ -1076,7 +1076,7 @@ class DataFrame(NDFrame, OpsMixin): def groupby( self, by: Series[SeriesByT], - axis: Axis = ..., + axis: AxisIndex = ..., level: Level | None = ..., as_index: _bool = ..., sort: _bool = ..., @@ -1089,7 +1089,7 @@ class DataFrame(NDFrame, OpsMixin): def groupby( self, by: CategoricalIndex | Index | Series, - axis: Axis = ..., + axis: AxisIndex = ..., level: Level | None = ..., as_index: _bool = ..., sort: _bool = ..., @@ -1643,7 +1643,7 @@ class DataFrame(NDFrame, OpsMixin): def expanding( self, min_periods: int = ..., - axis: Axis = ..., + axis: AxisIndex = ..., method: CalculationMethod = ..., ) -> Expanding[DataFrame]: ... @overload @@ -1962,7 +1962,7 @@ class DataFrame(NDFrame, OpsMixin): min_periods: int | None = ..., center: _bool = ..., on: Hashable | None = ..., - axis: Axis = ..., + axis: AxisIndex = ..., closed: IntervalClosedType | None = ..., step: int | None = ..., method: CalculationMethod = ..., @@ -1976,7 +1976,7 @@ class DataFrame(NDFrame, OpsMixin): min_periods: int | None = ..., center: _bool = ..., on: Hashable | None = ..., - axis: Axis = ..., + axis: AxisIndex = ..., closed: IntervalClosedType | None = ..., step: int | None = ..., method: CalculationMethod = ..., diff --git a/pandas-stubs/core/groupby/generic.pyi b/pandas-stubs/core/groupby/generic.pyi index 550b8e81e..fc61fbb3d 100644 --- a/pandas-stubs/core/groupby/generic.pyi +++ b/pandas-stubs/core/groupby/generic.pyi @@ -146,15 +146,24 @@ class DataFrameGroupBy(GroupBy, Generic[ByT]): # error: Overload 3 for "apply" will never be used because its parameters overlap overload 1 @overload def apply( # type: ignore[misc] - self, func: Callable[[DataFrame], Scalar | list | dict], *args, **kwargs + self, + func: Callable[[DataFrame], Scalar | list | dict], + *args, + **kwargs, ) -> Series: ... @overload def apply( - self, func: Callable[[DataFrame], Series | DataFrame], *args, **kwargs + self, + func: Callable[[DataFrame], Series | DataFrame], + *args, + **kwargs, ) -> DataFrame: ... @overload def apply( # pyright: ignore[reportOverlappingOverload] - self, func: Callable[[Iterable], float], *args, **kwargs + self, + func: Callable[[Iterable], float], + *args, + **kwargs, ) -> DataFrame: ... # error: overload 1 overlaps overload 2 because of different return types @overload diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 12f8f9524..374e2830f 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -1637,12 +1637,10 @@ class Series(IndexOpsMixin[S1], NDFrame): min_periods: int = ..., adjust: _bool = ..., ignore_na: _bool = ..., - axis: AxisIndex = ..., ) -> ExponentialMovingWindow[Series]: ... def expanding( self, min_periods: int = ..., - axis: AxisIndex = ..., method: CalculationMethod = ..., ) -> Expanding[Series]: ... def floordiv( @@ -1825,7 +1823,6 @@ class Series(IndexOpsMixin[S1], NDFrame): min_periods: int | None = ..., center: _bool = ..., on: _str | None = ..., - axis: AxisIndex = ..., closed: IntervalClosedType | None = ..., step: int | None = ..., method: CalculationMethod = ..., @@ -1839,7 +1836,6 @@ class Series(IndexOpsMixin[S1], NDFrame): min_periods: int | None = ..., center: _bool = ..., on: _str | None = ..., - axis: AxisIndex = ..., closed: IntervalClosedType | None = ..., step: int | None = ..., method: CalculationMethod = ..., diff --git a/pyproject.toml b/pyproject.toml index b2a23e1c3..6795e779c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,14 +32,15 @@ packages = [ [tool.poetry.dependencies] python = ">=3.9" types-pytz = ">= 2022.1.1" -numpy = ">=1.25.0" +numpy = { version = ">=1.26.0", python = "<3.13" } [tool.poetry.dev-dependencies] mypy = "1.5.1" -pandas = "2.0.3" +pandas = "2.1.1" pyarrow = ">=10.0.1" pytest = ">=7.1.2" -pyright = ">= 1.1.327" +# pyright 1.1.327 has bug fixed in 1.1.328 +pyright = "1.1.326" poethepoet = ">=0.16.5" loguru = ">=0.6.0" typing-extensions = ">=4.4.0" @@ -58,7 +59,7 @@ odfpy = ">=1.4.1" xarray = ">=22.6.0" tabulate = ">=0.8.10" jinja2 = ">=3.1" -scipy = ">=1.9.1" +scipy = { version = ">=1.9.1", python = "<3.13" } SQLAlchemy = ">=2.0.12" types-python-dateutil = ">=2.8.19" numexpr = "<2.8.5" # https://github.com/pandas-dev/pandas/issues/54449 @@ -195,3 +196,7 @@ useLibraryCodeForTypes = false [tool.codespell] ignore-words-list = "indext, mose, sav, ser" + +# Next line needed to avoid poetry complaint +[tool.setuptools_scm] + diff --git a/tests/__init__.py b/tests/__init__.py index 7c4c7293b..847f7f52a 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -20,7 +20,7 @@ TYPE_CHECKING_INVALID_USAGE: Final = TYPE_CHECKING WINDOWS = os.name == "nt" or "cygwin" in platform.system().lower() -PD_LTE_20 = Version(pd.__version__) < Version("2.0.999") +PD_LTE_21 = Version(pd.__version__) < Version("2.1.999") def check(actual: T, klass: type, dtype: type | None = None, attr: str = "left") -> T: diff --git a/tests/test_dtypes.py b/tests/test_dtypes.py index 065861772..c9b2c4a5b 100644 --- a/tests/test_dtypes.py +++ b/tests/test_dtypes.py @@ -57,11 +57,13 @@ def test_period_dtype() -> None: p_dt = pd.PeriodDtype(freq="D") check(assert_type(p_dt, pd.PeriodDtype), pd.PeriodDtype) check(assert_type(pd.PeriodDtype(freq=Day()), pd.PeriodDtype), pd.PeriodDtype) - check( - assert_type(pd.PeriodDtype(freq=BusinessDay()), pd.PeriodDtype), pd.PeriodDtype - ) if TYPE_CHECKING_INVALID_USAGE: - pd.PeriodDtype(freq=CustomBusinessDay()) # TODO(raises on 2.1) + pd.PeriodDtype( + freq=CustomBusinessDay() # type:ignore[arg-type] # pyright: ignore[reportGeneralTypeIssues] + ) + pd.PeriodDtype( + freq=BusinessDay() # type:ignore[arg-type] # pyright: ignore[reportGeneralTypeIssues] + ) check( assert_type(p_dt.freq, pd.tseries.offsets.BaseOffset), pd.tseries.offsets.DateOffset, diff --git a/tests/test_frame.py b/tests/test_frame.py index e1e1f7e27..bb4ea46f7 100644 --- a/tests/test_frame.py +++ b/tests/test_frame.py @@ -39,7 +39,6 @@ from pandas._typing import Scalar from tests import ( - PD_LTE_20, TYPE_CHECKING_INVALID_USAGE, check, pytest_warns_bounded, @@ -180,9 +179,8 @@ class MyEnum(Enum): def test_slice_setitem() -> None: - # Due to the bug in pandas 1.2.3(https://github.com/pandas-dev/pandas/issues/40440), this is in separate test case df = pd.DataFrame(data={"col1": [1, 2], "col2": [3, 4], 5: [6, 7]}) - df[1:] = ["a", "b", "c"] + df[1:] = [10, 11, 12] def test_types_setitem() -> None: @@ -387,9 +385,9 @@ def test_types_mean() -> None: s1: pd.Series = df.mean() s2: pd.Series = df.mean(axis=0) df2: pd.DataFrame = df.groupby(level=0).mean() - if PD_LTE_20: - df3: pd.DataFrame = df.groupby(axis=1, level=0).mean() - df4: pd.DataFrame = df.groupby(axis=1, level=0, dropna=True).mean() + if TYPE_CHECKING_INVALID_USAGE: + df3: pd.DataFrame = df.groupby(axis=1, level=0).mean() # type: ignore[call-overload] # pyright: ignore[reportGeneralTypeIssues] + df4: pd.DataFrame = df.groupby(axis=1, level=0, dropna=True).mean() # type: ignore[call-overload] # pyright: ignore[reportGeneralTypeIssues] s3: pd.Series = df.mean(axis=1, skipna=True, numeric_only=False) @@ -398,9 +396,9 @@ def test_types_median() -> None: s1: pd.Series = df.median() s2: pd.Series = df.median(axis=0) df2: pd.DataFrame = df.groupby(level=0).median() - if PD_LTE_20: - df3: pd.DataFrame = df.groupby(axis=1, level=0).median() - df4: pd.DataFrame = df.groupby(axis=1, level=0, dropna=True).median() + if TYPE_CHECKING_INVALID_USAGE: + df3: pd.DataFrame = df.groupby(axis=1, level=0).median() # type: ignore[call-overload] # pyright: ignore[reportGeneralTypeIssues] + df4: pd.DataFrame = df.groupby(axis=1, level=0, dropna=True).median() # type: ignore[call-overload] # pyright: ignore[reportGeneralTypeIssues] s3: pd.Series = df.median(axis=1, skipna=True, numeric_only=False) @@ -1068,11 +1066,10 @@ def test_types_plot() -> None: def test_types_window() -> None: df = pd.DataFrame(data={"col1": [1, 1, 2], "col2": [3, 4, 5]}) df.expanding() - if PD_LTE_20: - df.expanding(axis=1) - df.rolling(2, axis=1, center=True) if TYPE_CHECKING_INVALID_USAGE: - df.expanding(axis=1, center=True) # type: ignore[call-arg] # pyright: ignore[reportGeneralTypeIssues] + df.expanding(axis=1) # type: ignore[arg-type] # pyright: ignore[reportGeneralTypeIssues] + df.rolling(2, axis=1, center=True) # type: ignore[call-overload] # pyright: ignore[reportGeneralTypeIssues] + df.expanding(axis=1, center=True) # type: ignore[arg-type, call-arg] # pyright: ignore[reportGeneralTypeIssues] df.rolling(2) @@ -1311,7 +1308,8 @@ def test_types_to_html() -> None: def test_types_resample() -> None: df = pd.DataFrame({"values": [2, 11, 3, 13, 14, 18, 17, 19]}) df["date"] = pd.date_range("01/01/2018", periods=8, freq="W") - df.resample("M", on="date") + with pytest_warns_bounded(UserWarning, "'M' will be deprecated", lower="2.1.99"): + df.resample("M", on="date") # origin and offset params added in 1.1.0 https://pandas.pydata.org/docs/whatsnew/v1.1.0.html df.resample("20min", origin="epoch", offset=pd.Timedelta(2, "minutes"), on="date") @@ -1355,17 +1353,18 @@ def test_pipe() -> None: def foo(df: pd.DataFrame) -> pd.DataFrame: return pd.DataFrame(df) - val = ( - pd.DataFrame( - { - "price": [10, 11, 9, 13, 14, 18, 17, 19], - "volume": [50, 60, 40, 100, 50, 100, 40, 50], - } + with pytest_warns_bounded(UserWarning, "'M' will be deprecated", lower="2.1.99"): + val = ( + pd.DataFrame( + { + "price": [10, 11, 9, 13, 14, 18, 17, 19], + "volume": [50, 60, 40, 100, 50, 100, 40, 50], + } + ) + .assign(week_starting=pd.date_range("01/01/2018", periods=8, freq="W")) + .resample("M", on="week_starting") + .pipe(foo) ) - .assign(week_starting=pd.date_range("01/01/2018", periods=8, freq="W")) - .resample("M", on="week_starting") - .pipe(foo) - ) check(assert_type(val, pd.DataFrame), pd.DataFrame) @@ -2207,53 +2206,84 @@ def test_groupby_apply() -> None: def sum_mean(x: pd.DataFrame) -> float: return x.sum().mean() - check(assert_type(df.groupby("col1").apply(sum_mean), pd.Series), pd.Series) + with pytest_warns_bounded( + FutureWarning, + "DataFrameGroupBy.apply operated on the grouping columns.", + lower="2.1.99", + ): + check( + assert_type(df.groupby("col1").apply(sum_mean), pd.Series), + pd.Series, + ) lfunc: Callable[[pd.DataFrame], float] = lambda x: x.sum().mean() - check(assert_type(df.groupby("col1").apply(lfunc), pd.Series), pd.Series) + with pytest_warns_bounded( + FutureWarning, + "DataFrameGroupBy.apply operated on the grouping columns.", + lower="2.1.99", + ): + check(assert_type(df.groupby("col1").apply(lfunc), pd.Series), pd.Series) def sum_to_list(x: pd.DataFrame) -> list: return x.sum().tolist() - check(assert_type(df.groupby("col1").apply(sum_to_list), pd.Series), pd.Series) + with pytest_warns_bounded( + FutureWarning, + "DataFrameGroupBy.apply operated on the grouping columns.", + lower="2.1.99", + ): + check(assert_type(df.groupby("col1").apply(sum_to_list), pd.Series), pd.Series) def sum_to_series(x: pd.DataFrame) -> pd.Series: return x.sum() - check( - assert_type(df.groupby("col1").apply(sum_to_series), pd.DataFrame), pd.DataFrame - ) + with pytest_warns_bounded( + FutureWarning, + "DataFrameGroupBy.apply operated on the grouping columns.", + lower="2.1.99", + ): + check( + assert_type(df.groupby("col1").apply(sum_to_series), pd.DataFrame), + pd.DataFrame, + ) def sample_to_df(x: pd.DataFrame) -> pd.DataFrame: return x.sample() - check( - assert_type( - df.groupby("col1", group_keys=False).apply(sample_to_df), pd.DataFrame - ), - pd.DataFrame, - ) + with pytest_warns_bounded( + FutureWarning, + "DataFrameGroupBy.apply operated on the grouping columns.", + lower="2.1.99", + ): + check( + assert_type( + df.groupby("col1", group_keys=False).apply(sample_to_df), pd.DataFrame + ), + pd.DataFrame, + ) def test_resample() -> None: # GH 181 N = 10 - index = pd.date_range("1/1/2000", periods=N, freq="T") x = [x for x in range(N)] - df = pd.DataFrame({"a": x, "b": x, "c": x}, index=index) - check(assert_type(df.resample("2T").std(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").var(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").quantile(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").sum(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").prod(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").min(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").max(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").first(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").last(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").mean(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").sem(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").median(), pd.DataFrame), pd.DataFrame) - check(assert_type(df.resample("2T").ohlc(), pd.DataFrame), pd.DataFrame) + with pytest_warns_bounded(FutureWarning, "'T' is deprecated", lower="2.1.99"): + index = pd.date_range("1/1/2000", periods=N, freq="T") + x = [x for x in range(N)] + df = pd.DataFrame({"a": x, "b": x, "c": x}, index=index) + check(assert_type(df.resample("2T").std(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").var(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").quantile(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").sum(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").prod(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").min(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").max(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").first(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").last(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").mean(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").sem(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").median(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2T").ohlc(), pd.DataFrame), pd.DataFrame) def test_loc_set() -> None: @@ -2442,7 +2472,8 @@ def test_quantile_150_changes() -> None: def test_resample_150_changes() -> None: idx = pd.date_range("2020-1-1", periods=700) frame = pd.DataFrame(np.random.standard_normal((700, 1)), index=idx, columns=["a"]) - resampler = frame.resample("M", group_keys=True) + with pytest_warns_bounded(UserWarning, "'M' will be deprecated", lower="2.1.99"): + resampler = frame.resample("M", group_keys=True) assert_type(resampler, "Resampler[pd.DataFrame]") def f(s: pd.DataFrame) -> pd.Series: diff --git a/tests/test_indexes.py b/tests/test_indexes.py index 1de763227..a9b6f9119 100644 --- a/tests/test_indexes.py +++ b/tests/test_indexes.py @@ -16,6 +16,7 @@ from tests import ( TYPE_CHECKING_INVALID_USAGE, check, + pytest_warns_bounded, ) @@ -251,16 +252,17 @@ def test_interval_range(): pd.IntervalIndex, pd.Interval, ) - check( - assert_type( - pd.interval_range( - pd.Timestamp(2000, 1, 1), pd.Timestamp(2010, 1, 1), freq="1M" + with pytest_warns_bounded(UserWarning, "'M' will be deprecated", lower="2.1.99"): + check( + assert_type( + pd.interval_range( + pd.Timestamp(2000, 1, 1), pd.Timestamp(2010, 1, 1), freq="1M" + ), + "pd.IntervalIndex[pd.Interval[pd.Timestamp]]", ), - "pd.IntervalIndex[pd.Interval[pd.Timestamp]]", - ), - pd.IntervalIndex, - pd.Interval, - ) + pd.IntervalIndex, + pd.Interval, + ) check( assert_type( pd.interval_range( diff --git a/tests/test_io.py b/tests/test_io.py index ca6274071..20c86788b 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -353,7 +353,12 @@ def test_sas_xport() -> None: def test_hdf(): with ensure_clean() as path: - check(assert_type(DF.to_hdf(path, "df"), None), type(None)) + with pytest_warns_bounded( + FutureWarning, + r".*all arguments of to_hdf except for the argument 'path_or_buf' will be keyword-only", + lower="2.1.99", + ): + check(assert_type(DF.to_hdf(path, "df"), None), type(None)) check(assert_type(read_hdf(path), Union[DataFrame, Series]), DataFrame) @@ -416,7 +421,14 @@ def test_read_hdf_iterator(): version_str=np.__version__, ): with ensure_clean() as path: - check(assert_type(DF.to_hdf(path, "df", format="table"), None), type(None)) + with pytest_warns_bounded( + FutureWarning, + r".*all arguments of to_hdf except for the argument 'path_or_buf' will be keyword-only", + lower="2.1.99", + ): + check( + assert_type(DF.to_hdf(path, "df", format="table"), None), type(None) + ) ti = read_hdf(path, chunksize=1) check(assert_type(ti, TableIterator), TableIterator) ti.close() @@ -436,7 +448,14 @@ def test_hdf_context_manager(): version_str=np.__version__, ): with ensure_clean() as path: - check(assert_type(DF.to_hdf(path, "df", format="table"), None), type(None)) + with pytest_warns_bounded( + FutureWarning, + r".*all arguments of to_hdf except for the argument 'path_or_buf' will be keyword-only", + lower="2.1.99", + ): + check( + assert_type(DF.to_hdf(path, "df", format="table"), None), type(None) + ) with HDFStore(path, mode="r") as store: check(assert_type(store.is_open, bool), bool) check(assert_type(store.get("df"), Union[DataFrame, Series]), DataFrame) @@ -445,7 +464,12 @@ def test_hdf_context_manager(): def test_hdf_series(): s = DF["a"] with ensure_clean() as path: - check(assert_type(s.to_hdf(path, "s"), None), type(None)) + with pytest_warns_bounded( + FutureWarning, + r".*all arguments of to_hdf except for the argument 'path_or_buf' will be keyword-only", + lower="2.1.99", + ): + check(assert_type(s.to_hdf(path, "s"), None), type(None)) check(assert_type(read_hdf(path, "s"), Union[DataFrame, Series]), Series) diff --git a/tests/test_pandas.py b/tests/test_pandas.py index 65a58619f..b709de293 100644 --- a/tests/test_pandas.py +++ b/tests/test_pandas.py @@ -24,7 +24,6 @@ from pandas._typing import Scalar from tests import ( - PD_LTE_20, TYPE_CHECKING_INVALID_USAGE, check, pytest_warns_bounded, @@ -1033,10 +1032,7 @@ def test_merge() -> None: ), pd.DataFrame, ) - if PD_LTE_20: - # https://github.com/pandas-dev/pandas/issues/54055 needs to be fixed - # TODO: When cross don't need on?? - check(assert_type(pd.merge(ls, rs, how="cross"), pd.DataFrame), pd.DataFrame) + check(assert_type(pd.merge(ls, rs, how="cross"), pd.DataFrame), pd.DataFrame) check( assert_type( pd.merge(ls, rs, how="inner", left_index=True, right_index=True), @@ -1962,51 +1958,52 @@ def g(x: pd.Series) -> int: }, index=idx, ) - check( - assert_type( - pd.pivot_table( - df, index=pd.Index(idx.month), columns=Grouper(key="dt", freq="M") + with pytest_warns_bounded(UserWarning, "'M' will be deprecated", lower="2.1.99"): + check( + assert_type( + pd.pivot_table( + df, index=pd.Index(idx.month), columns=Grouper(key="dt", freq="M") + ), + pd.DataFrame, ), pd.DataFrame, - ), - pd.DataFrame, - ) - check( - assert_type( - pd.pivot_table( - df, index=np.array(idx.month), columns=Grouper(key="dt", freq="M") + ) + check( + assert_type( + pd.pivot_table( + df, index=np.array(idx.month), columns=Grouper(key="dt", freq="M") + ), + pd.DataFrame, ), pd.DataFrame, - ), - pd.DataFrame, - ) - check( - assert_type( - pd.pivot_table( - df, index=Grouper(key="dt", freq="M"), columns=pd.Index(idx.month) + ) + check( + assert_type( + pd.pivot_table( + df, index=Grouper(key="dt", freq="M"), columns=pd.Index(idx.month) + ), + pd.DataFrame, ), pd.DataFrame, - ), - pd.DataFrame, - ) - check( - assert_type( - pd.pivot_table( - df, index=Grouper(key="dt", freq="M"), columns=np.array(idx.month) + ) + check( + assert_type( + pd.pivot_table( + df, index=Grouper(key="dt", freq="M"), columns=np.array(idx.month) + ), + pd.DataFrame, ), pd.DataFrame, - ), - pd.DataFrame, - ) - check( - assert_type( - pd.pivot_table( - df, index=Grouper(freq="A"), columns=Grouper(key="dt", freq="M") + ) + check( + assert_type( + pd.pivot_table( + df, index=Grouper(freq="A"), columns=Grouper(key="dt", freq="M") + ), + pd.DataFrame, ), pd.DataFrame, - ), - pd.DataFrame, - ) + ) def test_argmin_and_argmax_return() -> None: diff --git a/tests/test_resampler.py b/tests/test_resampler.py index f87e98942..3129a247e 100644 --- a/tests/test_resampler.py +++ b/tests/test_resampler.py @@ -20,6 +20,7 @@ from pandas._typing import Scalar from tests import ( + PD_LTE_21, check, pytest_warns_bounded, ) @@ -31,57 +32,64 @@ _AggRetType = Union[DataFrame, Series] +if PD_LTE_21: + MonthFreq = "M" +else: + MonthFreq = "ME" + def test_props() -> None: - check(assert_type(DF.resample("m").obj, DataFrame), DataFrame) - check(assert_type(DF.resample("m").ax, Index), DatetimeIndex) + check(assert_type(DF.resample(MonthFreq).obj, DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).ax, Index), DatetimeIndex) def test_iter() -> None: assert_type( - iter(DF.resample("m")), Generator[tuple[Hashable, DataFrame], None, None] + iter(DF.resample(MonthFreq)), Generator[tuple[Hashable, DataFrame], None, None] ) - for v in DF.resample("m"): + for v in DF.resample(MonthFreq): check(assert_type(v, tuple[Hashable, DataFrame]), tuple) def test_agg_funcs() -> None: - check(assert_type(DF.resample("m").sum(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").prod(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").min(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").max(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").first(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").last(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").mean(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").sum(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").median(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").ohlc(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").nunique(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).sum(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).prod(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).min(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).max(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).first(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).last(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).mean(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).sum(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).median(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).ohlc(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).nunique(), DataFrame), DataFrame) def test_quantile() -> None: - check(assert_type(DF.resample("m").quantile(0.5), DataFrame), DataFrame) - check(assert_type(DF.resample("m").quantile([0.5, 0.7]), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).quantile(0.5), DataFrame), DataFrame) + check( + assert_type(DF.resample(MonthFreq).quantile([0.5, 0.7]), DataFrame), DataFrame + ) check( - assert_type(DF.resample("m").quantile(np.array([0.5, 0.7])), DataFrame), + assert_type(DF.resample(MonthFreq).quantile(np.array([0.5, 0.7])), DataFrame), DataFrame, ) def test_std_var() -> None: - check(assert_type(DF.resample("m").std(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").var(2), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).std(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).var(2), DataFrame), DataFrame) def test_size_count() -> None: - check(assert_type(DF.resample("m").size(), Series), Series) - check(assert_type(DF.resample("m").count(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).size(), Series), Series) + check(assert_type(DF.resample(MonthFreq).count(), DataFrame), DataFrame) def test_filling() -> None: - check(assert_type(DF.resample("m").ffill(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").nearest(), DataFrame), DataFrame) - check(assert_type(DF.resample("m").bfill(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).ffill(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).nearest(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).bfill(), DataFrame), DataFrame) def test_fillna() -> None: @@ -90,12 +98,14 @@ def test_fillna() -> None: "DatetimeIndexResampler.fillna is deprecated ", lower="2.0.99", ): - check(assert_type(DF.resample("m").fillna("pad"), DataFrame), DataFrame) - check(assert_type(DF.resample("m").fillna("backfill"), DataFrame), DataFrame) - check(assert_type(DF.resample("m").fillna("ffill"), DataFrame), DataFrame) - check(assert_type(DF.resample("m").fillna("bfill"), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).fillna("pad"), DataFrame), DataFrame) + check( + assert_type(DF.resample(MonthFreq).fillna("backfill"), DataFrame), DataFrame + ) + check(assert_type(DF.resample(MonthFreq).fillna("ffill"), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).fillna("bfill"), DataFrame), DataFrame) check( - assert_type(DF.resample("m").fillna("nearest", limit=2), DataFrame), + assert_type(DF.resample(MonthFreq).fillna("nearest", limit=2), DataFrame), DataFrame, ) @@ -106,27 +116,36 @@ def test_aggregate() -> None: r"The provided callable is currently using ", lower="2.0.99", ): - check(assert_type(DF.resample("m").aggregate(np.sum), _AggRetType), DataFrame) - check(assert_type(DF.resample("m").agg(np.sum), _AggRetType), DataFrame) - check(assert_type(DF.resample("m").apply(np.sum), _AggRetType), DataFrame) check( - assert_type(DF.resample("m").aggregate([np.sum, np.mean]), _AggRetType), + assert_type(DF.resample(MonthFreq).aggregate(np.sum), _AggRetType), + DataFrame, + ) + check(assert_type(DF.resample(MonthFreq).agg(np.sum), _AggRetType), DataFrame) + check(assert_type(DF.resample(MonthFreq).apply(np.sum), _AggRetType), DataFrame) + check( + assert_type( + DF.resample(MonthFreq).aggregate([np.sum, np.mean]), _AggRetType + ), DataFrame, ) check( - assert_type(DF.resample("m").aggregate(["sum", np.mean]), _AggRetType), + assert_type( + DF.resample(MonthFreq).aggregate(["sum", np.mean]), _AggRetType + ), DataFrame, ) check( assert_type( - DF.resample("m").aggregate({"col1": "sum", "col2": np.mean}), + DF.resample(MonthFreq).aggregate({"col1": "sum", "col2": np.mean}), _AggRetType, ), DataFrame, ) check( assert_type( - DF.resample("m").aggregate({"col1": ["sum", np.mean], "col2": np.mean}), + DF.resample(MonthFreq).aggregate( + {"col1": ["sum", np.mean], "col2": np.mean} + ), _AggRetType, ), DataFrame, @@ -135,99 +154,102 @@ def test_aggregate() -> None: def f(val: DataFrame) -> Series: return val.mean() - check(assert_type(DF.resample("m").aggregate(f), _AggRetType), DataFrame) + check(assert_type(DF.resample(MonthFreq).aggregate(f), _AggRetType), DataFrame) def test_asfreq() -> None: - check(assert_type(DF.resample("m").asfreq(-1.0), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).asfreq(-1.0), DataFrame), DataFrame) def test_getattr() -> None: - check(assert_type(DF.resample("m").col1, SeriesGroupBy), SeriesGroupBy) + check(assert_type(DF.resample(MonthFreq).col1, SeriesGroupBy), SeriesGroupBy) def test_interpolate() -> None: - check(assert_type(DF.resample("m").interpolate(), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).interpolate(), DataFrame), DataFrame) check( - assert_type(DF.resample("m").interpolate(method="time"), DataFrame), DataFrame + assert_type(DF.resample(MonthFreq).interpolate(method="time"), DataFrame), + DataFrame, ) def test_interpolate_inplace() -> None: - check(assert_type(DF.resample("m").interpolate(inplace=True), None), type(None)) + check( + assert_type(DF.resample(MonthFreq).interpolate(inplace=True), None), type(None) + ) def test_pipe() -> None: def f(val: DataFrame) -> DataFrame: return DataFrame(val) - check(assert_type(DF.resample("m").pipe(f), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).pipe(f), DataFrame), DataFrame) def g(val: DataFrame) -> Series: return val.mean() - check(assert_type(DF.resample("m").pipe(g), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).pipe(g), DataFrame), DataFrame) def h(val: DataFrame) -> float: return val.mean().mean() - check(assert_type(DF.resample("m").pipe(h), Series), Series) + check(assert_type(DF.resample(MonthFreq).pipe(h), Series), Series) def test_transform() -> None: def f(val: Series) -> Series: return -1 * val - check(assert_type(DF.resample("m").transform(f), DataFrame), DataFrame) + check(assert_type(DF.resample(MonthFreq).transform(f), DataFrame), DataFrame) def test_props_series() -> None: - check(assert_type(S.resample("m").obj, Series), Series) - check(assert_type(S.resample("m").ax, Index), DatetimeIndex) + check(assert_type(S.resample(MonthFreq).obj, Series), Series) + check(assert_type(S.resample(MonthFreq).ax, Index), DatetimeIndex) def test_iter_series() -> None: - for v in S.resample("m"): + for v in S.resample(MonthFreq): check(assert_type(v, tuple[Hashable, Series]), tuple) def test_agg_funcs_series() -> None: - check(assert_type(S.resample("m").sum(), Series), Series) - check(assert_type(S.resample("m").prod(), Series), Series) - check(assert_type(S.resample("m").min(), Series), Series) - check(assert_type(S.resample("m").max(), Series), Series) - check(assert_type(S.resample("m").first(), Series), Series) - check(assert_type(S.resample("m").last(), Series), Series) - check(assert_type(S.resample("m").mean(), Series), Series) - check(assert_type(S.resample("m").sum(), Series), Series) - check(assert_type(S.resample("m").median(), Series), Series) - check(assert_type(S.resample("m").ohlc(), DataFrame), DataFrame) - check(assert_type(S.resample("m").nunique(), Series), Series) + check(assert_type(S.resample(MonthFreq).sum(), Series), Series) + check(assert_type(S.resample(MonthFreq).prod(), Series), Series) + check(assert_type(S.resample(MonthFreq).min(), Series), Series) + check(assert_type(S.resample(MonthFreq).max(), Series), Series) + check(assert_type(S.resample(MonthFreq).first(), Series), Series) + check(assert_type(S.resample(MonthFreq).last(), Series), Series) + check(assert_type(S.resample(MonthFreq).mean(), Series), Series) + check(assert_type(S.resample(MonthFreq).sum(), Series), Series) + check(assert_type(S.resample(MonthFreq).median(), Series), Series) + check(assert_type(S.resample(MonthFreq).ohlc(), DataFrame), DataFrame) + check(assert_type(S.resample(MonthFreq).nunique(), Series), Series) def test_quantile_series() -> None: - check(assert_type(S.resample("m").quantile(0.5), Series), Series) - check(assert_type(S.resample("m").quantile([0.5, 0.7]), Series), Series) + check(assert_type(S.resample(MonthFreq).quantile(0.5), Series), Series) + check(assert_type(S.resample(MonthFreq).quantile([0.5, 0.7]), Series), Series) check( - assert_type(S.resample("m").quantile(np.array([0.5, 0.7])), Series), + assert_type(S.resample(MonthFreq).quantile(np.array([0.5, 0.7])), Series), Series, ) def test_std_var_series() -> None: - check(assert_type(S.resample("m").std(), Series), Series) - check(assert_type(S.resample("m").var(2), Series), Series) + check(assert_type(S.resample(MonthFreq).std(), Series), Series) + check(assert_type(S.resample(MonthFreq).var(2), Series), Series) def test_size_count_series() -> None: - check(assert_type(S.resample("m").size(), Series), Series) - check(assert_type(S.resample("m").count(), Series), Series) + check(assert_type(S.resample(MonthFreq).size(), Series), Series) + check(assert_type(S.resample(MonthFreq).count(), Series), Series) def test_filling_series() -> None: - check(assert_type(S.resample("m").ffill(), Series), Series) - check(assert_type(S.resample("m").nearest(), Series), Series) - check(assert_type(S.resample("m").bfill(), Series), Series) + check(assert_type(S.resample(MonthFreq).ffill(), Series), Series) + check(assert_type(S.resample(MonthFreq).nearest(), Series), Series) + check(assert_type(S.resample(MonthFreq).bfill(), Series), Series) def test_fillna_series() -> None: @@ -236,11 +258,14 @@ def test_fillna_series() -> None: "DatetimeIndexResampler.fillna is deprecated ", lower="2.0.99", ): - check(assert_type(S.resample("m").fillna("pad"), Series), Series) - check(assert_type(S.resample("m").fillna("backfill"), Series), Series) - check(assert_type(S.resample("m").fillna("ffill"), Series), Series) - check(assert_type(S.resample("m").fillna("bfill"), Series), Series) - check(assert_type(S.resample("m").fillna("nearest", limit=2), Series), Series) + check(assert_type(S.resample(MonthFreq).fillna("pad"), Series), Series) + check(assert_type(S.resample(MonthFreq).fillna("backfill"), Series), Series) + check(assert_type(S.resample(MonthFreq).fillna("ffill"), Series), Series) + check(assert_type(S.resample(MonthFreq).fillna("bfill"), Series), Series) + check( + assert_type(S.resample(MonthFreq).fillna("nearest", limit=2), Series), + Series, + ) def test_aggregate_series() -> None: @@ -249,20 +274,22 @@ def test_aggregate_series() -> None: r"The provided callable is currently using ", lower="2.0.99", ): - check(assert_type(S.resample("m").aggregate(np.sum), _AggRetType), Series) - check(assert_type(S.resample("m").agg(np.sum), _AggRetType), Series) - check(assert_type(S.resample("m").apply(np.sum), _AggRetType), Series) + check(assert_type(S.resample(MonthFreq).aggregate(np.sum), _AggRetType), Series) + check(assert_type(S.resample(MonthFreq).agg(np.sum), _AggRetType), Series) + check(assert_type(S.resample(MonthFreq).apply(np.sum), _AggRetType), Series) check( - assert_type(S.resample("m").aggregate([np.sum, np.mean]), _AggRetType), + assert_type( + S.resample(MonthFreq).aggregate([np.sum, np.mean]), _AggRetType + ), DataFrame, ) check( - assert_type(S.resample("m").aggregate(["sum", np.mean]), _AggRetType), + assert_type(S.resample(MonthFreq).aggregate(["sum", np.mean]), _AggRetType), DataFrame, ) check( assert_type( - S.resample("m").aggregate({"col1": "sum", "col2": np.mean}), + S.resample(MonthFreq).aggregate({"col1": "sum", "col2": np.mean}), _AggRetType, ), DataFrame, @@ -271,44 +298,46 @@ def test_aggregate_series() -> None: def f(val: Series) -> float: return val.mean() - check(assert_type(S.resample("m").aggregate(f), _AggRetType), Series) + check(assert_type(S.resample(MonthFreq).aggregate(f), _AggRetType), Series) def test_asfreq_series() -> None: - check(assert_type(S.resample("m").asfreq(-1.0), Series), Series) + check(assert_type(S.resample(MonthFreq).asfreq(-1.0), Series), Series) def test_interpolate_series() -> None: - check(assert_type(S.resample("m").interpolate(), Series), Series) - check(assert_type(S.resample("m").interpolate(method="time"), Series), Series) + check(assert_type(S.resample(MonthFreq).interpolate(), Series), Series) + check(assert_type(S.resample(MonthFreq).interpolate(method="time"), Series), Series) def test_interpolate_inplace_series() -> None: - check(assert_type(S.resample("m").interpolate(inplace=True), None), type(None)) + check( + assert_type(S.resample(MonthFreq).interpolate(inplace=True), None), type(None) + ) def test_pipe_series() -> None: def f(val: Series) -> Series: return Series(val) - check(assert_type(S.resample("m").pipe(f), Series), Series) + check(assert_type(S.resample(MonthFreq).pipe(f), Series), Series) def g(val: Resampler) -> float: return float(val.mean().mean()) - check(assert_type(S.resample("m").pipe(g), Scalar), float) + check(assert_type(S.resample(MonthFreq).pipe(g), Scalar), float) def h(val: Series) -> DataFrame: return DataFrame({0: val, 1: val}) - check(assert_type(S.resample("m").pipe(h), DataFrame), DataFrame) + check(assert_type(S.resample(MonthFreq).pipe(h), DataFrame), DataFrame) def test_transform_series() -> None: def f(val: Series) -> Series: return -1 * val - check(assert_type(S.resample("m").transform(f), Series), Series) + check(assert_type(S.resample(MonthFreq).transform(f), Series), Series) def test_aggregate_series_combinations() -> None: @@ -323,14 +352,16 @@ def s2scalar(val: Series) -> float: r"The provided callable is currently using ", lower="2.0.99", ): - check(S.resample("m").aggregate(np.sum), Series) - check(S.resample("m").aggregate([np.mean]), DataFrame) - check(S.resample("m").aggregate(["sum", np.mean]), DataFrame) - check(S.resample("m").aggregate({"sum": np.sum}), DataFrame) - check(S.resample("m").aggregate({"sum": np.sum, "mean": np.mean}), DataFrame) - check(S.resample("m").aggregate("sum"), Series) - check(S.resample("m").aggregate(s2series), Series) - check(S.resample("m").aggregate(s2scalar), Series) + check(S.resample(MonthFreq).aggregate(np.sum), Series) + check(S.resample(MonthFreq).aggregate([np.mean]), DataFrame) + check(S.resample(MonthFreq).aggregate(["sum", np.mean]), DataFrame) + check(S.resample(MonthFreq).aggregate({"sum": np.sum}), DataFrame) + check( + S.resample(MonthFreq).aggregate({"sum": np.sum, "mean": np.mean}), DataFrame + ) + check(S.resample(MonthFreq).aggregate("sum"), Series) + check(S.resample(MonthFreq).aggregate(s2series), Series) + check(S.resample(MonthFreq).aggregate(s2scalar), Series) def test_aggregate_frame_combinations() -> None: @@ -348,22 +379,32 @@ def df2scalar(val: DataFrame) -> float: r"The provided callable is currently using ", lower="2.0.99", ): - check(DF.resample("m").aggregate(np.sum), DataFrame) - check(DF.resample("m").aggregate([np.mean]), DataFrame) - check(DF.resample("m").aggregate(["sum", np.mean]), DataFrame) - check(DF.resample("m").aggregate({"col1": np.sum}), DataFrame) - check(DF.resample("m").aggregate({"col1": np.sum, "col2": np.mean}), DataFrame) + check(DF.resample(MonthFreq).aggregate(np.sum), DataFrame) + check(DF.resample(MonthFreq).aggregate([np.mean]), DataFrame) + check(DF.resample(MonthFreq).aggregate(["sum", np.mean]), DataFrame) + check(DF.resample(MonthFreq).aggregate({"col1": np.sum}), DataFrame) check( - DF.resample("m").aggregate({"col1": [np.sum], "col2": ["sum", np.mean]}), + DF.resample(MonthFreq).aggregate({"col1": np.sum, "col2": np.mean}), + DataFrame, + ) + check( + DF.resample(MonthFreq).aggregate( + {"col1": [np.sum], "col2": ["sum", np.mean]} + ), + DataFrame, + ) + check( + DF.resample(MonthFreq).aggregate( + {"col1": np.sum, "col2": ["sum", np.mean]} + ), DataFrame, ) check( - DF.resample("m").aggregate({"col1": np.sum, "col2": ["sum", np.mean]}), + DF.resample(MonthFreq).aggregate({"col1": "sum", "col2": [np.mean]}), DataFrame, ) - check(DF.resample("m").aggregate({"col1": "sum", "col2": [np.mean]}), DataFrame) - check(DF.resample("m").aggregate("sum"), DataFrame) - check(DF.resample("m").aggregate(df2frame), DataFrame) - check(DF.resample("m").aggregate(df2series), DataFrame) - check(DF.resample("m").aggregate(df2scalar), DataFrame) + check(DF.resample(MonthFreq).aggregate("sum"), DataFrame) + check(DF.resample(MonthFreq).aggregate(df2frame), DataFrame) + check(DF.resample(MonthFreq).aggregate(df2series), DataFrame) + check(DF.resample(MonthFreq).aggregate(df2scalar), DataFrame) diff --git a/tests/test_scalars.py b/tests/test_scalars.py index 9692676b2..3fad574db 100644 --- a/tests/test_scalars.py +++ b/tests/test_scalars.py @@ -28,6 +28,7 @@ from tests import ( TYPE_CHECKING_INVALID_USAGE, check, + pytest_warns_bounded, ) from pandas.tseries.offsets import Day @@ -384,11 +385,16 @@ def test_interval_cmp(): def test_timedelta_construction() -> None: check(assert_type(pd.Timedelta(1, "H"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta(1, "T"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta(1, "S"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta(1, "L"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta(1, "U"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta(1, "N"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'T' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta(1, "T"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'S' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta(1, "S"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'L' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta(1, "L"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'U' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta(1, "U"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'N' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta(1, "N"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "W"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "w"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "D"), pd.Timedelta), pd.Timedelta) @@ -403,7 +409,8 @@ def test_timedelta_construction() -> None: check(assert_type(pd.Timedelta(1, "minute"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "min"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "minutes"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta(1, "t"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'t' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta(1, "t"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "s"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "seconds"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "sec"), pd.Timedelta), pd.Timedelta) @@ -413,20 +420,23 @@ def test_timedelta_construction() -> None: check(assert_type(pd.Timedelta(1, "millisecond"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "milli"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "millis"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta(1, "l"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'l' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta(1, "l"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "us"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "microseconds"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "microsecond"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "µs"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "micro"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "micros"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta(1, "u"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'u' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta(1, "u"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "ns"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "nanoseconds"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "nano"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "nanos"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(1, "nanosecond"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta(1, "n"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'n' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta(1, "n"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 W"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 w"), pd.Timedelta), pd.Timedelta) @@ -442,7 +452,8 @@ def test_timedelta_construction() -> None: check(assert_type(pd.Timedelta("1 minute"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 min"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 minutes"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta("1 t"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'t' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta("1 t"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 s"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 seconds"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 sec"), pd.Timedelta), pd.Timedelta) @@ -452,20 +463,23 @@ def test_timedelta_construction() -> None: check(assert_type(pd.Timedelta("1 millisecond"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 milli"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 millis"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta("1 l"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'l' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta("1 l"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 us"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 microseconds"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 microsecond"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 µs"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 micro"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 micros"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta("1 u"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'u' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta("1 u"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 ns"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 nanoseconds"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 nano"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 nanos"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta("1 nanosecond"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.Timedelta("1 n"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded(FutureWarning, "'n' is deprecated", lower="2.1.99"): + check(assert_type(pd.Timedelta("1 n"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(days=1), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(seconds=1), pd.Timedelta), pd.Timedelta) check(assert_type(pd.Timedelta(microseconds=1), pd.Timedelta), pd.Timedelta) @@ -1516,11 +1530,11 @@ def test_timestamp_misc_methods() -> None: pd.Timestamp, ) - check(assert_type(ts2.round("1S"), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.round("1S", ambiguous="raise"), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.round("1S", ambiguous=True), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.round("1S", ambiguous=False), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.round("1S", ambiguous="NaT"), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.round("1s"), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.round("1s", ambiguous="raise"), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.round("1s", ambiguous=True), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.round("1s", ambiguous=False), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.round("1s", ambiguous="NaT"), pd.Timestamp), pd.Timestamp) check( assert_type(ts2.round("2H", nonexistent="shift_forward"), pd.Timestamp), @@ -1541,11 +1555,11 @@ def test_timestamp_misc_methods() -> None: pd.Timestamp, ) - check(assert_type(ts2.ceil("1S"), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.ceil("1S", ambiguous="raise"), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.ceil("1S", ambiguous=True), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.ceil("1S", ambiguous=False), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.ceil("1S", ambiguous="NaT"), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.ceil("1s"), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.ceil("1s", ambiguous="raise"), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.ceil("1s", ambiguous=True), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.ceil("1s", ambiguous=False), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.ceil("1s", ambiguous="NaT"), pd.Timestamp), pd.Timestamp) check( assert_type(ts2.ceil("2H", nonexistent="shift_forward"), pd.Timestamp), @@ -1566,11 +1580,11 @@ def test_timestamp_misc_methods() -> None: pd.Timestamp, ) - check(assert_type(ts2.floor("1S"), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.floor("1S", ambiguous="raise"), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.floor("1S", ambiguous=True), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.floor("1S", ambiguous=False), pd.Timestamp), pd.Timestamp) - check(assert_type(ts2.floor("1S", ambiguous="NaT"), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.floor("1s"), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.floor("1s", ambiguous="raise"), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.floor("1s", ambiguous=True), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.floor("1s", ambiguous=False), pd.Timestamp), pd.Timestamp) + check(assert_type(ts2.floor("1s", ambiguous="NaT"), pd.Timestamp), pd.Timestamp) check( assert_type(ts2.floor("2H", nonexistent="shift_forward"), pd.Timestamp), diff --git a/tests/test_series.py b/tests/test_series.py index e5262fc79..10658fc40 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -42,7 +42,6 @@ ) from tests import ( - PD_LTE_20, TYPE_CHECKING_INVALID_USAGE, check, pytest_warns_bounded, @@ -830,10 +829,10 @@ def test_types_plot() -> None: def test_types_window() -> None: s = pd.Series([0, 1, 1, 0, 5, 1, -10]) s.expanding() - if PD_LTE_20: - s.expanding(axis=0) - s.rolling(2, axis=0, center=True) + s.rolling(2, center=True) if TYPE_CHECKING_INVALID_USAGE: + s.expanding(axis=0) # type: ignore[call-arg] # pyright: ignore[reportGeneralTypeIssues] + s.rolling(2, axis=0, center=True) # type: ignore[call-overload] # pyright: ignore[reportGeneralTypeIssues] s.expanding(axis=0, center=True) # type: ignore[call-arg] # pyright: ignore[reportGeneralTypeIssues] s.rolling(2) @@ -978,8 +977,8 @@ def test_types_describe() -> None: def test_types_resample() -> None: - s = pd.Series(range(9), index=pd.date_range("1/1/2000", periods=9, freq="T")) - s.resample("3T").sum() + s = pd.Series(range(9), index=pd.date_range("1/1/2000", periods=9, freq="min")) + s.resample("3min").sum() # origin and offset params added in 1.1.0 https://pandas.pydata.org/docs/whatsnew/v1.1.0.html s.resample("20min", origin="epoch", offset=pd.Timedelta(value=2, unit="minutes")) @@ -1069,14 +1068,21 @@ def test_types_bfill() -> None: def test_types_ewm() -> None: s1 = pd.Series([1, 2, 3]) - if PD_LTE_20: + if TYPE_CHECKING_INVALID_USAGE: check( assert_type( - s1.ewm(com=0.3, min_periods=0, adjust=False, ignore_na=True, axis=0), + s1.ewm(com=0.3, min_periods=0, adjust=False, ignore_na=True, axis=0), # type: ignore[call-arg] # pyright: ignore[reportGeneralTypeIssues] "ExponentialMovingWindow[pd.Series]", ), ExponentialMovingWindow, ) + check( + assert_type( + s1.ewm(com=0.3, min_periods=0, adjust=False, ignore_na=True), + "ExponentialMovingWindow[pd.Series]", + ), + ExponentialMovingWindow, + ) check( assert_type(s1.ewm(alpha=0.4), "ExponentialMovingWindow[pd.Series]"), ExponentialMovingWindow, @@ -1551,22 +1557,22 @@ def test_relops() -> None: def test_resample() -> None: # GH 181 N = 10 - index = pd.date_range("1/1/2000", periods=N, freq="T") + index = pd.date_range("1/1/2000", periods=N, freq="min") x = [x for x in range(N)] df = pd.Series(x, index=index) - check(assert_type(df.resample("2T").std(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").var(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").quantile(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").sum(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").prod(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").min(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").max(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").first(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").last(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").mean(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").sem(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").median(), pd.Series), pd.Series) - check(assert_type(df.resample("2T").ohlc(), pd.DataFrame), pd.DataFrame) + check(assert_type(df.resample("2min").std(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").var(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").quantile(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").sum(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").prod(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").min(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").max(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").first(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").last(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").mean(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").sem(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").median(), pd.Series), pd.Series) + check(assert_type(df.resample("2min").ohlc(), pd.DataFrame), pd.DataFrame) def test_to_xarray(): diff --git a/tests/test_timefuncs.py b/tests/test_timefuncs.py index 4977d43ca..796f14cd7 100644 --- a/tests/test_timefuncs.py +++ b/tests/test_timefuncs.py @@ -25,7 +25,6 @@ else: FulldatetimeDict = Any from tests import ( - PD_LTE_20, TYPE_CHECKING_INVALID_USAGE, check, pytest_warns_bounded, @@ -702,7 +701,7 @@ def test_to_timdelta_units() -> None: check(assert_type(pd.to_timedelta(1, "minutes"), pd.Timedelta), pd.Timedelta) with pytest_warns_bounded( FutureWarning, - r"Unit '[tl]' is deprecated", + r"'[tl]' is deprecated", lower="2.0.99", ): check(assert_type(pd.to_timedelta(1, "t"), pd.Timedelta), pd.Timedelta) @@ -723,13 +722,23 @@ def test_to_timdelta_units() -> None: check(assert_type(pd.to_timedelta(1, "µs"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.to_timedelta(1, "micro"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.to_timedelta(1, "micros"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.to_timedelta(1, "u"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded( + FutureWarning, + r"'u' is deprecated", + lower="2.1.99", + ): + check(assert_type(pd.to_timedelta(1, "u"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.to_timedelta(1, "ns"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.to_timedelta(1, "nanoseconds"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.to_timedelta(1, "nano"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.to_timedelta(1, "nanos"), pd.Timedelta), pd.Timedelta) check(assert_type(pd.to_timedelta(1, "nanosecond"), pd.Timedelta), pd.Timedelta) - check(assert_type(pd.to_timedelta(1, "n"), pd.Timedelta), pd.Timedelta) + with pytest_warns_bounded( + FutureWarning, + r"'n' is deprecated", + lower="2.1.99", + ): + check(assert_type(pd.to_timedelta(1, "n"), pd.Timedelta), pd.Timedelta) def test_to_timedelta_scalar() -> None: @@ -1132,18 +1141,16 @@ def test_timedelta64_and_arithmatic_operator() -> None: s4 = s1.astype(object) check(assert_type(s4 - td1, "TimestampSeries"), pd.Series, pd.Timestamp) - # https://github.com/pandas-dev/pandas/issues/54059 says this is invalid - if PD_LTE_20: - td = np.timedelta64(1, "M") - check(assert_type((s1 - td), "TimestampSeries"), pd.Series, pd.Timestamp) - check(assert_type((s1 + td), "TimestampSeries"), pd.Series, pd.Timestamp) - check(assert_type((s3 - td), "TimedeltaSeries"), pd.Series, pd.Timedelta) - check(assert_type((s3 + td), "TimedeltaSeries"), pd.Series, pd.Timedelta) - check(assert_type((s3 / td), "pd.Series[float]"), pd.Series, float) - if TYPE_CHECKING_INVALID_USAGE: - r1 = s1 * td # type: ignore[operator] # pyright: ignore[reportGeneralTypeIssues] - r2 = s1 / td # type: ignore[operator] # pyright: ignore[reportGeneralTypeIssues] - r3 = s3 * td # type: ignore[operator] # pyright: ignore[reportGeneralTypeIssues] + td = np.timedelta64(1, "D") + check(assert_type((s1 - td), "TimestampSeries"), pd.Series, pd.Timestamp) + check(assert_type((s1 + td), "TimestampSeries"), pd.Series, pd.Timestamp) + check(assert_type((s3 - td), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type((s3 + td), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type((s3 / td), "pd.Series[float]"), pd.Series, float) + if TYPE_CHECKING_INVALID_USAGE: + r1 = s1 * td # type: ignore[operator] # pyright: ignore[reportGeneralTypeIssues] + r2 = s1 / td # type: ignore[operator] # pyright: ignore[reportGeneralTypeIssues] + r3 = s3 * td # type: ignore[operator] # pyright: ignore[reportGeneralTypeIssues] def test_timedeltaseries_add_timestampseries() -> None: