summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/include/numpy/ndarrayobject.h2
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src33
-rw-r--r--numpy/core/src/multiarray/descriptor.c26
3 files changed, 40 insertions, 21 deletions
diff --git a/numpy/core/include/numpy/ndarrayobject.h b/numpy/core/include/numpy/ndarrayobject.h
index 740f664cb..a8b4e160a 100644
--- a/numpy/core/include/numpy/ndarrayobject.h
+++ b/numpy/core/include/numpy/ndarrayobject.h
@@ -592,7 +592,7 @@ typedef struct {
} npy_timedeltastruct;
-#define PyDataType_GetDatetimeMetaData(descr) ((PyArray_DatetimeMetaData *)(PyCObject_AsVoidPtr(PyDict_GetItemString(((PyArray_Descr *)descr)->metadata, NPY_METADATA_DTSTR))))
+#define PyDataType_GetDatetimeMetaData(descr) (descr->metadata == NULL ? NULL : ((PyArray_DatetimeMetaData *)(PyCObject_AsVoidPtr(PyDict_GetItemString((descr->metadata, NPY_METADATA_DTSTR))))))
typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *);
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src
index b64d2585c..49f9cceaf 100644
--- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -158,7 +158,7 @@ static int
units since the epoch (1970-01-01T00:00:00Z) ignoring leap seconds.
*/
-static PyObject *
+NPY_NO_EXPORT PyObject *
PyDateTime_FromNormalized(npy_datetime val, NPY_DATETIMEUNIT base)
{
npy_datetimestruct ydate;
@@ -179,7 +179,7 @@ PyDateTime_FromNormalized(npy_datetime val, NPY_DATETIMEUNIT base)
Don't use this function if you care.
*/
-static PyObject *
+NPY_NO_EXPORT PyObject *
PyTimeDelta_FromNormalized(npy_timedelta val, NPY_DATETIMEUNIT base)
{
npy_timedeltastruct td;
@@ -194,11 +194,15 @@ PyTimeDelta_FromNormalized(npy_timedelta val, NPY_DATETIMEUNIT base)
}
-static PyObject *
+NPY_NO_EXPORT PyObject *
PyDateTime_FromInt64(datetime val, PyArray_Descr *descr)
{
PyArray_DatetimeMetaData *meta;
meta = PyDataType_GetDatetimeMetaData(descr);
+ if (meta == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "metadata not set for descriptor");
+ return NULL;
+ }
if (meta->events > 1) {
int events, rem, div;
@@ -232,11 +236,15 @@ PyDateTime_FromInt64(datetime val, PyArray_Descr *descr)
}
-static PyObject *
+NPY_NO_EXPORT PyObject *
PyTimeDelta_FromInt64(timedelta val, PyArray_Descr *descr)
{
PyArray_DatetimeMetaData *meta;
meta = PyDataType_GetDatetimeMetaData(descr);
+ if (meta == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "metadata not set for descriptor");
+ return NULL;
+ }
if (meta->events > 1) {
int events, rem, div;
@@ -262,7 +270,7 @@ PyTimeDelta_FromInt64(timedelta val, PyArray_Descr *descr)
-static npy_datetime
+NPY_NO_EXPORT npy_datetime
PyDateTime_AsNormalized(PyObject *obj, NPY_DATETIMEUNIT base)
{
npy_datetimestruct ydate;
@@ -299,7 +307,7 @@ PyDateTime_AsNormalized(PyObject *obj, NPY_DATETIMEUNIT base)
return PyArray_DatetimeStructToDatetime(base, &ydate);
}
-static npy_timedelta
+NPY_NO_EXPORT npy_timedelta
PyTimeDelta_AsNormalized(PyObject *obj, NPY_DATETIMEUNIT base)
{
npy_timedeltastruct td;
@@ -329,13 +337,18 @@ PyTimeDelta_AsNormalized(PyObject *obj, NPY_DATETIMEUNIT base)
*/
-static npy_datetime
+NPY_NO_EXPORT npy_datetime
PyDateTime_AsInt64(PyObject *obj, PyArray_Descr *descr)
{
PyArray_DatetimeMetaData *meta;
npy_datetime res;
meta = PyDataType_GetDatetimeMetaData(descr);
+ if (meta == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "metadata not set for descriptor");
+ return NULL;
+ }
+
if (meta->events > 1) {
datetime tmp;
@@ -357,12 +370,16 @@ PyDateTime_AsInt64(PyObject *obj, PyArray_Descr *descr)
}
-static timedelta
+NPY_NO_EXPORT timedelta
PyTimeDelta_AsInt64(PyObject *obj, PyArray_Descr *descr)
{
PyArray_DatetimeMetaData *meta;
npy_timedelta res;
meta = PyDataType_GetDatetimeMetaData(descr);
+ if (meta == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "metadata not set for descriptor");
+ return NULL;
+ }
if (meta->events > 1) {
timedelta tmp;
diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c
index 2bec10455..001617364 100644
--- a/numpy/core/src/multiarray/descriptor.c
+++ b/numpy/core/src/multiarray/descriptor.c
@@ -521,11 +521,12 @@ static int _multiples_table[16][4] = {
{60, 60000}, /* NPY_FR_m */
{NPY_FR_s, NPY_FR_ms},
{1000, 1000000}, /* >=NPY_FR_s */
+ {0, 0}
};
/* Translate divisors into multiples of smaller units */
-static void
+static int
_convert_divisor_to_multiple(PyArray_DatetimeMetaData *meta)
{
int i, num, ind;
@@ -542,7 +543,7 @@ _convert_divisor_to_multiple(PyArray_DatetimeMetaData *meta)
else if (meta->base > NPY_FR_D) num = 2;
if (meta->base >= NPY_FR_s) {
- ind = (int)NPY_FR_s - (int)NPY_FR_Y;
+ ind = ((int)NPY_FR_s - (int)NPY_FR_Y)*2;
totry = _multiples_table[ind];
baseunit = (NPY_DATETIMEUNIT *)_multiples_table[ind+1];
baseunit[0] = meta->base - 1;
@@ -551,16 +552,19 @@ _convert_divisor_to_multiple(PyArray_DatetimeMetaData *meta)
}
for (i=0; i<num; i++) {
- q = totry[1] / meta->den;
- r = totry[1] % meta->den;
+ q = totry[i] / meta->den;
+ r = totry[i] % meta->den;
if (r==0) break;
}
if (i==num) {
- PyErr_SetString(PyExc_ValueError, "Divisor is not a multiple of a lower-unit");
+ PyErr_Format(PyExc_ValueError, "divisor (%d) is not a multiple of a lower-unit", meta->den);
+ return -1;
}
meta->base = (NPY_DATETIMEUNIT) baseunit[i];
meta->den = 1;
meta->num = q;
+
+ return 0;
}
@@ -601,8 +605,7 @@ _convert_datetime_tuple_to_cobj(PyObject *tuple)
dt_data->events = PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 3));
if (dt_data->den > 1) {
- _convert_divisor_to_multiple(dt_data);
- if (PyErr_Occurred()) return NULL;
+ if (_convert_divisor_to_multiple(dt_data) < 0) return NULL;
}
return PyCObject_FromVoidPtr((void *)dt_data, _pya_free);
@@ -658,16 +661,15 @@ _convert_from_datetime_tuple(PyObject *obj)
}
dt_cobj = _convert_datetime_tuple_to_cobj(dt_tuple);
-
- /* Assume this sets a new reference to dt_cobj */
- PyDict_SetItem(new->metadata, freq_key, dt_cobj);
- Py_XDECREF(dt_cobj);
-
if (dt_cobj == NULL) { /* Failure in conversion */
Py_DECREF(new);
return NULL;
}
+ /* Assume this sets a new reference to dt_cobj */
+ PyDict_SetItem(new->metadata, freq_key, dt_cobj);
+ Py_DECREF(dt_cobj);
+
return new;
}