Skip to content

Fix bug in calculation of holidays #31416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 9, 2020
Merged

Conversation

dhirschfeld
Copy link
Contributor

@dhirschfeld dhirschfeld commented Jan 29, 2020

Closes #31415

  • closes #xxxx
  • tests added / passed
  • passes black pandas
  • passes git diff upstream/master -u -- "*.py" | flake8 --diff
  • whatsnew entry

@pep8speaks
Copy link

pep8speaks commented Jan 29, 2020

Hello @dhirschfeld! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

There are currently no PEP 8 issues detected in this Pull Request. Cheers! 🍻

Comment last updated at 2020-02-07 04:22:19 UTC

@jbrockmendel
Copy link
Member

Can you add tests for the behavior this fixes

@dhirschfeld dhirschfeld force-pushed the patch-4 branch 2 times, most recently from a29e232 to 9ad40d5 Compare January 30, 2020 13:47
if holidays is None:
holidays = rule_holidays
else:
holidays = holidays.append(rule_holidays)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation also has the benefit of doing a single concat outside the loop rather than an O(N²) append on each iteration.

@dhirschfeld dhirschfeld force-pushed the patch-4 branch 2 times, most recently from 96bcd89 to 10b2759 Compare January 31, 2020 06:01
@dhirschfeld
Copy link
Contributor Author

CI is passing! 🎉

@@ -16,6 +16,8 @@ including other versions of pandas.
Bug fixes
~~~~~~~~~

- Bug in :meth:`AbstractHolidayCalendar.holidays` when no rules were defined (:issue:`31415`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this change between 0.25.X and 1.0.0? If not should target 1.1.0 instead of 1.0.1

@@ -16,6 +16,8 @@ including other versions of pandas.
Bug fixes
~~~~~~~~~

- Bug in :meth:`AbstractHolidayCalendar.holidays` when no rules were defined (:issue:`31415`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this bug new between 0.25.x and 1.0.0? If not should target 1.1.0 instead of 1.0.1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this bug has been present for the last 6 years. I don't think the AbstractHolidayCalendar functionality gets all that much use and this is a particular corner case.

Given that this PR fixes a bug and changes no apis or behaviours, other than returning a sensible value instead of throwing an unintended exception, I think this should get in the soonest possible release which IIUC would be 1.0.1.

I'm not sure why when the bug was introduced should have any bearing on when it can be fixed. I think it's fine to fix bugs which don't change any apis or behaviours in patch releases - I think this is exactly what patch releases are for!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dhirschfeld pls move to 1.1 whatsnew

if holidays:
holidays = concat(holidays)
else:
holidays = Series(index=DatetimeIndex([]), dtype=object)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't holidays typically return a DatetimeIndex ? Should maintain the same type even when empty

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internally, the holidays are constructed with return_name=True which returns a Series with the holiday names as values:

In [7]: USFederalHolidayCalendar().holidays('01-Jan-2020', '01-Apr-2020', return_name=True)
Out[7]: 
2020-01-01                 New Years Day
2020-01-20    Martin Luther King Jr. Day
2020-02-17                Presidents Day
dtype: object

Only if return_name=False are the values striped at the end of the method - behaviour which remains unchanged from master:

if return_name:
return holidays
else:
return holidays.index

@WillAyd WillAyd added the Datetime Datetime data dtype label Jan 31, 2020
@@ -16,6 +16,8 @@ including other versions of pandas.
Bug fixes
~~~~~~~~~

- Bug in :meth:`AbstractHolidayCalendar.holidays` when no rules were defined (:issue:`31415`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dhirschfeld pls move to 1.1 whatsnew



def test_no_holidays_calendar():
class NoHolidaysCalendar(AbstractHolidayCalendar):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add the issue number here as a comment

# 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)
holidays.append(rule.dates(start, end, return_name=True))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you re-write as a list-comprehension

@jreback jreback added the Frequency DateOffsets label Feb 1, 2020
@jreback
Copy link
Contributor

jreback commented Feb 2, 2020

code change looks fine. I think you need to isort the files you change. btw we have a pre-commit hook for this (pip install precommit turns it on).

merge master and ping on green.

@dhirschfeld dhirschfeld force-pushed the patch-4 branch 4 times, most recently from 0e62415 to 3d84f8b Compare February 3, 2020 00:11
@dhirschfeld
Copy link
Contributor Author

I rebased on master but I think I'm now getting an unrelated failure bout libindex:

black --version
black, version 19.10b0
Checking black formatting
All done! ✨ 🍰 ✨
941 files would be left unchanged.
Checking black formatting DONE
flake8 --version
3.7.9 (flake8-comprehensions: 3.2.2, mccabe: 0.6.1, pycodestyle: 2.5.0, pyflakes: 2.1.1) CPython 3.7.6 on Linux
Linting .py code
##[error]./pandas/core/series.py:1025:9:F821:undefined name 'libindex'
##[error]./pandas/core/series.py:1108:17:F821:undefined name 'libindex'
Linting .py code DONE

@dhirschfeld
Copy link
Contributor Author

Possibly related to #31506?

@dhirschfeld dhirschfeld closed this Feb 4, 2020
@dhirschfeld dhirschfeld reopened this Feb 4, 2020
@dhirschfeld
Copy link
Contributor Author

ping @jreback - rebased on (the latest) master and the tests are passing! 🎉


cal = NoHolidaysCalendar()
holidays = cal.holidays(Timestamp("01-Jan-2020"), Timestamp("01-Jan-2021"))
assert holidays.empty
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you use tm.assert_series_equal here and construct an empty Series with a DTI?

@dhirschfeld
Copy link
Contributor Author

ping @jreback!

@jreback jreback added this to the 1.1 milestone Feb 9, 2020
@jreback jreback merged commit c4e8eb3 into pandas-dev:master Feb 9, 2020
@jreback
Copy link
Contributor

jreback commented Feb 9, 2020

thanks @dhirschfeld very nice

@@ -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`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We ought to limit notes in the Other section if at all possible if someone wants to try to classify these better

cc @pandas-dev/pandas-core

@dhirschfeld dhirschfeld deleted the patch-4 branch February 9, 2020 23:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Datetime Datetime data dtype Frequency DateOffsets
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug in AbstractHolidayCalendar.holidays
5 participants