From b6aea60fe2657387fd4f932710613aef9f7f8673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sat, 2 Jul 2022 15:28:42 -0400 Subject: [PATCH 01/12] TYP: return values in core/*.py --- pandas/core/algorithms.py | 2 +- pandas/core/arrays/masked.py | 4 +- pandas/core/arrays/sparse/array.py | 14 +- pandas/core/base.py | 11 +- pandas/core/common.py | 6 +- pandas/core/config_init.py | 14 +- pandas/core/flags.py | 6 +- pandas/core/frame.py | 329 +++++++++++++++++++++++--- pandas/core/generic.py | 271 ++++++++++++++++++---- pandas/core/indexing.py | 9 +- pandas/core/missing.py | 4 +- pandas/core/nanops.py | 7 +- pandas/core/resample.py | 4 +- pandas/core/reshape/pivot.py | 6 +- pandas/core/series.py | 359 ++++++++++++++++++++++++----- 15 files changed, 884 insertions(+), 162 deletions(-) diff --git a/pandas/core/algorithms.py b/pandas/core/algorithms.py index 7e292f4ccf8cb..159c0bb2e72c0 100644 --- a/pandas/core/algorithms.py +++ b/pandas/core/algorithms.py @@ -948,7 +948,7 @@ def value_counts( # Called once from SparseArray, otherwise could be private def value_counts_arraylike( values: np.ndarray, dropna: bool, mask: npt.NDArray[np.bool_] | None = None -): +) -> tuple[ArrayLike, npt.NDArray[np.int64]]: """ Parameters ---------- diff --git a/pandas/core/arrays/masked.py b/pandas/core/arrays/masked.py index 0a25be38e81df..2fce5fc747312 100644 --- a/pandas/core/arrays/masked.py +++ b/pandas/core/arrays/masked.py @@ -945,9 +945,9 @@ def value_counts(self, dropna: bool = True) -> Series: index = index.astype(self.dtype) mask = np.zeros(len(counts), dtype="bool") - counts = IntegerArray(counts, mask) + counts_array = IntegerArray(counts, mask) - return Series(counts, index=index) + return Series(counts_array, index=index) @doc(ExtensionArray.equals) def equals(self, other) -> bool: diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index 26c577886f174..e7c745e902a49 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -889,12 +889,20 @@ def value_counts(self, dropna: bool = True) -> Series: if mask.any(): counts[mask] += fcounts else: - keys = np.insert(keys, 0, self.fill_value) + # error: Argument 1 to "insert" has incompatible type "Union[ + # ExtensionArray,ndarray[Any, Any]]"; expected "Union[ + # _SupportsArray[dtype[Any]], Sequence[_SupportsArray[dtype + # [Any]]], Sequence[Sequence[_SupportsArray[dtype[Any]]]], + # Sequence[Sequence[Sequence[_SupportsArray[dtype[Any]]]]], Sequence + # [Sequence[Sequence[Sequence[_SupportsArray[dtype[Any]]]]]]]" + keys = np.insert(keys, 0, self.fill_value) # type: ignore[arg-type] counts = np.insert(counts, 0, fcounts) if not isinstance(keys, ABCIndex): - keys = Index(keys) - return Series(counts, index=keys) + index = Index(keys) + else: + index = keys + return Series(counts, index=index) def _quantile(self, qs: npt.NDArray[np.float64], interpolation: str): diff --git a/pandas/core/base.py b/pandas/core/base.py index 3d18194d14bec..93e2dc3975aeb 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -81,7 +81,10 @@ NumpyValueArrayLike, ) - from pandas import Categorical + from pandas import ( + Categorical, + Series, + ) _shared_docs: dict[str, str] = {} @@ -161,7 +164,7 @@ def _freeze(self): object.__setattr__(self, "__frozen", True) # prevent adding any attribute via s.xxx.new_attribute = ... - def __setattr__(self, key: str, value): + def __setattr__(self, key: str, value) -> None: # _cache is used by a decorator # We need to check both 1.) cls.__dict__ and 2.) getattr(self, key) # because @@ -765,7 +768,7 @@ def hasnans(self) -> bool: # has no attribute "any" return bool(isna(self).any()) # type: ignore[union-attr] - def isna(self): + def isna(self) -> npt.NDArray[np.bool_]: return isna(self._values) def _reduce( @@ -890,7 +893,7 @@ def value_counts( ascending: bool = False, bins=None, dropna: bool = True, - ): + ) -> Series: """ Return a Series containing counts of unique values. diff --git a/pandas/core/common.py b/pandas/core/common.py index 707201153e44a..980e7a79414ba 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -553,7 +553,7 @@ def temp_setattr(obj, attr: str, value) -> Iterator[None]: setattr(obj, attr, old_value) -def require_length_match(data, index: Index): +def require_length_match(data, index: Index) -> None: """ Check the length of data matches the length of the index. """ @@ -665,7 +665,9 @@ def resolve_numeric_only(numeric_only: bool | None | lib.NoDefault) -> bool: return result -def deprecate_numeric_only_default(cls: type, name: str, deprecate_none: bool = False): +def deprecate_numeric_only_default( + cls: type, name: str, deprecate_none: bool = False +) -> None: """Emit FutureWarning message for deprecation of numeric_only. See GH#46560 for details on the deprecation. diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py index 47cf64ba24022..a49e35539656f 100644 --- a/pandas/core/config_init.py +++ b/pandas/core/config_init.py @@ -37,7 +37,7 @@ """ -def use_bottleneck_cb(key): +def use_bottleneck_cb(key) -> None: from pandas.core import nanops nanops.set_use_bottleneck(cf.get_option(key)) @@ -51,7 +51,7 @@ def use_bottleneck_cb(key): """ -def use_numexpr_cb(key): +def use_numexpr_cb(key) -> None: from pandas.core.computation import expressions expressions.set_use_numexpr(cf.get_option(key)) @@ -65,7 +65,7 @@ def use_numexpr_cb(key): """ -def use_numba_cb(key): +def use_numba_cb(key) -> None: from pandas.core.util import numba_ numba_.set_use_numba(cf.get_option(key)) @@ -329,7 +329,7 @@ def use_numba_cb(key): """ -def table_schema_cb(key): +def table_schema_cb(key) -> None: from pandas.io.formats.printing import enable_data_resource_formatter enable_data_resource_formatter(cf.get_option(key)) @@ -500,7 +500,7 @@ def _deprecate_negative_int_max_colwidth(key): # or we'll hit circular deps. -def use_inf_as_na_cb(key): +def use_inf_as_na_cb(key) -> None: from pandas.core.dtypes.missing import _use_inf_as_na _use_inf_as_na(key) @@ -720,7 +720,7 @@ def use_inf_as_na_cb(key): """ -def register_plotting_backend_cb(key): +def register_plotting_backend_cb(key) -> None: if key == "matplotlib": # We defer matplotlib validation, since it's the default return @@ -746,7 +746,7 @@ def register_plotting_backend_cb(key): """ -def register_converter_cb(key): +def register_converter_cb(key) -> None: from pandas.plotting import ( deregister_matplotlib_converters, register_matplotlib_converters, diff --git a/pandas/core/flags.py b/pandas/core/flags.py index 001cd3d41177a..b4e1039e216c0 100644 --- a/pandas/core/flags.py +++ b/pandas/core/flags.py @@ -81,7 +81,7 @@ def allows_duplicate_labels(self) -> bool: return self._allows_duplicate_labels @allows_duplicate_labels.setter - def allows_duplicate_labels(self, value: bool): + def allows_duplicate_labels(self, value: bool) -> None: value = bool(value) obj = self._obj() if obj is None: @@ -99,12 +99,12 @@ def __getitem__(self, key): return getattr(self, key) - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: if key not in self._keys: raise ValueError(f"Unknown flag {key}. Must be one of {self._keys}") setattr(self, key, value) - def __repr__(self): + def __repr__(self) -> str: return f"" def __eq__(self, other): diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 82ae93ad31763..33d912b50e96f 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1601,7 +1601,7 @@ def __matmul__(self, other: AnyArrayLike | DataFrame) -> DataFrame | Series: """ return self.dot(other) - def __rmatmul__(self, other): + def __rmatmul__(self, other) -> DataFrame: """ Matrix multiplication using binary `@` operator in Python>=3.5. """ @@ -2988,6 +2988,64 @@ def to_orc( self, path, engine=engine, index=index, engine_kwargs=engine_kwargs ) + @overload + def to_html( + self, + buf: FilePath | WriteBuffer[str], + columns: Sequence[str] | None = ..., + col_space: ColspaceArgType | None = ..., + header: bool | Sequence[str] = ..., + index: bool = ..., + na_rep: str = ..., + formatters: FormattersType | None = ..., + float_format: FloatFormatType | None = ..., + sparsify: bool | None = ..., + index_names: bool = ..., + justify: str | None = ..., + max_rows: int | None = ..., + max_cols: int | None = ..., + show_dimensions: bool | str = ..., + decimal: str = ..., + bold_rows: bool = ..., + classes: str | list | tuple | None = ..., + escape: bool = ..., + notebook: bool = ..., + border: int | bool | None = ..., + table_id: str | None = ..., + render_links: bool = ..., + encoding: str | None = ..., + ) -> None: + ... + + @overload + def to_html( + self, + buf: None = ..., + columns: Sequence[str] | None = ..., + col_space: ColspaceArgType | None = ..., + header: bool | Sequence[str] = ..., + index: bool = ..., + na_rep: str = ..., + formatters: FormattersType | None = ..., + float_format: FloatFormatType | None = ..., + sparsify: bool | None = ..., + index_names: bool = ..., + justify: str | None = ..., + max_rows: int | None = ..., + max_cols: int | None = ..., + show_dimensions: bool | str = ..., + decimal: str = ..., + bold_rows: bool = ..., + classes: str | list | tuple | None = ..., + escape: bool = ..., + notebook: bool = ..., + border: int | bool | None = ..., + table_id: str | None = ..., + render_links: bool = ..., + encoding: str | None = ..., + ) -> str: + ... + @Substitution( header_type="bool", header="Whether to print column labels, default True", @@ -3023,7 +3081,7 @@ def to_html( table_id: str | None = None, render_links: bool = False, encoding: str | None = None, - ): + ) -> str | None: """ Render a DataFrame as an HTML table. %(shared_params)s @@ -4136,7 +4194,7 @@ def _maybe_cache_changed(self, item, value: Series, inplace: bool) -> None: # ---------------------------------------------------------------------- # Unsorted - def query(self, expr: str, inplace: bool = False, **kwargs): + def query(self, expr: str, inplace: bool = False, **kwargs) -> None: """ Query the columns of a DataFrame with a boolean expression. @@ -4902,21 +4960,17 @@ def align( @overload def set_axis( - self, labels, axis: Axis = ..., inplace: Literal[False] = ... + self, labels, *, axis: Axis = ..., inplace: Literal[False] = ... ) -> DataFrame: ... @overload - def set_axis(self, labels, axis: Axis, inplace: Literal[True]) -> None: - ... - - @overload - def set_axis(self, labels, *, inplace: Literal[True]) -> None: + def set_axis(self, labels, *, axis: Axis = ..., inplace: Literal[True]) -> None: ... @overload def set_axis( - self, labels, axis: Axis = ..., inplace: bool = ... + self, labels, *, axis: Axis = ..., inplace: bool = ... ) -> DataFrame | None: ... @@ -5539,16 +5593,47 @@ def pop(self, item: Hashable) -> Series: """ return super().pop(item=item) - @doc(NDFrame.replace, **_shared_doc_kwargs) + # error: Signature of "replace" incompatible with supertype "NDFrame" + @overload # type: ignore[override] def replace( + self, + to_replace=..., + value=..., + *, + inplace: Literal[False] = ..., + limit: int | None = ..., + regex: bool = ..., + method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = ..., + ) -> DataFrame: + ... + + @overload + def replace( + self, + to_replace=..., + value=..., + *, + inplace: Literal[True], + limit: int | None = ..., + regex: bool = ..., + method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = ..., + ) -> None: + ... + + # error: Signature of "replace" incompatible with supertype "NDFrame" + @deprecate_nonkeyword_arguments( + version=None, allowed_args=["self", "to_replace", "value"] + ) + @doc(NDFrame.replace, **_shared_doc_kwargs) + def replace( # type: ignore[override] self, to_replace=None, value=lib.no_default, inplace: bool = False, - limit=None, + limit: int | None = None, regex: bool = False, method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = lib.no_default, - ): + ) -> DataFrame | None: return super().replace( to_replace=to_replace, value=value, @@ -5680,6 +5765,30 @@ def shift( periods=periods, freq=freq, axis=axis, fill_value=fill_value ) + @overload + def set_index( + self, + keys, + *, + drop: bool = ..., + append: bool = ..., + inplace: Literal[False] = ..., + verify_integrity: bool = ..., + ) -> DataFrame: + ... + + @overload + def set_index( + self, + keys, + *, + drop: bool = ..., + append: bool = ..., + inplace: Literal[True], + verify_integrity: bool = ..., + ) -> None: + ... + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "keys"]) def set_index( self, @@ -5688,7 +5797,7 @@ def set_index( append: bool = False, inplace: bool = False, verify_integrity: bool = False, - ): + ) -> DataFrame | None: """ Set the DataFrame index using existing columns. @@ -5881,6 +5990,7 @@ def set_index( if not inplace: return frame + return None @overload def reset_index( @@ -6231,6 +6341,30 @@ def notnull(self) -> DataFrame: """ return ~self.isna() + @overload + def dropna( + self, + *, + axis: Axis = ..., + how: str | NoDefault = ..., + thresh: int | NoDefault = ..., + subset: IndexLabel = ..., + inplace: Literal[False] = ..., + ) -> DataFrame: + ... + + @overload + def dropna( + self, + *, + axis: Axis = ..., + how: str | NoDefault = ..., + thresh: int | NoDefault = ..., + subset: IndexLabel = ..., + inplace: Literal[True], + ) -> None: + ... + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) def dropna( self, @@ -6239,7 +6373,7 @@ def dropna( thresh: int | NoDefault = no_default, subset: IndexLabel = None, inplace: bool = False, - ): + ) -> DataFrame | None: """ Remove missing values. @@ -6388,10 +6522,10 @@ def dropna( else: result = self.loc(axis=axis)[mask] - if inplace: - self._update_inplace(result) - else: + if not inplace: return result + self._update_inplace(result) + return None @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "subset"]) def drop_duplicates( @@ -6636,11 +6770,42 @@ def f(vals) -> tuple[np.ndarray, int]: # ---------------------------------------------------------------------- # Sorting + # error: Signature of "sort_values" incompatible with supertype "NDFrame" + @overload # type: ignore[override] + def sort_values( + self, + by, + *, + axis: Axis = ..., + ascending=..., + inplace: Literal[False] = ..., + kind: str = ..., + na_position: str = ..., + ignore_index: bool = ..., + key: ValueKeyFunc = ..., + ) -> DataFrame: + ... + + @overload + def sort_values( + self, + by, + *, + axis: Axis = ..., + ascending=..., + inplace: Literal[True], + kind: str = ..., + na_position: str = ..., + ignore_index: bool = ..., + key: ValueKeyFunc = ..., + ) -> None: + ... + # TODO: Just move the sort_values doc here. + # error: Signature of "sort_values" incompatible with supertype "NDFrame" @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "by"]) @Substitution(**_shared_doc_kwargs) @Appender(NDFrame.sort_values.__doc__) - # error: Signature of "sort_values" incompatible with supertype "NDFrame" def sort_values( # type: ignore[override] self, by, @@ -6651,7 +6816,7 @@ def sort_values( # type: ignore[override] na_position: str = "last", ignore_index: bool = False, key: ValueKeyFunc = None, - ): + ) -> DataFrame | None: inplace = validate_bool_kwarg(inplace, "inplace") axis = self._get_axis_number(axis) ascending = validate_ascending(ascending) @@ -6883,7 +7048,7 @@ def value_counts( sort: bool = True, ascending: bool = False, dropna: bool = True, - ): + ) -> Series: """ Return a Series containing counts of unique rows in the DataFrame. @@ -11476,35 +11641,137 @@ def interpolate( **kwargs, ) + @overload + def where( + self, + cond, + other=..., + *, + inplace: Literal[False] = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> DataFrame: + ... + + @overload + def where( + self, + cond, + other=..., + *, + inplace: Literal[True], + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> None: + ... + + @overload + def where( + self, + cond, + other=..., + *, + inplace: bool = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> DataFrame | None: + ... + + # error: Signature of "where" incompatible with supertype "NDFrame" @deprecate_nonkeyword_arguments( version=None, allowed_args=["self", "cond", "other"] ) - def where( + def where( # type: ignore[override] self, cond, other=lib.no_default, - inplace=False, + inplace: bool = False, axis=None, level=None, - errors: IgnoreRaise = "raise", + errors: IgnoreRaise | lib.NoDefault = "raise", try_cast=lib.no_default, - ): - return super().where(cond, other, inplace, axis, level, errors, try_cast) + ) -> DataFrame | None: + return super().where( + cond, + other, + inplace=inplace, + axis=axis, + level=level, + errors=errors, + try_cast=try_cast, + ) + + @overload + def mask( + self, + cond, + other=..., + *, + inplace: Literal[False] = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> DataFrame: + ... + + @overload + def mask( + self, + cond, + other=..., + *, + inplace: Literal[True], + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> None: + ... + @overload + def mask( + self, + cond, + other=..., + *, + inplace: bool = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> DataFrame | None: + ... + + # error: Signature of "mask" incompatible with supertype "NDFrame" @deprecate_nonkeyword_arguments( version=None, allowed_args=["self", "cond", "other"] ) - def mask( + def mask( # type: ignore[override] self, cond, other=np.nan, - inplace=False, + inplace: bool = False, axis=None, level=None, - errors: IgnoreRaise = "raise", + errors: IgnoreRaise | lib.NoDefault = "raise", try_cast=lib.no_default, - ): - return super().mask(cond, other, inplace, axis, level, errors, try_cast) + ) -> DataFrame | None: + return super().mask( + cond, + other, + inplace=inplace, + axis=axis, + level=level, + errors=errors, + try_cast=try_cast, + ) DataFrame._add_numeric_operations() diff --git a/pandas/core/generic.py b/pandas/core/generic.py index f896169d0ae44..5130faef5e3e0 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -699,25 +699,24 @@ def size(self) -> int: @overload def set_axis( - self: NDFrameT, labels, axis: Axis = ..., inplace: Literal[False] = ... + self: NDFrameT, labels, *, axis: Axis = ..., inplace: Literal[False] = ... ) -> NDFrameT: ... @overload - def set_axis(self, labels, axis: Axis, inplace: Literal[True]) -> None: - ... - - @overload - def set_axis(self, labels, *, inplace: Literal[True]) -> None: + def set_axis(self, labels, *, axis: Axis = ..., inplace: Literal[True]) -> None: ... @overload def set_axis( - self: NDFrameT, labels, axis: Axis = ..., inplace: bool_t = ... + self: NDFrameT, labels, *, axis: Axis = ..., inplace: bool_t = ... ) -> NDFrameT | None: ... - def set_axis(self, labels, axis: Axis = 0, inplace: bool_t = False): + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "labels"]) + def set_axis( + self: NDFrameT, labels, axis: Axis = 0, inplace: bool_t = False + ) -> NDFrameT | None: """ Assign desired index to given axis. @@ -1377,7 +1376,7 @@ def equals(self, other: object) -> bool_t: # Unary Methods @final - def __neg__(self): + def __neg__(self: NDFrameT) -> NDFrameT: def blk_func(values: ArrayLike): if is_bool_dtype(values.dtype): # error: Argument 1 to "inv" has incompatible type "Union @@ -1395,7 +1394,7 @@ def blk_func(values: ArrayLike): return res.__finalize__(self, method="__neg__") @final - def __pos__(self): + def __pos__(self: NDFrameT) -> NDFrameT: def blk_func(values: ArrayLike): if is_bool_dtype(values.dtype): return values.copy() @@ -1410,7 +1409,7 @@ def blk_func(values: ArrayLike): return res.__finalize__(self, method="__pos__") @final - def __invert__(self): + def __invert__(self: NDFrameT) -> NDFrameT: if not self.size: # inv fails with 0 len return self @@ -1428,7 +1427,7 @@ def __nonzero__(self): __bool__ = __nonzero__ @final - def bool(self): + def bool(self) -> bool_t: """ Return the bool of a single element Series or DataFrame. @@ -1471,6 +1470,8 @@ def bool(self): ) self.__nonzero__() + # for mypy (__nonzero__ raises) + return True @final def abs(self: NDFrameT) -> NDFrameT: @@ -1731,7 +1732,14 @@ def _get_label_or_level_values(self, key: str, axis: int = 0) -> np.ndarray: self._check_label_or_level_ambiguity(key, axis=axis) values = self.xs(key, axis=other_axes[0])._values elif self._is_level_reference(key, axis=axis): - values = self.axes[axis].get_level_values(key)._values + # error: Incompatible types in assignment (expression has type "Union[ + # ExtensionArray, ndarray[Any, Any]]", variable has type "ndarray[Any, + # Any]") + values = ( + self.axes[axis] + .get_level_values(key) # type: ignore[assignment] + ._values + ) else: raise KeyError(key) @@ -1850,7 +1858,7 @@ def __iter__(self): return iter(self._info_axis) # can we get a better explanation of this? - def keys(self): + def keys(self) -> Index: """ Get the 'info axis' (see Indexing for more). @@ -3664,7 +3672,9 @@ def _take_with_is_copy(self: NDFrameT, indices, axis=0) -> NDFrameT: return result @final - def xs(self, key, axis=0, level=None, drop_level: bool_t = True): + def xs( + self: NDFrameT, key, axis=0, level=None, drop_level: bool_t = True + ) -> NDFrameT: """ Return cross-section from the Series/DataFrame. @@ -4487,16 +4497,59 @@ def add_suffix(self: NDFrameT, suffix: str) -> NDFrameT: # "**Dict[str, partial[str]]"; expected "Union[str, int, None]" return self._rename(**mapper) # type: ignore[return-value, arg-type] + @overload + def sort_values( + self: NDFrameT, + *, + axis: Axis = ..., + ascending=..., + inplace: Literal[False] = ..., + kind: str = ..., + na_position: str = ..., + ignore_index: bool_t = ..., + key: ValueKeyFunc = ..., + ) -> NDFrameT: + ... + + @overload def sort_values( self, - axis=0, + *, + axis: Axis = ..., + ascending=..., + inplace: Literal[True], + kind: str = ..., + na_position: str = ..., + ignore_index: bool_t = ..., + key: ValueKeyFunc = ..., + ) -> None: + ... + + @overload + def sort_values( + self: NDFrameT, + *, + axis: Axis = ..., + ascending=..., + inplace: bool_t = ..., + kind: str = ..., + na_position: str = ..., + ignore_index: bool_t = ..., + key: ValueKeyFunc = ..., + ) -> NDFrameT | None: + ... + + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) + def sort_values( + self: NDFrameT, + axis: Axis = 0, ascending=True, inplace: bool_t = False, kind: str = "quicksort", na_position: str = "last", ignore_index: bool_t = False, key: ValueKeyFunc = None, - ): + ) -> NDFrameT | None: """ Sort by the values along either axis. @@ -5739,7 +5792,7 @@ def _get_bool_data(self): # Internal Interface Methods @property - def values(self) -> np.ndarray: + def values(self): raise AbstractMethodError(self) @property @@ -6595,6 +6648,48 @@ def bfill( backfill = bfill + @overload + def replace( + self: NDFrameT, + to_replace=..., + value=..., + *, + inplace: Literal[False] = ..., + limit: int | None = ..., + regex=..., + method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = ..., + ) -> NDFrameT: + ... + + @overload + def replace( + self, + to_replace=..., + value=..., + *, + inplace: Literal[True], + limit: int | None = ..., + regex=..., + method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = ..., + ) -> None: + ... + + @overload + def replace( + self: NDFrameT, + to_replace=..., + value=..., + *, + inplace: bool_t = ..., + limit: int | None = ..., + regex=..., + method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = ..., + ) -> NDFrameT | None: + ... + + @deprecate_nonkeyword_arguments( + version=None, allowed_args=["self", "to_replace", "value"] + ) @doc( _shared_docs["replace"], klass=_shared_doc_kwargs["klass"], @@ -6602,14 +6697,14 @@ def bfill( replace_iloc=_shared_doc_kwargs["replace_iloc"], ) def replace( - self, + self: NDFrameT, to_replace=None, value=lib.no_default, inplace: bool_t = False, limit: int | None = None, regex=False, method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = lib.no_default, - ): + ) -> NDFrameT | None: if not ( is_scalar(to_replace) or is_re_compilable(to_replace) @@ -6650,9 +6745,9 @@ def replace( args=(to_replace, method, inplace, limit), ) if inplace: - return + return None return result - self = cast("Series", self) + # self = cast("Series", self) return self._replace_single(to_replace, method, inplace, limit) if not is_dict_like(to_replace): @@ -6701,7 +6796,7 @@ def replace( # need a non-zero len on all axes if not self.size: if inplace: - return + return None return self.copy() if is_dict_like(to_replace): @@ -9113,7 +9208,7 @@ def _where( inplace=False, axis=None, level=None, - errors: IgnoreRaise = "raise", + errors: IgnoreRaise | lib.NoDefault = "raise", ): """ Equivalent to public method `where`, except that `other` is not @@ -9238,6 +9333,51 @@ def _where( result = self._constructor(new_data) return result.__finalize__(self) + @overload + def where( + self: NDFrameT, + cond, + other=..., + *, + inplace: Literal[False] = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> NDFrameT: + ... + + @overload + def where( + self, + cond, + other=..., + *, + inplace: Literal[True], + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> None: + ... + + @overload + def where( + self: NDFrameT, + cond, + other=..., + *, + inplace: bool_t = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> NDFrameT | None: + ... + + @deprecate_nonkeyword_arguments( + version=None, allowed_args=["self", "cond", "other"] + ) @doc( klass=_shared_doc_kwargs["klass"], cond="True", @@ -9246,15 +9386,15 @@ def _where( name_other="mask", ) def where( - self, + self: NDFrameT, cond, other=np.nan, - inplace=False, + inplace: bool_t = False, axis=None, level=None, - errors: IgnoreRaise = "raise", + errors: IgnoreRaise | lib.NoDefault = "raise", try_cast=lib.no_default, - ): + ) -> NDFrameT | None: """ Replace values where the condition is {cond_rev}. @@ -9391,6 +9531,51 @@ def where( return self._where(cond, other, inplace, axis, level, errors=errors) + @overload + def mask( + self: NDFrameT, + cond, + other=..., + *, + inplace: Literal[False] = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> NDFrameT: + ... + + @overload + def mask( + self, + cond, + other=..., + *, + inplace: Literal[True], + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> None: + ... + + @overload + def mask( + self: NDFrameT, + cond, + other=..., + *, + inplace: bool_t = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> NDFrameT | None: + ... + + @deprecate_nonkeyword_arguments( + version=None, allowed_args=["self", "cond", "other"] + ) @doc( where, klass=_shared_doc_kwargs["klass"], @@ -9400,15 +9585,15 @@ def where( name_other="where", ) def mask( - self, + self: NDFrameT, cond, other=np.nan, - inplace=False, + inplace: bool_t = False, axis=None, level=None, - errors: IgnoreRaise = "raise", + errors: IgnoreRaise | lib.NoDefault = "raise", try_cast=lib.no_default, - ): + ) -> NDFrameT | None: inplace = validate_bool_kwarg(inplace, "inplace") cond = com.apply_if_callable(cond, self) @@ -11354,7 +11539,7 @@ def rolling( closed: str | None = None, step: int | None = None, method: str = "single", - ): + ) -> Window | Rolling: axis = self._get_axis_number(axis) if win_type is not None: @@ -11466,47 +11651,47 @@ def _inplace_method(self, other, op): ) return self - def __iadd__(self, other): + def __iadd__(self: NDFrameT, other) -> NDFrameT: # error: Unsupported left operand type for + ("Type[NDFrame]") return self._inplace_method(other, type(self).__add__) # type: ignore[operator] - def __isub__(self, other): + def __isub__(self: NDFrameT, other) -> NDFrameT: # error: Unsupported left operand type for - ("Type[NDFrame]") return self._inplace_method(other, type(self).__sub__) # type: ignore[operator] - def __imul__(self, other): + def __imul__(self: NDFrameT, other) -> NDFrameT: # error: Unsupported left operand type for * ("Type[NDFrame]") return self._inplace_method(other, type(self).__mul__) # type: ignore[operator] - def __itruediv__(self, other): + def __itruediv__(self: NDFrameT, other) -> NDFrameT: # error: Unsupported left operand type for / ("Type[NDFrame]") return self._inplace_method( other, type(self).__truediv__ # type: ignore[operator] ) - def __ifloordiv__(self, other): + def __ifloordiv__(self: NDFrameT, other) -> NDFrameT: # error: Unsupported left operand type for // ("Type[NDFrame]") return self._inplace_method( other, type(self).__floordiv__ # type: ignore[operator] ) - def __imod__(self, other): + def __imod__(self: NDFrameT, other) -> NDFrameT: # error: Unsupported left operand type for % ("Type[NDFrame]") return self._inplace_method(other, type(self).__mod__) # type: ignore[operator] - def __ipow__(self, other): + def __ipow__(self: NDFrameT, other) -> NDFrameT: # error: Unsupported left operand type for ** ("Type[NDFrame]") return self._inplace_method(other, type(self).__pow__) # type: ignore[operator] - def __iand__(self, other): + def __iand__(self: NDFrameT, other) -> NDFrameT: # error: Unsupported left operand type for & ("Type[NDFrame]") return self._inplace_method(other, type(self).__and__) # type: ignore[operator] - def __ior__(self, other): + def __ior__(self: NDFrameT, other) -> NDFrameT: # error: Unsupported left operand type for | ("Type[NDFrame]") return self._inplace_method(other, type(self).__or__) # type: ignore[operator] - def __ixor__(self, other): + def __ixor__(self: NDFrameT, other) -> NDFrameT: # error: Unsupported left operand type for ^ ("Type[NDFrame]") return self._inplace_method(other, type(self).__xor__) # type: ignore[operator] diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index b70904db8ae25..665333d0d7b4f 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -5,6 +5,7 @@ TYPE_CHECKING, Hashable, Sequence, + TypeVar, cast, final, ) @@ -74,6 +75,8 @@ Series, ) +_LocationIndexerT = TypeVar("_LocationIndexerT", bound="_LocationIndexer") + # "null slice" _NS = slice(None, None) _one_ellipsis_message = "indexer may only contain one '...' entry" @@ -654,7 +657,7 @@ class _LocationIndexer(NDFrameIndexerBase): _takeable: bool @final - def __call__(self, axis=None): + def __call__(self: _LocationIndexerT, axis=None) -> _LocationIndexerT: # we need to return a copy of ourselves new_self = type(self)(self.name, self.obj) @@ -798,7 +801,7 @@ def _ensure_listlike_indexer(self, key, axis=None, value=None): self.obj._mgr = self.obj._mgr.reindex_axis(keys, axis=0, only_slice=True) @final - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: check_deprecated_indexers(key) if isinstance(key, tuple): key = tuple(list(x) if is_iterator(x) else x for x in key) @@ -2362,7 +2365,7 @@ def __getitem__(self, key): key = self._convert_key(key) return self.obj._get_value(*key, takeable=self._takeable) - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: if isinstance(key, tuple): key = tuple(com.apply_if_callable(x, self.obj) for x in key) else: diff --git a/pandas/core/missing.py b/pandas/core/missing.py index 57b0a95f803b1..6005e11efbac4 100644 --- a/pandas/core/missing.py +++ b/pandas/core/missing.py @@ -104,7 +104,7 @@ def mask_missing(arr: ArrayLike, values_to_mask) -> npt.NDArray[np.bool_]: return mask -def clean_fill_method(method, allow_nearest: bool = False): +def clean_fill_method(method: str | None, allow_nearest: bool = False): # asfreq is compat for resampling if method in [None, "asfreq"]: return None @@ -907,7 +907,7 @@ def get_fill_func(method, ndim: int = 1): return {"pad": _pad_2d, "backfill": _backfill_2d}[method] -def clean_reindex_fill_method(method): +def clean_reindex_fill_method(method) -> str | None: return clean_fill_method(method, allow_nearest=True) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index a96fb9c8129dd..05a9bde700e32 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -5,6 +5,7 @@ import operator from typing import ( Any, + Callable, cast, ) import warnings @@ -1527,7 +1528,7 @@ def _zero_out_fperr(arg): @disallow("M8", "m8") def nancorr( a: np.ndarray, b: np.ndarray, *, method="pearson", min_periods: int | None = None -): +) -> float: """ a, b: ndarrays """ @@ -1549,7 +1550,7 @@ def nancorr( return f(a, b) -def get_corr_func(method): +def get_corr_func(method) -> Callable[[np.ndarray, np.ndarray], float]: if method == "kendall": from scipy.stats import kendalltau @@ -1586,7 +1587,7 @@ def nancov( *, min_periods: int | None = None, ddof: int | None = 1, -): +) -> float: if len(a) != len(b): raise AssertionError("Operands to nancov must have same size") diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 0a62861cdaba7..7306d13e44982 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -1491,7 +1491,9 @@ def _constructor(self): return TimedeltaIndexResampler -def get_resampler(obj, kind=None, **kwds): +def get_resampler( + obj, kind=None, **kwds +) -> DatetimeIndexResampler | PeriodIndexResampler | TimedeltaIndexResampler: """ Create a TimeGrouper and return our resampler. """ diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py index 8c861c199169b..03aad0ef64dec 100644 --- a/pandas/core/reshape/pivot.py +++ b/pandas/core/reshape/pivot.py @@ -481,6 +481,7 @@ def pivot( columns_listlike = com.convert_to_list_like(columns) + indexed: DataFrame | Series if values is None: if index is not None: cols = com.convert_to_list_like(index) @@ -517,7 +518,10 @@ def pivot( ) else: indexed = data._constructor_sliced(data[values]._values, index=multiindex) - return indexed.unstack(columns_listlike) + # error: Argument 1 to "unstack" of "DataFrame" has incompatible type "Union + # [List[Any], ExtensionArray, ndarray[Any, Any], Index, Series]"; expected + # "Hashable" + return indexed.unstack(columns_listlike) # type: ignore[arg-type] def crosstab( diff --git a/pandas/core/series.py b/pandas/core/series.py index cdebb67e1b6dc..38e71ff6ba00c 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -38,6 +38,7 @@ Axis, Dtype, DtypeObj, + FilePath, FillnaOptions, IgnoreRaise, IndexKeyFunc, @@ -51,6 +52,7 @@ TimedeltaConvertibleTypes, TimestampConvertibleTypes, ValueKeyFunc, + WriteBuffer, npt, ) from pandas.compat.numpy import function as nv @@ -1368,15 +1370,39 @@ def repeat(self, repeats, axis=None) -> Series: self, method="repeat" ) + @overload + def reset_index( + self, + level: Level = ..., + *, + drop: bool = ..., + name: Level = ..., + inplace: Literal[False] = ..., + allow_duplicates: bool = ..., + ) -> Series: + ... + + @overload + def reset_index( + self, + level: Level = ..., + *, + drop: bool = ..., + name: Level = ..., + inplace: Literal[True], + allow_duplicates: bool = ..., + ) -> None: + ... + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "level"]) def reset_index( self, - level=None, - drop=False, - name=lib.no_default, - inplace=False, + level: Level = None, + drop: bool = False, + name: Level = lib.no_default, + inplace: bool = False, allow_duplicates: bool = False, - ): + ) -> Series | None: """ Generate a new DataFrame or Series with the index reset. @@ -1493,10 +1519,10 @@ def reset_index( new_index = default_index(len(self)) if level is not None: if not isinstance(level, (tuple, list)): - level = [level] - level = [self.index._get_level_number(lev) for lev in level] - if len(level) < self.index.nlevels: - new_index = self.index.droplevel(level) + level_list = [level] + level_list = [self.index._get_level_number(lev) for lev in level_list] + if len(level_list) < self.index.nlevels: + new_index = self.index.droplevel(level_list) if inplace: self.index = new_index @@ -1518,9 +1544,12 @@ def reset_index( name = self.name df = self.to_frame(name) - return df.reset_index( + # error: Incompatible return value type (got "DataFrame", expected + # "Optional[Series]") + return df.reset_index( # type: ignore[return-value] level=level, drop=drop, allow_duplicates=allow_duplicates ) + return None # ---------------------------------------------------------------------- # Rendering Methods @@ -1532,19 +1561,51 @@ def __repr__(self) -> str: repr_params = fmt.get_series_repr_params() return self.to_string(**repr_params) + @overload def to_string( self, - buf=None, - na_rep="NaN", - float_format=None, - header=True, - index=True, + buf: None = ..., + na_rep: str = ..., + float_format: str | None = ..., + header: bool = ..., + index: bool = ..., + length=..., + dtype=..., + name=..., + max_rows: int | None = ..., + min_rows: int | None = ..., + ) -> str: + ... + + @overload + def to_string( + self, + buf: FilePath | WriteBuffer[str], + na_rep: str = ..., + float_format: str | None = ..., + header: bool = ..., + index: bool = ..., + length=..., + dtype=..., + name=..., + max_rows: int | None = ..., + min_rows: int | None = ..., + ) -> None: + ... + + def to_string( + self, + buf: FilePath | WriteBuffer[str] | None = None, + na_rep: str = "NaN", + float_format: str | None = None, + header: bool = True, + index: bool = True, length=False, dtype=False, name=False, - max_rows=None, - min_rows=None, - ): + max_rows: int | None = None, + min_rows: int | None = None, + ) -> str | None: """ Render a string representation of the Series. @@ -1603,11 +1664,17 @@ def to_string( if buf is None: return result else: - try: - buf.write(result) - except AttributeError: - with open(buf, "w") as f: + if hasattr(buf, "write"): + # error: Item "str" of "Union[str, PathLike[str], WriteBuffer + # [str]]" has no attribute "write" + buf.write(result) # type: ignore[union-attr] + else: + # error: Argument 1 to "open" has incompatible type "Union[str, + # PathLike[str], WriteBuffer[str]]"; expected "Union[Union[str, + # bytes, PathLike[str], PathLike[bytes]], int]" + with open(buf, "w") as f: # type: ignore[arg-type] f.write(result) + return None @doc( klass=_shared_doc_kwargs["klass"], @@ -2921,7 +2988,7 @@ def searchsorted( # type: ignore[override] def append( self, to_append, ignore_index: bool = False, verify_integrity: bool = False - ): + ) -> Series: """ Concatenate two or more Series. @@ -3399,17 +3466,47 @@ def update(self, other) -> None: # ---------------------------------------------------------------------- # Reindexing, sorting - @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) + # error: Signature of "sort_values" incompatible with supertype "NDFrame" + @overload # type: ignore[override] def sort_values( self, - axis=0, - ascending: bool | int | Sequence[bool | int] = True, + *, + axis: Axis = ..., + ascending: bool | int | Sequence[bool] | Sequence[int] = ..., + inplace: Literal[False] = ..., + kind: str = ..., + na_position: str = ..., + ignore_index: bool = ..., + key: ValueKeyFunc = ..., + ) -> Series: + ... + + @overload + def sort_values( + self, + *, + axis: Axis = ..., + ascending: bool | int | Sequence[bool] | Sequence[int] = ..., + inplace: Literal[True], + kind: str = ..., + na_position: str = ..., + ignore_index: bool = ..., + key: ValueKeyFunc = ..., + ) -> None: + ... + + # error: Signature of "sort_values" incompatible with supertype "NDFrame" + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) + def sort_values( # type: ignore[override] + self, + axis: Axis = 0, + ascending: bool | int | Sequence[bool] | Sequence[int] = True, inplace: bool = False, kind: str = "quicksort", na_position: str = "last", ignore_index: bool = False, key: ValueKeyFunc = None, - ): + ) -> Series | None: """ Sort by the values. @@ -3603,10 +3700,10 @@ def sort_values( if ignore_index: result.index = default_index(len(sorted_index)) - if inplace: - self._update_inplace(result) - else: + if not inplace: return result.__finalize__(self, method="sort_values") + self._update_inplace(result) + return None @overload def sort_index( @@ -4811,22 +4908,21 @@ def rename( @overload def set_axis( - self, labels, axis: Axis = ..., inplace: Literal[False] = ... + self, labels, *, axis: Axis = ..., inplace: Literal[False] = ... ) -> Series: ... @overload - def set_axis(self, labels, axis: Axis, inplace: Literal[True]) -> None: - ... - - @overload - def set_axis(self, labels, *, inplace: Literal[True]) -> None: + def set_axis(self, labels, *, axis: Axis = ..., inplace: Literal[True]) -> None: ... @overload - def set_axis(self, labels, axis: Axis = ..., inplace: bool = ...) -> Series | None: + def set_axis( + self, labels, *, axis: Axis = ..., inplace: bool = ... + ) -> Series | None: ... + # error: Signature of "set_axis" incompatible with supertype "NDFrame" @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "labels"]) @Appender( """ @@ -4853,7 +4949,9 @@ def set_axis(self, labels, axis: Axis = ..., inplace: bool = ...) -> Series | No see_also_sub="", ) @Appender(NDFrame.set_axis.__doc__) - def set_axis(self, labels, axis: Axis = 0, inplace: bool = False): + def set_axis( # type: ignore[override] + self, labels, axis: Axis = 0, inplace: bool = False + ) -> Series | None: return super().set_axis(labels, axis=axis, inplace=inplace) # error: Cannot determine type of 'reindex' @@ -5190,22 +5288,52 @@ def pop(self, item: Hashable) -> Any: """ return super().pop(item=item) - # error: Cannot determine type of 'replace' + # error: Signature of "replace" incompatible with supertype "NDFrame" + @overload # type: ignore[override] + def replace( + self, + to_replace=..., + value=..., + *, + inplace: Literal[False] = ..., + limit: int | None = ..., + regex=..., + method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = ..., + ) -> Series | None: + ... + + @overload + def replace( + self, + to_replace=..., + value=..., + *, + inplace: Literal[True], + limit: int | None = ..., + regex=..., + method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = ..., + ) -> Series | None: + ... + + # error: Signature of "replace" incompatible with supertype "NDFrame" + @deprecate_nonkeyword_arguments( + version=None, allowed_args=["self", "to_replace", "value"] + ) @doc( - NDFrame.replace, # type: ignore[has-type] + NDFrame.replace, klass=_shared_doc_kwargs["klass"], inplace=_shared_doc_kwargs["inplace"], replace_iloc=_shared_doc_kwargs["replace_iloc"], ) - def replace( + def replace( # type: ignore[override] self, to_replace=None, value=lib.no_default, - inplace=False, - limit=None, + inplace: bool = False, + limit: int | None = None, regex=False, method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = lib.no_default, - ): + ) -> Series | None: return super().replace( to_replace=to_replace, value=value, @@ -5522,8 +5650,10 @@ def _convert_dtypes( return result # error: Cannot determine type of 'isna' + # error: Return type "Series" of "isna" incompatible with return type "ndarray + # [Any, dtype[bool_]]" in supertype "IndexOpsMixin" @doc(NDFrame.isna, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type] - def isna(self) -> Series: + def isna(self) -> Series: # type: ignore[override] return NDFrame.isna(self) # error: Cannot determine type of 'isna' @@ -5547,8 +5677,22 @@ def notnull(self) -> Series: """ return super().notnull() + @overload + def dropna( + self, *, axis: Axis = ..., inplace: Literal[False] = ..., how: str | None = ... + ) -> Series: + ... + + @overload + def dropna( + self, *, axis: Axis = ..., inplace: Literal[True], how: str | None = ... + ) -> None: + ... + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) - def dropna(self, axis=0, inplace=False, how=None): + def dropna( + self, axis: Axis = 0, inplace: bool = False, how: str | None = None + ) -> Series | None: """ Return a new Series with missing values removed. @@ -5635,6 +5779,7 @@ def dropna(self, axis=0, inplace=False, how=None): pass else: return self.copy() + return None # ---------------------------------------------------------------------- # Time series-oriented methods @@ -5804,35 +5949,137 @@ def interpolate( **kwargs, ) + @overload + def where( + self, + cond, + other=..., + *, + inplace: Literal[False] = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> Series: + ... + + @overload + def where( + self, + cond, + other=..., + *, + inplace: Literal[True], + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> None: + ... + + @overload + def where( + self, + cond, + other=..., + *, + inplace: bool = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> Series | None: + ... + + # error: Signature of "where" incompatible with supertype "NDFrame" @deprecate_nonkeyword_arguments( version=None, allowed_args=["self", "cond", "other"] ) - def where( + def where( # type: ignore[override] self, cond, other=lib.no_default, - inplace=False, + inplace: bool = False, axis=None, level=None, - errors=lib.no_default, + errors: IgnoreRaise | lib.NoDefault = lib.no_default, try_cast=lib.no_default, - ): - return super().where(cond, other, inplace, axis, level, errors, try_cast) + ) -> Series | None: + return super().where( + cond, + other, + inplace=inplace, + axis=axis, + level=level, + errors=errors, + try_cast=try_cast, + ) + + @overload + def mask( + self, + cond, + other=..., + *, + inplace: Literal[False] = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> Series: + ... + + @overload + def mask( + self, + cond, + other=..., + *, + inplace: Literal[True], + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> None: + ... + + @overload + def mask( + self, + cond, + other=..., + *, + inplace: bool = ..., + axis=..., + level=..., + errors: IgnoreRaise | lib.NoDefault = ..., + try_cast=..., + ) -> Series | None: + ... + # error: Signature of "mask" incompatible with supertype "NDFrame" @deprecate_nonkeyword_arguments( version=None, allowed_args=["self", "cond", "other"] ) - def mask( + def mask( # type: ignore[override] self, cond, other=np.nan, - inplace=False, + inplace: bool = False, axis=None, level=None, - errors=lib.no_default, + errors: IgnoreRaise | lib.NoDefault = lib.no_default, try_cast=lib.no_default, - ): - return super().mask(cond, other, inplace, axis, level, errors, try_cast) + ) -> Series | None: + return super().mask( + cond, + other, + inplace=inplace, + axis=axis, + level=level, + errors=errors, + try_cast=try_cast, + ) # ---------------------------------------------------------------------- # Add index From 4b304cb9256e1ee2224deaed0307141ef9d0265b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sat, 2 Jul 2022 22:15:28 -0400 Subject: [PATCH 02/12] fix test --- pandas/core/series.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/core/series.py b/pandas/core/series.py index 38e71ff6ba00c..d36c7c79c9aa0 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1518,8 +1518,11 @@ def reset_index( if drop: new_index = default_index(len(self)) if level is not None: + level_list: Sequence[Hashable] if not isinstance(level, (tuple, list)): level_list = [level] + else: + level_list = level level_list = [self.index._get_level_number(lev) for lev in level_list] if len(level_list) < self.index.nlevels: new_index = self.index.droplevel(level_list) From 3ea1449fb515973c074a0963fafe079af0657570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 3 Jul 2022 11:23:22 -0400 Subject: [PATCH 03/12] to_html --- pandas/core/frame.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 33d912b50e96f..d41c1b93090ea 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2992,7 +2992,7 @@ def to_orc( def to_html( self, buf: FilePath | WriteBuffer[str], - columns: Sequence[str] | None = ..., + columns: Sequence[Level] | None = ..., col_space: ColspaceArgType | None = ..., header: bool | Sequence[str] = ..., index: bool = ..., @@ -3021,7 +3021,7 @@ def to_html( def to_html( self, buf: None = ..., - columns: Sequence[str] | None = ..., + columns: Sequence[Level] | None = ..., col_space: ColspaceArgType | None = ..., header: bool | Sequence[str] = ..., index: bool = ..., @@ -3059,7 +3059,7 @@ def to_html( def to_html( self, buf: FilePath | WriteBuffer[str] | None = None, - columns: Sequence[str] | None = None, + columns: Sequence[Level] | None = None, col_space: ColspaceArgType | None = None, header: bool | Sequence[str] = True, index: bool = True, From 0dd7dd6611738dfd7e3059b440aa02b035ac83f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 3 Jul 2022 11:35:00 -0400 Subject: [PATCH 04/12] to_html part 2 --- pandas/io/formats/format.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 497523211f2d8..6d497f7d9bb94 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -564,7 +564,7 @@ class DataFrameFormatter: def __init__( self, frame: DataFrame, - columns: Sequence[str] | None = None, + columns: Sequence[Hashable] | None = None, col_space: ColspaceArgType | None = None, header: bool | Sequence[str] = True, index: bool = True, @@ -686,7 +686,7 @@ def _initialize_justify(self, justify: str | None) -> str: else: return justify - def _initialize_columns(self, columns: Sequence[str] | None) -> Index: + def _initialize_columns(self, columns: Sequence[Hashable] | None) -> Index: if columns is not None: cols = ensure_index(columns) self.frame = self.frame[cols] From 25c26ceff862148d7a166c1179a165db27b19d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 3 Jul 2022 20:41:07 -0400 Subject: [PATCH 05/12] DataFrame.query --- pandas/core/frame.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index db875e8ab7631..253f770dece85 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4194,7 +4194,20 @@ def _maybe_cache_changed(self, item, value: Series, inplace: bool) -> None: # ---------------------------------------------------------------------- # Unsorted - def query(self, expr: str, inplace: bool = False, **kwargs) -> None: + @overload + def query(self, expr: str, *, inplace: Literal[False] = ..., **kwargs) -> DataFrame: + ... + + @overload + def query(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: + ... + + @overload + def query(self, expr: str, *, inplace: bool = ..., **kwargs) -> DataFrame | None: + ... + + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "expr"]) + def query(self, expr: str, inplace: bool = False, **kwargs) -> DataFrame | None: """ Query the columns of a DataFrame with a boolean expression. From ef4f674925a855b54b7e7c370c6e75d2f247c8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 3 Jul 2022 22:00:05 -0400 Subject: [PATCH 06/12] more overloads --- pandas/core/frame.py | 130 +++++++++++++++++++++++++---- pandas/core/generic.py | 185 +++++++++++++++++++++++++++++++++++++---- pandas/core/series.py | 109 +++++++++++++++++++----- 3 files changed, 372 insertions(+), 52 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 253f770dece85..a6de871b75831 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2791,6 +2791,32 @@ def to_markdown( handles.handle.write(result) return None + @overload + def to_parquet( + self, + path: None = ..., + engine: str = ..., + compression: str | None = ..., + index: bool | None = ..., + partition_cols: list[str] | None = ..., + storage_options: StorageOptions = ..., + **kwargs, + ) -> bytes: + ... + + @overload + def to_parquet( + self, + path: FilePath | WriteBuffer[bytes], + engine: str = ..., + compression: str | None = ..., + index: bool | None = ..., + partition_cols: list[str] | None = ..., + storage_options: StorageOptions = ..., + **kwargs, + ) -> None: + ... + @doc(storage_options=_shared_docs["storage_options"]) @deprecate_kwarg(old_arg_name="fname", new_arg_name="path") def to_parquet( @@ -5055,11 +5081,11 @@ def reindex(self, *args, **kwargs) -> DataFrame: @overload def drop( self, - labels: Hashable | list[Hashable] = ..., + labels: IndexLabel = ..., *, axis: Axis = ..., - index: Hashable | list[Hashable] = ..., - columns: Hashable | list[Hashable] = ..., + index: IndexLabel = ..., + columns: IndexLabel = ..., level: Level | None = ..., inplace: Literal[True], errors: IgnoreRaise = ..., @@ -5069,11 +5095,11 @@ def drop( @overload def drop( self, - labels: Hashable | list[Hashable] = ..., + labels: IndexLabel = ..., *, axis: Axis = ..., - index: Hashable | list[Hashable] = ..., - columns: Hashable | list[Hashable] = ..., + index: IndexLabel = ..., + columns: IndexLabel = ..., level: Level | None = ..., inplace: Literal[False] = ..., errors: IgnoreRaise = ..., @@ -5083,11 +5109,11 @@ def drop( @overload def drop( self, - labels: Hashable | list[Hashable] = ..., + labels: IndexLabel = ..., *, axis: Axis = ..., - index: Hashable | list[Hashable] = ..., - columns: Hashable | list[Hashable] = ..., + index: IndexLabel = ..., + columns: IndexLabel = ..., level: Level | None = ..., inplace: bool = ..., errors: IgnoreRaise = ..., @@ -5099,10 +5125,10 @@ def drop( @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "labels"]) def drop( # type: ignore[override] self, - labels: Hashable | list[Hashable] = None, + labels: IndexLabel = None, axis: Axis = 0, - index: Hashable | list[Hashable] = None, - columns: Hashable | list[Hashable] = None, + index: IndexLabel = None, + columns: IndexLabel = None, level: Level | None = None, inplace: bool = False, errors: IgnoreRaise = "raise", @@ -11585,25 +11611,93 @@ def values(self) -> np.ndarray: self._consolidate_inplace() return self._mgr.as_array() - @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) + @overload def ffill( - self: DataFrame, + self, + *, + axis: None | Axis = ..., + inplace: Literal[False] = ..., + limit: None | int = ..., + downcast=..., + ) -> DataFrame: + ... + + @overload + def ffill( + self, + *, + axis: None | Axis = ..., + inplace: Literal[True], + limit: None | int = ..., + downcast=..., + ) -> None: + ... + + @overload + def ffill( + self, + *, + axis: None | Axis = ..., + inplace: bool = ..., + limit: None | int = ..., + downcast=..., + ) -> DataFrame | None: + ... + + # error: Signature of "ffill" incompatible with supertype "NDFrame" + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) + def ffill( # type: ignore[override] + self, axis: None | Axis = None, inplace: bool = False, limit: None | int = None, downcast=None, ) -> DataFrame | None: - return super().ffill(axis, inplace, limit, downcast) + return super().ffill(axis=axis, inplace=inplace, limit=limit, downcast=downcast) - @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) + @overload def bfill( - self: DataFrame, + self, + *, + axis: None | Axis = ..., + inplace: Literal[False] = ..., + limit: None | int = ..., + downcast=..., + ) -> DataFrame: + ... + + @overload + def bfill( + self, + *, + axis: None | Axis = ..., + inplace: Literal[True], + limit: None | int = ..., + downcast=..., + ) -> None: + ... + + @overload + def bfill( + self, + *, + axis: None | Axis = ..., + inplace: bool = ..., + limit: None | int = ..., + downcast=..., + ) -> DataFrame | None: + ... + + # error: Signature of "bfill" incompatible with supertype "NDFrame" + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) + def bfill( # type: ignore[override] + self, axis: None | Axis = None, inplace: bool = False, limit: None | int = None, downcast=None, ) -> DataFrame | None: - return super().bfill(axis, inplace, limit, downcast) + return super().bfill(axis=axis, inplace=inplace, limit=limit, downcast=downcast) @deprecate_nonkeyword_arguments( version=None, allowed_args=["self", "lower", "upper"] diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 47bc929a99108..c93569c5d94bd 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1048,10 +1048,44 @@ def _rename( else: return result.__finalize__(self, method="rename") + @overload + def rename_axis( + self: NDFrameT, + mapper: IndexLabel | lib.NoDefault = ..., + *, + inplace: Literal[False] = ..., + **kwargs, + ) -> NDFrameT: + ... + + @overload + def rename_axis( + self: NDFrameT, + mapper: IndexLabel | lib.NoDefault = ..., + *, + inplace: Literal[True], + **kwargs, + ) -> None: + ... + + @overload + def rename_axis( + self: NDFrameT, + mapper: IndexLabel | lib.NoDefault = ..., + *, + inplace: bool_t = ..., + **kwargs, + ) -> NDFrameT | None: + ... + @rewrite_axis_style_signature("mapper", [("copy", True), ("inplace", False)]) + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "mapper"]) def rename_axis( - self, mapper: IndexLabel | lib.NoDefault = lib.no_default, **kwargs - ): + self: NDFrameT, + mapper: IndexLabel | lib.NoDefault = lib.no_default, + inplace: bool_t = False, + **kwargs, + ) -> NDFrameT | None: """ Set the name of the axis for the index or columns. @@ -1220,6 +1254,7 @@ class name result._set_axis_name(newnames, axis=axis, inplace=True) if not inplace: return result + return None @final def _set_axis_name(self, name, axis=0, inplace=False): @@ -3301,6 +3336,60 @@ def to_latex( position=position, ) + @overload + def to_csv( + self, + path_or_buf: None = ..., + sep: str = ..., + na_rep: str = ..., + float_format: str | Callable | None = ..., + columns: Sequence[Hashable] | None = ..., + header: bool_t | list[str] = ..., + index: bool_t = ..., + index_label: IndexLabel | None = ..., + mode: str = ..., + encoding: str | None = ..., + compression: CompressionOptions = ..., + quoting: int | None = ..., + quotechar: str = ..., + lineterminator: str | None = ..., + chunksize: int | None = ..., + date_format: str | None = ..., + doublequote: bool_t = ..., + escapechar: str | None = ..., + decimal: str = ..., + errors: str = ..., + storage_options: StorageOptions = ..., + ) -> str: + ... + + @overload + def to_csv( + self, + path_or_buf: FilePath | WriteBuffer[bytes] | WriteBuffer[str], + sep: str = ..., + na_rep: str = ..., + float_format: str | Callable | None = ..., + columns: Sequence[Hashable] | None = ..., + header: bool_t | list[str] = ..., + index: bool_t = ..., + index_label: IndexLabel | None = ..., + mode: str = ..., + encoding: str | None = ..., + compression: CompressionOptions = ..., + quoting: int | None = ..., + quotechar: str = ..., + lineterminator: str | None = ..., + chunksize: int | None = ..., + date_format: str | None = ..., + doublequote: bool_t = ..., + escapechar: str | None = ..., + decimal: str = ..., + errors: str = ..., + storage_options: StorageOptions = ..., + ) -> None: + ... + @final @doc( storage_options=_shared_docs["storage_options"], @@ -4191,11 +4280,11 @@ def reindex_like( @overload def drop( self, - labels: Hashable | list[Hashable] = ..., + labels: IndexLabel = ..., *, axis: Axis = ..., - index: Hashable | list[Hashable] = ..., - columns: Hashable | list[Hashable] = ..., + index: IndexLabel = ..., + columns: IndexLabel = ..., level: Level | None = ..., inplace: Literal[True], errors: IgnoreRaise = ..., @@ -4205,11 +4294,11 @@ def drop( @overload def drop( self: NDFrameT, - labels: Hashable | list[Hashable] = ..., + labels: IndexLabel = ..., *, axis: Axis = ..., - index: Hashable | list[Hashable] = ..., - columns: Hashable | list[Hashable] = ..., + index: IndexLabel = ..., + columns: IndexLabel = ..., level: Level | None = ..., inplace: Literal[False] = ..., errors: IgnoreRaise = ..., @@ -4219,11 +4308,11 @@ def drop( @overload def drop( self: NDFrameT, - labels: Hashable | list[Hashable] = ..., + labels: IndexLabel = ..., *, axis: Axis = ..., - index: Hashable | list[Hashable] = ..., - columns: Hashable | list[Hashable] = ..., + index: IndexLabel = ..., + columns: IndexLabel = ..., level: Level | None = ..., inplace: bool_t = ..., errors: IgnoreRaise = ..., @@ -4233,10 +4322,10 @@ def drop( @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "labels"]) def drop( self: NDFrameT, - labels: Hashable | list[Hashable] = None, + labels: IndexLabel = None, axis: Axis = 0, - index: Hashable | list[Hashable] = None, - columns: Hashable | list[Hashable] = None, + index: IndexLabel = None, + columns: IndexLabel = None, level: Level | None = None, inplace: bool_t = False, errors: IgnoreRaise = "raise", @@ -6606,6 +6695,40 @@ def fillna( else: return result.__finalize__(self, method="fillna") + @overload + def ffill( + self: NDFrameT, + *, + axis: None | Axis = ..., + inplace: Literal[False] = ..., + limit: None | int = ..., + downcast=..., + ) -> NDFrameT: + ... + + @overload + def ffill( + self, + *, + axis: None | Axis = ..., + inplace: Literal[True], + limit: None | int = ..., + downcast=..., + ) -> None: + ... + + @overload + def ffill( + self: NDFrameT, + *, + axis: None | Axis = ..., + inplace: bool_t = ..., + limit: None | int = ..., + downcast=..., + ) -> NDFrameT | None: + ... + + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) @doc(klass=_shared_doc_kwargs["klass"]) def ffill( self: NDFrameT, @@ -6628,6 +6751,40 @@ def ffill( pad = ffill + @overload + def bfill( + self: NDFrameT, + *, + axis: None | Axis = ..., + inplace: Literal[False] = ..., + limit: None | int = ..., + downcast=..., + ) -> NDFrameT: + ... + + @overload + def bfill( + self, + *, + axis: None | Axis = ..., + inplace: Literal[True], + limit: None | int = ..., + downcast=..., + ) -> None: + ... + + @overload + def bfill( + self: NDFrameT, + *, + axis: None | Axis = ..., + inplace: bool_t = ..., + limit: None | int = ..., + downcast=..., + ) -> NDFrameT | None: + ... + + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) @doc(klass=_shared_doc_kwargs["klass"]) def bfill( self: NDFrameT, diff --git a/pandas/core/series.py b/pandas/core/series.py index d36c7c79c9aa0..fc55a7dfa1dac 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -42,6 +42,7 @@ FillnaOptions, IgnoreRaise, IndexKeyFunc, + IndexLabel, Level, NaPosition, QuantileInterpolation, @@ -4980,11 +4981,11 @@ def reindex(self, *args, **kwargs) -> Series: @overload def drop( self, - labels: Hashable | list[Hashable] = ..., + labels: IndexLabel = ..., *, axis: Axis = ..., - index: Hashable | list[Hashable] = ..., - columns: Hashable | list[Hashable] = ..., + index: IndexLabel = ..., + columns: IndexLabel = ..., level: Level | None = ..., inplace: Literal[True], errors: IgnoreRaise = ..., @@ -4994,11 +4995,11 @@ def drop( @overload def drop( self, - labels: Hashable | list[Hashable] = ..., + labels: IndexLabel = ..., *, axis: Axis = ..., - index: Hashable | list[Hashable] = ..., - columns: Hashable | list[Hashable] = ..., + index: IndexLabel = ..., + columns: IndexLabel = ..., level: Level | None = ..., inplace: Literal[False] = ..., errors: IgnoreRaise = ..., @@ -5008,11 +5009,11 @@ def drop( @overload def drop( self, - labels: Hashable | list[Hashable] = ..., + labels: IndexLabel = ..., *, axis: Axis = ..., - index: Hashable | list[Hashable] = ..., - columns: Hashable | list[Hashable] = ..., + index: IndexLabel = ..., + columns: IndexLabel = ..., level: Level | None = ..., inplace: bool = ..., errors: IgnoreRaise = ..., @@ -5024,10 +5025,10 @@ def drop( @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "labels"]) def drop( # type: ignore[override] self, - labels: Hashable | list[Hashable] = None, + labels: IndexLabel = None, axis: Axis = 0, - index: Hashable | list[Hashable] = None, - columns: Hashable | list[Hashable] = None, + index: IndexLabel = None, + columns: IndexLabel = None, level: Level | None = None, inplace: bool = False, errors: IgnoreRaise = "raise", @@ -5302,7 +5303,7 @@ def replace( limit: int | None = ..., regex=..., method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = ..., - ) -> Series | None: + ) -> Series: ... @overload @@ -5315,7 +5316,7 @@ def replace( limit: int | None = ..., regex=..., method: Literal["pad", "ffill", "bfill"] | lib.NoDefault = ..., - ) -> Series | None: + ) -> None: ... # error: Signature of "replace" incompatible with supertype "NDFrame" @@ -5895,25 +5896,93 @@ def to_period(self, freq=None, copy=True) -> Series: self, method="to_period" ) - @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) + @overload def ffill( - self: Series, + self, + *, + axis: None | Axis = ..., + inplace: Literal[False] = ..., + limit: None | int = ..., + downcast=..., + ) -> Series: + ... + + @overload + def ffill( + self, + *, + axis: None | Axis = ..., + inplace: Literal[True], + limit: None | int = ..., + downcast=..., + ) -> None: + ... + + @overload + def ffill( + self, + *, + axis: None | Axis = ..., + inplace: bool = ..., + limit: None | int = ..., + downcast=..., + ) -> Series | None: + ... + + # error: Signature of "ffill" incompatible with supertype "NDFrame" + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) + def ffill( # type: ignore[override] + self, axis: None | Axis = None, inplace: bool = False, limit: None | int = None, downcast=None, ) -> Series | None: - return super().ffill(axis, inplace, limit, downcast) + return super().ffill(axis=axis, inplace=inplace, limit=limit, downcast=downcast) - @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) + @overload def bfill( - self: Series, + self, + *, + axis: None | Axis = ..., + inplace: Literal[False] = ..., + limit: None | int = ..., + downcast=..., + ) -> Series: + ... + + @overload + def bfill( + self, + *, + axis: None | Axis = ..., + inplace: Literal[True], + limit: None | int = ..., + downcast=..., + ) -> None: + ... + + @overload + def bfill( + self, + *, + axis: None | Axis = ..., + inplace: bool = ..., + limit: None | int = ..., + downcast=..., + ) -> Series | None: + ... + + # error: Signature of "bfill" incompatible with supertype "NDFrame" + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) + def bfill( # type: ignore[override] + self, axis: None | Axis = None, inplace: bool = False, limit: None | int = None, downcast=None, ) -> Series | None: - return super().bfill(axis, inplace, limit, downcast) + return super().bfill(axis=axis, inplace=inplace, limit=limit, downcast=downcast) @deprecate_nonkeyword_arguments( version=None, allowed_args=["self", "lower", "upper"] From 9fa68be15cb7f3b29424213fb54f0f9932b0ff7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 3 Jul 2022 22:37:16 -0400 Subject: [PATCH 07/12] fix query? --- pandas/core/frame.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index a6de871b75831..ad2848fda0cff 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4232,7 +4232,6 @@ def query(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: def query(self, expr: str, *, inplace: bool = ..., **kwargs) -> DataFrame | None: ... - @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "expr"]) def query(self, expr: str, inplace: bool = False, **kwargs) -> DataFrame | None: """ Query the columns of a DataFrame with a boolean expression. From bd854f13e8147b6cc39b03e37c5c849f6cb8198b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 3 Jul 2022 22:51:34 -0400 Subject: [PATCH 08/12] increase stacklevel by one --- pandas/core/frame.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index ad2848fda0cff..3775aaf2c7381 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4232,6 +4232,7 @@ def query(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: def query(self, expr: str, *, inplace: bool = ..., **kwargs) -> DataFrame | None: ... + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "expr"]) def query(self, expr: str, inplace: bool = False, **kwargs) -> DataFrame | None: """ Query the columns of a DataFrame with a boolean expression. @@ -4379,7 +4380,7 @@ def query(self, expr: str, inplace: bool = False, **kwargs) -> DataFrame | None: if not isinstance(expr, str): msg = f"expr must be a string to be evaluated, {type(expr)} given" raise ValueError(msg) - kwargs["level"] = kwargs.pop("level", 0) + 1 + kwargs["level"] = kwargs.pop("level", 0) + 2 kwargs["target"] = None res = self.eval(expr, **kwargs) From ddaac7421024865eb5673de6ce3dd6264ae2aa2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Mon, 4 Jul 2022 08:08:35 -0400 Subject: [PATCH 09/12] fix rename_axis --- pandas/core/generic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index c93569c5d94bd..5878412f2fabe 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1078,7 +1078,7 @@ def rename_axis( ) -> NDFrameT | None: ... - @rewrite_axis_style_signature("mapper", [("copy", True), ("inplace", False)]) + @rewrite_axis_style_signature("mapper", [("copy", True)]) @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "mapper"]) def rename_axis( self: NDFrameT, @@ -1209,6 +1209,7 @@ class name cat 4 0 monkey 2 2 """ + kwargs["inplace"] = inplace axes, kwargs = self._construct_axes_from_arguments( (), kwargs, sentinel=lib.no_default ) From 6c47c339510ff8be7f96c95c376c69146d5cdd3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Mon, 4 Jul 2022 11:48:29 -0400 Subject: [PATCH 10/12] and an overload for DataFrame.eval --- pandas/core/frame.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 3775aaf2c7381..ead4ea744c647 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4397,7 +4397,16 @@ def query(self, expr: str, inplace: bool = False, **kwargs) -> DataFrame | None: else: return result - def eval(self, expr: str, inplace: bool = False, **kwargs): + @overload + def eval(self, expr: str, *, inplace: Literal[False] = ..., **kwargs) -> Any: + ... + + @overload + def eval(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: + ... + + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "expr"]) + def eval(self, expr: str, inplace: bool = False, **kwargs) -> Any | None: """ Evaluate a string describing operations on DataFrame columns. @@ -4503,7 +4512,7 @@ def eval(self, expr: str, inplace: bool = False, **kwargs): from pandas.core.computation.eval import eval as _eval inplace = validate_bool_kwarg(inplace, "inplace") - kwargs["level"] = kwargs.pop("level", 0) + 1 + kwargs["level"] = kwargs.pop("level", 0) + 2 index_resolvers = self._get_index_resolvers() column_resolvers = self._get_cleaned_column_resolvers() resolvers = column_resolvers, index_resolvers From 3be312ceea0ac7e0a1601673a533a7358bf8fa63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Wed, 6 Jul 2022 14:26:43 -0400 Subject: [PATCH 11/12] address comments --- pandas/core/generic.py | 1 - pandas/core/series.py | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 5878412f2fabe..afcd08fbebd45 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -6907,7 +6907,6 @@ def replace( if inplace: return None return result - # self = cast("Series", self) return self._replace_single(to_replace, method, inplace, limit) if not is_dict_like(to_replace): diff --git a/pandas/core/series.py b/pandas/core/series.py index fc55a7dfa1dac..05a48c575d56d 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -5778,10 +5778,7 @@ def dropna( else: return result else: - if inplace: - # do nothing - pass - else: + if not inplace: return self.copy() return None From dc56d787306c858c2f4d3fa24d1155187b7fd5e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Wed, 6 Jul 2022 14:31:30 -0400 Subject: [PATCH 12/12] fix typevar --- pandas/core/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 9e09ca076e98f..ba3474a2513fb 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1060,7 +1060,7 @@ def rename_axis( @overload def rename_axis( - self: NDFrameT, + self, mapper: IndexLabel | lib.NoDefault = ..., *, inplace: Literal[True],