diff --git a/pandas/_libs/properties.pyi b/pandas/_libs/properties.pyi new file mode 100644 index 0000000000000..b2ba55aefb8a5 --- /dev/null +++ b/pandas/_libs/properties.pyi @@ -0,0 +1,9 @@ +# pyright: reportIncompleteStub = false +from typing import Any + +# note: this is a lie to make type checkers happy (they special +# case property). cache_readonly uses attribute names similar to +# property (fget) but it does not provide fset and fdel. +cache_readonly = property + +def __getattr__(name: str) -> Any: ... # incomplete diff --git a/pandas/_libs/properties.pyx b/pandas/_libs/properties.pyx index 7b786e9c0493d..0ae29a6a641a7 100644 --- a/pandas/_libs/properties.pyx +++ b/pandas/_libs/properties.pyx @@ -10,12 +10,12 @@ from cpython.dict cimport ( cdef class CachedProperty: cdef readonly: - object func, name, __doc__ + object fget, name, __doc__ - def __init__(self, func): - self.func = func - self.name = func.__name__ - self.__doc__ = getattr(func, '__doc__', None) + def __init__(self, fget): + self.fget = fget + self.name = fget.__name__ + self.__doc__ = getattr(fget, '__doc__', None) def __get__(self, obj, typ): if obj is None: @@ -34,7 +34,7 @@ cdef class CachedProperty: # not necessary to Py_INCREF val = PyDict_GetItem(cache, self.name) else: - val = self.func(obj) + val = self.fget(obj) PyDict_SetItem(cache, self.name, val) return val diff --git a/pandas/conftest.py b/pandas/conftest.py index 75711b19dfcfd..1e1d14f46cc6e 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -17,6 +17,7 @@ - Dtypes - Misc """ +# pyright: reportUntypedFunctionDecorator = false from collections import abc from datetime import ( diff --git a/pandas/core/_numba/executor.py b/pandas/core/_numba/executor.py index c666bb1a0ad4b..c2b6191c05152 100644 --- a/pandas/core/_numba/executor.py +++ b/pandas/core/_numba/executor.py @@ -44,7 +44,8 @@ def generate_shared_aggregator( numba = import_optional_dependency("numba") - @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) + # error: Untyped decorator makes function "column_looper" untyped + @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) # type: ignore[misc] def column_looper( values: np.ndarray, start: np.ndarray, diff --git a/pandas/core/_numba/kernels/mean_.py b/pandas/core/_numba/kernels/mean_.py index 8f67dd9b51c06..f3a2c7c2170a8 100644 --- a/pandas/core/_numba/kernels/mean_.py +++ b/pandas/core/_numba/kernels/mean_.py @@ -14,7 +14,8 @@ from pandas.core._numba.kernels.shared import is_monotonic_increasing -@numba.jit(nopython=True, nogil=True, parallel=False) +# error: Untyped decorator makes function "add_mean" untyped +@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc] def add_mean( val: float, nobs: int, sum_x: float, neg_ct: int, compensation: float ) -> tuple[int, float, int, float]: @@ -29,7 +30,8 @@ def add_mean( return nobs, sum_x, neg_ct, compensation -@numba.jit(nopython=True, nogil=True, parallel=False) +# error: Untyped decorator makes function "remove_mean" untyped +@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc] def remove_mean( val: float, nobs: int, sum_x: float, neg_ct: int, compensation: float ) -> tuple[int, float, int, float]: @@ -44,7 +46,8 @@ def remove_mean( return nobs, sum_x, neg_ct, compensation -@numba.jit(nopython=True, nogil=True, parallel=False) +# error: Untyped decorator makes function "sliding_mean" untyped +@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc] def sliding_mean( values: np.ndarray, start: np.ndarray, diff --git a/pandas/core/_numba/kernels/shared.py b/pandas/core/_numba/kernels/shared.py index d84e409ca879d..7c2e7636c7d81 100644 --- a/pandas/core/_numba/kernels/shared.py +++ b/pandas/core/_numba/kernels/shared.py @@ -2,7 +2,10 @@ import numpy as np -@numba.jit(numba.boolean(numba.int64[:]), nopython=True, nogil=True, parallel=False) +# error: Untyped decorator makes function "is_monotonic_increasing" untyped +@numba.jit( # type: ignore[misc] + numba.boolean(numba.int64[:]), nopython=True, nogil=True, parallel=False +) def is_monotonic_increasing(bounds: np.ndarray) -> bool: """Check if int64 values are monotonically increasing.""" n = len(bounds) diff --git a/pandas/core/_numba/kernels/sum_.py b/pandas/core/_numba/kernels/sum_.py index c2e81b4990ba9..66a1587c49f3f 100644 --- a/pandas/core/_numba/kernels/sum_.py +++ b/pandas/core/_numba/kernels/sum_.py @@ -14,7 +14,8 @@ from pandas.core._numba.kernels.shared import is_monotonic_increasing -@numba.jit(nopython=True, nogil=True, parallel=False) +# error: Untyped decorator makes function "add_sum" untyped +@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc] def add_sum( val: float, nobs: int, sum_x: float, compensation: float ) -> tuple[int, float, float]: @@ -27,7 +28,8 @@ def add_sum( return nobs, sum_x, compensation -@numba.jit(nopython=True, nogil=True, parallel=False) +# error: Untyped decorator makes function "remove_sum" untyped +@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc] def remove_sum( val: float, nobs: int, sum_x: float, compensation: float ) -> tuple[int, float, float]: @@ -40,7 +42,8 @@ def remove_sum( return nobs, sum_x, compensation -@numba.jit(nopython=True, nogil=True, parallel=False) +# error: Untyped decorator makes function "sliding_sum" untyped +@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc] def sliding_sum( values: np.ndarray, start: np.ndarray, diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 107cefdf31188..c7f587b35f557 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -2699,7 +2699,7 @@ def _get_codes_for_values(values, categories: Index) -> np.ndarray: """ dtype_equal = is_dtype_equal(values.dtype, categories.dtype) - if is_extension_array_dtype(categories.dtype) and is_object_dtype(values): + if isinstance(categories.dtype, ExtensionDtype) and is_object_dtype(values): # Support inferring the correct extension dtype from an array of # scalar objects. e.g. # Categorical(array[Period, Period], categories=PeriodIndex(...)) diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 84e611659b165..2f36b72229225 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -669,7 +669,9 @@ def fillna(self, value=None, method=None, limit=None) -> PeriodArray: # view as dt64 so we get treated as timelike in core.missing dta = self.view("M8[ns]") result = dta.fillna(value=value, method=method, limit=limit) - return result.view(self.dtype) + # error: Incompatible return value type (got "Union[ExtensionArray, + # ndarray[Any, Any]]", expected "PeriodArray") + return result.view(self.dtype) # type: ignore[return-value] return super().fillna(value=value, method=method, limit=limit) # ------------------------------------------------------------------ diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 5f2ee996c26b4..8a330d08bef78 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -675,7 +675,11 @@ def apply_series_value_counts(): # multi-index components codes = self.grouper.reconstructed_codes codes = [rep(level_codes) for level_codes in codes] + [llab(lab, inc)] - levels = [ping.group_index for ping in self.grouper.groupings] + [lev] + # error: List item 0 has incompatible type "Union[ndarray[Any, Any], Index]"; + # expected "Index" + levels = [ping.group_index for ping in self.grouper.groupings] + [ + lev # type: ignore[list-item] + ] names = self.grouper.names + [self.obj.name] if dropna: diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 77281441c2ed2..d583c2fc6dd9e 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -3449,7 +3449,9 @@ def _reindex_output( levels_list = [ping.group_index for ping in groupings] names = self.grouper.names if qs is not None: - levels_list.append(qs) + # error: Argument 1 to "append" of "list" has incompatible type + # "ndarray[Any, dtype[floating[_64Bit]]]"; expected "Index" + levels_list.append(qs) # type: ignore[arg-type] names = names + [None] index, _ = MultiIndex.from_product(levels_list, names=names).sortlevel() diff --git a/pandas/core/groupby/numba_.py b/pandas/core/groupby/numba_.py index beb77360d5a3f..ea295af8d7910 100644 --- a/pandas/core/groupby/numba_.py +++ b/pandas/core/groupby/numba_.py @@ -92,7 +92,8 @@ def generate_numba_agg_func( numba_func = jit_user_function(func, nopython, nogil, parallel) numba = import_optional_dependency("numba") - @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) + # error: Untyped decorator makes function "group_agg" untyped + @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) # type: ignore[misc] def group_agg( values: np.ndarray, index: np.ndarray, @@ -153,7 +154,8 @@ def generate_numba_transform_func( numba_func = jit_user_function(func, nopython, nogil, parallel) numba = import_optional_dependency("numba") - @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) + # error: Untyped decorator makes function "group_transform" untyped + @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) # type: ignore[misc] def group_transform( values: np.ndarray, index: np.ndarray, diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index e82bd61938f15..7ad24015ac371 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3681,7 +3681,11 @@ def _get_indexer( else: tgt_values = target._get_engine_target() if target._is_multi and self._is_multi: - tgt_values = self._engine._extract_level_codes(target) + engine = self._engine + # error: "IndexEngine" has no attribute "_extract_level_codes" + tgt_values = engine._extract_level_codes( # type: ignore[attr-defined] + target + ) indexer = self._engine.get_indexer(tgt_values) @@ -3758,7 +3762,8 @@ def _get_fill_indexer( if self._is_multi: # TODO: get_indexer_with_fill docstring says values must be _sorted_ # but that doesn't appear to be enforced - return self._engine.get_indexer_with_fill( + # error: "IndexEngine" has no attribute "get_indexer_with_fill" + return self._engine.get_indexer_with_fill( # type: ignore[attr-defined] target=target._values, values=self._values, method=method, limit=limit ) @@ -4677,7 +4682,9 @@ def values(self) -> ArrayLike: """ return self._data - @cache_readonly + # error: Decorated property not supported + # https://github.com/python/mypy/issues/1362 + @cache_readonly # type: ignore[misc] @doc(IndexOpsMixin.array) def array(self) -> ExtensionArray: array = self._data @@ -5596,7 +5603,11 @@ def get_indexer_non_unique( # self and non-Multi target tgt_values = target._get_engine_target() if self._is_multi and target._is_multi: - tgt_values = self._engine._extract_level_codes(target) + engine = self._engine + # error: "IndexEngine" has no attribute "_extract_level_codes" + tgt_values = engine._extract_level_codes( # type: ignore[attr-defined] + target + ) indexer, missing = self._engine.get_indexer_non_unique(tgt_values) return ensure_platform_int(indexer), ensure_platform_int(missing) @@ -7049,7 +7060,9 @@ def unpack_nested_dtype(other: _IndexT) -> _IndexT: if is_categorical_dtype(dtype): # If there is ever a SparseIndex, this could get dispatched # here too. - return dtype.categories + # error: Item "dtype[Any]"/"ExtensionDtype" of "Union[dtype[Any], + # ExtensionDtype]" has no attribute "categories" + return dtype.categories # type: ignore[union-attr] return other diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 791c1110e3cd2..a0902a5fb32fe 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -95,8 +95,11 @@ class DatetimeIndexOpsMixin(NDArrayBackedExtensionIndex): _field_ops: list[str] = [] # error: "Callable[[Any], Any]" has no attribute "fget" - hasnans = cache_readonly( - DatetimeLikeArrayMixin._hasnans.fget # type: ignore[attr-defined] + hasnans = cast( + bool, + cache_readonly( + DatetimeLikeArrayMixin._hasnans.fget # type: ignore[attr-defined] + ), ) @property diff --git a/pandas/core/indexes/extension.py b/pandas/core/indexes/extension.py index 7c7f1b267b5be..28a0b43d5b02b 100644 --- a/pandas/core/indexes/extension.py +++ b/pandas/core/indexes/extension.py @@ -3,7 +3,10 @@ """ from __future__ import annotations -from typing import TypeVar +from typing import ( + Callable, + TypeVar, +) import numpy as np @@ -23,9 +26,12 @@ from pandas.core.indexes.base import Index _T = TypeVar("_T", bound="NDArrayBackedExtensionIndex") +_ExtensionIndexT = TypeVar("_ExtensionIndexT", bound="ExtensionIndex") -def _inherit_from_data(name: str, delegate, cache: bool = False, wrap: bool = False): +def _inherit_from_data( + name: str, delegate: type, cache: bool = False, wrap: bool = False +): """ Make an alias for a method of the underlying ExtensionArray. @@ -81,8 +87,9 @@ def fset(self, value): method = attr else: - - def method(self, *args, **kwargs): + # error: Incompatible redefinition (redefinition with type "Callable[[Any, + # VarArg(Any), KwArg(Any)], Any]", original type "property") + def method(self, *args, **kwargs): # type: ignore[misc] if "inplace" in kwargs: raise ValueError(f"cannot use inplace with {type(self).__name__}") result = attr(self._data, *args, **kwargs) @@ -94,12 +101,15 @@ def method(self, *args, **kwargs): return Index(result, name=self.name) return result - method.__name__ = name + # error: "property" has no attribute "__name__" + method.__name__ = name # type: ignore[attr-defined] method.__doc__ = attr.__doc__ return method -def inherit_names(names: list[str], delegate, cache: bool = False, wrap: bool = False): +def inherit_names( + names: list[str], delegate: type, cache: bool = False, wrap: bool = False +) -> Callable[[type[_ExtensionIndexT]], type[_ExtensionIndexT]]: """ Class decorator to pin attributes from an ExtensionArray to a Index subclass. @@ -112,7 +122,7 @@ def inherit_names(names: list[str], delegate, cache: bool = False, wrap: bool = Whether to wrap the inherited result in an Index. """ - def wrapper(cls): + def wrapper(cls: type[_ExtensionIndexT]) -> type[_ExtensionIndexT]: for name in names: meth = _inherit_from_data(name, delegate, cache=cache, wrap=wrap) setattr(cls, name, meth) diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 72398ab9d43f6..5791f89828ca3 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -531,7 +531,9 @@ def _maybe_convert_i8(self, key): key_i8 = key_i8.where(~key._isnan) # ensure consistency with IntervalIndex subtype - subtype = self.dtype.subtype + # error: Item "ExtensionDtype"/"dtype[Any]" of "Union[dtype[Any], + # ExtensionDtype]" has no attribute "subtype" + subtype = self.dtype.subtype # type: ignore[union-attr] if not is_dtype_equal(subtype, key_dtype): raise ValueError( @@ -766,7 +768,9 @@ def _convert_slice_indexer(self, key: slice, kind: str): def _should_fallback_to_positional(self) -> bool: # integer lookups in Series.__getitem__ are unambiguously # positional in this case - return self.dtype.subtype.kind in ["m", "M"] + # error: Item "ExtensionDtype"/"dtype[Any]" of "Union[dtype[Any], + # ExtensionDtype]" has no attribute "subtype" + return self.dtype.subtype.kind in ["m", "M"] # type: ignore[union-attr] def _maybe_cast_slice_bound(self, label, side: str, kind=lib.no_default): self._deprecated_arg(kind, "kind", "_maybe_cast_slice_bound") diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index e2f1a2d6a1e23..d753307aea109 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -1095,8 +1095,10 @@ def _engine(self): return MultiIndexPyIntEngine(self.levels, self.codes, offsets) return MultiIndexUIntEngine(self.levels, self.codes, offsets) + # Return type "Callable[..., MultiIndex]" of "_constructor" incompatible with return + # type "Type[MultiIndex]" in supertype "Index" @property - def _constructor(self) -> Callable[..., MultiIndex]: + def _constructor(self) -> Callable[..., MultiIndex]: # type: ignore[override] return type(self).from_tuples @doc(Index._shallow_copy) diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index 8e8ed294304c5..40aa70a2ada2f 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -101,8 +101,9 @@ class NumericIndex(Index): _can_hold_strings = False _is_backward_compat_public_numeric_index: bool = True + # error: Signature of "_can_hold_na" incompatible with supertype "Index" @cache_readonly - def _can_hold_na(self) -> bool: + def _can_hold_na(self) -> bool: # type: ignore[override] if is_float_dtype(self.dtype): return True else: @@ -123,7 +124,9 @@ def _can_hold_na(self) -> bool: @property def _engine_type(self): - return self._engine_types[self.dtype] + # error: Invalid index type "Union[dtype[Any], ExtensionDtype]" for + # "Dict[dtype[Any], Type[IndexEngine]]"; expected type "dtype[Any]" + return self._engine_types[self.dtype] # type: ignore[index] @cache_readonly def inferred_type(self) -> str: @@ -264,7 +267,8 @@ def astype(self, dtype, copy=True): # ---------------------------------------------------------------- # Indexing Methods - @cache_readonly + # error: Decorated property not supported + @cache_readonly # type: ignore[misc] @doc(Index._should_fallback_to_positional) def _should_fallback_to_positional(self) -> bool: return False diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index e422f2bc3ff9a..e80a88826e4ed 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -434,7 +434,9 @@ def get_loc(self, key, method=None, tolerance=None): # TODO: pass if method is not None, like DTI does? raise KeyError(key) from err - if reso == self.dtype.resolution: + # error: Item "ExtensionDtype"/"dtype[Any]" of "Union[dtype[Any], + # ExtensionDtype]" has no attribute "resolution" + if reso == self.dtype.resolution: # type: ignore[union-attr] # the reso < self.dtype.resolution case goes through _get_string_slice key = Period(parsed, freq=self.freq) loc = self.get_loc(key, method=method, tolerance=tolerance) @@ -487,7 +489,9 @@ def _parsed_string_to_bounds(self, reso: Resolution, parsed: datetime): def _can_partial_date_slice(self, reso: Resolution) -> bool: assert isinstance(reso, Resolution), (type(reso), reso) # e.g. test_getitem_setitem_periodindex - return reso > self.dtype.resolution + # error: Item "ExtensionDtype"/"dtype[Any]" of "Union[dtype[Any], + # ExtensionDtype]" has no attribute "resolution" + return reso > self.dtype.resolution # type: ignore[union-attr] def period_range( diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 3fae0fbe7d2a0..8aedc56d8e1cd 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -177,13 +177,16 @@ def _simple_new(cls, values: range, name: Hashable = None) -> RangeIndex: # -------------------------------------------------------------------- + # error: Return type "Type[Int64Index]" of "_constructor" incompatible with return + # type "Type[RangeIndex]" in supertype "Index" @cache_readonly - def _constructor(self) -> type[Int64Index]: + def _constructor(self) -> type[Int64Index]: # type: ignore[override] """return the class to use for construction""" return Int64Index + # error: Signature of "_data" incompatible with supertype "Index" @cache_readonly - def _data(self) -> np.ndarray: + def _data(self) -> np.ndarray: # type: ignore[override] """ An int array that for performance reasons is created only when needed. diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 57f07313ebdc4..e461706aab760 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1593,7 +1593,9 @@ def where(self, other, cond, errors="raise") -> list[Block]: # The default `other` for Series / Frame is np.nan # we want to replace that with the correct NA value # for the type - other = self.dtype.na_value + # error: Item "dtype[Any]" of "Union[dtype[Any], ExtensionDtype]" has no + # attribute "na_value" + other = self.dtype.na_value # type: ignore[union-attr] try: result = self.values._where(cond, other) diff --git a/pandas/core/reshape/reshape.py b/pandas/core/reshape/reshape.py index 567f0c20bbfd5..813c4282e543a 100644 --- a/pandas/core/reshape/reshape.py +++ b/pandas/core/reshape/reshape.py @@ -313,7 +313,12 @@ def get_new_columns(self, value_columns: Index | None): new_codes = [lab.take(propagator) for lab in value_columns.codes] else: - new_levels = [value_columns, self.removed_level_full] + # error: Incompatible types in assignment (expression has type "List[Any]", + # variable has type "FrozenList") + new_levels = [ # type: ignore[assignment] + value_columns, + self.removed_level_full, + ] new_names = [value_columns.name, self.removed_name] new_codes = [propagator] diff --git a/pandas/core/series.py b/pandas/core/series.py index 15715af05f904..39cf884e21e31 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -302,7 +302,9 @@ class Series(base.IndexOpsMixin, generic.NDFrame): # error: Incompatible types in assignment (expression has type "property", # base class "IndexOpsMixin" defined the type as "Callable[[IndexOpsMixin], bool]") hasnans = property( # type: ignore[assignment] - base.IndexOpsMixin.hasnans.func, doc=base.IndexOpsMixin.hasnans.__doc__ + # error: "Callable[[IndexOpsMixin], bool]" has no attribute "fget" + base.IndexOpsMixin.hasnans.fget, # type: ignore[attr-defined] + doc=base.IndexOpsMixin.hasnans.__doc__, ) _mgr: SingleManager div: Callable[[Series, Any], Series] diff --git a/pandas/core/strings/accessor.py b/pandas/core/strings/accessor.py index 4ea29edb7d41b..a62d701413bf1 100644 --- a/pandas/core/strings/accessor.py +++ b/pandas/core/strings/accessor.py @@ -1,19 +1,23 @@ from __future__ import annotations import codecs -from collections.abc import Callable # noqa: PDF001 from functools import wraps import re from typing import ( TYPE_CHECKING, + Callable, Hashable, + cast, ) import warnings import numpy as np import pandas._libs.lib as lib -from pandas._typing import DtypeObj +from pandas._typing import ( + DtypeObj, + F, +) from pandas.util._decorators import Appender from pandas.core.dtypes.common import ( @@ -56,7 +60,9 @@ _cpython_optimized_decoders = _cpython_optimized_encoders + ("utf-16", "utf-32") -def forbid_nonstring_types(forbidden, name=None): +def forbid_nonstring_types( + forbidden: list[str] | None, name: str | None = None +) -> Callable[[F], F]: """ Decorator to forbid specific types for a method of StringMethods. @@ -104,7 +110,7 @@ def forbid_nonstring_types(forbidden, name=None): forbidden ) - def _forbid_nonstring_types(func): + def _forbid_nonstring_types(func: F) -> F: func_name = func.__name__ if name is None else name @wraps(func) @@ -118,7 +124,7 @@ def wrapper(self, *args, **kwargs): return func(self, *args, **kwargs) wrapper.__name__ = func_name - return wrapper + return cast(F, wrapper) return _forbid_nonstring_types diff --git a/pandas/core/util/numba_.py b/pandas/core/util/numba_.py index 03a0157a8bde4..c738213d4c487 100644 --- a/pandas/core/util/numba_.py +++ b/pandas/core/util/numba_.py @@ -1,4 +1,5 @@ """Common utilities for Numba operations""" +# pyright: reportUntypedFunctionDecorator = false from __future__ import annotations import types diff --git a/pandas/core/window/numba_.py b/pandas/core/window/numba_.py index f41711a4d1f19..74dc104b6db90 100644 --- a/pandas/core/window/numba_.py +++ b/pandas/core/window/numba_.py @@ -1,3 +1,4 @@ +# pyright: reportUntypedFunctionDecorator = false from __future__ import annotations import functools @@ -57,7 +58,8 @@ def generate_numba_apply_func( numba_func = jit_user_function(func, nopython, nogil, parallel) numba = import_optional_dependency("numba") - @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) + # error: Untyped decorator makes function "roll_apply" untyped + @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) # type: ignore[misc] def roll_apply( values: np.ndarray, begin: np.ndarray, @@ -115,7 +117,8 @@ def generate_numba_ewm_func( numba = import_optional_dependency("numba") - @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) + # error: Untyped decorator makes function "ewma" untyped + @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) # type: ignore[misc] def ewm( values: np.ndarray, begin: np.ndarray, @@ -216,7 +219,8 @@ def generate_numba_table_func( numba_func = jit_user_function(func, nopython, nogil, parallel) numba = import_optional_dependency("numba") - @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) + # error: Untyped decorator makes function "roll_table" untyped + @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) # type: ignore[misc] def roll_table( values: np.ndarray, begin: np.ndarray, @@ -294,7 +298,8 @@ def generate_numba_ewm_table_func( numba = import_optional_dependency("numba") - @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) + # error: Untyped decorator makes function "ewm_table" untyped + @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) # type: ignore[misc] def ewm_table( values: np.ndarray, begin: np.ndarray, diff --git a/pandas/core/window/online.py b/pandas/core/window/online.py index 5a9e8d65255ae..e8804936da78f 100644 --- a/pandas/core/window/online.py +++ b/pandas/core/window/online.py @@ -33,7 +33,8 @@ def generate_online_numba_ewma_func(engine_kwargs: Optional[Dict[str, bool]]): numba = import_optional_dependency("numba") - @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) + # error: Untyped decorator makes function "online_ewma" untyped + @numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) # type: ignore[misc] def online_ewma( values: np.ndarray, deltas: np.ndarray, diff --git a/pyproject.toml b/pyproject.toml index f329784d050e0..7966e94cff2f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,7 +82,7 @@ disallow_untyped_calls = false # TODO disallow_untyped_defs = false # TODO disallow_incomplete_defs = false # TODO check_untyped_defs = true -disallow_untyped_decorators = false # GH#33455 +disallow_untyped_decorators = true # None and Optional handling no_implicit_optional = true strict_optional = true @@ -176,7 +176,6 @@ reportUnnecessaryComparison = false reportUnnecessaryIsInstance = false reportUnsupportedDunderAll = false reportUntypedBaseClass = false -reportUntypedFunctionDecorator = false reportUnusedClass = false reportUnusedFunction = false reportUnusedImport = false