diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index dc7edd8db662e..dc17cddd32df9 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -223,6 +223,8 @@ Other - Appending a dictionary to a :class:`DataFrame` without passing ``ignore_index=True`` will raise ``TypeError: Can only append a dict if ignore_index=True`` instead of ``TypeError: Can only append a Series if ignore_index=True or if the Series has a name`` (:issue:`30871`) - Set operations on an object-dtype :class:`Index` now always return object-dtype results (:issue:`31401`) +- Bug in :meth:`AbstractHolidayCalendar.holidays` when no rules were defined (:issue:`31415`) +- .. --------------------------------------------------------------------------- diff --git a/pandas/tests/tseries/holiday/test_calendar.py b/pandas/tests/tseries/holiday/test_calendar.py index 5b4a7c74b1af1..cd3b1aab33a2a 100644 --- a/pandas/tests/tseries/holiday/test_calendar.py +++ b/pandas/tests/tseries/holiday/test_calendar.py @@ -98,3 +98,15 @@ class testCalendar(AbstractHolidayCalendar): Sat_before_Labor_Day_2031 = to_datetime("2031-08-30") next_working_day = Sat_before_Labor_Day_2031 + 0 * workDay assert next_working_day == to_datetime("2031-09-02") + + +def test_no_holidays_calendar(): + # Test for issue #31415 + + class NoHolidaysCalendar(AbstractHolidayCalendar): + pass + + cal = NoHolidaysCalendar() + holidays = cal.holidays(Timestamp("01-Jan-2020"), Timestamp("01-Jan-2021")) + empty_index = DatetimeIndex([]) # Type is DatetimeIndex since return_name=False + tm.assert_index_equal(holidays, empty_index) diff --git a/pandas/tseries/holiday.py b/pandas/tseries/holiday.py index 62d7c26b590cc..fe30130e87c01 100644 --- a/pandas/tseries/holiday.py +++ b/pandas/tseries/holiday.py @@ -7,7 +7,7 @@ from pandas.errors import PerformanceWarning -from pandas import DateOffset, Series, Timestamp, date_range +from pandas import DateOffset, DatetimeIndex, Series, Timestamp, concat, date_range from pandas.tseries.offsets import Day, Easter @@ -406,17 +406,14 @@ def holidays(self, start=None, end=None, return_name=False): start = Timestamp(start) end = Timestamp(end) - holidays = None # If we don't have a cache or the dates are outside the prior cache, we # get them again if self._cache is None or start < self._cache[0] or end > self._cache[1]: - for rule in self.rules: - rule_holidays = rule.dates(start, end, return_name=True) - - if holidays is None: - holidays = rule_holidays - else: - holidays = holidays.append(rule_holidays) + holidays = [rule.dates(start, end, return_name=True) for rule in self.rules] + if holidays: + holidays = concat(holidays) + else: + holidays = Series(index=DatetimeIndex([]), dtype=object) self._cache = (start, end, holidays.sort_index())