From 76d7e923262540cc5182b4e7e023fae1337c68fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sat, 4 Sep 2021 10:41:36 -0400 Subject: [PATCH 1/4] TYP: type some un-typed decorators --- pandas/core/indexes/multi.py | 7 +++++-- pandas/core/nanops.py | 6 ++++-- pandas/core/window/expanding.py | 2 +- pandas/core/window/rolling.py | 4 ++-- pandas/io/pytables.py | 6 +++--- pandas/plotting/_matplotlib/converter.py | 7 +++++-- pandas/plotting/_matplotlib/core.py | 18 +++++++++++++----- pandas/tests/frame/methods/test_sort_index.py | 6 +++--- 8 files changed, 36 insertions(+), 20 deletions(-) diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 0c158d47cfa3b..6af01753ffd03 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -29,6 +29,7 @@ from pandas._typing import ( AnyArrayLike, DtypeObj, + F, Scalar, Shape, npt, @@ -185,7 +186,7 @@ def _codes_to_ints(self, codes): return np.bitwise_or.reduce(codes, axis=1) -def names_compat(meth): +def names_compat(meth: F) -> F: """ A decorator to allow either `name` or `names` keyword but not both. @@ -201,7 +202,9 @@ def new_meth(self_or_cls, *args, **kwargs): return meth(self_or_cls, *args, **kwargs) - return new_meth + # error: Incompatible return value type (got "Callable[[Any, VarArg(Any), + # KwArg(Any)], Any]", expected "F") + return new_meth # type: ignore[return-value] class MultiIndex(Index): diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 5d96e9bb6cd19..22a4f8a89e054 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -449,7 +449,7 @@ def _na_for_min_count(values: np.ndarray, axis: int | None) -> Scalar | np.ndarr return np.full(result_shape, fill_value, dtype=values.dtype) -def maybe_operate_rowwise(func): +def maybe_operate_rowwise(func: F) -> F: """ NumPy operations on C-contiguous ndarrays with axis=1 can be very slow. Operate row-by-row and concatenate the results. @@ -475,7 +475,9 @@ def newfunc(values: np.ndarray, *, axis: int | None = None, **kwargs): return func(values, axis=axis, **kwargs) - return newfunc + # error: Incompatible return value type (got "Callable[[ndarray[Any, Any], + # DefaultNamedArg(Optional[int], 'axis'), KwArg(Any)], Any]", expected "F") + return newfunc # type: ignore[return-value] def nanany( diff --git a/pandas/core/window/expanding.py b/pandas/core/window/expanding.py index 36a6399df7dbc..45ebee6db5ad4 100644 --- a/pandas/core/window/expanding.py +++ b/pandas/core/window/expanding.py @@ -96,7 +96,7 @@ class Expanding(RollingAndExpandingMixin): 4 7.0 """ - _attributes = ["min_periods", "center", "axis", "method"] + _attributes: list[str] = ["min_periods", "center", "axis", "method"] def __init__( self, diff --git a/pandas/core/window/rolling.py b/pandas/core/window/rolling.py index a8e2ecf3d7f54..f6e991c7d7cd2 100644 --- a/pandas/core/window/rolling.py +++ b/pandas/core/window/rolling.py @@ -583,7 +583,7 @@ class BaseWindowGroupby(BaseWindow): _grouper: BaseGrouper _as_index: bool - _attributes = ["_grouper"] + _attributes: list[str] = ["_grouper"] def __init__( self, @@ -1500,7 +1500,7 @@ def corr_func(x, y): class Rolling(RollingAndExpandingMixin): - _attributes = [ + _attributes: list[str] = [ "window", "min_periods", "center", diff --git a/pandas/io/pytables.py b/pandas/io/pytables.py index 75f8e043ea864..d7a90511e3c73 100644 --- a/pandas/io/pytables.py +++ b/pandas/io/pytables.py @@ -4549,10 +4549,10 @@ def read( # we could have a multi-index constructor here # ensure_index doesn't recognized our list-of-tuples here - if info.get("type") == "MultiIndex": - cols = MultiIndex.from_tuples(index_vals) - else: + if info.get("type") != "MultiIndex": cols = Index(index_vals) + else: + cols = MultiIndex.from_tuples(index_vals) names = info.get("names") if names is not None: diff --git a/pandas/plotting/_matplotlib/converter.py b/pandas/plotting/_matplotlib/converter.py index 7e3bf0b224e0e..cc6ba303ea88b 100644 --- a/pandas/plotting/_matplotlib/converter.py +++ b/pandas/plotting/_matplotlib/converter.py @@ -28,6 +28,7 @@ ) from pandas._libs.tslibs.dtypes import FreqGroup from pandas._libs.tslibs.offsets import BaseOffset +from pandas._typing import F from pandas.core.dtypes.common import ( is_float, @@ -76,7 +77,7 @@ def get_pairs(): return pairs -def register_pandas_matplotlib_converters(func): +def register_pandas_matplotlib_converters(func: F) -> F: """ Decorator applying pandas_converters. """ @@ -86,7 +87,9 @@ def wrapper(*args, **kwargs): with pandas_converters(): return func(*args, **kwargs) - return wrapper + # error: Incompatible return value type (got "Callable[[VarArg(Any), KwArg(Any)], + # Any]", expected "F") + return wrapper # type: ignore[return-value] @contextlib.contextmanager diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index ff76bd771d1c0..061e36e457443 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -1248,8 +1248,9 @@ def _make_plot(self): left, right = get_xlim(lines) ax.set_xlim(left, right) + # error: Signature of "_plot" incompatible with supertype "MPLPlot" @classmethod - def _plot( + def _plot( # type: ignore[override] cls, ax: Axes, x, y, style=None, column_num=None, stacking_id=None, **kwds ): # column_num is used to get the target column from plotf in line and @@ -1383,8 +1384,9 @@ def __init__(self, data, **kwargs): if self.logy or self.loglog: raise ValueError("Log-y scales are not supported in area plot") + # error: Signature of "_plot" incompatible with supertype "MPLPlot" @classmethod - def _plot( + def _plot( # type: ignore[override] cls, ax: Axes, x, @@ -1392,7 +1394,7 @@ def _plot( style=None, column_num=None, stacking_id=None, - is_errorbar=False, + is_errorbar: bool = False, **kwds, ): @@ -1483,8 +1485,11 @@ def _args_adjust(self): if is_list_like(self.left): self.left = np.array(self.left) + # error: Signature of "_plot" incompatible with supertype "MPLPlot" @classmethod - def _plot(cls, ax: Axes, x, y, w, start=0, log=False, **kwds): + def _plot( # type: ignore[override] + cls, ax: Axes, x, y, w, start=0, log=False, **kwds + ): return ax.bar(x, y, w, bottom=start, log=log, **kwds) @property @@ -1601,8 +1606,11 @@ class BarhPlot(BarPlot): def _start_base(self): return self.left + # error: Signature of "_plot" incompatible with supertype "MPLPlot" @classmethod - def _plot(cls, ax: Axes, x, y, w, start=0, log=False, **kwds): + def _plot( # type: ignore[override] + cls, ax: Axes, x, y, w, start=0, log=False, **kwds + ): return ax.barh(x, y, w, left=start, log=log, **kwds) def _decorate_ticks(self, ax: Axes, name, ticklabels, start_edge, end_edge): diff --git a/pandas/tests/frame/methods/test_sort_index.py b/pandas/tests/frame/methods/test_sort_index.py index dac3c0382df01..23d61885bde41 100644 --- a/pandas/tests/frame/methods/test_sort_index.py +++ b/pandas/tests/frame/methods/test_sort_index.py @@ -441,14 +441,14 @@ def test_sort_index_ignore_index( {"M1": [1, 2], "M2": [3, 4]}, True, False, - MultiIndex.from_tuples([[2, 1], [3, 4]], names=list("AB")), + MultiIndex.from_tuples(((2, 1), (3, 4)), names=list("AB")), ), ( {"M1": [1, 2], "M2": [3, 4]}, {"M1": [2, 1], "M2": [4, 3]}, False, False, - MultiIndex.from_tuples([[3, 4], [2, 1]], names=list("AB")), + MultiIndex.from_tuples(((3, 4), (2, 1)), names=list("AB")), ), ], ) @@ -456,7 +456,7 @@ def test_sort_index_ignore_index_multi_index( self, inplace, original_dict, sorted_dict, ascending, ignore_index, output_index ): # GH 30114, this is to test ignore_index on MulitIndex of index - mi = MultiIndex.from_tuples([[2, 1], [3, 4]], names=list("AB")) + mi = MultiIndex.from_tuples(((2, 1), (2, 4)), names=list("AB")) df = DataFrame(original_dict, index=mi) expected_df = DataFrame(sorted_dict, index=output_index) From 525b1478518eeb3af1b61937fbeadc1435109f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sat, 4 Sep 2021 12:13:59 -0400 Subject: [PATCH 2/4] use cast --- pandas/core/indexes/multi.py | 4 +--- pandas/core/nanops.py | 4 +--- pandas/plotting/_matplotlib/converter.py | 9 +++++---- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 6af01753ffd03..1b9f1d1d052ab 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -202,9 +202,7 @@ def new_meth(self_or_cls, *args, **kwargs): return meth(self_or_cls, *args, **kwargs) - # error: Incompatible return value type (got "Callable[[Any, VarArg(Any), - # KwArg(Any)], Any]", expected "F") - return new_meth # type: ignore[return-value] + return cast(F, new_meth) class MultiIndex(Index): diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 22a4f8a89e054..ea4982f52991c 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -475,9 +475,7 @@ def newfunc(values: np.ndarray, *, axis: int | None = None, **kwargs): return func(values, axis=axis, **kwargs) - # error: Incompatible return value type (got "Callable[[ndarray[Any, Any], - # DefaultNamedArg(Optional[int], 'axis'), KwArg(Any)], Any]", expected "F") - return newfunc # type: ignore[return-value] + return cast(F, newfunc) def nanany( diff --git a/pandas/plotting/_matplotlib/converter.py b/pandas/plotting/_matplotlib/converter.py index cc6ba303ea88b..ead0a2129d29f 100644 --- a/pandas/plotting/_matplotlib/converter.py +++ b/pandas/plotting/_matplotlib/converter.py @@ -8,7 +8,10 @@ tzinfo, ) import functools -from typing import Any +from typing import ( + Any, + cast, +) from dateutil.relativedelta import relativedelta import matplotlib.dates as dates @@ -87,9 +90,7 @@ def wrapper(*args, **kwargs): with pandas_converters(): return func(*args, **kwargs) - # error: Incompatible return value type (got "Callable[[VarArg(Any), KwArg(Any)], - # Any]", expected "F") - return wrapper # type: ignore[return-value] + return cast(F, wrapper) @contextlib.contextmanager From 60d395f0b7e438f0edd460b2930921d6f7f0e739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sat, 4 Sep 2021 13:28:26 -0400 Subject: [PATCH 3/4] fix test --- pandas/core/nanops.py | 2 +- pandas/tests/frame/methods/test_sort_index.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index ea4982f52991c..d37295eff83c4 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -72,7 +72,7 @@ def set_use_bottleneck(v: bool = True) -> None: class disallow: - def __init__(self, *dtypes): + def __init__(self, *dtypes: Dtype): super().__init__() self.dtypes = tuple(pandas_dtype(dtype).type for dtype in dtypes) diff --git a/pandas/tests/frame/methods/test_sort_index.py b/pandas/tests/frame/methods/test_sort_index.py index 23d61885bde41..aba2611911740 100644 --- a/pandas/tests/frame/methods/test_sort_index.py +++ b/pandas/tests/frame/methods/test_sort_index.py @@ -456,7 +456,7 @@ def test_sort_index_ignore_index_multi_index( self, inplace, original_dict, sorted_dict, ascending, ignore_index, output_index ): # GH 30114, this is to test ignore_index on MulitIndex of index - mi = MultiIndex.from_tuples(((2, 1), (2, 4)), names=list("AB")) + mi = MultiIndex.from_tuples(((2, 1), (3, 4)), names=list("AB")) df = DataFrame(original_dict, index=mi) expected_df = DataFrame(sorted_dict, index=output_index) From 83d9aae698cf741ab520f55837f24df0bafa477e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Sun, 5 Sep 2021 00:05:55 -0400 Subject: [PATCH 4/4] list of tuples --- pandas/tests/frame/methods/test_sort_index.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/tests/frame/methods/test_sort_index.py b/pandas/tests/frame/methods/test_sort_index.py index aba2611911740..e0f3286ec1f2f 100644 --- a/pandas/tests/frame/methods/test_sort_index.py +++ b/pandas/tests/frame/methods/test_sort_index.py @@ -441,14 +441,14 @@ def test_sort_index_ignore_index( {"M1": [1, 2], "M2": [3, 4]}, True, False, - MultiIndex.from_tuples(((2, 1), (3, 4)), names=list("AB")), + MultiIndex.from_tuples([(2, 1), (3, 4)], names=list("AB")), ), ( {"M1": [1, 2], "M2": [3, 4]}, {"M1": [2, 1], "M2": [4, 3]}, False, False, - MultiIndex.from_tuples(((3, 4), (2, 1)), names=list("AB")), + MultiIndex.from_tuples([(3, 4), (2, 1)], names=list("AB")), ), ], ) @@ -456,7 +456,7 @@ def test_sort_index_ignore_index_multi_index( self, inplace, original_dict, sorted_dict, ascending, ignore_index, output_index ): # GH 30114, this is to test ignore_index on MulitIndex of index - mi = MultiIndex.from_tuples(((2, 1), (3, 4)), names=list("AB")) + mi = MultiIndex.from_tuples([(2, 1), (3, 4)], names=list("AB")) df = DataFrame(original_dict, index=mi) expected_df = DataFrame(sorted_dict, index=output_index)