diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 782340178f462..42ff96603b71f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -132,11 +132,11 @@ repos: types: [python] stages: [manual] additional_dependencies: &pyright_dependencies - - pyright@1.1.318 + - pyright@1.1.339 - id: pyright # note: assumes python env is setup and activated name: pyright reportGeneralTypeIssues - entry: pyright --skipunannotated -p pyright_reportGeneralTypeIssues.json --level warning + entry: pyright -p pyright_reportGeneralTypeIssues.json --level warning language: node pass_filenames: false types: [python] diff --git a/doc/source/whatsnew/v2.2.0.rst b/doc/source/whatsnew/v2.2.0.rst index 9c3a46339769f..53fdffd964f4f 100644 --- a/doc/source/whatsnew/v2.2.0.rst +++ b/doc/source/whatsnew/v2.2.0.rst @@ -345,6 +345,8 @@ Optional libraries below the lowest tested version may still work, but are not c +-----------------+-----------------+---------+ | Package | Minimum Version | Changed | +=================+=================+=========+ +| mypy (dev) | 1.7.1 | X | ++-----------------+-----------------+---------+ | | | X | +-----------------+-----------------+---------+ diff --git a/environment.yml b/environment.yml index 0014e71ed0804..5fad8b5031b0a 100644 --- a/environment.yml +++ b/environment.yml @@ -76,7 +76,7 @@ dependencies: # code checks - flake8=6.1.0 # run in subprocess over docstring examples - - mypy=1.4.1 # pre-commit uses locally installed mypy + - mypy=1.7.1 # pre-commit uses locally installed mypy - tokenize-rt # scripts/check_for_inconsistent_pandas_namespace.py - pre-commit>=3.6.0 diff --git a/pandas/_config/config.py b/pandas/_config/config.py index a776825732090..c391939d22491 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -220,6 +220,8 @@ def get_default_val(pat: str): class DictWrapper: """provide attribute-style access to a nested dict""" + d: dict[str, Any] + def __init__(self, d: dict[str, Any], prefix: str = "") -> None: object.__setattr__(self, "d", d) object.__setattr__(self, "prefix", prefix) @@ -250,7 +252,7 @@ def __getattr__(self, key: str): else: return _get_option(prefix) - def __dir__(self) -> Iterable[str]: + def __dir__(self) -> list[str]: return list(self.d.keys()) diff --git a/pandas/_libs/tslibs/nattype.pyi b/pandas/_libs/tslibs/nattype.pyi index 437b5ab6676c8..bd86a6fdc2174 100644 --- a/pandas/_libs/tslibs/nattype.pyi +++ b/pandas/_libs/tslibs/nattype.pyi @@ -8,6 +8,7 @@ import typing import numpy as np from pandas._libs.tslibs.period import Period +from pandas._typing import Self NaT: NaTType iNaT: int @@ -132,4 +133,9 @@ class NaTType: __le__: _NatComparison __gt__: _NatComparison __ge__: _NatComparison + def __sub__(self, other: Self | timedelta | datetime) -> Self: ... + def __rsub__(self, other: Self | timedelta | datetime) -> Self: ... + def __add__(self, other: Self | timedelta | datetime) -> Self: ... + def __radd__(self, other: Self | timedelta | datetime) -> Self: ... + def __hash__(self) -> int: ... def as_unit(self, unit: str, round_ok: bool = ...) -> NaTType: ... diff --git a/pandas/_libs/tslibs/timestamps.pyi b/pandas/_libs/tslibs/timestamps.pyi index c78c174e27902..c769b09d1b7a1 100644 --- a/pandas/_libs/tslibs/timestamps.pyi +++ b/pandas/_libs/tslibs/timestamps.pyi @@ -10,7 +10,6 @@ from typing import ( ClassVar, Literal, TypeAlias, - TypeVar, overload, ) @@ -28,7 +27,6 @@ from pandas._typing import ( TimestampNonexistent, ) -_DatetimeT = TypeVar("_DatetimeT", bound=datetime) _TimeZones: TypeAlias = str | _tzinfo | None | int def integer_op_not_supported(obj: object) -> TypeError: ... @@ -42,7 +40,7 @@ class Timestamp(datetime): _value: int # np.int64 # error: "__new__" must return a class instance (got "Union[Timestamp, NaTType]") def __new__( # type: ignore[misc] - cls: type[_DatetimeT], + cls: type[Self], ts_input: np.integer | float | str | _date | datetime | np.datetime64 = ..., year: int | None = ..., month: int | None = ..., @@ -57,7 +55,7 @@ class Timestamp(datetime): tz: _TimeZones = ..., unit: str | int | None = ..., fold: int | None = ..., - ) -> _DatetimeT | NaTType: ... + ) -> Self | NaTType: ... @classmethod def _from_value_and_reso( cls, value: int, reso: int, tz: _TimeZones diff --git a/pandas/_testing/_hypothesis.py b/pandas/_testing/_hypothesis.py index 5256a303de34e..084ca9c306d19 100644 --- a/pandas/_testing/_hypothesis.py +++ b/pandas/_testing/_hypothesis.py @@ -54,8 +54,12 @@ DATETIME_NO_TZ = st.datetimes() DATETIME_JAN_1_1900_OPTIONAL_TZ = st.datetimes( - min_value=pd.Timestamp(1900, 1, 1).to_pydatetime(), - max_value=pd.Timestamp(1900, 1, 1).to_pydatetime(), + min_value=pd.Timestamp( + 1900, 1, 1 + ).to_pydatetime(), # pyright: ignore[reportGeneralTypeIssues] + max_value=pd.Timestamp( + 1900, 1, 1 + ).to_pydatetime(), # pyright: ignore[reportGeneralTypeIssues] timezones=st.one_of(st.none(), dateutil_timezones(), pytz_timezones()), ) diff --git a/pandas/_typing.py b/pandas/_typing.py index c2d51f63eb2ab..3df9a47a35fca 100644 --- a/pandas/_typing.py +++ b/pandas/_typing.py @@ -234,7 +234,9 @@ def __reversed__(self) -> Iterator[_T_co]: # types of `func` kwarg for DataFrame.aggregate and Series.aggregate AggFuncTypeBase = Union[Callable, str] -AggFuncTypeDict = dict[Hashable, Union[AggFuncTypeBase, list[AggFuncTypeBase]]] +AggFuncTypeDict = MutableMapping[ + Hashable, Union[AggFuncTypeBase, list[AggFuncTypeBase]] +] AggFuncType = Union[ AggFuncTypeBase, list[AggFuncTypeBase], diff --git a/pandas/conftest.py b/pandas/conftest.py index 7bfd1b35f5314..53173fe93bb57 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -1353,7 +1353,7 @@ def fixed_now_ts() -> Timestamp: """ Fixture emits fixed Timestamp.now() """ - return Timestamp( + return Timestamp( # pyright: ignore[reportGeneralTypeIssues] year=2021, month=1, day=1, hour=12, minute=4, second=13, microsecond=22 ) diff --git a/pandas/core/_numba/kernels/var_.py b/pandas/core/_numba/kernels/var_.py index e150c719b87b4..c63d0b90b0fc3 100644 --- a/pandas/core/_numba/kernels/var_.py +++ b/pandas/core/_numba/kernels/var_.py @@ -116,7 +116,7 @@ def sliding_var( ssqdm_x, compensation_add, num_consecutive_same_value, - prev_value, # pyright: ignore[reportGeneralTypeIssues] + prev_value, ) else: for j in range(start[i - 1], s): @@ -141,7 +141,7 @@ def sliding_var( ssqdm_x, compensation_add, num_consecutive_same_value, - prev_value, # pyright: ignore[reportGeneralTypeIssues] + prev_value, ) if nobs >= min_periods and nobs > ddof: diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 169a44accf066..25a71ce5b5f4f 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -9,7 +9,6 @@ TYPE_CHECKING, Any, Callable, - DefaultDict, Literal, cast, ) @@ -63,6 +62,7 @@ Generator, Hashable, Iterable, + MutableMapping, Sequence, ) @@ -1642,7 +1642,7 @@ def transform(self): def reconstruct_func( func: AggFuncType | None, **kwargs -) -> tuple[bool, AggFuncType, list[str] | None, npt.NDArray[np.intp] | None]: +) -> tuple[bool, AggFuncType, tuple[str, ...] | None, npt.NDArray[np.intp] | None]: """ This is the internal function to reconstruct func given if there is relabeling or not and also normalize the keyword to get new order of columns. @@ -1668,7 +1668,7 @@ def reconstruct_func( ------- relabelling: bool, if there is relabelling or not func: normalized and mangled func - columns: list of column names + columns: tuple of column names order: array of columns indices Examples @@ -1680,7 +1680,7 @@ def reconstruct_func( (False, 'min', None, None) """ relabeling = func is None and is_multi_agg_with_relabel(**kwargs) - columns: list[str] | None = None + columns: tuple[str, ...] | None = None order: npt.NDArray[np.intp] | None = None if not relabeling: @@ -1696,7 +1696,14 @@ def reconstruct_func( raise TypeError("Must provide 'func' or tuples of '(column, aggfunc).") if relabeling: - func, columns, order = normalize_keyword_aggregation(kwargs) + # error: Incompatible types in assignment (expression has type + # "MutableMapping[Hashable, list[Callable[..., Any] | str]]", variable has type + # "Callable[..., Any] | str | list[Callable[..., Any] | str] | + # MutableMapping[Hashable, Callable[..., Any] | str | list[Callable[..., Any] | + # str]] | None") + func, columns, order = normalize_keyword_aggregation( # type: ignore[assignment] + kwargs + ) assert func is not None return relabeling, func, columns, order @@ -1730,7 +1737,11 @@ def is_multi_agg_with_relabel(**kwargs) -> bool: def normalize_keyword_aggregation( kwargs: dict, -) -> tuple[dict, list[str], npt.NDArray[np.intp]]: +) -> tuple[ + MutableMapping[Hashable, list[AggFuncTypeBase]], + tuple[str, ...], + npt.NDArray[np.intp], +]: """ Normalize user-provided "named aggregation" kwargs. Transforms from the new ``Mapping[str, NamedAgg]`` style kwargs @@ -1744,7 +1755,7 @@ def normalize_keyword_aggregation( ------- aggspec : dict The transformed kwargs. - columns : List[str] + columns : tuple[str, ...] The user-provided keys. col_idx_order : List[int] List of columns indices. @@ -1759,9 +1770,7 @@ def normalize_keyword_aggregation( # Normalize the aggregation functions as Mapping[column, List[func]], # process normally, then fixup the names. # TODO: aggspec type: typing.Dict[str, List[AggScalar]] - # May be hitting https://github.com/python/mypy/issues/5958 - # saying it doesn't have an attribute __name__ - aggspec: DefaultDict = defaultdict(list) + aggspec = defaultdict(list) order = [] columns, pairs = list(zip(*kwargs.items())) diff --git a/pandas/core/arrays/_ranges.py b/pandas/core/arrays/_ranges.py index 5f0409188e5e3..6a1ef0800385d 100644 --- a/pandas/core/arrays/_ranges.py +++ b/pandas/core/arrays/_ranges.py @@ -57,9 +57,7 @@ def generate_regular_range( b: int | np.int64 | np.uint64 e: int | np.int64 | np.uint64 try: - td = td.as_unit( # pyright: ignore[reportGeneralTypeIssues] - unit, round_ok=False - ) + td = td.as_unit(unit, round_ok=False) except ValueError as err: raise ValueError( f"freq={freq} is incompatible with unit={unit}. " diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 20aec52b606b6..065a942cae768 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -2894,9 +2894,7 @@ def _validate(data): if not isinstance(data.dtype, CategoricalDtype): raise AttributeError("Can only use .cat accessor with a 'category' dtype") - # error: Signature of "_delegate_property_get" incompatible with supertype - # "PandasDelegate" - def _delegate_property_get(self, name: str): # type: ignore[override] + def _delegate_property_get(self, name: str): return getattr(self._parent, name) # error: Signature of "_delegate_property_set" incompatible with supertype diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 91dd40c2deced..1530fae89aa00 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -600,7 +600,9 @@ def _validate_scalar( raise TypeError(msg) elif isinstance(value, self._recognized_scalars): - value = self._scalar_type(value) + # error: Argument 1 to "Timestamp" has incompatible type "object"; expected + # "integer[Any] | float | str | date | datetime | datetime64" + value = self._scalar_type(value) # type: ignore[arg-type] else: msg = self._validation_error_message(value, allow_listlike) diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 0074645a482b2..9329f82c1b646 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -397,10 +397,8 @@ def _from_sequence_not_strict( result._maybe_pin_freq(freq, validate_kwds) return result - # error: Signature of "_generate_range" incompatible with supertype - # "DatetimeLikeArrayMixin" @classmethod - def _generate_range( # type: ignore[override] + def _generate_range( cls, start, end, diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index ccb63d6677b1a..95c3c641fd51a 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -267,10 +267,8 @@ def _from_sequence_not_strict( result._maybe_pin_freq(freq, {}) return result - # Signature of "_generate_range" incompatible with supertype - # "DatetimeLikeArrayMixin" @classmethod - def _generate_range( # type: ignore[override] + def _generate_range( cls, start, end, periods, freq, closed=None, *, unit: str | None = None ) -> Self: periods = dtl.validate_periods(periods) diff --git a/pandas/core/base.py b/pandas/core/base.py index 9c722bad019a4..e98f1157572bb 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -1310,12 +1310,10 @@ def factorize( # This overload is needed so that the call to searchsorted in # pandas.core.resample.TimeGrouper._get_period_bins picks the correct result - @overload - # The following ignore is also present in numpy/__init__.pyi - # Possibly a mypy bug?? # error: Overloaded function signatures 1 and 2 overlap with incompatible - # return types [misc] - def searchsorted( # type: ignore[misc] + # return types + @overload + def searchsorted( # type: ignore[overload-overlap] self, value: ScalarLike_co, side: Literal["left", "right"] = ..., diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 9a8387ce02dfb..13e0df4a5ef86 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -6896,14 +6896,7 @@ def f(vals) -> tuple[np.ndarray, int]: vals = (col.values for name, col in self.items() if name in subset) labels, shape = map(list, zip(*map(f, vals))) - ids = get_group_index( - labels, - # error: Argument 1 to "tuple" has incompatible type "List[_T]"; - # expected "Iterable[int]" - tuple(shape), # type: ignore[arg-type] - sort=False, - xnull=False, - ) + ids = get_group_index(labels, tuple(shape), sort=False, xnull=False) result = self._constructor_sliced(duplicated(ids, keep), index=self.index) return result.__finalize__(self, method="duplicated") diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 22ac3f44d0d56..bce76a155fc16 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -7970,7 +7970,9 @@ def replace( if items: keys, values = zip(*items) else: - keys, values = ([], []) + # error: Incompatible types in assignment (expression has type + # "list[Never]", variable has type "tuple[Any, ...]") + keys, values = ([], []) # type: ignore[assignment] are_mappings = [is_dict_like(v) for v in values] @@ -7985,7 +7987,12 @@ def replace( value_dict = {} for k, v in items: - keys, values = list(zip(*v.items())) or ([], []) + # error: Incompatible types in assignment (expression has type + # "list[Never]", variable has type "tuple[Any, ...]") + keys, values = list(zip(*v.items())) or ( # type: ignore[assignment] + [], + [], + ) to_rep_dict[k] = list(keys) value_dict[k] = list(values) diff --git a/pandas/core/indexes/accessors.py b/pandas/core/indexes/accessors.py index 10a3fcc61b5bc..929c7f4a63f8f 100644 --- a/pandas/core/indexes/accessors.py +++ b/pandas/core/indexes/accessors.py @@ -85,9 +85,7 @@ def _get_values(self): f"cannot convert an object of type {type(data)} to a datetimelike index" ) - # error: Signature of "_delegate_property_get" incompatible with supertype - # "PandasDelegate" - def _delegate_property_get(self, name: str): # type: ignore[override] + def _delegate_property_get(self, name: str): from pandas import Series values = self._get_values() @@ -175,7 +173,7 @@ def __init__(self, data: Series, orig) -> None: self._orig = orig self._freeze() - def _delegate_property_get(self, name: str): # type: ignore[override] + def _delegate_property_get(self, name: str): if not hasattr(self._parent.array, f"_dt_{name}"): raise NotImplementedError( f"dt.{name} is not supported for {self._parent.dtype}" diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 9a5fae445df75..17ed50dad29e5 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -71,6 +71,7 @@ from pandas.util._decorators import ( Appender, cache_readonly, + deprecate_nonkeyword_arguments, doc, ) from pandas.util._exceptions import ( @@ -1896,7 +1897,18 @@ def set_names(self, names, *, level=None, inplace: bool = False) -> Self | None: return idx return None - def rename(self, name, inplace: bool = False): + @overload + def rename(self, name, *, inplace: Literal[False] = ...) -> Self: + ... + + @overload + def rename(self, name, *, inplace: Literal[True]) -> None: + ... + + @deprecate_nonkeyword_arguments( + version="3.0", allowed_args=["self", "name"], name="rename" + ) + def rename(self, name, inplace: bool = False) -> Self | None: """ Alter Index or MultiIndex name. @@ -5792,13 +5804,49 @@ def asof_locs( return result + @overload + def sort_values( + self, + *, + return_indexer: Literal[False] = ..., + ascending: bool = ..., + na_position: NaPosition = ..., + key: Callable | None = ..., + ) -> Self: + ... + + @overload + def sort_values( + self, + *, + return_indexer: Literal[True], + ascending: bool = ..., + na_position: NaPosition = ..., + key: Callable | None = ..., + ) -> tuple[Self, np.ndarray]: + ... + + @overload + def sort_values( + self, + *, + return_indexer: bool = ..., + ascending: bool = ..., + na_position: NaPosition = ..., + key: Callable | None = ..., + ) -> Self | tuple[Self, np.ndarray]: + ... + + @deprecate_nonkeyword_arguments( + version="3.0", allowed_args=["self"], name="sort_values" + ) def sort_values( self, return_indexer: bool = False, ascending: bool = True, na_position: NaPosition = "last", key: Callable | None = None, - ): + ) -> Self | tuple[Self, np.ndarray]: """ Return a sorted copy of the index. diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 46343b84afb43..2a4e027e2b806 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -4054,14 +4054,18 @@ def sparsify_labels(label_list, start: int = 0, sentinel: object = ""): for i, (p, t) in enumerate(zip(prev, cur)): if i == k - 1: sparse_cur.append(t) - result.append(sparse_cur) + # error: Argument 1 to "append" of "list" has incompatible + # type "list[Any]"; expected "tuple[Any, ...]" + result.append(sparse_cur) # type: ignore[arg-type] break if p == t: sparse_cur.append(sentinel) else: sparse_cur.extend(cur[i:]) - result.append(sparse_cur) + # error: Argument 1 to "append" of "list" has incompatible + # type "list[Any]"; expected "tuple[Any, ...]" + result.append(sparse_cur) # type: ignore[arg-type] break prev = cur diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 30b11aea6317f..62afcf8badb50 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -11,7 +11,9 @@ TYPE_CHECKING, Any, Callable, + Literal, cast, + overload, ) import numpy as np @@ -25,6 +27,7 @@ from pandas.compat.numpy import function as nv from pandas.util._decorators import ( cache_readonly, + deprecate_nonkeyword_arguments, doc, ) @@ -555,13 +558,50 @@ def equals(self, other: object) -> bool: return self._range == other._range return super().equals(other) + # error: Signature of "sort_values" incompatible with supertype "Index" + @overload # type: ignore[override] + def sort_values( + self, + *, + return_indexer: Literal[False] = ..., + ascending: bool = ..., + na_position: NaPosition = ..., + key: Callable | None = ..., + ) -> Self: + ... + + @overload + def sort_values( + self, + *, + return_indexer: Literal[True], + ascending: bool = ..., + na_position: NaPosition = ..., + key: Callable | None = ..., + ) -> tuple[Self, np.ndarray | RangeIndex]: + ... + + @overload + def sort_values( + self, + *, + return_indexer: bool = ..., + ascending: bool = ..., + na_position: NaPosition = ..., + key: Callable | None = ..., + ) -> Self | tuple[Self, np.ndarray | RangeIndex]: + ... + + @deprecate_nonkeyword_arguments( + version="3.0", allowed_args=["self"], name="sort_values" + ) def sort_values( self, return_indexer: bool = False, ascending: bool = True, na_position: NaPosition = "last", key: Callable | None = None, - ): + ) -> Self | tuple[Self, np.ndarray | RangeIndex]: if key is not None: return super().sort_values( return_indexer=return_indexer, diff --git a/pandas/core/internals/base.py b/pandas/core/internals/base.py index 33f5b9feb1387..ae91f167205a0 100644 --- a/pandas/core/internals/base.py +++ b/pandas/core/internals/base.py @@ -146,7 +146,7 @@ def equals(self, other: object) -> bool: """ Implementation for DataFrame.equals """ - if not isinstance(other, DataManager): + if not isinstance(other, type(self)): return False self_axes, other_axes = self.axes, other.axes diff --git a/pandas/core/methods/describe.py b/pandas/core/methods/describe.py index dcdf0067d45b0..c620bb9d17976 100644 --- a/pandas/core/methods/describe.py +++ b/pandas/core/methods/describe.py @@ -146,6 +146,8 @@ class DataFrameDescriber(NDFrameDescriberAbstract): A black list of data types to omit from the result. """ + obj: DataFrame + def __init__( self, obj: DataFrame, @@ -196,7 +198,7 @@ def _select_data(self) -> DataFrame: include=self.include, exclude=self.exclude, ) - return data # pyright: ignore[reportGeneralTypeIssues] + return data def reorder_columns(ldesc: Sequence[Series]) -> list[Hashable]: diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 20dc3f20bbb5e..6cb825e9b79a2 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -1145,9 +1145,10 @@ def nanargmax( array([2, 2, 1, 1]) """ values, mask = _get_values(values, True, fill_value_typ="-inf", mask=mask) - # error: Need type annotation for 'result' - result = values.argmax(axis) # type: ignore[var-annotated] - result = _maybe_arg_null_out(result, axis, mask, skipna) + result = values.argmax(axis) + # error: Argument 1 to "_maybe_arg_null_out" has incompatible type "Any | + # signedinteger[Any]"; expected "ndarray[Any, Any]" + result = _maybe_arg_null_out(result, axis, mask, skipna) # type: ignore[arg-type] return result @@ -1190,9 +1191,10 @@ def nanargmin( array([0, 0, 1, 1]) """ values, mask = _get_values(values, True, fill_value_typ="+inf", mask=mask) - # error: Need type annotation for 'result' - result = values.argmin(axis) # type: ignore[var-annotated] - result = _maybe_arg_null_out(result, axis, mask, skipna) + result = values.argmin(axis) + # error: Argument 1 to "_maybe_arg_null_out" has incompatible type "Any | + # signedinteger[Any]"; expected "ndarray[Any, Any]" + result = _maybe_arg_null_out(result, axis, mask, skipna) # type: ignore[arg-type] return result diff --git a/pandas/core/reshape/concat.py b/pandas/core/reshape/concat.py index d46348fff7a02..aacea92611697 100644 --- a/pandas/core/reshape/concat.py +++ b/pandas/core/reshape/concat.py @@ -865,12 +865,14 @@ def _make_concat_multiindex(indexes, keys, levels=None, names=None) -> MultiInde # do something a bit more speedy for hlevel, level in zip(zipped, levels): - hlevel = ensure_index(hlevel) - mapped = level.get_indexer(hlevel) + hlevel_index = ensure_index(hlevel) + mapped = level.get_indexer(hlevel_index) mask = mapped == -1 if mask.any(): - raise ValueError(f"Values not found in passed level: {hlevel[mask]!s}") + raise ValueError( + f"Values not found in passed level: {hlevel_index[mask]!s}" + ) new_codes.append(np.repeat(mapped, n)) diff --git a/pandas/core/reshape/util.py b/pandas/core/reshape/util.py index bcd51e095a1a1..476e3922b6989 100644 --- a/pandas/core/reshape/util.py +++ b/pandas/core/reshape/util.py @@ -63,7 +63,7 @@ def cartesian_product(X) -> list[np.ndarray]: return [ tile_compat( np.repeat(x, b[i]), - np.prod(a[i]), # pyright: ignore[reportGeneralTypeIssues] + np.prod(a[i]), ) for i, x in enumerate(X) ] diff --git a/pandas/io/excel/_calamine.py b/pandas/io/excel/_calamine.py index 1b30d0f759634..4f65acf1aa40e 100644 --- a/pandas/io/excel/_calamine.py +++ b/pandas/io/excel/_calamine.py @@ -10,10 +10,8 @@ TYPE_CHECKING, Any, Union, - cast, ) -from pandas._typing import Scalar from pandas.compat._optional import import_optional_dependency from pandas.util._decorators import doc @@ -30,11 +28,13 @@ from pandas._typing import ( FilePath, + NaTType, ReadBuffer, + Scalar, StorageOptions, ) -_CellValueT = Union[int, float, str, bool, time, date, datetime, timedelta] +_CellValue = Union[int, float, str, bool, time, date, datetime, timedelta] class CalamineReader(BaseExcelReader["CalamineWorkbook"]): @@ -98,8 +98,8 @@ def get_sheet_by_index(self, index: int) -> CalamineSheet: def get_sheet_data( self, sheet: CalamineSheet, file_rows_needed: int | None = None - ) -> list[list[Scalar]]: - def _convert_cell(value: _CellValueT) -> Scalar: + ) -> list[list[Scalar | NaTType | time]]: + def _convert_cell(value: _CellValue) -> Scalar | NaTType | time: if isinstance(value, float): val = int(value) if val == value: @@ -111,16 +111,13 @@ def _convert_cell(value: _CellValueT) -> Scalar: elif isinstance(value, timedelta): return pd.Timedelta(value) elif isinstance(value, time): - # cast needed here because Scalar doesn't include datetime.time - return cast(Scalar, value) + return value return value - rows: list[list[_CellValueT]] = sheet.to_python( + rows: list[list[_CellValue]] = sheet.to_python( skip_empty_area=False, nrows=file_rows_needed ) - data: list[list[Scalar]] = [ - [_convert_cell(cell) for cell in row] for row in rows - ] + data = [[_convert_cell(cell) for cell in row] for row in rows] return data diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 445d60be1dc15..00c7526edfa48 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -796,13 +796,13 @@ def space_format(x, y): return " " + y return y - str_columns = list( + str_columns_tuple = list( zip(*([space_format(x, y) for y in x] for x in fmt_columns)) ) - if self.sparsify and len(str_columns): - str_columns = sparsify_labels(str_columns) + if self.sparsify and len(str_columns_tuple): + str_columns_tuple = sparsify_labels(str_columns_tuple) - str_columns = [list(x) for x in zip(*str_columns)] + str_columns = [list(x) for x in zip(*str_columns_tuple)] else: fmt_columns = columns._format_flat(include_name=False) dtypes = self.frame.dtypes diff --git a/pandas/io/parquet.py b/pandas/io/parquet.py index 295eb3cbdd500..9570d6f8b26bd 100644 --- a/pandas/io/parquet.py +++ b/pandas/io/parquet.py @@ -207,9 +207,10 @@ def write( and hasattr(path_or_handle, "name") and isinstance(path_or_handle.name, (str, bytes)) ): - path_or_handle = path_or_handle.name - if isinstance(path_or_handle, bytes): - path_or_handle = path_or_handle.decode() + if isinstance(path_or_handle.name, bytes): + path_or_handle = path_or_handle.name.decode() + else: + path_or_handle = path_or_handle.name try: if partition_cols is not None: diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index 1355bda9025b9..cb5598a98d5af 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -1884,7 +1884,7 @@ def _load_backend(backend: str) -> types.ModuleType: # entry_points lost dict API ~ PY 3.10 # https://github.com/python/importlib_metadata/issues/298 if hasattr(eps, "select"): - entry = eps.select(group=key) # pyright: ignore[reportGeneralTypeIssues] + entry = eps.select(group=key) else: # Argument 2 to "get" of "dict" has incompatible type "Tuple[]"; # expected "EntryPoints" [arg-type] diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index 2a1503b84a634..479a5e19dc1c5 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -1178,7 +1178,7 @@ def match_labels(data, e): elif is_number(err): err = np.tile( - [err], # pyright: ignore[reportGeneralTypeIssues] + [err], (nseries, len(data)), ) @@ -1186,7 +1186,7 @@ def match_labels(data, e): msg = f"No valid {label} detected" raise ValueError(msg) - return err, data # pyright: ignore[reportGeneralTypeIssues] + return err, data @final def _get_errorbars( @@ -1365,7 +1365,7 @@ def _make_plot(self, fig: Figure): # error: Argument 2 to "_append_legend_handles_labels" of # "MPLPlot" has incompatible type "Hashable"; expected "str" scatter, - label, # type: ignore[arg-type] # pyright: ignore[reportGeneralTypeIssues] + label, # type: ignore[arg-type] ) errors_x = self._get_errorbars(label=x, index=0, yerr=False) @@ -1531,7 +1531,7 @@ def _make_plot(self, fig: Figure) -> None: i, # error: Argument 4 to "_apply_style_colors" of "MPLPlot" has # incompatible type "Hashable"; expected "str" - label, # type: ignore[arg-type] # pyright: ignore[reportGeneralTypeIssues] + label, # type: ignore[arg-type] ) errors = self._get_errorbars(label=label, index=i) @@ -1544,7 +1544,7 @@ def _make_plot(self, fig: Figure) -> None: newlines = plotf( ax, x, - y, # pyright: ignore[reportGeneralTypeIssues] + y, style=style, column_num=i, stacking_id=stacking_id, diff --git a/pyproject.toml b/pyproject.toml index f6ba25f448540..1831f5afd363e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -754,6 +754,7 @@ reportUntypedClassDecorator = true reportUntypedFunctionDecorator = true reportUntypedNamedTuple = true reportUnusedImport = true +disableBytesTypePromotions = true # disable subset of "basic" reportGeneralTypeIssues = false reportMissingModuleSource = false diff --git a/pyright_reportGeneralTypeIssues.json b/pyright_reportGeneralTypeIssues.json index e155b34053069..a38343d6198ae 100644 --- a/pyright_reportGeneralTypeIssues.json +++ b/pyright_reportGeneralTypeIssues.json @@ -2,6 +2,8 @@ "typeCheckingMode": "off", "reportGeneralTypeIssues": true, "useLibraryCodeForTypes": false, + "analyzeUnannotatedFunctions": false, + "disableBytesTypePromotions": true, "include": [ "pandas", @@ -16,10 +18,10 @@ "pandas/_testing/__init__.py", "pandas/_testing/_io.py", + "pandas/compat/pickle_compat.py", "pandas/core/_numba/extensions.py", "pandas/core/_numba/kernels/sum_.py", "pandas/core/_numba/kernels/var_.py", - "pandas/compat/pickle_compat.py", "pandas/core/algorithms.py", "pandas/core/apply.py", "pandas/core/array_algos/take.py", @@ -39,6 +41,7 @@ "pandas/core/arrays/string_arrow.py", "pandas/core/arrays/timedeltas.py", "pandas/core/computation/align.py", + "pandas/core/computation/ops.py", "pandas/core/construction.py", "pandas/core/dtypes/cast.py", "pandas/core/dtypes/common.py", @@ -89,6 +92,7 @@ "pandas/io/formats/info.py", "pandas/io/formats/printing.py", "pandas/io/formats/style.py", + "pandas/io/formats/style_render.py", "pandas/io/json/_json.py", "pandas/io/json/_normalize.py", "pandas/io/parsers/arrow_parser_wrapper.py", diff --git a/requirements-dev.txt b/requirements-dev.txt index 50a81fbff1b6a..76f4de2d8f0c4 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -53,7 +53,7 @@ moto flask asv>=0.6.1 flake8==6.1.0 -mypy==1.4.1 +mypy==1.7.1 tokenize-rt pre-commit>=3.6.0 gitpython