From 3bb8ebfb32fb88c399180afc69b149dd46eb7229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 4 Sep 2022 12:06:48 -0400 Subject: [PATCH 1/8] remove append --- pandas-stubs/core/frame.pyi | 11 ----------- pandas-stubs/core/generic.pyi | 1 - pandas-stubs/core/series.pyi | 6 ------ tests/test_frame.py | 34 +++++++++++++++++----------------- 4 files changed, 17 insertions(+), 35 deletions(-) diff --git a/pandas-stubs/core/frame.pyi b/pandas-stubs/core/frame.pyi index feaa11846..0d2210275 100644 --- a/pandas-stubs/core/frame.pyi +++ b/pandas-stubs/core/frame.pyi @@ -1089,17 +1089,6 @@ class DataFrame(NDFrame, OpsMixin): def applymap( self, func: Callable, na_action: Literal["ignore"] | None = ..., **kwargs ) -> DataFrame: ... - def append( - self, - other: DataFrame - | Series - | dict[Any, Any] - | Sequence[Scalar] - | Sequence[ListLike], - ignore_index: _bool = ..., - verify_integrity: _bool = ..., - sort: _bool = ..., - ) -> DataFrame: ... def join( self, other: DataFrame | Series | list[DataFrame | Series], diff --git a/pandas-stubs/core/generic.pyi b/pandas-stubs/core/generic.pyi index 8dfcba55c..be8b5db29 100644 --- a/pandas-stubs/core/generic.pyi +++ b/pandas-stubs/core/generic.pyi @@ -359,7 +359,6 @@ class NDFrame(PandasObject, indexing.IndexingMixin): self, func: Callable[..., T] | tuple[Callable[..., T], str], *args, **kwargs ) -> T: ... def __finalize__(self, other, method=..., **kwargs) -> NDFrame: ... - def __getattr__(self, name: _str): ... def __setattr__(self, name: _str, value) -> None: ... @property def values(self) -> ArrayLike: ... diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 987b93ae8..eba61aa31 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -495,12 +495,6 @@ class Series(IndexOpsMixin, NDFrame, Generic[S1]): side: Literal["left", "right"] = ..., sorter: _ListLike | None = ..., ) -> int: ... - def append( - self, - to_append: Series | Sequence[Series], - ignore_index: _bool = ..., - verify_integrity: _bool = ..., - ) -> Series[S1]: ... @overload def compare( self, diff --git a/tests/test_frame.py b/tests/test_frame.py index 17a46951c..b8c2b330f 100644 --- a/tests/test_frame.py +++ b/tests/test_frame.py @@ -32,7 +32,10 @@ from pandas._typing import Scalar -from tests import check +from tests import ( + TYPE_CHECKING_INVALID_USAGE, + check, +) from pandas.io.parsers import TextFileReader @@ -70,26 +73,23 @@ def test_types_any() -> None: def test_types_append() -> None: df = pd.DataFrame(data={"col1": [1, 2], "col2": [3, 4]}) df2 = pd.DataFrame({"col1": [10, 20], "col2": [30, 40]}) - with pytest.warns(FutureWarning, match="The frame.append"): - res1: pd.DataFrame = df.append(df2) - with pytest.warns(FutureWarning, match="The frame.append"): - res2: pd.DataFrame = df.append([1, 2, 3]) - with pytest.warns(FutureWarning, match="The frame.append"): - res3: pd.DataFrame = df.append([[1, 2, 3]]) - with pytest.warns(FutureWarning, match="The frame.append"): - res4: pd.DataFrame = df.append( + if TYPE_CHECKING_INVALID_USAGE: + res1: pd.DataFrame = df.append(df2) # type: ignore[attr-defined] + res2: pd.DataFrame = df.append([1, 2, 3]) # type: ignore[attr-defined] + res3: pd.DataFrame = df.append([[1, 2, 3]]) # type: ignore[attr-defined] + res4: pd.DataFrame = df.append( # type: ignore[attr-defined] {("a", 1): [1, 2, 3], "b": df2}, ignore_index=True ) - with pytest.warns(FutureWarning, match="The frame.append"): - res5: pd.DataFrame = df.append({1: [1, 2, 3]}, ignore_index=True) - with pytest.warns(FutureWarning, match="The frame.append"): - res6: pd.DataFrame = df.append( + res5: pd.DataFrame = df.append( # type: ignore[attr-defined] + {1: [1, 2, 3]}, ignore_index=True + ) + res6: pd.DataFrame = df.append( # type: ignore[attr-defined] {1: [1, 2, 3], "col2": [1, 2, 3]}, ignore_index=True ) - with pytest.warns(FutureWarning, match="The frame.append"): - res7: pd.DataFrame = df.append(pd.Series([5, 6]), ignore_index=True) - with pytest.warns(FutureWarning, match="The frame.append"): - res8: pd.DataFrame = df.append( + res7: pd.DataFrame = df.append( # type: ignore[attr-defined] + pd.Series([5, 6]), ignore_index=True + ) + res8: pd.DataFrame = df.append( # type: ignore[attr-defined] pd.Series([5, 6], index=["col1", "col2"]), ignore_index=True ) From 0fa3b049f2389678cfd416314b3b5785256cbe69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 4 Sep 2022 18:43:42 -0400 Subject: [PATCH 2/8] __getattr__ -> Series --- pandas-stubs/core/generic.pyi | 2 ++ tests/test_frame.py | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/pandas-stubs/core/generic.pyi b/pandas-stubs/core/generic.pyi index be8b5db29..57ec44b41 100644 --- a/pandas-stubs/core/generic.pyi +++ b/pandas-stubs/core/generic.pyi @@ -45,6 +45,7 @@ from pandas._typing import ( from pandas.io.pytables import HDFStore from pandas.io.sql import SQLTable +from pandas.core.series import Series _bool = bool _str = str @@ -359,6 +360,7 @@ class NDFrame(PandasObject, indexing.IndexingMixin): self, func: Callable[..., T] | tuple[Callable[..., T], str], *args, **kwargs ) -> T: ... def __finalize__(self, other, method=..., **kwargs) -> NDFrame: ... + def __getattr__(self, name: _str) -> Series: ... def __setattr__(self, name: _str, value) -> None: ... @property def values(self) -> ArrayLike: ... diff --git a/tests/test_frame.py b/tests/test_frame.py index b8c2b330f..8191cf4ba 100644 --- a/tests/test_frame.py +++ b/tests/test_frame.py @@ -74,22 +74,22 @@ def test_types_append() -> None: df = pd.DataFrame(data={"col1": [1, 2], "col2": [3, 4]}) df2 = pd.DataFrame({"col1": [10, 20], "col2": [30, 40]}) if TYPE_CHECKING_INVALID_USAGE: - res1: pd.DataFrame = df.append(df2) # type: ignore[attr-defined] - res2: pd.DataFrame = df.append([1, 2, 3]) # type: ignore[attr-defined] - res3: pd.DataFrame = df.append([[1, 2, 3]]) # type: ignore[attr-defined] - res4: pd.DataFrame = df.append( # type: ignore[attr-defined] + res1: pd.DataFrame = df.append(df2) # type: ignore[operator] + res2: pd.DataFrame = df.append([1, 2, 3]) # type: ignore[operator] + res3: pd.DataFrame = df.append([[1, 2, 3]]) # type: ignore[operator] + res4: pd.DataFrame = df.append( # type: ignore[operator] {("a", 1): [1, 2, 3], "b": df2}, ignore_index=True ) - res5: pd.DataFrame = df.append( # type: ignore[attr-defined] + res5: pd.DataFrame = df.append( # type: ignore[operator] {1: [1, 2, 3]}, ignore_index=True ) - res6: pd.DataFrame = df.append( # type: ignore[attr-defined] + res6: pd.DataFrame = df.append( # type: ignore[operator] {1: [1, 2, 3], "col2": [1, 2, 3]}, ignore_index=True ) - res7: pd.DataFrame = df.append( # type: ignore[attr-defined] + res7: pd.DataFrame = df.append( # type: ignore[operator] pd.Series([5, 6]), ignore_index=True ) - res8: pd.DataFrame = df.append( # type: ignore[attr-defined] + res8: pd.DataFrame = df.append( # type: ignore[operator] pd.Series([5, 6], index=["col1", "col2"]), ignore_index=True ) From dc05df5985d1337aa358cbbaf5248e71d4ea1874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 4 Sep 2022 19:11:10 -0400 Subject: [PATCH 3/8] tests --- pandas-stubs/core/series.pyi | 1 + tests/test_frame.py | 6 ++++++ tests/test_series.py | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index eba61aa31..4656f2501 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -245,6 +245,7 @@ class Series(IndexOpsMixin, NDFrame, Generic[S1]): is_copy: _bool | None = ..., **kwargs, ) -> Series[S1]: ... + def __getattr__(self, name: str) -> S1: ... # type: ignore[override] @overload def __getitem__( self, diff --git a/tests/test_frame.py b/tests/test_frame.py index 8191cf4ba..6703fd32f 100644 --- a/tests/test_frame.py +++ b/tests/test_frame.py @@ -1745,3 +1745,9 @@ def test_pos() -> None: # GH 253 df = pd.DataFrame(data={"col1": [1, 2], "col2": [3, 4]}) check(assert_type(+df, pd.DataFrame), pd.DataFrame) + + +def test_getattr() -> None: + # GH 261 + df = pd.DataFrame({"a": [1, 2]}) + check(assert_type(df.a, pd.Series), pd.Series) diff --git a/tests/test_series.py b/tests/test_series.py index d82e9f59f..bf01b0d12 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -1139,3 +1139,9 @@ def test_neg() -> None: sr_int = pd.Series([1, 2, 3], dtype=int) check(assert_type(-sr, pd.Series), pd.Series) check(assert_type(-sr_int, "pd.Series[int]"), pd.Series, int) + + +def test_getattr() -> None: + # GH 261 + series = pd.Series([1, 2, 3], index=["a", "b", "c"], dtype=int) + check(assert_type(series.a, int), np.int64) From d84e253095e372ac77aa09a170722552fb8e12af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 4 Sep 2022 19:23:41 -0400 Subject: [PATCH 4/8] black --- tests/test_frame.py | 2 +- tests/test_series.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_frame.py b/tests/test_frame.py index 6154bb6e9..c88303a6f 100644 --- a/tests/test_frame.py +++ b/tests/test_frame.py @@ -1728,4 +1728,4 @@ def test_xs_key() -> None: df = pd.DataFrame({"x": [10, 20, 30, 40], "y": [50, 60, 70, 80]}, index=mi) check( assert_type(df.xs(0, level="foo"), Union[pd.DataFrame, pd.Series]), pd.DataFrame - ) \ No newline at end of file + ) diff --git a/tests/test_series.py b/tests/test_series.py index 1e294f2f5..8626361ca 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -1165,4 +1165,4 @@ def test_dtype_type() -> None: s3 = pd.Series([1, 2, 3]) check(assert_type(s3.dtype, DtypeObj), np.dtype) - check(assert_type(s3.dtype.kind, str), str) \ No newline at end of file + check(assert_type(s3.dtype.kind, str), str) From f900f10d7c1aef58b2a1b14abdbf4a47ccd580f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 4 Sep 2022 19:27:22 -0400 Subject: [PATCH 5/8] and isort --- pandas-stubs/core/generic.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas-stubs/core/generic.pyi b/pandas-stubs/core/generic.pyi index 984f54f78..dd41887a3 100644 --- a/pandas-stubs/core/generic.pyi +++ b/pandas-stubs/core/generic.pyi @@ -15,6 +15,7 @@ import numpy as np from pandas.core.base import PandasObject from pandas.core.indexes.base import Index import pandas.core.indexing as indexing +from pandas.core.series import Series import sqlalchemy.engine from pandas._typing import ( @@ -45,7 +46,6 @@ from pandas._typing import ( from pandas.io.pytables import HDFStore from pandas.io.sql import SQLTable -from pandas.core.series import Series _bool = bool _str = str From 866886550fd671b6b0252616744681bf06c3aafd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 4 Sep 2022 19:36:43 -0400 Subject: [PATCH 6/8] maybe fix win32bit issue --- tests/test_series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_series.py b/tests/test_series.py index 8626361ca..2aaf0f19d 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -1150,7 +1150,7 @@ def test_neg() -> None: def test_getattr() -> None: # GH 261 series = pd.Series([1, 2, 3], index=["a", "b", "c"], dtype=int) - check(assert_type(series.a, int), np.int64) + check(assert_type(series.a, int), np.intp) def test_dtype_type() -> None: From 8179584875a4c6455268efbcb0bac0a57ddfde3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 4 Sep 2022 19:44:23 -0400 Subject: [PATCH 7/8] generic np.integer --- tests/test_series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_series.py b/tests/test_series.py index 2aaf0f19d..553241fb0 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -1150,7 +1150,7 @@ def test_neg() -> None: def test_getattr() -> None: # GH 261 series = pd.Series([1, 2, 3], index=["a", "b", "c"], dtype=int) - check(assert_type(series.a, int), np.intp) + check(assert_type(series.a, int), np.integer) def test_dtype_type() -> None: From f1bc1eb27843aebf698183592eebd04d20ea0bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 4 Sep 2022 23:14:01 -0400 Subject: [PATCH 8/8] move __getattr__ --- pandas-stubs/core/frame.pyi | 1 + pandas-stubs/core/generic.pyi | 2 -- pandas-stubs/core/series.pyi | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pandas-stubs/core/frame.pyi b/pandas-stubs/core/frame.pyi index 6ef69f3e9..480377898 100644 --- a/pandas-stubs/core/frame.pyi +++ b/pandas-stubs/core/frame.pyi @@ -478,6 +478,7 @@ class DataFrame(NDFrame, OpsMixin): def transpose(self, *args, copy: _bool = ...) -> DataFrame: ... @property def T(self) -> DataFrame: ... + def __getattr__(self, name: str) -> Series: ... @overload def __getitem__(self, idx: Scalar) -> Series: ... @overload diff --git a/pandas-stubs/core/generic.pyi b/pandas-stubs/core/generic.pyi index dd41887a3..eedd6cc33 100644 --- a/pandas-stubs/core/generic.pyi +++ b/pandas-stubs/core/generic.pyi @@ -15,7 +15,6 @@ import numpy as np from pandas.core.base import PandasObject from pandas.core.indexes.base import Index import pandas.core.indexing as indexing -from pandas.core.series import Series import sqlalchemy.engine from pandas._typing import ( @@ -360,7 +359,6 @@ class NDFrame(PandasObject, indexing.IndexingMixin): self, func: Callable[..., T] | tuple[Callable[..., T], str], *args, **kwargs ) -> T: ... def __finalize__(self, other, method=..., **kwargs) -> NDFrame: ... - def __getattr__(self, name: _str) -> Series: ... def __setattr__(self, name: _str, value) -> None: ... @property def values(self) -> ArrayLike: ... diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 88249b213..757a04044 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -245,7 +245,7 @@ class Series(IndexOpsMixin, NDFrame, Generic[S1]): is_copy: _bool | None = ..., **kwargs, ) -> Series[S1]: ... - def __getattr__(self, name: str) -> S1: ... # type: ignore[override] + def __getattr__(self, name: str) -> S1: ... @overload def __getitem__( self,