Skip to content

Commit e394c53

Browse files
authored
TYP: enable disallow_untyped_decorators (#43828)
1 parent 199cacb commit e394c53

28 files changed

+153
-59
lines changed

pandas/_libs/properties.pyi

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# pyright: reportIncompleteStub = false
2+
from typing import Any
3+
4+
# note: this is a lie to make type checkers happy (they special
5+
# case property). cache_readonly uses attribute names similar to
6+
# property (fget) but it does not provide fset and fdel.
7+
cache_readonly = property
8+
9+
def __getattr__(name: str) -> Any: ... # incomplete

pandas/_libs/properties.pyx

+6-6
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ from cpython.dict cimport (
1010
cdef class CachedProperty:
1111

1212
cdef readonly:
13-
object func, name, __doc__
13+
object fget, name, __doc__
1414

15-
def __init__(self, func):
16-
self.func = func
17-
self.name = func.__name__
18-
self.__doc__ = getattr(func, '__doc__', None)
15+
def __init__(self, fget):
16+
self.fget = fget
17+
self.name = fget.__name__
18+
self.__doc__ = getattr(fget, '__doc__', None)
1919

2020
def __get__(self, obj, typ):
2121
if obj is None:
@@ -34,7 +34,7 @@ cdef class CachedProperty:
3434
# not necessary to Py_INCREF
3535
val = <object>PyDict_GetItem(cache, self.name)
3636
else:
37-
val = self.func(obj)
37+
val = self.fget(obj)
3838
PyDict_SetItem(cache, self.name, val)
3939
return val
4040

pandas/conftest.py

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- Dtypes
1818
- Misc
1919
"""
20+
# pyright: reportUntypedFunctionDecorator = false
2021

2122
from collections import abc
2223
from datetime import (

pandas/core/_numba/executor.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ def generate_shared_aggregator(
4444

4545
numba = import_optional_dependency("numba")
4646

47-
@numba.jit(nopython=nopython, nogil=nogil, parallel=parallel)
47+
# error: Untyped decorator makes function "column_looper" untyped
48+
@numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) # type: ignore[misc]
4849
def column_looper(
4950
values: np.ndarray,
5051
start: np.ndarray,

pandas/core/_numba/kernels/mean_.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
from pandas.core._numba.kernels.shared import is_monotonic_increasing
1515

1616

17-
@numba.jit(nopython=True, nogil=True, parallel=False)
17+
# error: Untyped decorator makes function "add_mean" untyped
18+
@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc]
1819
def add_mean(
1920
val: float, nobs: int, sum_x: float, neg_ct: int, compensation: float
2021
) -> tuple[int, float, int, float]:
@@ -29,7 +30,8 @@ def add_mean(
2930
return nobs, sum_x, neg_ct, compensation
3031

3132

32-
@numba.jit(nopython=True, nogil=True, parallel=False)
33+
# error: Untyped decorator makes function "remove_mean" untyped
34+
@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc]
3335
def remove_mean(
3436
val: float, nobs: int, sum_x: float, neg_ct: int, compensation: float
3537
) -> tuple[int, float, int, float]:
@@ -44,7 +46,8 @@ def remove_mean(
4446
return nobs, sum_x, neg_ct, compensation
4547

4648

47-
@numba.jit(nopython=True, nogil=True, parallel=False)
49+
# error: Untyped decorator makes function "sliding_mean" untyped
50+
@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc]
4851
def sliding_mean(
4952
values: np.ndarray,
5053
start: np.ndarray,

pandas/core/_numba/kernels/shared.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
import numpy as np
33

44

5-
@numba.jit(numba.boolean(numba.int64[:]), nopython=True, nogil=True, parallel=False)
5+
# error: Untyped decorator makes function "is_monotonic_increasing" untyped
6+
@numba.jit( # type: ignore[misc]
7+
numba.boolean(numba.int64[:]), nopython=True, nogil=True, parallel=False
8+
)
69
def is_monotonic_increasing(bounds: np.ndarray) -> bool:
710
"""Check if int64 values are monotonically increasing."""
811
n = len(bounds)

pandas/core/_numba/kernels/sum_.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
from pandas.core._numba.kernels.shared import is_monotonic_increasing
1515

1616

17-
@numba.jit(nopython=True, nogil=True, parallel=False)
17+
# error: Untyped decorator makes function "add_sum" untyped
18+
@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc]
1819
def add_sum(
1920
val: float, nobs: int, sum_x: float, compensation: float
2021
) -> tuple[int, float, float]:
@@ -27,7 +28,8 @@ def add_sum(
2728
return nobs, sum_x, compensation
2829

2930

30-
@numba.jit(nopython=True, nogil=True, parallel=False)
31+
# error: Untyped decorator makes function "remove_sum" untyped
32+
@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc]
3133
def remove_sum(
3234
val: float, nobs: int, sum_x: float, compensation: float
3335
) -> tuple[int, float, float]:
@@ -40,7 +42,8 @@ def remove_sum(
4042
return nobs, sum_x, compensation
4143

4244

43-
@numba.jit(nopython=True, nogil=True, parallel=False)
45+
# error: Untyped decorator makes function "sliding_sum" untyped
46+
@numba.jit(nopython=True, nogil=True, parallel=False) # type: ignore[misc]
4447
def sliding_sum(
4548
values: np.ndarray,
4649
start: np.ndarray,

pandas/core/arrays/categorical.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2699,7 +2699,7 @@ def _get_codes_for_values(values, categories: Index) -> np.ndarray:
26992699
"""
27002700
dtype_equal = is_dtype_equal(values.dtype, categories.dtype)
27012701

2702-
if is_extension_array_dtype(categories.dtype) and is_object_dtype(values):
2702+
if isinstance(categories.dtype, ExtensionDtype) and is_object_dtype(values):
27032703
# Support inferring the correct extension dtype from an array of
27042704
# scalar objects. e.g.
27052705
# Categorical(array[Period, Period], categories=PeriodIndex(...))

pandas/core/arrays/period.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,9 @@ def fillna(self, value=None, method=None, limit=None) -> PeriodArray:
669669
# view as dt64 so we get treated as timelike in core.missing
670670
dta = self.view("M8[ns]")
671671
result = dta.fillna(value=value, method=method, limit=limit)
672-
return result.view(self.dtype)
672+
# error: Incompatible return value type (got "Union[ExtensionArray,
673+
# ndarray[Any, Any]]", expected "PeriodArray")
674+
return result.view(self.dtype) # type: ignore[return-value]
673675
return super().fillna(value=value, method=method, limit=limit)
674676

675677
# ------------------------------------------------------------------

pandas/core/groupby/generic.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,11 @@ def apply_series_value_counts():
675675
# multi-index components
676676
codes = self.grouper.reconstructed_codes
677677
codes = [rep(level_codes) for level_codes in codes] + [llab(lab, inc)]
678-
levels = [ping.group_index for ping in self.grouper.groupings] + [lev]
678+
# error: List item 0 has incompatible type "Union[ndarray[Any, Any], Index]";
679+
# expected "Index"
680+
levels = [ping.group_index for ping in self.grouper.groupings] + [
681+
lev # type: ignore[list-item]
682+
]
679683
names = self.grouper.names + [self.obj.name]
680684

681685
if dropna:

pandas/core/groupby/groupby.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -3449,7 +3449,9 @@ def _reindex_output(
34493449
levels_list = [ping.group_index for ping in groupings]
34503450
names = self.grouper.names
34513451
if qs is not None:
3452-
levels_list.append(qs)
3452+
# error: Argument 1 to "append" of "list" has incompatible type
3453+
# "ndarray[Any, dtype[floating[_64Bit]]]"; expected "Index"
3454+
levels_list.append(qs) # type: ignore[arg-type]
34533455
names = names + [None]
34543456
index, _ = MultiIndex.from_product(levels_list, names=names).sortlevel()
34553457

pandas/core/groupby/numba_.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ def generate_numba_agg_func(
9292
numba_func = jit_user_function(func, nopython, nogil, parallel)
9393
numba = import_optional_dependency("numba")
9494

95-
@numba.jit(nopython=nopython, nogil=nogil, parallel=parallel)
95+
# error: Untyped decorator makes function "group_agg" untyped
96+
@numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) # type: ignore[misc]
9697
def group_agg(
9798
values: np.ndarray,
9899
index: np.ndarray,
@@ -153,7 +154,8 @@ def generate_numba_transform_func(
153154
numba_func = jit_user_function(func, nopython, nogil, parallel)
154155
numba = import_optional_dependency("numba")
155156

156-
@numba.jit(nopython=nopython, nogil=nogil, parallel=parallel)
157+
# error: Untyped decorator makes function "group_transform" untyped
158+
@numba.jit(nopython=nopython, nogil=nogil, parallel=parallel) # type: ignore[misc]
157159
def group_transform(
158160
values: np.ndarray,
159161
index: np.ndarray,

pandas/core/indexes/base.py

+18-5
Original file line numberDiff line numberDiff line change
@@ -3683,7 +3683,11 @@ def _get_indexer(
36833683
else:
36843684
tgt_values = target._get_engine_target()
36853685
if target._is_multi and self._is_multi:
3686-
tgt_values = self._engine._extract_level_codes(target)
3686+
engine = self._engine
3687+
# error: "IndexEngine" has no attribute "_extract_level_codes"
3688+
tgt_values = engine._extract_level_codes( # type: ignore[attr-defined]
3689+
target
3690+
)
36873691

36883692
indexer = self._engine.get_indexer(tgt_values)
36893693

@@ -3760,7 +3764,8 @@ def _get_fill_indexer(
37603764
if self._is_multi:
37613765
# TODO: get_indexer_with_fill docstring says values must be _sorted_
37623766
# but that doesn't appear to be enforced
3763-
return self._engine.get_indexer_with_fill(
3767+
# error: "IndexEngine" has no attribute "get_indexer_with_fill"
3768+
return self._engine.get_indexer_with_fill( # type: ignore[attr-defined]
37643769
target=target._values, values=self._values, method=method, limit=limit
37653770
)
37663771

@@ -4679,7 +4684,9 @@ def values(self) -> ArrayLike:
46794684
"""
46804685
return self._data
46814686

4682-
@cache_readonly
4687+
# error: Decorated property not supported
4688+
# https://github.com/python/mypy/issues/1362
4689+
@cache_readonly # type: ignore[misc]
46834690
@doc(IndexOpsMixin.array)
46844691
def array(self) -> ExtensionArray:
46854692
array = self._data
@@ -5598,7 +5605,11 @@ def get_indexer_non_unique(
55985605
# self and non-Multi target
55995606
tgt_values = target._get_engine_target()
56005607
if self._is_multi and target._is_multi:
5601-
tgt_values = self._engine._extract_level_codes(target)
5608+
engine = self._engine
5609+
# error: "IndexEngine" has no attribute "_extract_level_codes"
5610+
tgt_values = engine._extract_level_codes( # type: ignore[attr-defined]
5611+
target
5612+
)
56025613

56035614
indexer, missing = self._engine.get_indexer_non_unique(tgt_values)
56045615
return ensure_platform_int(indexer), ensure_platform_int(missing)
@@ -7051,7 +7062,9 @@ def unpack_nested_dtype(other: _IndexT) -> _IndexT:
70517062
if is_categorical_dtype(dtype):
70527063
# If there is ever a SparseIndex, this could get dispatched
70537064
# here too.
7054-
return dtype.categories
7065+
# error: Item "dtype[Any]"/"ExtensionDtype" of "Union[dtype[Any],
7066+
# ExtensionDtype]" has no attribute "categories"
7067+
return dtype.categories # type: ignore[union-attr]
70557068
return other
70567069

70577070

pandas/core/indexes/datetimelike.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,11 @@ class DatetimeIndexOpsMixin(NDArrayBackedExtensionIndex):
9595
_field_ops: list[str] = []
9696

9797
# error: "Callable[[Any], Any]" has no attribute "fget"
98-
hasnans = cache_readonly(
99-
DatetimeLikeArrayMixin._hasnans.fget # type: ignore[attr-defined]
98+
hasnans = cast(
99+
bool,
100+
cache_readonly(
101+
DatetimeLikeArrayMixin._hasnans.fget # type: ignore[attr-defined]
102+
),
100103
)
101104

102105
@property

pandas/core/indexes/extension.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
"""
44
from __future__ import annotations
55

6-
from typing import TypeVar
6+
from typing import (
7+
Callable,
8+
TypeVar,
9+
)
710

811
import numpy as np
912

@@ -23,9 +26,12 @@
2326
from pandas.core.indexes.base import Index
2427

2528
_T = TypeVar("_T", bound="NDArrayBackedExtensionIndex")
29+
_ExtensionIndexT = TypeVar("_ExtensionIndexT", bound="ExtensionIndex")
2630

2731

28-
def _inherit_from_data(name: str, delegate, cache: bool = False, wrap: bool = False):
32+
def _inherit_from_data(
33+
name: str, delegate: type, cache: bool = False, wrap: bool = False
34+
):
2935
"""
3036
Make an alias for a method of the underlying ExtensionArray.
3137
@@ -81,8 +87,9 @@ def fset(self, value):
8187
method = attr
8288

8389
else:
84-
85-
def method(self, *args, **kwargs):
90+
# error: Incompatible redefinition (redefinition with type "Callable[[Any,
91+
# VarArg(Any), KwArg(Any)], Any]", original type "property")
92+
def method(self, *args, **kwargs): # type: ignore[misc]
8693
if "inplace" in kwargs:
8794
raise ValueError(f"cannot use inplace with {type(self).__name__}")
8895
result = attr(self._data, *args, **kwargs)
@@ -94,12 +101,15 @@ def method(self, *args, **kwargs):
94101
return Index(result, name=self.name)
95102
return result
96103

97-
method.__name__ = name
104+
# error: "property" has no attribute "__name__"
105+
method.__name__ = name # type: ignore[attr-defined]
98106
method.__doc__ = attr.__doc__
99107
return method
100108

101109

102-
def inherit_names(names: list[str], delegate, cache: bool = False, wrap: bool = False):
110+
def inherit_names(
111+
names: list[str], delegate: type, cache: bool = False, wrap: bool = False
112+
) -> Callable[[type[_ExtensionIndexT]], type[_ExtensionIndexT]]:
103113
"""
104114
Class decorator to pin attributes from an ExtensionArray to a Index subclass.
105115
@@ -112,7 +122,7 @@ def inherit_names(names: list[str], delegate, cache: bool = False, wrap: bool =
112122
Whether to wrap the inherited result in an Index.
113123
"""
114124

115-
def wrapper(cls):
125+
def wrapper(cls: type[_ExtensionIndexT]) -> type[_ExtensionIndexT]:
116126
for name in names:
117127
meth = _inherit_from_data(name, delegate, cache=cache, wrap=wrap)
118128
setattr(cls, name, meth)

pandas/core/indexes/interval.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,9 @@ def _maybe_convert_i8(self, key):
531531
key_i8 = key_i8.where(~key._isnan)
532532

533533
# ensure consistency with IntervalIndex subtype
534-
subtype = self.dtype.subtype
534+
# error: Item "ExtensionDtype"/"dtype[Any]" of "Union[dtype[Any],
535+
# ExtensionDtype]" has no attribute "subtype"
536+
subtype = self.dtype.subtype # type: ignore[union-attr]
535537

536538
if not is_dtype_equal(subtype, key_dtype):
537539
raise ValueError(
@@ -766,7 +768,9 @@ def _convert_slice_indexer(self, key: slice, kind: str):
766768
def _should_fallback_to_positional(self) -> bool:
767769
# integer lookups in Series.__getitem__ are unambiguously
768770
# positional in this case
769-
return self.dtype.subtype.kind in ["m", "M"]
771+
# error: Item "ExtensionDtype"/"dtype[Any]" of "Union[dtype[Any],
772+
# ExtensionDtype]" has no attribute "subtype"
773+
return self.dtype.subtype.kind in ["m", "M"] # type: ignore[union-attr]
770774

771775
def _maybe_cast_slice_bound(self, label, side: str, kind=lib.no_default):
772776
self._deprecated_arg(kind, "kind", "_maybe_cast_slice_bound")

pandas/core/indexes/multi.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1095,8 +1095,10 @@ def _engine(self):
10951095
return MultiIndexPyIntEngine(self.levels, self.codes, offsets)
10961096
return MultiIndexUIntEngine(self.levels, self.codes, offsets)
10971097

1098+
# Return type "Callable[..., MultiIndex]" of "_constructor" incompatible with return
1099+
# type "Type[MultiIndex]" in supertype "Index"
10981100
@property
1099-
def _constructor(self) -> Callable[..., MultiIndex]:
1101+
def _constructor(self) -> Callable[..., MultiIndex]: # type: ignore[override]
11001102
return type(self).from_tuples
11011103

11021104
@doc(Index._shallow_copy)

pandas/core/indexes/numeric.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,9 @@ class NumericIndex(Index):
101101
_can_hold_strings = False
102102
_is_backward_compat_public_numeric_index: bool = True
103103

104+
# error: Signature of "_can_hold_na" incompatible with supertype "Index"
104105
@cache_readonly
105-
def _can_hold_na(self) -> bool:
106+
def _can_hold_na(self) -> bool: # type: ignore[override]
106107
if is_float_dtype(self.dtype):
107108
return True
108109
else:
@@ -123,7 +124,9 @@ def _can_hold_na(self) -> bool:
123124

124125
@property
125126
def _engine_type(self):
126-
return self._engine_types[self.dtype]
127+
# error: Invalid index type "Union[dtype[Any], ExtensionDtype]" for
128+
# "Dict[dtype[Any], Type[IndexEngine]]"; expected type "dtype[Any]"
129+
return self._engine_types[self.dtype] # type: ignore[index]
127130

128131
@cache_readonly
129132
def inferred_type(self) -> str:
@@ -264,7 +267,8 @@ def astype(self, dtype, copy=True):
264267
# ----------------------------------------------------------------
265268
# Indexing Methods
266269

267-
@cache_readonly
270+
# error: Decorated property not supported
271+
@cache_readonly # type: ignore[misc]
268272
@doc(Index._should_fallback_to_positional)
269273
def _should_fallback_to_positional(self) -> bool:
270274
return False

0 commit comments

Comments
 (0)