summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/conversion_utils.c35
-rw-r--r--numpy/core/src/multiarray/conversion_utils.h16
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c7
-rw-r--r--numpy/core/tests/test_multiarray.py2
4 files changed, 52 insertions, 8 deletions
diff --git a/numpy/core/src/multiarray/conversion_utils.c b/numpy/core/src/multiarray/conversion_utils.c
index 68d6e75fb..35595005c 100644
--- a/numpy/core/src/multiarray/conversion_utils.c
+++ b/numpy/core/src/multiarray/conversion_utils.c
@@ -1000,6 +1000,18 @@ PyArray_IntpFromSequence(PyObject *seq, npy_intp *vals, int maxvals)
return nd;
}
+/**
+ * WARNING: This flag is a bad idea, but was the only way to both
+ * 1) Support unpickling legacy pickles with object types.
+ * 2) Deprecate (and later disable) usage of O4 and O8
+ *
+ * The key problem is that the pickled representation unpickles by
+ * directly calling the dtype constructor, which has no way of knowing
+ * that it is in an unpickle context instead of a normal context without
+ * evil global state like we create here.
+ */
+NPY_NO_EXPORT int evil_global_disable_warn_O4O8_flag = 0;
+
/*NUMPY_API
* Typestr converter
*/
@@ -1007,7 +1019,6 @@ NPY_NO_EXPORT int
PyArray_TypestrConvert(int itemsize, int gentype)
{
int newtype = NPY_NOTYPE;
- int ret;
switch (gentype) {
case NPY_GENBOOLLTR:
@@ -1116,12 +1127,22 @@ PyArray_TypestrConvert(int itemsize, int gentype)
break;
case NPY_OBJECTLTR:
- /* raise PyErr_Warn|Ex depending on version */
- ret = DEPRECATE("DType strings 'O4' and 'O8' are deprecated "
- "because they are platform specific. Use "
- "'O' instead");
- if (ret == 0 && (itemsize == 4 || itemsize == 8)) {
- newtype = NPY_OBJECT;
+ /*
+ * For 'O4' and 'O8', let it pass, but raise a
+ * deprecation warning. For all other cases, raise
+ * an exception by leaving newtype unset.
+ */
+ if (itemsize == 4 || itemsize == 8) {
+ int ret = 0;
+ if (evil_global_disable_warn_O4O8_flag) {
+ ret = DEPRECATE("DType strings 'O4' and 'O8' are "
+ "deprecated because they are platform "
+ "specific. Use 'O' instead");
+ }
+
+ if (ret == 0) {
+ newtype = NPY_OBJECT;
+ }
}
break;
diff --git a/numpy/core/src/multiarray/conversion_utils.h b/numpy/core/src/multiarray/conversion_utils.h
index e344a19b0..3ecc46a12 100644
--- a/numpy/core/src/multiarray/conversion_utils.h
+++ b/numpy/core/src/multiarray/conversion_utils.h
@@ -45,4 +45,20 @@ PyArray_IntTupleFromIntp(int len, intp *vals);
NPY_NO_EXPORT int
PyArray_ConvertMultiAxis(PyObject *axis_in, int ndim, npy_bool *out_axis_flags);
+/**
+ * WARNING: This flag is a bad idea, but was the only way to both
+ * 1) Support unpickling legacy pickles with object types.
+ * 2) Deprecate (and later disable) usage of O4 and O8
+ *
+ * The key problem is that the pickled representation unpickles by
+ * directly calling the dtype constructor, which has no way of knowing
+ * that it is in an unpickle context instead of a normal context without
+ * evil global state like we create here.
+ */
+#ifdef NPY_ENABLE_SEPARATE_COMPILATION
+extern NPY_NO_EXPORT int evil_global_disable_warn_O4O8_flag;
+#else
+NPY_NO_EXPORT int evil_global_disable_warn_O4O8_flag;
+#endif
+
#endif
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index fff1c5ce3..53d03ae8e 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -2778,6 +2778,8 @@ array__reconstruct(PyObject *NPY_UNUSED(dummy), PyObject *args)
PyArray_Dims shape = {NULL, 0};
PyArray_Descr *dtype = NULL;
+ evil_global_disable_warn_O4O8_flag = 1;
+
if (!PyArg_ParseTuple(args, "O!O&O&",
&PyType_Type, &subtype,
PyArray_IntpConverter, &shape,
@@ -2794,9 +2796,14 @@ array__reconstruct(PyObject *NPY_UNUSED(dummy), PyObject *args)
if (shape.ptr) {
PyDimMem_FREE(shape.ptr);
}
+
+ evil_global_disable_warn_O4O8_flag = 0;
+
return ret;
fail:
+ evil_global_disable_warn_O4O8_flag = 0;
+
Py_XDECREF(dtype);
if (shape.ptr) {
PyDimMem_FREE(shape.ptr);
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index d3d517841..adcd73872 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -827,7 +827,7 @@ class TestPickling(TestCase):
def test_version0_object(self):
s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x02\x85cnumpy\ndtype\nq\x04U\x02O8K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89]q\x06(}q\x07U\x01aK\x01s}q\x08U\x01bK\x02setb.'
- a = array([{'a':1}, {'b':2}])
+ a = np.array([{'a':1}, {'b':2}])
p = self._loads(asbytes(s))
assert_equal(a, p)