-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
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
Conversation
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 |
Can you add tests for the behavior this fixes |
a29e232
to
9ad40d5
Compare
if holidays is None: | ||
holidays = rule_holidays | ||
else: | ||
holidays = holidays.append(rule_holidays) |
There was a problem hiding this comment.
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.
96bcd89
to
10b2759
Compare
CI is passing! 🎉 |
doc/source/whatsnew/v1.0.1.rst
Outdated
@@ -16,6 +16,8 @@ including other versions of pandas. | |||
Bug fixes | |||
~~~~~~~~~ | |||
|
|||
- Bug in :meth:`AbstractHolidayCalendar.holidays` when no rules were defined (:issue:`31415`) |
There was a problem hiding this comment.
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
doc/source/whatsnew/v1.0.1.rst
Outdated
@@ -16,6 +16,8 @@ including other versions of pandas. | |||
Bug fixes | |||
~~~~~~~~~ | |||
|
|||
- Bug in :meth:`AbstractHolidayCalendar.holidays` when no rules were defined (:issue:`31415`) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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:
pandas/pandas/tseries/holiday.py
Lines 426 to 429 in ba08390
if return_name: | |
return holidays | |
else: | |
return holidays.index |
doc/source/whatsnew/v1.0.1.rst
Outdated
@@ -16,6 +16,8 @@ including other versions of pandas. | |||
Bug fixes | |||
~~~~~~~~~ | |||
|
|||
- Bug in :meth:`AbstractHolidayCalendar.holidays` when no rules were defined (:issue:`31415`) |
There was a problem hiding this comment.
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): |
There was a problem hiding this comment.
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
pandas/tseries/holiday.py
Outdated
# 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)) |
There was a problem hiding this comment.
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
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. |
0e62415
to
3d84f8b
Compare
I rebased on master but I think I'm now getting an unrelated failure bout
|
Possibly related to #31506? |
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 |
There was a problem hiding this comment.
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?
ping @jreback! |
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`) |
There was a problem hiding this comment.
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
Closes #31415
black pandas
git diff upstream/master -u -- "*.py" | flake8 --diff