Skip to content

TYP: misc return values #57108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions pandas/_config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@
Any,
Callable,
Generic,
Literal,
NamedTuple,
cast,
overload,
)
import warnings

Expand Down Expand Up @@ -740,7 +742,23 @@ def _build_option_description(k: str) -> str:
return s


def pp_options_list(keys: Iterable[str], width: int = 80, _print: bool = False):
@overload
def pp_options_list(
keys: Iterable[str], *, width: int = ..., _print: Literal[False] = ...
) -> str:
...


@overload
def pp_options_list(
keys: Iterable[str], *, width: int = ..., _print: Literal[True]
) -> None:
...


def pp_options_list(
keys: Iterable[str], *, width: int = 80, _print: bool = False
) -> str | None:
"""Builds a concise listing of available options, grouped by prefix"""
from itertools import groupby
from textwrap import wrap
Expand Down Expand Up @@ -770,8 +788,7 @@ def pp(name: str, ks: Iterable[str]) -> list[str]:
s = "\n".join(ls)
if _print:
print(s)
else:
return s
return s


#
Expand Down
20 changes: 10 additions & 10 deletions pandas/_libs/arrays.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ class NDArrayBacked:
_ndarray: np.ndarray
def __init__(self, values: np.ndarray, dtype: DtypeObj) -> None: ...
@classmethod
def _simple_new(cls, values: np.ndarray, dtype: DtypeObj): ...
def _from_backing_data(self, values: np.ndarray): ...
def __setstate__(self, state): ...
def _simple_new(cls, values: np.ndarray, dtype: DtypeObj) -> Self: ...
def _from_backing_data(self, values: np.ndarray) -> Self: ...
def __setstate__(self, state) -> None: ...
def __len__(self) -> int: ...
@property
def shape(self) -> Shape: ...
Expand All @@ -26,14 +26,14 @@ class NDArrayBacked:
def size(self) -> int: ...
@property
def nbytes(self) -> int: ...
def copy(self, order=...): ...
def delete(self, loc, axis=...): ...
def swapaxes(self, axis1, axis2): ...
def repeat(self, repeats: int | Sequence[int], axis: int | None = ...): ...
def reshape(self, *args, **kwargs): ...
def ravel(self, order=...): ...
def copy(self, order=...) -> Self: ...
def delete(self, loc, axis=...) -> Self: ...
def swapaxes(self, axis1, axis2) -> Self: ...
def repeat(self, repeats: int | Sequence[int], axis: int | None = ...) -> Self: ...
def reshape(self, *args, **kwargs) -> Self: ...
def ravel(self, order=...) -> Self: ...
@property
def T(self): ...
def T(self) -> Self: ...
@classmethod
def _concat_same_type(
cls, to_concat: Sequence[Self], axis: AxisInt = ...
Expand Down
6 changes: 4 additions & 2 deletions pandas/_libs/testing.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
def assert_dict_equal(a, b, compare_keys: bool = ...): ...
from typing import Mapping

def assert_dict_equal(a: Mapping, b: Mapping, compare_keys: bool = ...) -> bool: ...
def assert_almost_equal(
a,
b,
Expand All @@ -9,4 +11,4 @@ def assert_almost_equal(
lobj=...,
robj=...,
index_values=...,
): ...
) -> bool: ...
4 changes: 3 additions & 1 deletion pandas/_libs/tslibs/dtypes.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from enum import Enum

from pandas._typing import Self

OFFSET_TO_PERIOD_FREQSTR: dict[str, str]

def periods_per_day(reso: int = ...) -> int: ...
Expand All @@ -12,7 +14,7 @@ class PeriodDtypeBase:
_n: int

# actually __cinit__
def __new__(cls, code: int, n: int): ...
def __new__(cls, code: int, n: int) -> Self: ...
@property
def _freq_group_code(self) -> int: ...
@property
Expand Down
6 changes: 3 additions & 3 deletions pandas/_libs/tslibs/offsets.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ class BaseOffset:
@overload
def __rsub__(self, other: npt.NDArray[np.object_]) -> npt.NDArray[np.object_]: ...
@overload
def __rsub__(self, other: BaseOffset): ...
def __rsub__(self, other: BaseOffset) -> Self: ...
@overload
def __rsub__(self, other: _DatetimeT) -> _DatetimeT: ...
@overload
def __rsub__(self, other: _TimedeltaT) -> _TimedeltaT: ...
@overload
def __mul__(self, other: np.ndarray) -> np.ndarray: ...
@overload
def __mul__(self, other: int): ...
def __mul__(self, other: int) -> Self: ...
@overload
def __rmul__(self, other: np.ndarray) -> np.ndarray: ...
@overload
Expand Down Expand Up @@ -100,7 +100,7 @@ def _get_offset(name: str) -> BaseOffset: ...

class SingleConstructorOffset(BaseOffset):
@classmethod
def _from_name(cls, suffix: None = ...): ...
def _from_name(cls, suffix: None = ...) -> Self: ...
def __reduce__(self): ...

@overload
Expand Down
2 changes: 1 addition & 1 deletion pandas/_testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ def iat(x):
_UNITS = ["s", "ms", "us", "ns"]


def get_finest_unit(left: str, right: str):
def get_finest_unit(left: str, right: str) -> str:
"""
Find the higher of two datetime64 units.
"""
Expand Down
6 changes: 4 additions & 2 deletions pandas/core/arrays/_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ def method(self, *args, **kwargs):
return cast(F, method)


class NDArrayBackedExtensionArray(NDArrayBacked, ExtensionArray):
# error: Definition of "delete/ravel/T/repeat/copy" in base class "NDArrayBacked"
# is incompatible with definition in base class "ExtensionArray"
class NDArrayBackedExtensionArray(NDArrayBacked, ExtensionArray): # type: ignore[misc]
"""
ExtensionArray that is backed by a single NumPy ndarray.
"""
Expand Down Expand Up @@ -386,7 +388,7 @@ def fillna(
# ------------------------------------------------------------------------
# Reductions

def _wrap_reduction_result(self, axis: AxisInt | None, result):
def _wrap_reduction_result(self, axis: AxisInt | None, result) -> Any:
if axis is None or self.ndim == 1:
return self._box_func(result)
return self._from_backing_data(result)
Expand Down
6 changes: 3 additions & 3 deletions pandas/core/arrays/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1781,7 +1781,7 @@ def _formatter(self, boxed: bool = False) -> Callable[[Any], str | None]:
# Reshaping
# ------------------------------------------------------------------------

def transpose(self, *axes: int) -> ExtensionArray:
def transpose(self, *axes: int) -> Self:
"""
Return a transposed view on this array.

Expand All @@ -1802,10 +1802,10 @@ def transpose(self, *axes: int) -> ExtensionArray:
return self[:]

@property
def T(self) -> ExtensionArray:
def T(self) -> Self:
return self.transpose()

def ravel(self, order: Literal["C", "F", "A", "K"] | None = "C") -> ExtensionArray:
def ravel(self, order: Literal["C", "F", "A", "K"] | None = "C") -> Self:
"""
Return a flattened view on this array.

Expand Down
23 changes: 16 additions & 7 deletions pandas/core/arrays/categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,9 @@ def contains(cat, key, container) -> bool:
return any(loc_ in container for loc_ in loc)


class Categorical(NDArrayBackedExtensionArray, PandasObject, ObjectStringArrayMixin):
# error: Definition of "delete/ravel/T/repeat/copy" in base class "NDArrayBacked"
# is incompatible with definition in base class "ExtensionArray"
class Categorical(NDArrayBackedExtensionArray, PandasObject, ObjectStringArrayMixin): # type: ignore[misc]
"""
Represent a categorical variable in classic R / S-plus fashion.

Expand Down Expand Up @@ -561,6 +563,7 @@ def astype(self, dtype: AstypeArg, copy: bool = True) -> ArrayLike:
object is returned.
"""
dtype = pandas_dtype(dtype)
result: Categorical | np.ndarray
if self.dtype is dtype:
result = self.copy() if copy else self

Expand Down Expand Up @@ -1818,10 +1821,14 @@ def value_counts(self, dropna: bool = True) -> Series:
ix = np.append(ix, -1)

ix = coerce_indexer_dtype(ix, self.dtype.categories)
ix = self._from_backing_data(ix)
ix_categorical = self._from_backing_data(ix)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to set mypy's allow_redefinition to true to avoid having to change the runtime behavior slightly (ix isn't freed immediately). Pyright allows redefinitions.


return Series(
count, index=CategoricalIndex(ix), dtype="int64", name="count", copy=False
count,
index=CategoricalIndex(ix_categorical),
dtype="int64",
name="count",
copy=False,
)

# error: Argument 2 of "_empty" is incompatible with supertype
Expand Down Expand Up @@ -2526,7 +2533,9 @@ def _concat_same_type(cls, to_concat: Sequence[Self], axis: AxisInt = 0) -> Self
result = res_flat.reshape(len(first), -1, order="F")
return result

result = union_categoricals(to_concat)
# error: Incompatible types in assignment (expression has type "Categorical",
# variable has type "Self")
result = union_categoricals(to_concat) # type: ignore[assignment]
return result

# ------------------------------------------------------------------
Expand Down Expand Up @@ -2666,11 +2675,11 @@ def _replace(self, *, to_replace, value, inplace: bool = False) -> Self | None:

new_categories = ser.take(locs)
new_categories = new_categories.drop_duplicates(keep="first")
new_categories = Index(new_categories)
index_categories = Index(new_categories)
new_codes = recode_for_categories(
cat._codes, all_values, new_categories, copy=False
cat._codes, all_values, index_categories, copy=False
)
new_dtype = CategoricalDtype(new_categories, ordered=self.dtype.ordered)
new_dtype = CategoricalDtype(index_categories, ordered=self.dtype.ordered)
NDArrayBacked.__init__(cat, new_codes, new_dtype)

if new_dtype != orig_dtype:
Expand Down
2 changes: 2 additions & 0 deletions pandas/core/arrays/interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -1727,6 +1727,8 @@ def insert(self, loc: int, item: Interval) -> Self:
return self._shallow_copy(new_left, new_right)

def delete(self, loc) -> Self:
new_left: np.ndarray | DatetimeArray | TimedeltaArray
new_right: np.ndarray | DatetimeArray | TimedeltaArray
if isinstance(self._left, np.ndarray):
new_left = np.delete(self._left, loc)
assert isinstance(self._right, np.ndarray)
Expand Down
6 changes: 3 additions & 3 deletions pandas/core/arrays/string_.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,10 +499,10 @@ def astype(self, dtype, copy: bool = True):
values = arr.astype(dtype.numpy_dtype)
return IntegerArray(values, mask, copy=False)
elif isinstance(dtype, FloatingDtype):
arr = self.copy()
arr_ea = self.copy()
mask = self.isna()
arr[mask] = "0"
values = arr.astype(dtype.numpy_dtype)
arr_ea[mask] = "0"
values = arr_ea.astype(dtype.numpy_dtype)
return FloatingArray(values, mask, copy=False)
elif isinstance(dtype, ExtensionDtype):
# Skip the NumpyExtensionArray.astype method
Expand Down
2 changes: 1 addition & 1 deletion pandas/plotting/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def hist_series(

Returns
-------
matplotlib.Axes
matplotlib.axes.Axes
A histogram plot.

See Also
Expand Down
12 changes: 7 additions & 5 deletions pandas/plotting/_matplotlib/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ def _col_idx_to_axis_idx(self, col_idx: int) -> int:
return col_idx

@final
def _get_ax(self, i: int):
def _get_ax(self, i: int) -> Axes:
# get the twinx ax if appropriate
if self.subplots:
i = self._col_idx_to_axis_idx(i)
Expand All @@ -1037,7 +1037,7 @@ def _get_ax(self, i: int):
return ax

@final
def on_right(self, i: int):
def on_right(self, i: int) -> bool:
if isinstance(self.secondary_y, bool):
return self.secondary_y

Expand Down Expand Up @@ -1210,7 +1210,7 @@ def _get_errorbars(
return errors

@final
def _get_subplots(self, fig: Figure):
def _get_subplots(self, fig: Figure) -> list[Axes]:
if Version(mpl.__version__) < Version("3.8"):
from matplotlib.axes import Subplot as Klass
else:
Expand Down Expand Up @@ -2100,9 +2100,11 @@ def blank_labeler(label, value):
results = ax.pie(y, labels=blabels, **kwds)

if kwds.get("autopct", None) is not None:
patches, texts, autotexts = results
# error: Need more than 2 values to unpack (3 expected)
patches, texts, autotexts = results # type: ignore[misc]
else:
patches, texts = results
# error: Too many values to unpack (2 expected, 3 provided)
patches, texts = results # type: ignore[misc]
autotexts = []

if self.fontsize is not None:
Expand Down
4 changes: 2 additions & 2 deletions pandas/tseries/holiday.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ def register(cls) -> None:
holiday_calendars[name] = cls


def get_calendar(name: str):
def get_calendar(name: str) -> AbstractHolidayCalendar:
"""
Return an instance of a calendar based on its name.

Expand Down Expand Up @@ -433,7 +433,7 @@ def __init__(self, name: str = "", rules=None) -> None:
if rules is not None:
self.rules = rules

def rule_from_name(self, name: str):
def rule_from_name(self, name: str) -> Holiday | None:
for rule in self.rules:
if rule.name == name:
return rule
Expand Down
6 changes: 5 additions & 1 deletion pandas/util/_doctools.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
if TYPE_CHECKING:
from collections.abc import Iterable

from matplotlib.figure import Figure


class TablePlotter:
"""
Expand Down Expand Up @@ -46,7 +48,9 @@ def _get_cells(self, left, right, vertical) -> tuple[int, int]:
hcells = sum([self._shape(df)[1] for df in left] + [self._shape(right)[1]])
return hcells, vcells

def plot(self, left, right, labels: Iterable[str] = (), vertical: bool = True):
def plot(
self, left, right, labels: Iterable[str] = (), vertical: bool = True
) -> Figure:
"""
Plot left / right DataFrames in specified layout.

Expand Down