diff --git a/.gitignore b/.gitignore index 175cf16f4..8a7420841 100644 --- a/.gitignore +++ b/.gitignore @@ -117,6 +117,9 @@ venv.bak/ # Rope project settings .ropeproject +# PyCharm project settings +.idea/ + # mkdocs documentation /site diff --git a/pandas-stubs/core/frame.pyi b/pandas-stubs/core/frame.pyi index 3f2c7c9e8..50f39c57a 100644 --- a/pandas-stubs/core/frame.pyi +++ b/pandas-stubs/core/frame.pyi @@ -544,18 +544,7 @@ class DataFrame(NDFrame, OpsMixin): self, to_replace=..., value: Optional[Union[Scalar, Sequence, Mapping, Pattern]] = ..., - limit: Optional[int] = ..., - regex=..., - method: Optional[_str] = ..., - *, - inplace: Literal[False], - ) -> DataFrame: ... - @overload - def replace( - self, - to_replace=..., - value: Optional[Union[Scalar, Sequence, Mapping, Pattern]] = ..., - *, + inplace: Literal[False] = ..., limit: Optional[int] = ..., regex=..., method: Optional[_str] = ..., @@ -1238,7 +1227,7 @@ class DataFrame(NDFrame, OpsMixin): self, axis: Optional[AxisType] = ..., *, - inplace: Literal[False], + inplace: Literal[False] = ..., limit: Optional[int] = ..., downcast: Optional[Dict] = ..., ) -> DataFrame: ... @@ -1327,7 +1316,7 @@ class DataFrame(NDFrame, OpsMixin): self, axis: Optional[AxisType] = ..., *, - inplace: Literal[False], + inplace: Literal[False] = ..., limit: Optional[int] = ..., downcast: Optional[Dict] = ..., ) -> DataFrame: ... diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 2565b0845..9913891a0 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -467,18 +467,7 @@ class Series(IndexOpsMixin, NDFrame, Generic[S1]): na_position: Union[_str, Literal["first", "last"]] = ..., ignore_index: _bool = ..., *, - inplace: Literal[False], - key: Optional[Callable] = ..., - ) -> Series[S1]: ... - @overload - def sort_values( - self, - axis: AxisType = ..., - ascending: Union[_bool, Sequence[_bool]] = ..., - *, - kind: Union[_str, Literal["quicksort", "mergesort", "heapsort"]] = ..., - na_position: Union[_str, Literal["first", "last"]] = ..., - ignore_index: _bool = ..., + inplace: Literal[False] = ..., key: Optional[Callable] = ..., ) -> Series[S1]: ... @overload @@ -517,20 +506,7 @@ class Series(IndexOpsMixin, NDFrame, Generic[S1]): sort_remaining: _bool = ..., ignore_index: _bool = ..., *, - inplace: Literal[False], - key: Optional[Callable] = ..., - ) -> Series: ... - @overload - def sort_index( - self, - axis: AxisType = ..., - level: Optional[Union[Level, List[int], List[_str]]] = ..., - ascending: Union[_bool, Sequence[_bool]] = ..., - *, - kind: Union[_str, Literal["quicksort", "mergesort", "heapsort"]] = ..., - na_position: Union[_str, Literal["first", "last"]] = ..., - sort_remaining: _bool = ..., - ignore_index: _bool = ..., + inplace: Literal[False] = ..., key: Optional[Callable] = ..., ) -> Series: ... @overload @@ -747,15 +723,37 @@ class Series(IndexOpsMixin, NDFrame, Generic[S1]): limit: Optional[int] = ..., downcast: Optional[Dict] = ..., ) -> Union[Series[S1], None]: ... + @overload def replace( self, to_replace: Optional[Union[_str, List, Dict, Series[S1], int, float]] = ..., value: Optional[Union[Scalar, Dict, List, _str]] = ..., - inplace: _bool = ..., + inplace: Literal[False] = ..., limit: Optional[int] = ..., regex=..., method: Optional[Union[_str, Literal["pad", "ffill", "bfill"]]] = ..., ) -> Series[S1]: ... + @overload + def replace( + self, + to_replace: Optional[Union[_str, List, Dict, Series[S1], int, float]] = ..., + value: Optional[Union[Scalar, Dict, List, _str]] = ..., + limit: Optional[int] = ..., + regex=..., + method: Optional[Union[_str, Literal["pad", "ffill", "bfill"]]] = ..., + *, + inplace: Literal[True], + ) -> None: ... + @overload + def replace( + self, + to_replace: Optional[Union[_str, List, Dict, Series[S1], int, float]] = ..., + value: Optional[Union[Scalar, Dict, List, _str]] = ..., + inplace: _bool = ..., + limit: Optional[int] = ..., + regex=..., + method: Optional[Union[_str, Literal["pad", "ffill", "bfill"]]] = ..., + ) -> Union[Series[S1], None]: ... def shift( self, periods: int = ..., @@ -878,7 +876,7 @@ class Series(IndexOpsMixin, NDFrame, Generic[S1]): self, axis: Optional[SeriesAxisType] = ..., *, - inplace: Literal[False], + inplace: Literal[False] = ..., limit: Optional[int] = ..., downcast: Optional[Dict] = ..., ) -> Series[S1]: ... @@ -896,7 +894,7 @@ class Series(IndexOpsMixin, NDFrame, Generic[S1]): self, axis: Optional[SeriesAxisType] = ..., *, - inplace: Literal[False], + inplace: Literal[False] = ..., limit: Optional[int] = ..., downcast: Optional[Dict] = ..., ) -> Series[S1]: ... diff --git a/tests/test_frame.py b/tests/test_frame.py index 5d20821ac..5cc74044b 100644 --- a/tests/test_frame.py +++ b/tests/test_frame.py @@ -1020,3 +1020,27 @@ def test_join() -> None: frameCD = float_frame[["C", "D"]] right: List[Union[pd.Series, pd.DataFrame]] = [seriesB, frameCD] result = left.join(right) + + +def test_types_ffill() -> None: + # GH 44 + df = pd.DataFrame([[1, 2, 3]]) + assert_type(df.ffill(), pd.DataFrame) + assert_type(df.ffill(inplace=False), pd.DataFrame) + assert_type(df.ffill(inplace=True), None) + + +def test_types_bfill() -> None: + # GH 44 + df = pd.DataFrame([[1, 2, 3]]) + assert_type(df.bfill(), pd.DataFrame) + assert_type(df.bfill(inplace=False), pd.DataFrame) + assert_type(df.bfill(inplace=True), None) + + +def test_types_replace() -> None: + # GH 44 + df = pd.DataFrame([[1, 2, 3]]) + assert_type(df.replace(1, 2), pd.DataFrame) + assert_type(df.replace(1, 2, inplace=False), pd.DataFrame) + assert_type(df.replace(1, 2, inplace=True), None) diff --git a/tests/test_series.py b/tests/test_series.py index 1e6fe6263..2abada045 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -146,11 +146,11 @@ def test_types_setting() -> None: def test_types_drop() -> None: s = pd.Series([0, 1, 2]) - res: pd.Series = s.drop(0) - res2: pd.Series = s.drop([0, 1]) - res3: pd.Series = s.drop(0, axis=0) - res4: None = s.drop([0, 1], inplace=True, errors="raise") - res5: None = s.drop([0, 1], inplace=True, errors="ignore") + assert_type(s.drop(0), pd.Series) + assert_type(s.drop([0, 1]), pd.Series) + assert_type(s.drop(0, axis=0), pd.Series) + assert_type(s.drop([0, 1], inplace=True, errors="raise"), None) + assert_type(s.drop([0, 1], inplace=True, errors="ignore"), None) def test_types_drop_multilevel() -> None: @@ -164,25 +164,26 @@ def test_types_drop_multilevel() -> None: def test_types_dropna() -> None: s = pd.Series([1, np.nan, np.nan]) - res: pd.Series = s.dropna() - res2: None = s.dropna(axis=0, inplace=True) + assert_type(s.dropna(), pd.Series) + assert_type(s.dropna(axis=0, inplace=True), None) def test_types_fillna() -> None: s = pd.Series([1, np.nan, np.nan, 3]) - res: pd.Series = s.fillna(0) - res2: pd.Series = s.fillna(0, axis="index") - res3: pd.Series = s.fillna(method="backfill", axis=0) - res4: None = s.fillna(method="bfill", inplace=True) - res5: pd.Series = s.fillna(method="pad") - res6: pd.Series = s.fillna(method="ffill", limit=1) + assert_type(s.fillna(0), pd.Series) + assert_type(s.fillna(0, axis="index"), pd.Series) + assert_type(s.fillna(method="backfill", axis=0), pd.Series) + assert_type(s.fillna(method="bfill", inplace=True), None) + assert_type(s.fillna(method="pad"), pd.Series) + assert_type(s.fillna(method="ffill", limit=1), pd.Series) def test_types_sort_index() -> None: s = pd.Series([1, 2, 3], index=[2, 3, 1]) - res: pd.Series = s.sort_index() - res2: None = s.sort_index(ascending=False, inplace=True) - res3: pd.Series = s.sort_index(kind="mergesort") + assert_type(s.sort_index(), pd.Series) + assert_type(s.sort_index(ascending=False), pd.Series) + assert_type(s.sort_index(ascending=False, inplace=True), None) + assert_type(s.sort_index(kind="mergesort"), pd.Series) # This was added in 1.1.0 https://pandas.pydata.org/docs/whatsnew/v1.1.0.html @@ -193,11 +194,12 @@ def test_types_sort_index_with_key() -> None: def test_types_sort_values() -> None: s = pd.Series([4, 2, 1, 3]) - res: pd.Series = s.sort_values(0) - res2: pd.Series = s.sort_values(ascending=False) - res3: None = s.sort_values(inplace=True, kind="quicksort") - res4: pd.Series = s.sort_values(na_position="last") - res5: pd.Series = s.sort_values(ignore_index=True) + assert_type(s.sort_values(), pd.Series) + assert_type(s.sort_values(0), pd.Series) + assert_type(s.sort_values(ascending=False), pd.Series) + assert_type(s.sort_values(inplace=True, kind="quicksort"), None) + assert_type(s.sort_values(na_position="last"), pd.Series) + assert_type(s.sort_values(ignore_index=True), pd.Series) # This was added in 1.1.0 https://pandas.pydata.org/docs/whatsnew/v1.1.0.html @@ -547,8 +549,9 @@ def test_types_ne() -> None: def test_types_bfill() -> None: s1 = pd.Series([1, 2, 3]) - s2: pd.Series = s1.bfill(inplace=False) - s3: None = s1.bfill(inplace=True) + assert_type(s1.bfill(), pd.Series) + assert_type(s1.bfill(inplace=False), pd.Series) + assert_type(s1.bfill(inplace=True), None) def test_types_ewm() -> None: @@ -563,8 +566,9 @@ def test_types_ewm() -> None: def test_types_ffill() -> None: s1 = pd.Series([1, 2, 3]) - s2: pd.Series = s1.ffill(inplace=False) - s3: None = s1.ffill(inplace=True) + assert_type(s1.ffill(), pd.Series) + assert_type(s1.ffill(inplace=False), pd.Series) + assert_type(s1.ffill(inplace=True), None) def test_types_as_type() -> None: @@ -671,3 +675,11 @@ def test_series_add_str() -> None: def test_series_dtype() -> None: s = pd.Series(["abc", "def"], dtype=str) assert_type(s, "pd.Series[str]") + + +def test_types_replace() -> None: + # GH 44 + s = pd.Series([1, 2, 3]) + assert_type(s.replace(1, 2), pd.Series) + assert_type(s.replace(1, 2, inplace=False), pd.Series) + assert_type(s.replace(1, 2, inplace=True), None)