-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Bitesize offsets #17318
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
Bitesize offsets #17318
Changes from 5 commits
3822f99
309dd54
87f659b
3d1e6f8
0f5b2a6
c66b842
f016855
1fbe61d
030afde
2ca3bf2
1f4b5cd
d1e9161
3d3c2a6
24f6eee
c22ee24
e52a791
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -322,37 +322,42 @@ def _params(self): | |
|
||
def __repr__(self): | ||
className = getattr(self, '_outputName', type(self).__name__) | ||
|
||
if abs(self.n) != 1: | ||
plural = 's' | ||
else: | ||
plural = '' | ||
|
||
n_str = "" | ||
if self.n != 1: | ||
n_str = "%s * " % self.n | ||
|
||
out = '<%s' % n_str + className + plural + self._repr_attrs() + '>' | ||
return out | ||
|
||
# TODO: Combine this with BusinessMixin version by defining a whitelisted | ||
# set of attributes on each object rather than the existing behavior of | ||
# iterating over internal ``__dict__`` | ||
def _repr_attrs(self): | ||
exclude = set(['n', 'inc', 'normalize']) | ||
attrs = [] | ||
for attr in sorted(self.__dict__): | ||
if ((attr == 'kwds' and len(self.kwds) == 0) or | ||
attr.startswith('_')): | ||
if attr.startswith('_'): | ||
continue | ||
elif attr == 'kwds': | ||
elif attr == 'kwds': # TODO: get rid of this | ||
kwds_new = {} | ||
for key in self.kwds: | ||
if not hasattr(self, key): | ||
kwds_new[key] = self.kwds[key] | ||
if len(kwds_new) > 0: | ||
attrs.append('='.join((attr, repr(kwds_new)))) | ||
else: | ||
if attr not in exclude: | ||
attrs.append('='.join((attr, repr(getattr(self, attr))))) | ||
|
||
plural = '' | ||
if abs(self.n) != 1: | ||
plural = 's' | ||
attrs.append('kwds=%s' % (kwds_new)) | ||
elif attr not in exclude: | ||
value = getattr(self, attr) | ||
attrs.append('%s=%s' % (attr, value)) | ||
|
||
n_str = '' | ||
if self.n != 1: | ||
n_str = '{n} * '.format(n=self.n) | ||
|
||
attrs_str = '' | ||
out = '' | ||
if attrs: | ||
attrs_str = ': ' + ', '.join(attrs) | ||
|
||
repr_content = ''.join([n_str, className, plural, attrs_str]) | ||
out = '<{content}>'.format(content=repr_content) | ||
out += ': ' + ', '.join(attrs) | ||
return out | ||
|
||
@property | ||
|
@@ -506,8 +511,18 @@ def freqstr(self): | |
else: | ||
fstr = code | ||
|
||
try: | ||
if self._offset: | ||
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. is this still needed? 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. Yes. Not all subclasses define the |
||
fstr += self._offset_str() | ||
except AttributeError: | ||
# TODO: standardize `_offset` vs `offset` naming convention | ||
pass | ||
|
||
return fstr | ||
|
||
def _offset_str(self): | ||
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. try not to add new things which just clutter up 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.
|
||
return '' | ||
|
||
@property | ||
def nanos(self): | ||
raise ValueError("{name} is a non-fixed frequency".format(name=self)) | ||
|
@@ -526,24 +541,6 @@ def _from_name(cls, suffix=None): | |
class BusinessMixin(object): | ||
""" mixin to business types to provide related functions """ | ||
|
||
# TODO: Combine this with DateOffset by defining a whitelisted set of | ||
# attributes on each object rather than the existing behavior of iterating | ||
# over internal ``__dict__`` | ||
def __repr__(self): | ||
className = getattr(self, '_outputName', self.__class__.__name__) | ||
|
||
plural = '' | ||
if abs(self.n) != 1: | ||
plural = 's' | ||
|
||
n_str = '' | ||
if self.n != 1: | ||
n_str = '{n} * '.format(n=self.n) | ||
|
||
repr_content = ''.join([n_str, className, plural, self._repr_attrs()]) | ||
out = '<{content}>'.format(content=repr_content) | ||
return out | ||
|
||
def _repr_attrs(self): | ||
if self.offset: | ||
attrs = ['offset={offset!r}'.format(offset=self.offset)] | ||
|
@@ -593,23 +590,7 @@ def __init__(self, n=1, normalize=False, **kwds): | |
self.normalize = normalize | ||
self.kwds = kwds | ||
self.offset = kwds.get('offset', timedelta(0)) | ||
|
||
@property | ||
def freqstr(self): | ||
try: | ||
code = self.rule_code | ||
except NotImplementedError: | ||
return repr(self) | ||
|
||
if self.n != 1: | ||
fstr = '{n}{code}'.format(n=self.n, code=code) | ||
else: | ||
fstr = code | ||
|
||
if self.offset: | ||
fstr += self._offset_str() | ||
|
||
return fstr | ||
self._offset = self.offset # alias for backward compat | ||
|
||
def _offset_str(self): | ||
def get_str(td): | ||
|
@@ -642,9 +623,6 @@ def get_str(td): | |
else: | ||
return '+' + repr(self.offset) | ||
|
||
def isAnchored(self): | ||
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. pls don't simply remove things. instead in a separate PR deprecate them. 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. The method is still available. It's inherited verbatim from the parent class. |
||
return (self.n == 1) | ||
|
||
@apply_wraps | ||
def apply(self, other): | ||
if isinstance(other, datetime): | ||
|
@@ -709,6 +687,7 @@ def __init__(self, **kwds): | |
kwds['end'] = self._validate_time(kwds.get('end', '17:00')) | ||
self.kwds = kwds | ||
self.offset = kwds.get('offset', timedelta(0)) | ||
self._offset = self.offset # alias for backward compat | ||
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. why don't you just define 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. I definitely tried this, don't remember off the top why it didn't work. Maybe when the caffeine kicks in. 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. ok, let's try that type of refactor again. |
||
self.start = kwds.get('start', '09:00') | ||
self.end = kwds.get('end', '17:00') | ||
|
||
|
@@ -775,7 +754,7 @@ def _get_business_hours_by_sec(self): | |
Return business hours in a day by seconds. | ||
""" | ||
if self._get_daytime_flag(): | ||
# create dummy datetime to calcurate businesshours in a day | ||
# create dummy datetime to calculate businesshours in a day | ||
dtstart = datetime(2014, 4, 1, self.start.hour, self.start.minute) | ||
until = datetime(2014, 4, 1, self.end.hour, self.end.minute) | ||
return tslib.tot_seconds(until - dtstart) | ||
|
@@ -810,7 +789,7 @@ def rollforward(self, dt): | |
|
||
@apply_wraps | ||
def apply(self, other): | ||
# calcurate here because offset is not immutable | ||
# calculate here because offset is not immutable | ||
daytime = self._get_daytime_flag() | ||
businesshours = self._get_business_hours_by_sec() | ||
bhdelta = timedelta(seconds=businesshours) | ||
|
@@ -859,7 +838,7 @@ def apply(self, other): | |
if n >= 0: | ||
bday_edge = self._prev_opening_time(other) | ||
bday_edge = bday_edge + bhdelta | ||
# calcurate remainder | ||
# calculate remainder | ||
bday_remain = result - bday_edge | ||
result = self._next_opening_time(other) | ||
result += bday_remain | ||
|
@@ -897,7 +876,7 @@ def onOffset(self, dt): | |
|
||
def _onOffset(self, dt, businesshours): | ||
""" | ||
Slight speedups using calcurated values | ||
Slight speedups using calculated values | ||
""" | ||
# if self.normalize and not _is_normalized(dt): | ||
# return False | ||
|
@@ -978,6 +957,7 @@ def __init__(self, n=1, normalize=False, weekmask='Mon Tue Wed Thu Fri', | |
self.normalize = normalize | ||
self.kwds = kwds | ||
self.offset = kwds.get('offset', timedelta(0)) | ||
self._offset = self.offset # alias for backward compat | ||
calendar, holidays = self.get_calendar(weekmask=weekmask, | ||
holidays=holidays, | ||
calendar=calendar) | ||
|
@@ -1378,9 +1358,6 @@ def _apply_index_days(self, i, roll): | |
class BusinessMonthEnd(MonthOffset): | ||
"""DateOffset increments between business EOM dates""" | ||
|
||
def isAnchored(self): | ||
return (self.n == 1) | ||
|
||
@apply_wraps | ||
def apply(self, other): | ||
n = self.n | ||
|
@@ -1471,6 +1448,7 @@ def __init__(self, n=1, normalize=False, weekmask='Mon Tue Wed Thu Fri', | |
self.normalize = normalize | ||
self.kwds = kwds | ||
self.offset = kwds.get('offset', timedelta(0)) | ||
self._offset = self.offset # alias for backward compat | ||
self.cbday = CustomBusinessDay(n=self.n, normalize=normalize, | ||
weekmask=weekmask, holidays=holidays, | ||
calendar=calendar, **kwds) | ||
|
@@ -1531,6 +1509,7 @@ def __init__(self, n=1, normalize=False, weekmask='Mon Tue Wed Thu Fri', | |
self.normalize = normalize | ||
self.kwds = kwds | ||
self.offset = kwds.get('offset', timedelta(0)) | ||
self._offset = self.offset # alias for backward compat | ||
self.cbday = CustomBusinessDay(n=self.n, normalize=normalize, | ||
weekmask=weekmask, holidays=holidays, | ||
calendar=calendar, **kwds) | ||
|
@@ -1985,16 +1964,6 @@ class QuarterEnd(QuarterOffset): | |
_default_startingMonth = 3 | ||
_prefix = 'Q' | ||
|
||
def __init__(self, n=1, normalize=False, **kwds): | ||
self.n = n | ||
self.normalize = normalize | ||
self.startingMonth = kwds.get('startingMonth', 3) | ||
|
||
self.kwds = kwds | ||
|
||
def isAnchored(self): | ||
return (self.n == 1 and self.startingMonth is not None) | ||
|
||
@apply_wraps | ||
def apply(self, other): | ||
n = self.n | ||
|
@@ -2030,9 +1999,6 @@ class QuarterBegin(QuarterOffset): | |
_from_name_startingMonth = 1 | ||
_prefix = 'QS' | ||
|
||
def isAnchored(self): | ||
return (self.n == 1 and self.startingMonth is not None) | ||
|
||
@apply_wraps | ||
def apply(self, other): | ||
n = self.n | ||
|
@@ -2660,9 +2626,6 @@ class Easter(DateOffset): | |
""" | ||
_adjust_dst = True | ||
|
||
def __init__(self, n=1, **kwds): | ||
super(Easter, self).__init__(n, **kwds) | ||
|
||
@apply_wraps | ||
def apply(self, other): | ||
currentEaster = easter(other.year) | ||
|
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 whole thing should just be moved to a separate function, much more clear this way
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.
Not sure what you're referring to as "this whole thing".
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 formatting function (e.g. repr should just call it, passing parameters in).