10000 ENH: missingdata: Improve error message when assigning NA to non-NA-m… · numpy/numpy@92ffa03 · GitHub
[go: up one dir, main page]

Skip to content

Commit 92ffa03

Browse files
committed
ENH: missingdata: Improve error message when assigning NA to non-NA-masked arrays
1 parent 4a0b15b commit 92ffa03

File tree

3 files changed

+73
-4
lines changed

3 files changed

+73
-4
lines changed

numpy/core/src/multiarray/arraytypes.c.src

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "ctors.h"
1919
#include "usertypes.h"
2020
#include "_datetime.h"
21+
#include "na_singleton.h"
2122

2223
#include "numpyos.h"
2324

@@ -142,6 +143,12 @@ static int
142143
if (PyArray_IsScalar(op, @kind@)) {
143144
temp = ((Py@kind@ScalarObject *)op)->obval;
144145
}
146+
else if (NpyNA_Check(op) || NpyNA_IsZeroDimArrayNA(op)) {
147+
PyErr_SetString(PyExc_ValueError,
148+
"Cannot assign NA to an array which "
149+
"does not support NAs");
150+
return -1;
151+
}
145152
else {
146153
temp = (@type@)@func2@(op);
147154
}
@@ -204,7 +211,16 @@ static int
204211
c@type@ temp;
205212
int rsize;
206213

207-
if (!(PyArray_IsScalar(op, @kind@))) {
214+
if (PyArray_IsScalar(op, @kind@)){
215+
temp = ((Py@kind@ScalarObject *)op)->obval;
216+
}
217+
else if (NpyNA_Check(op) || NpyNA_IsZeroDimArrayNA(op)) {
218+
PyErr_SetString(PyExc_ValueError,
219+
"Cannot assign NA to an array which "
220+
"does not support NAs");
221+
return -1;
222+
}
223+
else {
208224
if (PyArray_Check(op) && (PyArray_NDIM((PyArrayObject *)op) == 0)) {
209225
op2 = PyArray_DESCR((PyArrayObject *)op)->f->getitem(
210226
PyArray_BYTES((PyArrayObject *)op),
@@ -227,9 +243,7 @@ static int
227243
temp.real = (@type@) oop.real;
228244
temp.imag = (@type@) oop.imag;
229245
}
230-
else {
231-
temp = ((Py@kind@ScalarObject *)op)->obval;
232-
}
246+
233247
memcpy(ov, &temp, PyArray_DESCR(ap)->elsize);
234248
if (!PyArray_ISNOTSWAPPED(ap)) {
235249
byte_swap_vector(ov, 2, sizeof(@type@));
@@ -259,6 +273,12 @@ LONGDOUBLE_setitem(PyObject *op, char *ov, PyArrayObject *ap) {
259273
if (PyArray_IsScalar(op, LongDouble)) {
260274
temp = ((PyLongDoubleScalarObject *)op)->obval;
261275
}
276+
else if (NpyNA_Check(op) || NpyNA_IsZeroDimArrayNA(op)) {
277+
PyErr_SetString(PyExc_ValueError,
278+
"Cannot assign NA to an array which "
279+
"does not support NAs");
280+
return -1;
281+
}
262282
else {
263283
temp = (longdouble) MyPyFloat_AsDouble(op);
264284
}
@@ -353,6 +373,12 @@ UNICODE_setitem(PyObject *op, char *ov, PyArrayObject *ap)
353373
"setting an array element with a sequence");
354374
return -1;
355375
}
376+
if (NpyNA_Check(op) || NpyNA_IsZeroDimArrayNA(op)) {
377+
PyErr_SetString(PyExc_ValueError,
378+
"Cannot assign NA to an array which "
379+
"does not support NAs");
380+
return -1;
381+
}
356382
/* Sequence_Size might have returned an error */
357383
if (PyErr_Occurred()) {
358384
PyErr_Clear();
@@ -457,6 +483,12 @@ STRING_setitem(PyObject *op, char *ov, PyArrayObject *ap)
457483
"cannot set an array element with a sequence");
458484
return -1;
459485
}
486+
if (NpyNA_Check(op) || NpyNA_IsZeroDimArrayNA(op)) {
487+
PyErr_SetString(PyExc_ValueError,
488+
"Cannot assign NA to an array which "
489+
"does not support NAs");
490+
return -1;
491+
}
460492
#if defined(NPY_PY3K)
461493
if (PyUnicode_Check(op)) {
462494
/* Assume ASCII codec -- function similarly as Python 2 */
@@ -752,6 +784,13 @@ VOID_setitem(PyObject *op, char *ip, PyArrayObject *ap)
752784
return res;
753785
}
754786

787+
if (NpyNA_Check(op) || NpyNA_IsZeroDimArrayNA(op)) {
788+
PyErr_SetString(PyExc_ValueError,
789+
"Cannot assign NA to an array which "
790+
"does not support NAs");
791+
return -1;
792+
}
793+
755794
/* Default is to use buffer interface to set item */
756795
{
757796
const void *buffer;

numpy/core/src/multiarray/datetime.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "methods.h"
2525
#include "_datetime.h"
2626
#include "datetime_strings.h"
27+
#include "na_singleton.h"
2728

2829
/*
2930
* Imports the PyDateTime functions so we can create these objects.
@@ -2655,6 +2656,13 @@ convert_pyobject_to_datetime(PyArray_DatetimeMetaData *meta, PyObject *obj,
26552656
*out = NPY_DATETIME_NAT;
26562657
return 0;
26572658
}
2659+
/* Check for NA */
2660+
else if (NpyNA_Check(obj) || NpyNA_IsZeroDimArrayNA(obj)) {
2661+
PyErr_SetString(PyExc_ValueError,
2662+
"Cannot assign NA to an array which "
2663+
"does not support NAs");
2664+
return -1;
2665+
}
26582666
else {
26592667
PyErr_SetString(PyExc_ValueError,
26602668
"Could not convert object to NumPy datetime");
@@ -2916,6 +2924,13 @@ convert_pyobject_to_timedelta(PyArray_DatetimeMetaData *meta, PyObject *obj,
29162924
*out = NPY_DATETIME_NAT;
29172925
return 0;
29182926
}
2927+
/* Check for NA */
2928+
else if (NpyNA_Check(obj) || NpyNA_IsZeroDimArrayNA(obj)) {
2929+
PyErr_SetString(PyExc_ValueError,
2930+
"Cannot assign NA to an array which "
2931+
"does not support NAs");
2932+
return -1;
2933+
}
29192934
else {
29202935
PyErr_SetString(PyExc_ValueError,
29212936
"Could not convert object to NumPy timedelta");

numpy/core/src/multiarray/na_singleton.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,19 @@ NpyNA_FromDTypeAndMaskValue(PyArray_Descr *dtype, npy_mask maskvalue,
6363
NPY_NO_EXPORT npy_mask
6464
NpyNA_AsMaskValue(NpyNA *na);
6565

66+
/*
67+
* Returns True if the object is an NA in the form of a 0-dimensional
68+
* array.
69+
*/
70+
static NPY_INLINE npy_bool
71+
NpyNA_IsZeroDimArrayNA(PyObject *obj)
72+
{
73+
return PyArray_Check(obj) &&
74+
PyArray_NDIM((PyArrayObject *)obj) == 0 &&
75+
PyArray_HASMASKNA((PyArrayObject *)obj) &&
76+
!PyArray_HASFIELDS((PyArrayObject *)obj) &&
77+
!NpyMaskValue_IsExposed((npy_mask)*PyArray_MASKNA_DATA(
78+
(PyArrayObject *)obj));
79+
}
80+
6681
#endif

0 commit comments

Comments
 (0)
0