8000 ENH: missingdata: Make ndarray.view validate the maskna= parameter be… · numpy/numpy@0f0bce9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0f0bce9

Browse files
committed
ENH: missingdata: Make ndarray.view validate the maskna= parameter better
1 parent bede98e commit 0f0bce9

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

numpy/core/src/multiarray/methods.c

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,17 +171,38 @@ array_view(PyArrayObject *self, PyObject *args, PyObject *kwds)
171171
PyObject *out_type = NULL;
172172
PyArray_Descr *dtype = NULL;
173173
PyObject *ret;
174-
int maskna = 0, ownmaskna = 0;
174+
int maskna = -1, ownmaskna = 0;
175+
PyObject *maskna_in = Py_None;
175176

176177
static char *kwlist[] = {"dtype", "type", "maskna", "ownmaskna", NULL};
177-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOii", kwlist,
178+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOi", kwlist,
178179
&out_dtype,
179180
&out_type,
180-
&maskna,
181+
&maskna_in,
181182
&ownmaskna)) {
182183
return NULL;
183184
}
184185

186+
/* Treat None the same as not providing the parameter */
187+
if (maskna_in != Py_None) {
188+
maskna = PyObject_IsTrue(maskna_in);
189+
if (maskna == -1) {
190+
return NULL;
191+
}
192+
}
193+
194+
/* 'ownmaskna' forces 'maskna' to be True */
195+
if (ownmaskna) {
196+
if (maskna == 0) {
197+
PyErr_SetString(PyExc_ValueError,
198+
"cannot specify maskna=False and ownmaskna=True");
199+
return NULL;
200+
}
201+
else {
202+
maskna = 1;
203+
}
204+
}
205+
185206
/* If user specified a positional argument, guess whether it
186207
represents a type or a dtype for backward compatibility. */
187208
if (out_dtype) {
@@ -213,8 +234,11 @@ array_view(PyArrayObject *self, PyObject *args, PyObject *kwds)
213234
}
214235

215236
ret = PyArray_View(self, dtype, (PyTypeObject*)out_type);
237+
if (ret == NULL) {
238+
return NULL;
239+
}
216240

217-
if (maskna || ownmaskna) {
241+
if (maskna == 1) {
218242
/* Ensure there is an NA mask if requested */
219243
if (PyArray_AllocateMaskNA((PyArrayObject *)ret,
220244
ownmaskna, 0, 1) < 0) {
@@ -223,6 +247,13 @@ array_view(PyArrayObject *self, PyObject *args, PyObject *kwds)
223247
}
224248
return ret;
225249
}
250+
else if (maskna == 0 && PyArray_HASMASKNA(ret)) {
251+
PyErr_SetString(PyExc_ValueError,
252+
"Cannot take a view of an NA-masked array "
253+
"with maskna=False");
254+
Py_DECREF(ret);
255+
return NULL;
256+
}
226257
else {
227258
return ret;
228259
}

numpy/core/tests/test_maskna.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ def test_array_maskna_view_function():
334334
assert_(c.flags.maskna)
335335
assert_(not c.flags.ownmaskna)
336336

337+
# Taking a view of a masked array with maskna=False is invalid
338+
assert_raises(ValueError, b.view, maskna=False)
339+
337340
# Taking a view of a masked array, making sure there's a mask
338341
c = b.view(maskna = True)
339342
assert_(b.flags.maskna)

0 commit comments

Comments
 (0)
0