Skip to content

Commit c2c2ce5

Browse files
authored
TYP: libperiod (#40990)
1 parent 691a2c4 commit c2c2ce5

File tree

5 files changed

+186
-17
lines changed

5 files changed

+186
-17
lines changed

pandas/_libs/tslibs/period.pyi

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
from typing import Literal
2+
3+
import numpy as np
4+
5+
from pandas._libs.tslibs.nattype import NaTType
6+
from pandas._libs.tslibs.offsets import BaseOffset
7+
from pandas._libs.tslibs.timestamps import Timestamp
8+
from pandas._typing import (
9+
Frequency,
10+
Timezone,
11+
)
12+
13+
INVALID_FREQ_ERR_MSG: str
14+
DIFFERENT_FREQ: str
15+
16+
class IncompatibleFrequency(ValueError): ...
17+
18+
def periodarr_to_dt64arr(
19+
periodarr: np.ndarray, # const int64_t[:]
20+
freq: int,
21+
) -> np.ndarray: ... # np.ndarray[np.int64]
22+
23+
def period_asfreq_arr(
24+
arr: np.ndarray, # ndarray[int64_t] arr,
25+
freq1: int,
26+
freq2: int,
27+
end: bool,
28+
) -> np.ndarray: ... # np.ndarray[np.int64]
29+
30+
def get_period_field_arr(
31+
field: str,
32+
arr: np.ndarray, # const int64_t[:]
33+
freq: int,
34+
) -> np.ndarray: ... # np.ndarray[np.int64]
35+
36+
def from_ordinals(
37+
values: np.ndarray, # const int64_t[:]
38+
freq: Frequency,
39+
) -> np.ndarray: ... # np.ndarray[np.int64]
40+
41+
def extract_ordinals(
42+
values: np.ndarray, # np.ndarray[object]
43+
freq: Frequency | int,
44+
) -> np.ndarray: ... # np.ndarray[np.int64]
45+
46+
def extract_freq(
47+
values: np.ndarray, # np.ndarray[object]
48+
) -> BaseOffset: ...
49+
50+
# exposed for tests
51+
def period_asfreq(ordinal: int, freq1: int, freq2: int, end: bool) -> int: ...
52+
53+
def period_ordinal(
54+
y: int, m: int, d: int, h: int, min: int, s: int, us: int, ps: int, freq: int
55+
) -> int: ...
56+
57+
def freq_to_dtype_code(freq: BaseOffset) -> int: ...
58+
def validate_end_alias(how: str) -> Literal["E", "S"]: ...
59+
60+
class Period:
61+
ordinal: int # int64_t
62+
freq: BaseOffset
63+
64+
# error: "__new__" must return a class instance (got "Union[Period, NaTType]")
65+
def __new__( # type: ignore[misc]
66+
cls,
67+
value=None,
68+
freq=None,
69+
ordinal=None,
70+
year=None,
71+
month=None,
72+
quarter=None,
73+
day=None,
74+
hour=None,
75+
minute=None,
76+
second=None,
77+
) -> Period | NaTType: ...
78+
79+
@classmethod
80+
def _maybe_convert_freq(cls, freq) -> BaseOffset: ...
81+
82+
@classmethod
83+
def _from_ordinal(cls, ordinal: int, freq) -> Period: ...
84+
85+
@classmethod
86+
def now(cls, freq=...) -> Period: ...
87+
88+
def strftime(self, fmt: str) -> str: ...
89+
90+
def to_timestamp(
91+
self,
92+
freq: str | BaseOffset | None =...,
93+
how: str = ...,
94+
tz: Timezone | None = ...,
95+
) -> Timestamp: ...
96+
97+
def asfreq(self, freq, how=...) -> Period: ...
98+
99+
@property
100+
def freqstr(self) -> str: ...
101+
102+
@property
103+
def is_leap_year(self) -> bool: ...
104+
105+
@property
106+
def daysinmonth(self) -> int: ...
107+
108+
@property
109+
def days_in_month(self) -> int: ...
110+
111+
@property
112+
def qyear(self) -> int: ...
113+
114+
@property
115+
def quarter(self) -> int: ...
116+
117+
@property
118+
def day_of_year(self) -> int: ...
119+
120+
@property
121+
def weekday(self) -> int: ...
122+
123+
@property
124+
def day_of_week(self) -> int: ...
125+
126+
@property
127+
def week(self) -> int: ...
128+
129+
@property
130+
def weekofyear(self) -> int: ...
131+
132+
@property
133+
def second(self) -> int: ...
134+
135+
@property
136+
def minute(self) -> int: ...
137+
138+
@property
139+
def hour(self) -> int: ...
140+
141+
@property
142+
def day(self) -> int: ...
143+
144+
@property
145+
def month(self) -> int: ...
146+
147+
@property
148+
def year(self) -> int: ...
149+
150+
@property
151+
def end_time(self) -> Timestamp: ...
152+
153+
@property
154+
def start_time(self) -> Timestamp: ...
155+
156+
def __sub__(self, other) -> Period | BaseOffset: ...
157+
158+
def __add__(self, other) -> Period: ...

pandas/_libs/tslibs/period.pyx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,7 +1445,7 @@ def from_ordinals(const int64_t[:] values, freq):
14451445

14461446
@cython.wraparound(False)
14471447
@cython.boundscheck(False)
1448-
def extract_ordinals(ndarray[object] values, freq):
1448+
def extract_ordinals(ndarray[object] values, freq) -> np.ndarray:
14491449
# TODO: Change type to const object[:] when Cython supports that.
14501450

14511451
cdef:
@@ -1483,7 +1483,7 @@ def extract_ordinals(ndarray[object] values, freq):
14831483
return ordinals.base # .base to access underlying np.ndarray
14841484

14851485

1486-
def extract_freq(ndarray[object] values):
1486+
def extract_freq(ndarray[object] values) -> BaseOffset:
14871487
# TODO: Change type to const object[:] when Cython supports that.
14881488

14891489
cdef:
@@ -2539,7 +2539,7 @@ cdef int64_t _ordinal_from_fields(int year, int month, quarter, int day,
25392539
minute, second, 0, 0, base)
25402540

25412541

2542-
def validate_end_alias(how):
2542+
def validate_end_alias(how: str) -> str: # Literal["E", "S"]
25432543
how_dict = {'S': 'S', 'E': 'E',
25442544
'START': 'S', 'FINISH': 'E',
25452545
'BEGIN': 'S', 'END': 'E'}

pandas/core/arrays/datetimelike.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,8 @@ def _validate_shift_value(self, fill_value):
584584
elif isinstance(fill_value, self._recognized_scalars):
585585
fill_value = self._scalar_type(fill_value)
586586
else:
587+
new_fill: DatetimeLikeScalar
588+
587589
# only warn if we're not going to raise
588590
if self._scalar_type is Period and lib.is_integer(fill_value):
589591
# kludge for #31971 since Period(integer) tries to cast to str

pandas/core/arrays/period.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,17 @@ def _generate_range(cls, start, end, periods, freq, fields):
295295
# -----------------------------------------------------------------
296296
# DatetimeLike Interface
297297

298-
def _unbox_scalar(self, value: Period | NaTType, setitem: bool = False) -> np.int64:
298+
# error: Argument 1 of "_unbox_scalar" is incompatible with supertype
299+
# "DatetimeLikeArrayMixin"; supertype defines the argument type as
300+
# "Union[Union[Period, Any, Timedelta], NaTType]"
301+
def _unbox_scalar( # type: ignore[override]
302+
self,
303+
value: Period | NaTType,
304+
setitem: bool = False,
305+
) -> np.int64:
299306
if value is NaT:
300-
return np.int64(value.value)
307+
# error: Item "Period" of "Union[Period, NaTType]" has no attribute "value"
308+
return np.int64(value.value) # type: ignore[union-attr]
301309
elif isinstance(value, self._scalar_type):
302310
self._check_compatible_with(value, setitem=setitem)
303311
return np.int64(value.ordinal)
@@ -482,9 +490,9 @@ def to_timestamp(self, freq=None, how: str = "start") -> DatetimeArray:
482490
freq = Period._maybe_convert_freq(freq)
483491
base = freq._period_dtype_code
484492

485-
new_data = self.asfreq(freq, how=how)
493+
new_parr = self.asfreq(freq, how=how)
486494

487-
new_data = libperiod.periodarr_to_dt64arr(new_data.asi8, base)
495+
new_data = libperiod.periodarr_to_dt64arr(new_parr.asi8, base)
488496
return DatetimeArray(new_data)._with_freq("infer")
489497

490498
# --------------------------------------------------------------------
@@ -910,7 +918,7 @@ def raise_on_incompatible(left, right):
910918

911919

912920
def period_array(
913-
data: Sequence[Period | None] | AnyArrayLike,
921+
data: Sequence[Period | str | None] | AnyArrayLike,
914922
freq: str | Tick | None = None,
915923
copy: bool = False,
916924
) -> PeriodArray:

pandas/core/resample.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,7 +1734,8 @@ def _get_period_bins(self, ax: PeriodIndex):
17341734

17351735
# Get offset for bin edge (not label edge) adjustment
17361736
start_offset = Period(start, self.freq) - Period(p_start, self.freq)
1737-
bin_shift = start_offset.n % freq_mult
1737+
# error: Item "Period" of "Union[Period, Any]" has no attribute "n"
1738+
bin_shift = start_offset.n % freq_mult # type: ignore[union-attr]
17381739
start = p_start
17391740

17401741
labels = binner = period_range(
@@ -1903,17 +1904,17 @@ def _get_period_range_edges(
19031904
raise TypeError("'first' and 'last' must be instances of type Period")
19041905

19051906
# GH 23882
1906-
first = first.to_timestamp()
1907-
last = last.to_timestamp()
1908-
adjust_first = not freq.is_on_offset(first)
1909-
adjust_last = freq.is_on_offset(last)
1907+
first_ts = first.to_timestamp()
1908+
last_ts = last.to_timestamp()
1909+
adjust_first = not freq.is_on_offset(first_ts)
1910+
adjust_last = freq.is_on_offset(last_ts)
19101911

1911-
first, last = _get_timestamp_range_edges(
1912-
first, last, freq, closed=closed, origin=origin, offset=offset
1912+
first_ts, last_ts = _get_timestamp_range_edges(
1913+
first_ts, last_ts, freq, closed=closed, origin=origin, offset=offset
19131914
)
19141915

1915-
first = (first + int(adjust_first) * freq).to_period(freq)
1916-
last = (last - int(adjust_last) * freq).to_period(freq)
1916+
first = (first_ts + int(adjust_first) * freq).to_period(freq)
1917+
last = (last_ts - int(adjust_last) * freq).to_period(freq)
19171918
return first, last
19181919

19191920

0 commit comments

Comments
 (0)