diff --git a/pandas-stubs/core/frame.pyi b/pandas-stubs/core/frame.pyi index 6ddde00e2..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 @@ -1091,17 +1092,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 b9cf20a27..eedd6cc33 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 324796736..757a04044 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: ... @overload def __getitem__( self, @@ -495,12 +496,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 1e38f8f4c..c88303a6f 100644 --- a/tests/test_frame.py +++ b/tests/test_frame.py @@ -33,7 +33,10 @@ from pandas._typing import Scalar -from tests import check +from tests import ( + TYPE_CHECKING_INVALID_USAGE, + check, +) from pandas.io.parsers import TextFileReader @@ -71,26 +74,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[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 ) - 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[operator] + {1: [1, 2, 3]}, ignore_index=True + ) + res6: pd.DataFrame = df.append( # type: ignore[operator] {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[operator] + pd.Series([5, 6]), ignore_index=True + ) + res8: pd.DataFrame = df.append( # type: ignore[operator] pd.Series([5, 6], index=["col1", "col2"]), ignore_index=True ) @@ -1716,6 +1716,12 @@ def test_pos() -> None: 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) + + def test_xs_key() -> None: # GH 214 mi = pd.MultiIndex.from_product([[0, 1], [0, 1]], names=["foo", "bar"]) diff --git a/tests/test_series.py b/tests/test_series.py index c51d759f5..553241fb0 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -1147,6 +1147,12 @@ def test_neg() -> None: 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.integer) + + def test_dtype_type() -> None: # GH 216 s1 = pd.Series(["foo"], dtype="string")