summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/code_generators/genapi.py1
-rw-r--r--numpy/core/code_generators/numpy_api.py5
-rw-r--r--numpy/core/src/multiarray/item_selection.c5
-rw-r--r--numpy/core/src/multiarray/mapping.c4
-rw-r--r--numpy/core/src/multiarray/na_object.c80
-rw-r--r--numpy/core/src/multiarray/na_object.h18
6 files changed, 66 insertions, 47 deletions
diff --git a/numpy/core/code_generators/genapi.py b/numpy/core/code_generators/genapi.py
index fdf043ddb..05f382240 100644
--- a/numpy/core/code_generators/genapi.py
+++ b/numpy/core/code_generators/genapi.py
@@ -44,6 +44,7 @@ API_FILES = [join('multiarray', 'array_assign_array.c'),
join('multiarray', 'methods.c'),
join('multiarray', 'multiarraymodule.c'),
join('multiarray', 'na_mask.c'),
+ join('multiarray', 'na_object.c'),
join('multiarray', 'nditer_api.c'),
join('multiarray', 'nditer_constr.c'),
join('multiarray', 'nditer_pywrap.c'),
diff --git a/numpy/core/code_generators/numpy_api.py b/numpy/core/code_generators/numpy_api.py
index 4d5d42074..ac5c12e24 100644
--- a/numpy/core/code_generators/numpy_api.py
+++ b/numpy/core/code_generators/numpy_api.py
@@ -337,6 +337,11 @@ multiarray_funcs_api = {
'PyArray_ReduceWrapper': 296,
'PyArray_RemoveAxesInPlace': 297,
'PyArray_DebugPrint': 298,
+ 'NpyNA_GetDType': 300,
+ 'NpyNA_IsMultiNA': 301,
+ 'NpyNA_GetPayload': 302,
+ 'NpyNA_FromObject': 303,
+ 'NpyNA_FromDTypeAndPayload': 304,
}
ufunc_types_api = {
diff --git a/numpy/core/src/multiarray/item_selection.c b/numpy/core/src/multiarray/item_selection.c
index 120ed75f3..663567014 100644
--- a/numpy/core/src/multiarray/item_selection.c
+++ b/numpy/core/src/multiarray/item_selection.c
@@ -2343,9 +2343,8 @@ PyArray_MultiIndexGetItem(PyArrayObject *self, npy_intp *multi_index)
return PyArray_DESCR(self)->f->getitem(data, self);
}
else {
- return (PyObject *)NpyNA_FromDTypeAndMaskValue(
- PyArray_DTYPE(self),
- maskvalue, 0);
+ return (PyObject *)NpyNA_FromDTypeAndPayload(
+ PyArray_DTYPE(self), 0, 0);
}
}
/* Case without an NA mask */
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c
index c6e42905f..92c0429aa 100644
--- a/numpy/core/src/multiarray/mapping.c
+++ b/numpy/core/src/multiarray/mapping.c
@@ -1803,8 +1803,8 @@ array_subscript_nice(PyArrayObject *self, PyObject *op)
(PyObject *)self);
}
else {
- return (PyObject *)NpyNA_FromDTypeAndMaskValue(
- PyArray_DESCR(self), (npy_mask)*maskna_item, 0);
+ return (PyObject *)NpyNA_FromDTypeAndPayload(
+ PyArray_DESCR(self), 0, 0);
}
}
}
diff --git a/numpy/core/src/multiarray/na_object.c b/numpy/core/src/multiarray/na_object.c
index 3b52a7678..c356fb421 100644
--- a/numpy/core/src/multiarray/na_object.c
+++ b/numpy/core/src/multiarray/na_object.c
@@ -368,7 +368,45 @@ NpyNA_CombineNAWithObject(NpyNA *na, PyObject *obj)
return (NpyNA *)ret;
}
-/*
+
+/*NUMPY_API
+ *
+ * Returns the *dtype* field of the NA object, which is NULL when
+ * the NA has no dtype. Does not raise an error.
+ */
+NPY_NO_EXPORT PyArray_Descr *
+NpyNA_GetDType(NpyNA* na)
+{
+ NpyNA_fields *fna = (NpyNA_fields *)na;
+ return fna->dtype;
+}
+
+/*NUMPY_API
+ *
+ * Returns true if the NA has a multi-NA payload, false otherwise.
+ */
+NPY_NO_EXPORT npy_bool
+NpyNA_IsMultiNA(NpyNA* na)
+{
+ NpyNA_fields *fna = (NpyNA_fields *)na;
+ return fna->payload != NPY_NA_NOPAYLOAD;
+}
+
+/*NUMPY_API
+ *
+ * Gets the multi-NA payload of the NA, or 0 if *na* doesn't have
+ * a multi-NA payload.
+ */
+NPY_NO_EXPORT int
+NpyNA_GetPayload(NpyNA* na)
+{
+ NpyNA_fields *fna = (NpyNA_fields *)na;
+ return fna->payload == NPY_NA_NOPAYLOAD ? 0 : fna->payload;
+}
+
+
+/*NUMPY_API
+ *
* Converts an object into an NA if possible.
*
* If 'suppress_error' is enabled, doesn't raise an error when something
@@ -433,28 +471,22 @@ NpyNA_FromObject(PyObject *obj, int suppress_error)
return NULL;
}
-/*
- * Converts a dtype reference and mask value into an NA.
+/*NUMPY_API
+ *
+ * Converts a dtype reference and payload value into an NA.
* Doesn't steal the 'dtype' reference. Raises an error
- * if 'maskvalue' represents an exposed mask.
+ * if the payload is invalid
*/
NPY_NO_EXPORT NpyNA *
-NpyNA_FromDTypeAndMaskValue(PyArray_Descr *dtype, npy_mask maskvalue,
- int multina)
+NpyNA_FromDTypeAndPayload(PyArray_Descr *dtype, int multina, int payload)
{
NpyNA_fields *fna;
- if (dtype == NULL && maskvalue == 0) {
+ if (dtype == NULL && multina == 0 && payload == 0) {
Py_INCREF(Npy_NA);
return (NpyNA *)Npy_NA;
}
- if (NpyMaskValue_IsExposed(maskvalue)) {
- PyErr_SetString(PyExc_ValueError,
- "Cannot convert exposed mask value into NA");
- return NULL;
- }
-
fna = (NpyNA_fields *)na_new(&NpyNA_Type, NULL, NULL);
if (fna == NULL) {
return NULL;
@@ -464,11 +496,17 @@ NpyNA_FromDTypeAndMaskValue(PyArray_Descr *dtype, npy_mask maskvalue,
Py_XINCREF(fna->dtype);
if (multina) {
- fna->payload = NpyMaskValue_GetPayload(maskvalue);
+ if (payload < 0 || payload > 0x7f) {
+ PyErr_Format(PyExc_ValueError,
+ "Given NA payload, %d, is out of bounds [0, 128)",
+ payload);
+ Py_DECREF(fna);
+ }
+ fna->payload = (npy_uint8)payload;
}
- else if (NpyMaskValue_GetPayload(maskvalue) != 0) {
+ else if (payload != 0) {
PyErr_SetString(PyExc_ValueError,
- "Cannot convert mask value into NA without enabling multi-NA");
+ "NA payload must be zero when multi-NA is disabled");
Py_DECREF(fna);
return NULL;
}
@@ -482,14 +520,7 @@ NpyNA_FromDTypeAndMaskValue(PyArray_Descr *dtype, npy_mask maskvalue,
NPY_NO_EXPORT npy_mask
NpyNA_AsMaskValue(NpyNA *na)
{
- NpyNA_fields *fna = (NpyNA_fields *)na;
-
- if (fna->payload == NPY_NA_NOPAYLOAD) {
- return 0;
- }
- else {
- return NpyMaskValue_Create(0, fna->payload);
- }
+ return NpyMaskValue_Create(0, NpyNA_GetPayload(na));
}
/* An NA unary op simply passes along the same NA */
@@ -749,4 +780,5 @@ NPY_NO_EXPORT NpyNA_fields _Npy_NASingleton = {
1 /* is_singleton */
};
+/* This symbol is exported in the NumPy C API */
NPY_NO_EXPORT PyObject *Npy_NA = (PyObject *)&_Npy_NASingleton;
diff --git a/numpy/core/src/multiarray/na_object.h b/numpy/core/src/multiarray/na_object.h
index 48770cfc2..3e602ccdf 100644
--- a/numpy/core/src/multiarray/na_object.h
+++ b/numpy/core/src/multiarray/na_object.h
@@ -37,24 +37,6 @@ NPY_NO_EXPORT NpyNA *
NpyNA_CombineNAWithObject(NpyNA *na, PyObject *obj);
/*
- * Converts an object into an NA if possible.
- *
- * If 'suppress_error' is enabled, doesn't raise an error when something
- * isn't NA.
- */
-NPY_NO_EXPORT NpyNA *
-NpyNA_FromObject(PyObject *obj, int suppress_error);
-
-/*
- * Converts a dtype reference and mask value into an NA.
- * Doesn't steal the 'dtype' reference. Raises an error
- * if 'maskvalue' represents an exposed mask.
- */
-NPY_NO_EXPORT NpyNA *
-NpyNA_FromDTypeAndMaskValue(PyArray_Descr *dtype, npy_mask maskvalue,
- int multina);
-
-/*
* Returns a mask value corresponding to the NA.
*/
NPY_NO_EXPORT npy_mask