Skip to content

Commit b1c3c4f

Browse files
twoertweincbpygit
authored andcommitted
TYP: misc annotations (pandas-dev#56667)
1 parent 1d7c182 commit b1c3c4f

File tree

11 files changed

+80
-41
lines changed

11 files changed

+80
-41
lines changed

pandas/_testing/_warnings.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
from contextlib import (
4+
AbstractContextManager,
45
contextmanager,
56
nullcontext,
67
)
@@ -112,7 +113,9 @@ class for all warnings. To raise multiple types of exceptions,
112113
)
113114

114115

115-
def maybe_produces_warning(warning: type[Warning], condition: bool, **kwargs):
116+
def maybe_produces_warning(
117+
warning: type[Warning], condition: bool, **kwargs
118+
) -> AbstractContextManager:
116119
"""
117120
Return a context manager that possibly checks a warning based on the condition
118121
"""

pandas/compat/_optional.py

+30-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import importlib
44
import sys
5-
from typing import TYPE_CHECKING
5+
from typing import (
6+
TYPE_CHECKING,
7+
Literal,
8+
overload,
9+
)
610
import warnings
711

812
from pandas.util._exceptions import find_stack_level
@@ -82,12 +86,35 @@ def get_version(module: types.ModuleType) -> str:
8286
return version
8387

8488

89+
@overload
90+
def import_optional_dependency(
91+
name: str,
92+
extra: str = ...,
93+
min_version: str | None = ...,
94+
*,
95+
errors: Literal["raise"] = ...,
96+
) -> types.ModuleType:
97+
...
98+
99+
100+
@overload
101+
def import_optional_dependency(
102+
name: str,
103+
extra: str = ...,
104+
min_version: str | None = ...,
105+
*,
106+
errors: Literal["warn", "ignore"],
107+
) -> types.ModuleType | None:
108+
...
109+
110+
85111
def import_optional_dependency(
86112
name: str,
87113
extra: str = "",
88-
errors: str = "raise",
89114
min_version: str | None = None,
90-
):
115+
*,
116+
errors: Literal["raise", "warn", "ignore"] = "raise",
117+
) -> types.ModuleType | None:
91118
"""
92119
Import an optional dependency.
93120

pandas/core/arrays/_arrow_string_mixins.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
from __future__ import annotations
22

3-
from typing import Literal
3+
from typing import (
4+
TYPE_CHECKING,
5+
Literal,
6+
)
47

58
import numpy as np
69

@@ -10,6 +13,9 @@
1013
import pyarrow as pa
1114
import pyarrow.compute as pc
1215

16+
if TYPE_CHECKING:
17+
from pandas._typing import Self
18+
1319

1420
class ArrowStringArrayMixin:
1521
_pa_array = None
@@ -22,7 +28,7 @@ def _str_pad(
2228
width: int,
2329
side: Literal["left", "right", "both"] = "left",
2430
fillchar: str = " ",
25-
):
31+
) -> Self:
2632
if side == "left":
2733
pa_pad = pc.utf8_lpad
2834
elif side == "right":
@@ -35,7 +41,7 @@ def _str_pad(
3541
)
3642
return type(self)(pa_pad(self._pa_array, width=width, padding=fillchar))
3743

38-
def _str_get(self, i: int):
44+
def _str_get(self, i: int) -> Self:
3945
lengths = pc.utf8_length(self._pa_array)
4046
if i >= 0:
4147
out_of_bounds = pc.greater_equal(i, lengths)
@@ -59,7 +65,7 @@ def _str_get(self, i: int):
5965

6066
def _str_slice_replace(
6167
self, start: int | None = None, stop: int | None = None, repl: str | None = None
62-
):
68+
) -> Self:
6369
if repl is None:
6470
repl = ""
6571
if start is None:
@@ -68,13 +74,13 @@ def _str_slice_replace(
6874
stop = np.iinfo(np.int64).max
6975
return type(self)(pc.utf8_replace_slice(self._pa_array, start, stop, repl))
7076

71-
def _str_capitalize(self):
77+
def _str_capitalize(self) -> Self:
7278
return type(self)(pc.utf8_capitalize(self._pa_array))
7379

74-
def _str_title(self):
80+
def _str_title(self) -> Self:
7581
return type(self)(pc.utf8_title(self._pa_array))
7682

77-
def _str_swapcase(self):
83+
def _str_swapcase(self) -> Self:
7884
return type(self)(pc.utf8_swapcase(self._pa_array))
7985

8086
def _str_removesuffix(self, suffix: str):

pandas/core/dtypes/inference.py

+20-17
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
is_iterator = lib.is_iterator
3737

3838

39-
def is_number(obj) -> TypeGuard[Number | np.number]:
39+
def is_number(obj: object) -> TypeGuard[Number | np.number]:
4040
"""
4141
Check if the object is a number.
4242
@@ -77,7 +77,7 @@ def is_number(obj) -> TypeGuard[Number | np.number]:
7777
return isinstance(obj, (Number, np.number))
7878

7979

80-
def iterable_not_string(obj) -> bool:
80+
def iterable_not_string(obj: object) -> bool:
8181
"""
8282
Check if the object is an iterable but not a string.
8383
@@ -102,7 +102,7 @@ def iterable_not_string(obj) -> bool:
102102
return isinstance(obj, abc.Iterable) and not isinstance(obj, str)
103103

104104

105-
def is_file_like(obj) -> bool:
105+
def is_file_like(obj: object) -> bool:
106106
"""
107107
Check if the object is a file-like object.
108108
@@ -138,7 +138,7 @@ def is_file_like(obj) -> bool:
138138
return bool(hasattr(obj, "__iter__"))
139139

140140

141-
def is_re(obj) -> TypeGuard[Pattern]:
141+
def is_re(obj: object) -> TypeGuard[Pattern]:
142142
"""
143143
Check if the object is a regex pattern instance.
144144
@@ -163,7 +163,7 @@ def is_re(obj) -> TypeGuard[Pattern]:
163163
return isinstance(obj, Pattern)
164164

165165

166-
def is_re_compilable(obj) -> bool:
166+
def is_re_compilable(obj: object) -> bool:
167167
"""
168168
Check if the object can be compiled into a regex pattern instance.
169169
@@ -185,14 +185,14 @@ def is_re_compilable(obj) -> bool:
185185
False
186186
"""
187187
try:
188-
re.compile(obj)
188+
re.compile(obj) # type: ignore[call-overload]
189189
except TypeError:
190190
return False
191191
else:
192192
return True
193193

194194

195-
def is_array_like(obj) -> bool:
195+
def is_array_like(obj: object) -> bool:
196196
"""
197197
Check if the object is array-like.
198198
@@ -224,7 +224,7 @@ def is_array_like(obj) -> bool:
224224
return is_list_like(obj) and hasattr(obj, "dtype")
225225

226226

227-
def is_nested_list_like(obj) -> bool:
227+
def is_nested_list_like(obj: object) -> bool:
228228
"""
229229
Check if the object is list-like, and that all of its elements
230230
are also list-like.
@@ -265,12 +265,13 @@ def is_nested_list_like(obj) -> bool:
265265
return (
266266
is_list_like(obj)
267267
and hasattr(obj, "__len__")
268-
and len(obj) > 0
269-
and all(is_list_like(item) for item in obj)
268+
# need PEP 724 to handle these typing errors
269+
and len(obj) > 0 # pyright: ignore[reportGeneralTypeIssues]
270+
and all(is_list_like(item) for item in obj) # type: ignore[attr-defined]
270271
)
271272

272273

273-
def is_dict_like(obj) -> bool:
274+
def is_dict_like(obj: object) -> bool:
274275
"""
275276
Check if the object is dict-like.
276277
@@ -303,7 +304,7 @@ def is_dict_like(obj) -> bool:
303304
)
304305

305306

306-
def is_named_tuple(obj) -> bool:
307+
def is_named_tuple(obj: object) -> bool:
307308
"""
308309
Check if the object is a named tuple.
309310
@@ -331,7 +332,7 @@ def is_named_tuple(obj) -> bool:
331332
return isinstance(obj, abc.Sequence) and hasattr(obj, "_fields")
332333

333334

334-
def is_hashable(obj) -> TypeGuard[Hashable]:
335+
def is_hashable(obj: object) -> TypeGuard[Hashable]:
335336
"""
336337
Return True if hash(obj) will succeed, False otherwise.
337338
@@ -370,7 +371,7 @@ def is_hashable(obj) -> TypeGuard[Hashable]:
370371
return True
371372

372373

373-
def is_sequence(obj) -> bool:
374+
def is_sequence(obj: object) -> bool:
374375
"""
375376
Check if the object is a sequence of objects.
376377
String types are not included as sequences here.
@@ -394,14 +395,16 @@ def is_sequence(obj) -> bool:
394395
False
395396
"""
396397
try:
397-
iter(obj) # Can iterate over it.
398-
len(obj) # Has a length associated with it.
398+
# Can iterate over it.
399+
iter(obj) # type: ignore[call-overload]
400+
# Has a length associated with it.
401+
len(obj) # type: ignore[arg-type]
399402
return not isinstance(obj, (str, bytes))
400403
except (TypeError, AttributeError):
401404
return False
402405

403406

404-
def is_dataclass(item) -> bool:
407+
def is_dataclass(item: object) -> bool:
405408
"""
406409
Checks if the object is a data-class instance
407410

pandas/core/flags.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def __setitem__(self, key: str, value) -> None:
111111
def __repr__(self) -> str:
112112
return f"<Flags(allows_duplicate_labels={self.allows_duplicate_labels})>"
113113

114-
def __eq__(self, other) -> bool:
114+
def __eq__(self, other: object) -> bool:
115115
if isinstance(other, type(self)):
116116
return self.allows_duplicate_labels == other.allows_duplicate_labels
117117
return False

pandas/core/ops/invalid.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
from __future__ import annotations
55

66
import operator
7-
from typing import TYPE_CHECKING
7+
from typing import (
8+
TYPE_CHECKING,
9+
Callable,
10+
NoReturn,
11+
)
812

913
import numpy as np
1014

@@ -41,7 +45,7 @@ def invalid_comparison(left, right, op) -> npt.NDArray[np.bool_]:
4145
return res_values
4246

4347

44-
def make_invalid_op(name: str):
48+
def make_invalid_op(name: str) -> Callable[..., NoReturn]:
4549
"""
4650
Return a binary method that always raises a TypeError.
4751
@@ -54,7 +58,7 @@ def make_invalid_op(name: str):
5458
invalid_op : function
5559
"""
5660

57-
def invalid_op(self, other=None):
61+
def invalid_op(self, other=None) -> NoReturn:
5862
typ = type(self).__name__
5963
raise TypeError(f"cannot perform {name} with this index type: {typ}")
6064

pandas/core/ops/missing.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from pandas.core import roperator
3131

3232

33-
def _fill_zeros(result: np.ndarray, x, y):
33+
def _fill_zeros(result: np.ndarray, x, y) -> np.ndarray:
3434
"""
3535
If this is a reversed op, then flip x,y
3636

pandas/io/orc.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from __future__ import annotations
33

44
import io
5-
from types import ModuleType
65
from typing import (
76
TYPE_CHECKING,
87
Any,
@@ -218,7 +217,7 @@ def to_orc(
218217

219218
if engine != "pyarrow":
220219
raise ValueError("engine must be 'pyarrow'")
221-
engine = import_optional_dependency(engine, min_version="10.0.1")
220+
pyarrow = import_optional_dependency(engine, min_version="10.0.1")
222221
pa = import_optional_dependency("pyarrow")
223222
orc = import_optional_dependency("pyarrow.orc")
224223

@@ -227,10 +226,9 @@ def to_orc(
227226
path = io.BytesIO()
228227
assert path is not None # For mypy
229228
with get_handle(path, "wb", is_text=False) as handles:
230-
assert isinstance(engine, ModuleType) # For mypy
231229
try:
232230
orc.write_table(
233-
engine.Table.from_pandas(df, preserve_index=index),
231+
pyarrow.Table.from_pandas(df, preserve_index=index),
234232
handles.handle,
235233
**engine_kwargs,
236234
)

pandas/util/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ def __getattr__(key: str):
2525
raise AttributeError(f"module 'pandas.util' has no attribute '{key}'")
2626

2727

28-
def capitalize_first_letter(s):
28+
def capitalize_first_letter(s: str) -> str:
2929
return s[:1].upper() + s[1:]

pandas/util/_decorators.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ def wrapper(*args, **kwargs):
340340
return decorate
341341

342342

343-
def doc(*docstrings: None | str | Callable, **params) -> Callable[[F], F]:
343+
def doc(*docstrings: None | str | Callable, **params: object) -> Callable[[F], F]:
344344
"""
345345
A decorator to take docstring templates, concatenate them and perform string
346346
substitution on them.

pyproject.toml

-2
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,6 @@ module = [
583583
"pandas._testing.*", # TODO
584584
"pandas.arrays", # TODO
585585
"pandas.compat.numpy.function", # TODO
586-
"pandas.compat._optional", # TODO
587586
"pandas.compat.compressors", # TODO
588587
"pandas.compat.pickle_compat", # TODO
589588
"pandas.core._numba.executor", # TODO
@@ -602,7 +601,6 @@ module = [
602601
"pandas.core.dtypes.concat", # TODO
603602
"pandas.core.dtypes.dtypes", # TODO
604603
"pandas.core.dtypes.generic", # TODO
605-
"pandas.core.dtypes.inference", # TODO
606604
"pandas.core.dtypes.missing", # TODO
607605
"pandas.core.groupby.categorical", # TODO
608606
"pandas.core.groupby.generic", # TODO

0 commit comments

Comments
 (0)