Skip to content

Commit 14ce816

Browse files
adamchainzDr-Irv
andauthored
Cover pandas.tseries.holiday (#645)
* Cover pandas.tseries.holiday * Apply suggestions from code review Co-authored-by: Irv Lustig <[email protected]> * Updates from review * fix overloads * start tests * Fix test * pre-commit fixes --------- Co-authored-by: Irv Lustig <[email protected]>
1 parent b4b6211 commit 14ce816

File tree

2 files changed

+160
-2
lines changed

2 files changed

+160
-2
lines changed

pandas-stubs/tseries/holiday.pyi

+128-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,129 @@
1-
class Holiday: ...
2-
class AbstractHolidayCalendar: ...
1+
from collections.abc import Callable
2+
from datetime import (
3+
date as _date,
4+
datetime,
5+
)
6+
from typing import (
7+
Literal,
8+
overload,
9+
)
10+
11+
import numpy as np
12+
from pandas import (
13+
DatetimeIndex,
14+
Series,
15+
)
16+
17+
from pandas._libs.tslibs.offsets import BaseOffset
18+
from pandas._libs.tslibs.timestamps import Timestamp
19+
20+
def next_monday(dt: datetime) -> datetime: ...
21+
def next_monday_or_tuesday(dt: datetime) -> datetime: ...
22+
def previous_friday(dt: datetime) -> datetime: ...
23+
def sunday_to_monday(dt: datetime) -> datetime: ...
24+
def weekend_to_monday(dt: datetime) -> datetime: ...
25+
def nearest_workday(dt: datetime) -> datetime: ...
26+
def next_workday(dt: datetime) -> datetime: ...
27+
def previous_workday(dt: datetime) -> datetime: ...
28+
def before_nearest_workday(dt: datetime) -> datetime: ...
29+
def after_nearest_workday(dt: datetime) -> datetime: ...
30+
31+
class Holiday:
32+
def __init__(
33+
self,
34+
name: str,
35+
year: int | None = ...,
36+
month: int | None = ...,
37+
day: int | None = ...,
38+
offset: BaseOffset | list[BaseOffset] | None = ...,
39+
observance: Callable[[datetime], datetime] | None = ...,
40+
# Values accepted by Timestamp(), or None:
41+
start_date: (
42+
np.integer | float | str | _date | datetime | np.datetime64 | None
43+
) = ...,
44+
end_date: (
45+
np.integer | float | str | _date | datetime | np.datetime64 | None
46+
) = ...,
47+
days_of_week: tuple[int, ...] | None = ...,
48+
) -> None: ...
49+
@overload
50+
def dates(
51+
self,
52+
start_date: (
53+
np.integer | float | str | _date | datetime | np.datetime64 | None
54+
),
55+
end_date: (np.integer | float | str | _date | datetime | np.datetime64 | None),
56+
return_name: Literal[False],
57+
) -> DatetimeIndex: ...
58+
@overload
59+
def dates(
60+
self,
61+
start_date: (
62+
np.integer | float | str | _date | datetime | np.datetime64 | None
63+
),
64+
end_date: (np.integer | float | str | _date | datetime | np.datetime64 | None),
65+
return_name: Literal[True] = ...,
66+
) -> Series: ...
67+
68+
holiday_calendars: dict[str, type[AbstractHolidayCalendar]]
69+
70+
def register(cls: type[AbstractHolidayCalendar]) -> None: ...
71+
def get_calendar(name: str) -> AbstractHolidayCalendar: ...
72+
73+
class AbstractHolidayCalendar:
74+
rules: list[Holiday] = ...
75+
start_date: Timestamp = ...
76+
end_date: Timestamp = ...
77+
78+
def __init__(self, name: str = "", rules: list[Holiday] | None = None) -> None: ...
79+
def rule_from_name(self, name: str) -> Holiday | None: ...
80+
@overload
81+
def holidays(
82+
self,
83+
start: datetime | None = ...,
84+
end: datetime | None = ...,
85+
*,
86+
return_name: Literal[True],
87+
) -> Series: ...
88+
@overload
89+
def holidays(
90+
self,
91+
start: datetime | None = ...,
92+
end: datetime | None = ...,
93+
return_name: Literal[False] = ...,
94+
) -> DatetimeIndex: ...
95+
@staticmethod
96+
def merge_class(
97+
base: AbstractHolidayCalendar | type[AbstractHolidayCalendar] | list[Holiday],
98+
other: AbstractHolidayCalendar | type[AbstractHolidayCalendar] | list[Holiday],
99+
) -> list[Holiday]: ...
100+
@overload
101+
def merge(
102+
self,
103+
other: AbstractHolidayCalendar | type[AbstractHolidayCalendar],
104+
inplace: Literal[True],
105+
) -> None: ...
106+
@overload
107+
def merge(
108+
self,
109+
other: AbstractHolidayCalendar | type[AbstractHolidayCalendar],
110+
inplace: Literal[False] = ...,
111+
) -> list[Holiday]: ...
112+
113+
USMemorialDay: Holiday
114+
USLaborDay: Holiday
115+
USColumbusDay: Holiday
116+
USThanksgivingDay: Holiday
117+
USMartinLutherKingJr: Holiday
118+
USPresidentsDay: Holiday
119+
GoodFriday: Holiday
120+
EasterMonday: Holiday
121+
3122
class USFederalHolidayCalendar(AbstractHolidayCalendar): ...
123+
124+
def HolidayCalendarFactory(
125+
name: str,
126+
base: type[AbstractHolidayCalendar],
127+
other: type[AbstractHolidayCalendar],
128+
base_class: type[AbstractHolidayCalendar] = ...,
129+
) -> type[AbstractHolidayCalendar]: ...

tests/test_holidays.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from datetime import datetime
2+
3+
import pandas as pd
4+
from typing_extensions import assert_type
5+
6+
from tests import check
7+
8+
from pandas.tseries.holiday import (
9+
AbstractHolidayCalendar,
10+
Holiday,
11+
USMemorialDay,
12+
nearest_workday,
13+
)
14+
15+
16+
def test_custom_calendar() -> None:
17+
class ExampleCalendar(AbstractHolidayCalendar):
18+
rules = [
19+
USMemorialDay,
20+
Holiday("July 4th", month=7, day=4, observance=nearest_workday),
21+
Holiday(
22+
"Columbus Day",
23+
month=10,
24+
day=1,
25+
offset=pd.DateOffset(weekday=1),
26+
),
27+
]
28+
29+
cal = ExampleCalendar()
30+
31+
result = cal.holidays(datetime(2012, 1, 1), datetime(2012, 12, 31))
32+
check(assert_type(result, pd.DatetimeIndex), pd.DatetimeIndex)

0 commit comments

Comments
 (0)