-
-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Prevent passing invalid kwds to DateOffset constructors #18226
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
Changes from 1 commit
b9fe60e
f10a1c6
807d769
687e3b7
d5443ca
5e5e0c0
17f7b5a
3834ef8
1c54e96
0e37a24
a572368
d0ff381
409dbd0
6a9233e
4406df8
44891cd
573abb6
c6cc8bc
a68f4a7
c8224c1
55779d8
d5b8302
b54e26b
fade4a2
38c2238
fe895ff
11ba1a9
bc90a19
0b3dca0
9c841fc
adee395
43dc17e
4ff8c22
d261be9
b4b9e15
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import inspect | ||
import os | ||
from distutils.version import LooseVersion | ||
from datetime import date, datetime, timedelta | ||
|
@@ -17,7 +18,7 @@ | |
get_offset, get_standard_freq) | ||
from pandas.core.indexes.datetimes import ( | ||
_to_m8, DatetimeIndex, _daterange_cache) | ||
from pandas._libs.tslibs.offsets import WeekDay, CacheableOffset | ||
from pandas._libs.tslibs.offsets import WeekDay, CacheableOffset, _rd_kwds | ||
from pandas.tseries.offsets import (BDay, CDay, BQuarterEnd, BMonthEnd, | ||
BusinessHour, WeekOfMonth, CBMonthEnd, | ||
CustomBusinessHour, | ||
|
@@ -4899,3 +4900,27 @@ def test_all_offset_classes(self): | |
first = Timestamp(test_values[0], tz='US/Eastern') + offset() | ||
second = Timestamp(test_values[1], tz='US/Eastern') | ||
assert first == second | ||
|
||
|
||
# --------------------------------------------------------------------- | ||
|
||
offset_classes = [getattr(offsets, x) for x in dir(offsets)] | ||
offset_classes = [x for x in offset_classes if inspect.isclass(x) and | ||
issubclass(x, DateOffset)] | ||
|
||
|
||
def test_valid_attributes(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. parameterize this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. |
||
# check that we cannot create e.g. MonthEnd(weeks=3) | ||
month_classes = [x for x in offset_classes if | ||
issubclass(x, offsets.MonthOffset)] | ||
|
||
for cls in month_classes: | ||
for kwd in _rd_kwds: | ||
with pytest.raises(TypeError): | ||
cls(**{kwd: 3}) | ||
|
||
tick_classes = [x for x in offset_classes if issubclass(x, offsets.Tick)] | ||
for cls in tick_classes: | ||
for kwd in _rd_kwds: | ||
with pytest.raises(TypeError): | ||
cls(**{kwd: 4}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -913,6 +913,13 @@ def next_bday(self): | |
class MonthOffset(SingleConstructorOffset): | ||
_adjust_dst = True | ||
|
||
def __init__(self, n=1, normalize=False): | ||
self.n = n | ||
self.normalize = normalize | ||
self._offset = timedelta(1) | ||
self._use_relativedelta = False | ||
self.kwds = {} | ||
|
||
@property | ||
def name(self): | ||
if self.isAnchored: | ||
|
@@ -2471,6 +2478,13 @@ class Easter(DateOffset): | |
""" | ||
_adjust_dst = True | ||
|
||
def __init__(self, n=1, normalize=False): | ||
self.n = n | ||
self.normalize = normalize | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same (and for other ones you are adding) |
||
self._offset = timedelta(1) | ||
self._use_relativedelta = False | ||
self.kwds = {} | ||
|
||
@apply_wraps | ||
def apply(self, other): | ||
currentEaster = easter(other.year) | ||
|
@@ -2515,6 +2529,14 @@ class Tick(SingleConstructorOffset): | |
_inc = Timedelta(microseconds=1000) | ||
_prefix = 'undefined' | ||
|
||
def __init__(self, n=1, normalize=False): | ||
# TODO: do Tick classes with normalize=True make sense? | ||
self.n = n | ||
self.normalize = normalize | ||
self._offset = timedelta(1) | ||
self._use_relativedelta = False | ||
self.kwds = {} | ||
|
||
__gt__ = _tick_comp(operator.gt) | ||
__ge__ = _tick_comp(operator.ge) | ||
__lt__ = _tick_comp(operator.lt) | ||
|
@@ -2573,6 +2595,7 @@ def delta(self): | |
def nanos(self): | ||
return delta_to_nanoseconds(self.delta) | ||
|
||
# TODO: Should Tick have its own apply_index? | ||
def apply(self, other): | ||
# Timestamp can handle tz and nano sec, thus no need to use apply_wraps | ||
if isinstance(other, Timestamp): | ||
|
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 already list the classes somewhere in this module iirc.
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.
Looks like a fixture defined in conftest, but only used in test_offsets. Instead of checking for the correct types it assume that
offsets.__all__
is exactly what it needs. Mind if I a) put it directly test_offsets and b) make it check explicitly to avoid future footgunning?