diff --git a/doc/source/release.rst b/doc/source/release.rst index 153b4c4f464be..d761f1f008754 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -184,6 +184,8 @@ pandas 0.13 - Fix arithmetic with series/datetimeindex and ``np.timedelta64`` not working the same (:issue:`4134`) and buggy timedelta in numpy 1.6 (:issue:`4135`) - Fix bug in ``pd.read_clipboard`` on windows with PY3 (:issue:`4561`); not decoding properly + - ``tslib.get_period_field()`` and ``tslib.get_period_field_arr()`` now raise + if code argument out of range (:issue:`4519`, :issue:`4520`) pandas 0.12 =========== diff --git a/pandas/tests/test_tseries.py b/pandas/tests/test_tseries.py index 1ed6dd4469f4d..6175b358a925c 100644 --- a/pandas/tests/test_tseries.py +++ b/pandas/tests/test_tseries.py @@ -700,6 +700,16 @@ def test_to_datetime_bijective(self): self.assertEqual(Timestamp(Timestamp.max.to_pydatetime()).value/1000, Timestamp.max.value/1000) self.assertEqual(Timestamp(Timestamp.min.to_pydatetime()).value/1000, Timestamp.min.value/1000) +class TestPeriodField(unittest.TestCase): + + def test_get_period_field_raises_on_out_of_range(self): + from pandas import tslib + self.assertRaises(ValueError, tslib.get_period_field, -1, 0, 0) + + def test_get_period_field_array_raises_on_out_of_range(self): + from pandas import tslib + self.assertRaises(ValueError, tslib.get_period_field_arr, -1, np.empty(1), 0) + if __name__ == '__main__': import nose nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'], diff --git a/pandas/tslib.pyx b/pandas/tslib.pyx index 698d9a81af387..18917fdd82d1b 100644 --- a/pandas/tslib.pyx +++ b/pandas/tslib.pyx @@ -2419,6 +2419,8 @@ ctypedef int (*accessor)(int64_t ordinal, int freq) except INT32_MIN def get_period_field(int code, int64_t value, int freq): cdef accessor f = _get_accessor_func(code) + if f is NULL: + raise ValueError('Unrecognized period code: %d' % code) return f(value, freq) def get_period_field_arr(int code, ndarray[int64_t] arr, int freq): @@ -2428,6 +2430,8 @@ def get_period_field_arr(int code, ndarray[int64_t] arr, int freq): accessor f f = _get_accessor_func(code) + if f is NULL: + raise ValueError('Unrecognized period code: %d' % code) sz = len(arr) out = np.empty(sz, dtype=np.int64) @@ -2462,8 +2466,7 @@ cdef accessor _get_accessor_func(int code): return &pday_of_year elif code == 10: return &pweekday - else: - raise ValueError('Unrecognized code: %s' % code) + return NULL def extract_ordinals(ndarray[object] values, freq):