Skip to content

Commit f841eda

Browse files
authored
TYP: nattype.pyi (#40503)
1 parent b94a1ee commit f841eda

File tree

9 files changed

+170
-26
lines changed

9 files changed

+170
-26
lines changed

pandas/_libs/tslibs/nattype.pyi

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
2+
from datetime import datetime
3+
4+
import numpy as np
5+
6+
NaT: NaTType
7+
iNaT: int
8+
nat_strings: set[str]
9+
10+
def is_null_datetimelike(val: object, inat_is_null: bool = ...) -> bool: ...
11+
12+
class NaTType(datetime):
13+
value: np.int64
14+
15+
def asm8(self) -> np.datetime64: ...
16+
def to_datetime64(self) -> np.datetime64: ...
17+
def to_numpy(self, dtype=..., copy: bool = ...) -> np.datetime64: ...
18+
19+
@property
20+
def is_leap_year(self) -> bool: ...
21+
@property
22+
def is_month_start(self) -> bool: ...
23+
@property
24+
def is_quarter_start(self) -> bool: ...
25+
@property
26+
def is_year_start(self) -> bool: ...
27+
@property
28+
def is_month_end(self) -> bool: ...
29+
@property
30+
def is_quarter_end(self) -> bool: ...
31+
@property
32+
def is_year_end(self) -> bool: ...
33+
34+
@property
35+
def day_of_year(self) -> float: ...
36+
@property
37+
def dayofyear(self) -> float: ...
38+
@property
39+
def days_in_month(self) -> float: ...
40+
@property
41+
def daysinmonth(self) -> float: ...
42+
@property
43+
def day_of_week(self) -> float: ...
44+
@property
45+
def dayofweek(self) -> float: ...
46+
@property
47+
def week(self) -> float: ...
48+
@property
49+
def weekofyear(self) -> float: ...
50+
51+
def day_name(self) -> float: ...
52+
def month_name(self) -> float: ...
53+
54+
# error: Return type "float" of "weekday" incompatible with return
55+
# type "int" in supertype "date"
56+
def weekday(self) -> float: ... # type: ignore[override]
57+
58+
# error: Return type "float" of "isoweekday" incompatible with return
59+
# type "int" in supertype "date"
60+
def isoweekday(self) -> float: ... # type: ignore[override]
61+
62+
def total_seconds(self) -> float: ...
63+
64+
# error: Signature of "today" incompatible with supertype "datetime"
65+
def today(self, *args, **kwargs) -> NaTType: ... # type: ignore[override]
66+
# error: Signature of "today" incompatible with supertype "datetime"
67+
def now(self, *args, **kwargs) -> NaTType: ... # type: ignore[override]
68+
69+
def to_pydatetime(self) -> NaTType: ...
70+
def date(self) -> NaTType: ...
71+
72+
def round(self) -> NaTType: ...
73+
def floor(self) -> NaTType: ...
74+
def ceil(self) -> NaTType: ...
75+
76+
def tz_convert(self) -> NaTType: ...
77+
def tz_localize(self) -> NaTType: ...
78+
79+
def replace(self, *args, **kwargs) -> NaTType: ...
80+
81+
# error: Return type "float" of "year" incompatible with return
82+
# type "int" in supertype "date"
83+
@property
84+
def year(self) -> float: ... # type: ignore[override]
85+
86+
@property
87+
def quarter(self) -> float: ...
88+
89+
# error: Return type "float" of "month" incompatible with return
90+
# type "int" in supertype "date"
91+
@property
92+
def month(self) -> float: ... # type: ignore[override]
93+
94+
# error: Return type "float" of "day" incompatible with return
95+
# type "int" in supertype "date"
96+
@property
97+
def day(self) -> float: ... # type: ignore[override]
98+
99+
# error: Return type "float" of "hour" incompatible with return
100+
# type "int" in supertype "date"
101+
@property
102+
def hour(self) -> float: ... # type: ignore[override]
103+
104+
# error: Return type "float" of "minute" incompatible with return
105+
# type "int" in supertype "date"
106+
@property
107+
def minute(self) -> float: ... # type: ignore[override]
108+
109+
# error: Return type "float" of "second" incompatible with return
110+
# type "int" in supertype "date"
111+
@property
112+
def second(self) -> float: ... # type: ignore[override]
113+
114+
@property
115+
def millisecond(self) -> float: ...
116+
117+
# error: Return type "float" of "microsecond" incompatible with return
118+
# type "int" in supertype "date"
119+
@property
120+
def microsecond(self) -> float: ... # type: ignore[override]
121+
122+
@property
123+
def nanosecond(self) -> float: ...
124+
125+
# inject Timedelta properties
126+
@property
127+
def days(self) -> float: ...
128+
@property
129+
def microseconds(self) -> float: ...
130+
@property
131+
def nanoseconds(self) -> float: ...
132+
133+
# inject Period properties
134+
@property
135+
def qyear(self) -> float: ...

pandas/core/algorithms.py

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
ArrayLike,
3434
DtypeObj,
3535
FrameOrSeriesUnion,
36+
Scalar,
3637
)
3738
from pandas.util._decorators import doc
3839

@@ -763,6 +764,7 @@ def factorize(
763764
dtype = original.dtype
764765
else:
765766
values, dtype = _ensure_data(values)
767+
na_value: Scalar
766768

767769
if original.dtype.kind in ["m", "M"]:
768770
# Note: factorize_array will cast NaT bc it has a __int__

pandas/core/indexes/base.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
)
3939
from pandas._libs.tslibs import (
4040
IncompatibleFrequency,
41+
NaTType,
4142
OutOfBoundsDatetime,
4243
Timestamp,
4344
tz_compare,
@@ -2371,7 +2372,7 @@ def __reduce__(self):
23712372
# --------------------------------------------------------------------
23722373
# Null Handling Methods
23732374

2374-
_na_value = np.nan
2375+
_na_value: Union[float, NaTType] = np.nan
23752376
"""The expected NA value to use with this index."""
23762377

23772378
@cache_readonly

pandas/core/indexes/datetimelike.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
)
2525
from pandas._libs.tslibs import (
2626
BaseOffset,
27+
NaTType,
2728
Resolution,
2829
Tick,
2930
)
@@ -218,7 +219,7 @@ def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
218219

219220
_can_hold_na = True
220221

221-
_na_value = NaT
222+
_na_value: NaTType = NaT
222223
"""The expected NA value to use with this index."""
223224

224225
def _convert_tolerance(self, tolerance, target):

pandas/core/internals/construction.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,10 @@ def maybe_squeeze_dt64tz(dta: ArrayLike) -> ArrayLike:
368368
# TODO(EA2D): kludge not needed with 2D EAs
369369
if isinstance(dta, DatetimeArray) and dta.ndim == 2 and dta.tz is not None:
370370
assert dta.shape[0] == 1
371-
dta = dta[0]
371+
# error: Incompatible types in assignment (expression has type
372+
# "Union[DatetimeLikeArrayMixin, Union[Any, NaTType]]", variable has
373+
# type "Union[ExtensionArray, ndarray]")
374+
dta = dta[0] # type: ignore[assignment]
372375
return dta
373376

374377

pandas/core/nanops.py

+9-13
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
from pandas._libs import (
2020
NaT,
21+
NaTType,
2122
Timedelta,
2223
iNaT,
2324
lib,
@@ -414,11 +415,8 @@ def new_func(
414415
if datetimelike:
415416
result = _wrap_results(result, orig_values.dtype, fill_value=iNaT)
416417
if not skipna:
417-
# error: Argument 3 to "_mask_datetimelike_result" has incompatible type
418-
# "Optional[ndarray]"; expected "ndarray"
419-
result = _mask_datetimelike_result(
420-
result, axis, mask, orig_values # type: ignore[arg-type]
421-
)
418+
assert mask is not None # checked above
419+
result = _mask_datetimelike_result(result, axis, mask, orig_values)
422420

423421
return result
424422

@@ -601,15 +599,15 @@ def _mask_datetimelike_result(
601599
axis: Optional[int],
602600
mask: np.ndarray,
603601
orig_values: np.ndarray,
604-
):
602+
) -> Union[np.ndarray, np.datetime64, np.timedelta64, NaTType]:
605603
if isinstance(result, np.ndarray):
606604
# we need to apply the mask
607605
result = result.astype("i8").view(orig_values.dtype)
608606
axis_mask = mask.any(axis=axis)
609607
result[axis_mask] = iNaT
610608
else:
611609
if mask.any():
612-
result = NaT
610+
return NaT
613611
return result
614612

615613

@@ -1435,19 +1433,19 @@ def _get_counts(
14351433

14361434

14371435
def _maybe_null_out(
1438-
result: np.ndarray,
1436+
result: np.ndarray | float | NaTType,
14391437
axis: Optional[int],
14401438
mask: Optional[np.ndarray],
14411439
shape: Tuple[int, ...],
14421440
min_count: int = 1,
1443-
) -> np.ndarray | float:
1441+
) -> np.ndarray | float | NaTType:
14441442
"""
14451443
Returns
14461444
-------
14471445
Dtype
14481446
The product of all elements on a given axis. ( NaNs are treated as 1)
14491447
"""
1450-
if mask is not None and axis is not None and getattr(result, "ndim", False):
1448+
if mask is not None and axis is not None and isinstance(result, np.ndarray):
14511449
null_mask = (mask.shape[axis] - mask.sum(axis) - min_count) < 0
14521450
if np.any(null_mask):
14531451
if is_numeric_dtype(result):
@@ -1461,9 +1459,7 @@ def _maybe_null_out(
14611459
result[null_mask] = None
14621460
elif result is not NaT:
14631461
if check_below_min_count(shape, mask, min_count):
1464-
# error: Incompatible types in assignment (expression has type
1465-
# "float", variable has type "ndarray")
1466-
result = np.nan # type: ignore[assignment]
1462+
result = np.nan
14671463

14681464
return result
14691465

pandas/core/tools/datetimes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ def to_datetime(
701701
infer_datetime_format: bool = False,
702702
origin="unix",
703703
cache: bool = True,
704-
) -> Union[DatetimeIndex, Series, DatetimeScalar, NaTType]:
704+
) -> Optional[Union[DatetimeIndex, Series, DatetimeScalar, NaTType]]:
705705
"""
706706
Convert argument to datetime.
707707

pandas/io/excel/_odfreader.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ def _get_cell_value(self, cell, convert_float: bool) -> Scalar:
202202
elif cell_type == "time":
203203
result = pd.to_datetime(str(cell))
204204
result = cast(pd.Timestamp, result)
205-
return result.time()
205+
# error: Item "str" of "Union[float, str, NaTType]" has no attribute "time"
206+
return result.time() # type: ignore[union-attr]
206207
else:
207208
self.close()
208209
raise ValueError(f"Unrecognized type {cell_type}")

pandas/io/formats/format.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -1723,7 +1723,10 @@ def _format_datetime64_dateonly(
17231723
if date_format:
17241724
return x.strftime(date_format)
17251725
else:
1726-
return x._date_repr
1726+
# error: Item "NaTType" of "Union[NaTType, Any]" has no attribute "_date_repr"
1727+
# The underlying problem here is that mypy doesn't understand that NaT
1728+
# is a singleton, so that the check above excludes it here.
1729+
return x._date_repr # type: ignore[union-attr]
17271730

17281731

17291732
def get_format_datetime64(
@@ -1801,13 +1804,15 @@ def get_format_timedelta64(
18011804
consider_values = values_int != iNaT
18021805

18031806
one_day_nanos = 86400 * 10 ** 9
1804-
even_days = (
1805-
# error: Unsupported operand types for % ("ExtensionArray" and "int")
1806-
np.logical_and(
1807-
consider_values, values_int % one_day_nanos != 0 # type: ignore[operator]
1808-
).sum()
1809-
== 0
1810-
)
1807+
# error: Unsupported operand types for % ("ExtensionArray" and "int")
1808+
not_midnight = values_int % one_day_nanos != 0 # type: ignore[operator]
1809+
# error: Argument 1 to "__call__" of "ufunc" has incompatible type
1810+
# "Union[Any, ExtensionArray, ndarray]"; expected
1811+
# "Union[Union[int, float, complex, str, bytes, generic],
1812+
# Sequence[Union[int, float, complex, str, bytes, generic]],
1813+
# Sequence[Sequence[Any]], _SupportsArray]"
1814+
both = np.logical_and(consider_values, not_midnight) # type: ignore[arg-type]
1815+
even_days = both.sum() == 0
18111816

18121817
if even_days:
18131818
format = None

0 commit comments

Comments
 (0)