Repository: pandas-dev/pandas
Pull request: TYP: fix a few annotations in offsets.pyi
- [ ] closes #46908
- [ ] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).

Some doc-strings refer to `pd.HolidayCalendar` but that doesn't seem to exist?!

There are a few more un-annotated variables and a few containers (list and dict) without types but I'm not familair enough with them to annotate them.

Problem statement:
TYP: offsets.WeekOfMonth needs better typing
For @twoertwein 

I was doing some work with frequencies and discovered `pd.tseries.offsets.WeekOfMonth` and then see that it is not typed correctly in `pandas._libs.tseries.offsets.pyi` .  Constructor is:
```python
def __init__(self, n=1, normalize=False, week=0, weekday=0)
```
Right now, it picks up the constructor for `BaseOffset` which is:
```python
def __init__(self, n: int = ..., normalize: bool = ...) -> None: ...
```

I'm guessing there might be other classes in `offsets.pyi` that have issues like this, but I'm not sure.

Hints from issue discussion:

Commit message: TYP: fix a few annotations in offsets.pyi

Patch to review:
diff --git a/pandas/_libs/tslibs/offsets.pyi b/pandas/_libs/tslibs/offsets.pyi
index 4cc301018e8f8..d0963dd15362c 100644
--- a/pandas/_libs/tslibs/offsets.pyi
+++ b/pandas/_libs/tslibs/offsets.pyi
@@ -9,9 +9,7 @@ from typing import (
     Any,
     Collection,
     Literal,
-    Tuple,
     TypeVar,
-    Union,
     overload,
 )
 
@@ -101,7 +99,7 @@ def _get_offset(name: str) -> BaseOffset: ...
 
 class SingleConstructorOffset(BaseOffset):
     @classmethod
-    def _from_name(cls, suffix=...): ...
+    def _from_name(cls, suffix: None = ...): ...
     def __reduce__(self): ...
 
 @overload
@@ -132,7 +130,7 @@ class RelativeDeltaOffset(BaseOffset):
 class BusinessMixin(SingleConstructorOffset):
     def __init__(
         self, n: int = ..., normalize: bool = ..., offset: timedelta = ...
-    ): ...
+    ) -> None: ...
 
 class BusinessDay(BusinessMixin): ...
 
@@ -144,14 +142,17 @@ class BusinessHour(BusinessMixin):
         start: str | Collection[str] = ...,
         end: str | Collection[str] = ...,
         offset: timedelta = ...,
-    ): ...
+    ) -> None: ...
 
-class WeekOfMonthMixin(SingleConstructorOffset): ...
+class WeekOfMonthMixin(SingleConstructorOffset):
+    def __init__(
+        self, n: int = ..., normalize: bool = ..., weekday: int = ...
+    ) -> None: ...
 
 class YearOffset(SingleConstructorOffset):
     def __init__(
         self, n: int = ..., normalize: bool = ..., month: int | None = ...
-    ): ...
+    ) -> None: ...
 
 class BYearEnd(YearOffset): ...
 class BYearBegin(YearOffset): ...
@@ -186,7 +187,11 @@ class Week(SingleConstructorOffset):
         self, n: int = ..., normalize: bool = ..., weekday: int | None = ...
     ) -> None: ...
 
-class WeekOfMonth(WeekOfMonthMixin): ...
+class WeekOfMonth(WeekOfMonthMixin):
+    def __init__(
+        self, n: int = ..., normalize: bool = ..., week: int = ..., weekday: int = ...
+    ) -> None: ...
+
 class LastWeekOfMonth(WeekOfMonthMixin): ...
 
 class FY5253Mixin(SingleConstructorOffset):
@@ -200,7 +205,18 @@ class FY5253Mixin(SingleConstructorOffset):
     ) -> None: ...
 
 class FY5253(FY5253Mixin): ...
-class FY5253Quarter(FY5253Mixin): ...
+
+class FY5253Quarter(FY5253Mixin):
+    def __init__(
+        self,
+        n: int = ...,
+        normalize: bool = ...,
+        weekday: int = ...,
+        startingMonth: int = ...,
+        qtr_with_extra_week: int = ...,
+        variation: str = ...,
+    ) -> None: ...
+
 class Easter(SingleConstructorOffset): ...
 
 class _CustomBusinessMonth(BusinessMixin):
@@ -208,29 +224,35 @@ class _CustomBusinessMonth(BusinessMixin):
         self,
         n: int = ...,
         normalize: bool = ...,
-        offset: timedelta = ...,
+        weekmask: str = ...,
         holidays: None | list = ...,
-    ): ...
+        calendar: np.busdaycalendar = ...,
+        offset: timedelta = ...,
+    ) -> None: ...
 
 class CustomBusinessDay(BusinessDay):
     def __init__(
         self,
         n: int = ...,
         normalize: bool = ...,
-        offset: timedelta = ...,
         weekmask: str = ...,
-    ): ...
+        holidays: None | list = ...,
+        calendar: np.busdaycalendar = ...,
+        offset: timedelta = ...,
+    ) -> None: ...
 
 class CustomBusinessHour(BusinessHour):
     def __init__(
         self,
         n: int = ...,
         normalize: bool = ...,
+        weekmask: str = ...,
+        holidays: None | list = ...,
+        calendar: np.busdaycalendar = ...,
         start: str = ...,
         end: str = ...,
         offset: timedelta = ...,
-        holidays: None | list = ...,
-    ): ...
+    ) -> None: ...
 
 class CustomBusinessMonthEnd(_CustomBusinessMonth): ...
 class CustomBusinessMonthBegin(_CustomBusinessMonth): ...
diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx
index 00ef4fcbf8986..6c96df9a7ea0b 100644
--- a/pandas/_libs/tslibs/offsets.pyx
+++ b/pandas/_libs/tslibs/offsets.pyx
@@ -3291,7 +3291,7 @@ cdef class CustomBusinessDay(BusinessDay):
     holidays : list
         List/array of dates to exclude from the set of valid business days,
         passed to ``numpy.busdaycalendar``.
-    calendar : pd.HolidayCalendar or np.busdaycalendar
+    calendar : np.busdaycalendar
     offset : timedelta, default timedelta(0)
     """
 
@@ -3417,7 +3417,7 @@ cdef class _CustomBusinessMonth(BusinessMixin):
     holidays : list
         List/array of dates to exclude from the set of valid business days,
         passed to ``numpy.busdaycalendar``.
-    calendar : pd.HolidayCalendar or np.busdaycalendar
+    calendar : np.busdaycalendar
         Calendar to integrate.
     offset : timedelta, default timedelta(0)
         Time offset to apply.


Code review comments:
diff_hunk: @@ -200,37 +205,54 @@ class FY5253Mixin(SingleConstructorOffset):
     ) -> None: ...
 
 class FY5253(FY5253Mixin): ...
-class FY5253Quarter(FY5253Mixin): ...
+
+class FY5253Quarter(FY5253Mixin):
+    def __init__(
+        self,
+        n: int = ...,
+        normalize: bool = ...,
+        weekday: int = ...,
+        startingMonth: int = ...,
+        qtr_with_extra_week: int = ...,
+        variation: str = ...,
path: pandas/_libs/tslibs/offsets.pyi
text: @user1:
`variation` should be `Literal["nearest", "last"]` according to the docs.

diff_hunk: @@ -200,37 +205,54 @@ class FY5253Mixin(SingleConstructorOffset):
     ) -> None: ...
 
 class FY5253(FY5253Mixin): ...
-class FY5253Quarter(FY5253Mixin): ...
+
+class FY5253Quarter(FY5253Mixin):
+    def __init__(
+        self,
+        n: int = ...,
+        normalize: bool = ...,
+        weekday: int = ...,
+        startingMonth: int = ...,
+        qtr_with_extra_week: int = ...,
+        variation: str = ...,
+    ) -> None: ...
+
 class Easter(SingleConstructorOffset): ...
 
 class _CustomBusinessMonth(BusinessMixin):
     def __init__(
         self,
         n: int = ...,
         normalize: bool = ...,
-        offset: timedelta = ...,
+        weekmask: str = ...,
         holidays: None | list = ...,
-    ): ...
+        calendar: np.busdaycalendar = ...,
+        offset: timedelta = ...,
+    ) -> None: ...
 
 class CustomBusinessDay(BusinessDay):
     def __init__(
         self,
         n: int = ...,
         normalize: bool = ...,
-        offset: timedelta = ...,
         weekmask: str = ...,
-    ): ...
+        holidays: None | list = ...,
+        calendar: np.busdaycalendar = ...,
+        offset: timedelta = ...,
+    ) -> None: ...
 
 class CustomBusinessHour(BusinessHour):
     def __init__(
         self,
         n: int = ...,
         normalize: bool = ...,
+        weekmask: str = ...,
+        holidays: None | list = ...,
+        calendar: np.busdaycalendar = ...,
path: pandas/_libs/tslibs/offsets.pyi
text: @user1:
allow `None` for calendar

diff_hunk: @@ -200,37 +205,54 @@ class FY5253Mixin(SingleConstructorOffset):
     ) -> None: ...
 
 class FY5253(FY5253Mixin): ...
-class FY5253Quarter(FY5253Mixin): ...
+
+class FY5253Quarter(FY5253Mixin):
+    def __init__(
+        self,
+        n: int = ...,
+        normalize: bool = ...,
+        weekday: int = ...,
+        startingMonth: int = ...,
+        qtr_with_extra_week: int = ...,
+        variation: str = ...,
+    ) -> None: ...
+
 class Easter(SingleConstructorOffset): ...
 
 class _CustomBusinessMonth(BusinessMixin):
     def __init__(
         self,
         n: int = ...,
         normalize: bool = ...,
-        offset: timedelta = ...,
+        weekmask: str = ...,
         holidays: None | list = ...,
-    ): ...
+        calendar: np.busdaycalendar = ...,
path: pandas/_libs/tslibs/offsets.pyi
text: @user1:
Looking at the `__init__()` in the `pyx` file, I think `calendar` should be `None | np.busdaycalendar`

diff_hunk: @@ -200,37 +205,54 @@ class FY5253Mixin(SingleConstructorOffset):
     ) -> None: ...
 
 class FY5253(FY5253Mixin): ...
-class FY5253Quarter(FY5253Mixin): ...
+
+class FY5253Quarter(FY5253Mixin):
+    def __init__(
+        self,
+        n: int = ...,
+        normalize: bool = ...,
+        weekday: int = ...,
+        startingMonth: int = ...,
+        qtr_with_extra_week: int = ...,
+        variation: str = ...,
+    ) -> None: ...
+
 class Easter(SingleConstructorOffset): ...
 
 class _CustomBusinessMonth(BusinessMixin):
     def __init__(
         self,
         n: int = ...,
         normalize: bool = ...,
-        offset: timedelta = ...,
+        weekmask: str = ...,
         holidays: None | list = ...,
-    ): ...
+        calendar: np.busdaycalendar = ...,
+        offset: timedelta = ...,
+    ) -> None: ...
 
 class CustomBusinessDay(BusinessDay):
     def __init__(
         self,
         n: int = ...,
         normalize: bool = ...,
-        offset: timedelta = ...,
         weekmask: str = ...,
-    ): ...
+        holidays: None | list = ...,
+        calendar: np.busdaycalendar = ...,
path: pandas/_libs/tslibs/offsets.pyi
text: @user1:
Allow `None` for `calendar`