From b21cec161bee07c7c150f163ab2457d8e54e7423 Mon Sep 17 00:00:00 2001 From: sinhrks Date: Sat, 12 Dec 2015 11:22:10 +0900 Subject: [PATCH] CLN: frequency.get_offset always return copy --- doc/source/whatsnew/v0.18.0.txt | 2 ++ pandas/tseries/frequencies.py | 30 ++++++++++-------------- pandas/tseries/offsets.py | 22 +----------------- pandas/tseries/tests/test_offsets.py | 34 +++++++++++++--------------- 4 files changed, 31 insertions(+), 57 deletions(-) diff --git a/doc/source/whatsnew/v0.18.0.txt b/doc/source/whatsnew/v0.18.0.txt index 733e86e38e47a..56a129fddee16 100644 --- a/doc/source/whatsnew/v0.18.0.txt +++ b/doc/source/whatsnew/v0.18.0.txt @@ -252,6 +252,8 @@ Deprecations For example, instead of ``s.rolling(window=5,freq='D').max()`` to get the max value on a rolling 5 Day window, one could use ``s.resample('D',how='max').rolling(window=5).max()``, which first resamples the data to daily data, then provides a rolling 5 day window. +- ``pd.tseries.frequencies.get_offset_name`` function is deprecated. Use offset's ``.freqstr`` property as alternative (:issue:`11192`) + .. _whatsnew_0180.prior_deprecations: Removal of prior version deprecations/changes diff --git a/pandas/tseries/frequencies.py b/pandas/tseries/frequencies.py index 07546a76be431..fced24c706246 100644 --- a/pandas/tseries/frequencies.py +++ b/pandas/tseries/frequencies.py @@ -286,8 +286,7 @@ def _get_freq_str(base, mult=1): MonthEnd, BMonthBegin, BMonthEnd, QuarterBegin, QuarterEnd, BQuarterBegin, BQuarterEnd, YearBegin, YearEnd, - BYearBegin, BYearEnd, _make_offset - ) + BYearBegin, BYearEnd, prefix_mapping) try: cday = CDay() except NotImplementedError: @@ -547,13 +546,17 @@ def get_offset(name): if name not in _offset_map: try: - # generate and cache offset - offset = _make_offset(name) + split = name.split('-') + klass = prefix_mapping[split[0]] + # handles case where there's no suffix (and will TypeError if too many '-') + offset = klass._from_name(*split[1:]) except (ValueError, TypeError, KeyError): # bad prefix or suffix raise ValueError('Bad rule name requested: %s.' % name) + # cache _offset_map[name] = offset - return _offset_map[name] + # do not return cache because it's mutable + return _offset_map[name].copy() getOffset = get_offset @@ -567,19 +570,10 @@ def get_offset_name(offset): -------- get_offset_name(BMonthEnd(1)) --> 'EOM' """ - if offset is None: - raise ValueError("Offset can't be none!") - # Hack because this is what it did before... - if isinstance(offset, BDay): - if offset.n != 1: - raise ValueError('Bad rule given: %s.' % 'BusinessDays') - else: - return offset.rule_code - try: - return offset.freqstr - except AttributeError: - # Bad offset, give useful error. - raise ValueError('Bad rule given: %s.' % offset) + + msg = "get_offset_name(offset) is deprecated. Use offset.freqstr instead" + warnings.warn(msg, FutureWarning, stacklevel=2) + return offset.freqstr def get_legacy_offset_name(offset): diff --git a/pandas/tseries/offsets.py b/pandas/tseries/offsets.py index 82ea9eebaefa8..5beb65f0ba640 100644 --- a/pandas/tseries/offsets.py +++ b/pandas/tseries/offsets.py @@ -309,8 +309,6 @@ def _params(self): return params def __repr__(self): - if hasattr(self, '_named'): - return self._named className = getattr(self, '_outputName', type(self).__name__) exclude = set(['n', 'inc', 'normalize']) attrs = [] @@ -346,10 +344,7 @@ def __repr__(self): @property def name(self): - if hasattr(self, '_named'): - return self._named - else: - return self.rule_code + return self.rule_code def __eq__(self, other): if other is None: @@ -516,8 +511,6 @@ class BusinessMixin(object): # attributes on each object rather than the existing behavior of iterating # over internal ``__dict__`` def __repr__(self): - if hasattr(self, '_named'): - return self._named className = getattr(self, '_outputName', self.__class__.__name__) if abs(self.n) != 1: @@ -2668,16 +2661,3 @@ def generate_range(start=None, end=None, periods=None, ]) prefix_mapping['N'] = Nano - -def _make_offset(key): - """Gets offset based on key. KeyError if prefix is bad, ValueError if - suffix is bad. All handled by `get_offset` in tseries/frequencies. Not - public.""" - if key is None: - return None - split = key.split('-') - klass = prefix_mapping[split[0]] - # handles case where there's no suffix (and will TypeError if too many '-') - obj = klass._from_name(*split[1:]) - obj._named = key - return obj diff --git a/pandas/tseries/tests/test_offsets.py b/pandas/tseries/tests/test_offsets.py index 30fadfac2a3ae..70e0cc288458e 100644 --- a/pandas/tseries/tests/test_offsets.py +++ b/pandas/tseries/tests/test_offsets.py @@ -16,7 +16,7 @@ QuarterBegin, BQuarterBegin, BMonthBegin, DateOffset, Week, YearBegin, YearEnd, Hour, Minute, Second, Day, Micro, Milli, Nano, Easter, WeekOfMonth, format, ole2datetime, QuarterEnd, to_datetime, normalize_date, - get_offset, get_offset_name, get_standard_freq) + get_offset, get_standard_freq) from pandas import Series from pandas.tseries.frequencies import _offset_map, get_freq_code, _get_freq_str @@ -3593,19 +3593,20 @@ def test_compare_ticks(self): class TestOffsetNames(tm.TestCase): def test_get_offset_name(self): - assertRaisesRegexp(ValueError, 'Bad rule.*BusinessDays', get_offset_name, BDay(2)) - - assert get_offset_name(BDay()) == 'B' - assert get_offset_name(BMonthEnd()) == 'BM' - assert get_offset_name(Week(weekday=0)) == 'W-MON' - assert get_offset_name(Week(weekday=1)) == 'W-TUE' - assert get_offset_name(Week(weekday=2)) == 'W-WED' - assert get_offset_name(Week(weekday=3)) == 'W-THU' - assert get_offset_name(Week(weekday=4)) == 'W-FRI' - - self.assertEqual(get_offset_name(LastWeekOfMonth(weekday=WeekDay.SUN)), "LWOM-SUN") - self.assertEqual(get_offset_name(makeFY5253LastOfMonthQuarter(weekday=1, startingMonth=3, qtr_with_extra_week=4)),"REQ-L-MAR-TUE-4") - self.assertEqual(get_offset_name(makeFY5253NearestEndMonthQuarter(weekday=1, startingMonth=3, qtr_with_extra_week=3)), "REQ-N-MAR-TUE-3") + self.assertEqual(BDay().freqstr, 'B') + self.assertEqual(BDay(2).freqstr, '2B') + self.assertEqual(BMonthEnd().freqstr, 'BM') + self.assertEqual(Week(weekday=0).freqstr, 'W-MON') + self.assertEqual(Week(weekday=1).freqstr, 'W-TUE') + self.assertEqual(Week(weekday=2).freqstr, 'W-WED') + self.assertEqual(Week(weekday=3).freqstr, 'W-THU') + self.assertEqual(Week(weekday=4).freqstr, 'W-FRI') + + self.assertEqual(LastWeekOfMonth(weekday=WeekDay.SUN).freqstr, "LWOM-SUN") + self.assertEqual(makeFY5253LastOfMonthQuarter(weekday=1, startingMonth=3, qtr_with_extra_week=4).freqstr, + "REQ-L-MAR-TUE-4") + self.assertEqual(makeFY5253NearestEndMonthQuarter(weekday=1, startingMonth=3, qtr_with_extra_week=3).freqstr, + "REQ-N-MAR-TUE-3") def test_get_offset(): assertRaisesRegexp(ValueError, "rule.*GIBBERISH", get_offset, 'gibberish') @@ -3834,13 +3835,10 @@ def test_str_for_named_is_name(self): names += ['W-' + day for day in days] names += ['WOM-' + week + day for week in ('1', '2', '3', '4') for day in days] - #singletons - names += ['S', 'T', 'U', 'BM', 'BMS', 'BQ', 'QS'] # No 'Q' _offset_map.clear() for name in names: offset = get_offset(name) - self.assertEqual(repr(offset), name) - self.assertEqual(str(offset), name) + self.assertEqual(offset.freqstr, name) def get_utc_offset_hours(ts):