diff --git a/numbuf/python/src/pynumbuf/adapters/numpy.cc b/numbuf/python/src/pynumbuf/adapters/numpy.cc index 238eb0092..1a6cecd27 100644 --- a/numbuf/python/src/pynumbuf/adapters/numpy.cc +++ b/numbuf/python/src/pynumbuf/adapters/numpy.cc @@ -27,8 +27,7 @@ namespace numbuf { num_dims, dim.data(), NPY_##TYPE, reinterpret_cast(data)); \ if (base != Py_None) { PyArray_SetBaseObject((PyArrayObject*)*out, base); } \ Py_XINCREF(base); \ - } \ - return Status::OK(); + } break; Status DeserializeArray( std::shared_ptr array, int32_t offset, PyObject* base, PyObject** out) { @@ -57,6 +56,11 @@ Status DeserializeArray( default: DCHECK(false) << "arrow type not recognized: " << content->value_type()->type; } + /* Mark the array as immutable. */ + PyObject* flags = PyObject_GetAttrString(*out, "flags"); + DCHECK(flags != NULL) << "Could not mark Numpy array immutable"; + int flag_set = PyObject_SetAttrString(flags, "writeable", Py_False); + DCHECK(flag_set == 0) << "Could not mark Numpy array immutable"; return Status::OK(); } diff --git a/numbuf/python/test/runtest.py b/numbuf/python/test/runtest.py index e90067967..3ffd29247 100644 --- a/numbuf/python/test/runtest.py +++ b/numbuf/python/test/runtest.py @@ -118,5 +118,13 @@ class SerializationTests(unittest.TestCase): result = numbuf.deserialize_list(array) assert_equal(result[0], obj) + def testObjectArrayImmutable(self): + obj = np.zeros([10]) + schema, size, serialized = numbuf.serialize_list([obj]) + result = numbuf.deserialize_list(serialized) + assert_equal(result[0], obj) + with self.assertRaises(ValueError): + result[0][0] = 1 + if __name__ == "__main__": unittest.main(verbosity=2)