diff options
-rw-r--r-- | numpy/core/src/multiarray/_datetime.h | 3 | ||||
-rw-r--r-- | numpy/core/src/multiarray/datetime.c | 58 | ||||
-rw-r--r-- | numpy/core/src/multiarray/descriptor.c | 3 | ||||
-rw-r--r-- | numpy/core/tests/test_deprecations.py | 16 |
4 files changed, 74 insertions, 6 deletions
diff --git a/numpy/core/src/multiarray/_datetime.h b/numpy/core/src/multiarray/_datetime.h index 345aed28a..3db1254d4 100644 --- a/numpy/core/src/multiarray/_datetime.h +++ b/numpy/core/src/multiarray/_datetime.h @@ -175,7 +175,8 @@ convert_datetime_metadata_to_tuple(PyArray_DatetimeMetaData *meta); */ NPY_NO_EXPORT int convert_datetime_metadata_tuple_to_datetime_metadata(PyObject *tuple, - PyArray_DatetimeMetaData *out_meta); + PyArray_DatetimeMetaData *out_meta, + npy_bool from_pickle); /* * Gets a tzoffset in minutes by calling the fromutc() function on diff --git a/numpy/core/src/multiarray/datetime.c b/numpy/core/src/multiarray/datetime.c index 69bff071b..93babe8bd 100644 --- a/numpy/core/src/multiarray/datetime.c +++ b/numpy/core/src/multiarray/datetime.c @@ -1804,7 +1804,8 @@ convert_datetime_metadata_to_tuple(PyArray_DatetimeMetaData *meta) */ NPY_NO_EXPORT int convert_datetime_metadata_tuple_to_datetime_metadata(PyObject *tuple, - PyArray_DatetimeMetaData *out_meta) + PyArray_DatetimeMetaData *out_meta, + npy_bool from_pickle) { char *basestr = NULL; Py_ssize_t len = 0, tuple_size; @@ -1859,7 +1860,56 @@ convert_datetime_metadata_tuple_to_datetime_metadata(PyObject *tuple, return -1; } - if (tuple_size == 4) { + /* + * The event metadata was removed way back in numpy 1.7 (cb4545), but was + * not deprecated at the time. + */ + + /* (unit, num, event) */ + if (tuple_size == 3) { + /* Numpy 1.14, 2017-08-11 */ + if (DEPRECATE( + "When passing a 3-tuple as (unit, num, event), the event " + "is ignored (since 1.7) - use (unit, num) instead") < 0) { + return -1; + } + } + /* (unit, num, den, event) */ + else if (tuple_size == 4) { + PyObject *event = PyTuple_GET_ITEM(tuple, 3); + if (from_pickle) { + /* if (event == 1) */ + PyObject *one = PyLong_FromLong(1); + int equal_one; + if (one == NULL) { + return -1; + } + equal_one = PyObject_RichCompareBool(event, one, Py_EQ); + if (equal_one == -1) { + return -1; + } + + /* if the event data is not 1, it had semantics different to how + * datetime types now behave, which are no longer respected. + */ + if (!equal_one) { + if (PyErr_WarnEx(PyExc_UserWarning, + "Loaded pickle file contains non-default event data " + "for a datetime type, which has been ignored since 1.7", + 1) < 0) { + return -1; + } + } + } + else if (event != Py_None) { + /* Numpy 1.14, 2017-08-11 */ + if (DEPRECATE( + "When passing a 4-tuple as (unit, num, den, event), the " + "event argument is ignored (since 1.7), so should be None" + ) < 0) { + return -1; + } + } den = PyInt_AsLong(PyTuple_GET_ITEM(tuple, 2)); if (error_converting(den)) { return -1; @@ -1897,8 +1947,8 @@ convert_pyobject_to_datetime_metadata(PyObject *obj, Py_ssize_t len = 0; if (PyTuple_Check(obj)) { - return convert_datetime_metadata_tuple_to_datetime_metadata(obj, - out_meta); + return convert_datetime_metadata_tuple_to_datetime_metadata( + obj, out_meta, NPY_FALSE); } /* Get an ASCII string */ diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index 32b926ae8..1ae6e34a6 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -2887,7 +2887,8 @@ arraydescr_setstate(PyArray_Descr *self, PyObject *args) if (convert_datetime_metadata_tuple_to_datetime_metadata( PyTuple_GET_ITEM(metadata, 1), - &temp_dt_data) < 0) { + &temp_dt_data, + NPY_TRUE) < 0) { return NULL; } diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py index 42871a77d..e3e8c32f9 100644 --- a/numpy/core/tests/test_deprecations.py +++ b/numpy/core/tests/test_deprecations.py @@ -434,5 +434,21 @@ class TestNPY_CHAR(_DeprecationTestCase): assert_(npy_char_deprecation() == 'S1') +class TestDatetimeEvent(_DeprecationTestCase): + # 2017-08-11, 1.14.0 + def test_3_tuple(self): + for cls in (np.datetime64, np.timedelta64): + # two valid uses - (unit, num) and (unit, num, den, None) + self.assert_not_deprecated(cls, args=(1, ('ms', 2))) + self.assert_not_deprecated(cls, args=(1, ('ms', 2, 1, None))) + + # trying to use the event argument, removed in 1.7.0, is deprecated + # it used to be a uint8 + self.assert_deprecated(cls, args=(1, ('ms', 2, 'event'))) + self.assert_deprecated(cls, args=(1, ('ms', 2, 63))) + self.assert_deprecated(cls, args=(1, ('ms', 2, 1, 'event'))) + self.assert_deprecated(cls, args=(1, ('ms', 2, 1, 63))) + + if __name__ == "__main__": run_module_suite() |