From 6b0d1e3e892e3d20e9accce702948e82a7271404 Mon Sep 17 00:00:00 2001 From: Raghav RV Date: Tue, 4 Oct 2016 15:46:17 +0200 Subject: [PATCH 1/5] TST add test to check pickling of object dtyped masked array --- numpy/ma/tests/test_core.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index 42676978ff25..a570fb58b632 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -476,13 +476,15 @@ def test_str_repr(self): def test_pickling(self): # Tests pickling - a = arange(10) - a[::3] = masked - a.fill_value = 999 - a_pickled = pickle.loads(a.dumps()) - assert_equal(a_pickled._mask, a._mask) - assert_equal(a_pickled._data, a._data) - assert_equal(a_pickled.fill_value, 999) + for dtype in (int, float, str, object): + a = arange(10).astype(dtype) + a[::3] = masked + a.fill_value = 999 + a_pickled = pickle.loads(a.dumps()) + assert_equal(a_pickled._mask, a._mask) + assert_equal(a_pickled._data, a._data) + if dtype is not object: + assert_equal(a_pickled.fill_value, dtype(999)) def test_pickling_subbaseclass(self): # Test pickling w/ a subclass of ndarray From 3669bfa9381189cfe4a4abb48d5b9f2b991212e8 Mon Sep 17 00:00:00 2001 From: Raghav RV Date: Wed, 5 Oct 2016 17:59:03 +0200 Subject: [PATCH 2/5] Serialize to list instead of bytestring for the data array --- numpy/ma/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/numpy/ma/core.py b/numpy/ma/core.py index f83e2adcc36d..ce3284c559a3 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -5860,12 +5860,12 @@ def __getstate__(self): """ cf = 'CF'[self.flags.fnc] + is_obj = self.dtype.kind == 'O' state = (1, self.shape, self.dtype, self.flags.fnc, - self._data.tobytes(cf), - # self._data.tolist(), + (self._data.tolist() if is_obj else self._data.tobytes(cf)), getmaskarray(self).tobytes(cf), # getmaskarray(self).tolist(), self._fill_value, From 2ed500288f9773f331fe59a7ba227a61c8693638 Mon Sep 17 00:00:00 2001 From: Raghav RV Date: Wed, 5 Oct 2016 18:12:33 +0200 Subject: [PATCH 3/5] Test for different masks --- numpy/ma/tests/test_core.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index a570fb58b632..470a6a664d38 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -478,13 +478,20 @@ def test_pickling(self): # Tests pickling for dtype in (int, float, str, object): a = arange(10).astype(dtype) - a[::3] = masked a.fill_value = 999 - a_pickled = pickle.loads(a.dumps()) - assert_equal(a_pickled._mask, a._mask) - assert_equal(a_pickled._data, a._data) - if dtype is not object: - assert_equal(a_pickled.fill_value, dtype(999)) + + masks = ([0, 0, 0, 1, 0, 1, 0, 1, 0, 1], # partially masked + True, # Fully masked + False) # Fully unmasked + + for mask in masks: + a.mask = mask + a_pickled = pickle.loads(a.dumps()) + assert_equal(a_pickled._mask, a._mask) + assert_equal(a_pickled._data, a._data) + if dtype is not object: + assert_equal(a_pickled.fill_value, dtype(999)) + assert_array_equal(a_pickled.mask, mask) def test_pickling_subbaseclass(self): # Test pickling w/ a subclass of ndarray From 66993e09c43ee9f23bcb22d311373301845c58c2 Mon Sep 17 00:00:00 2001 From: Raghav RV Date: Thu, 6 Oct 2016 12:53:32 +0200 Subject: [PATCH 4/5] Test fill value for object dtype too --- numpy/ma/tests/test_core.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index 470a6a664d38..be06e7230edd 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -489,7 +489,9 @@ def test_pickling(self): a_pickled = pickle.loads(a.dumps()) assert_equal(a_pickled._mask, a._mask) assert_equal(a_pickled._data, a._data) - if dtype is not object: + if dtype in (object, int): + assert_equal(a_pickled.fill_value, 999) + else: assert_equal(a_pickled.fill_value, dtype(999)) assert_array_equal(a_pickled.mask, mask) From 1fa49f8d102048f327287e51f44b8414d4dfbd6e Mon Sep 17 00:00:00 2001 From: Raghav RV Date: Thu, 6 Oct 2016 12:55:22 +0200 Subject: [PATCH 5/5] Use ndarray.__reduce__ to extract the bytestring/list --- numpy/ma/core.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/numpy/ma/core.py b/numpy/ma/core.py index ce3284c559a3..44b64bdc8290 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -5860,17 +5860,8 @@ def __getstate__(self): """ cf = 'CF'[self.flags.fnc] - is_obj = self.dtype.kind == 'O' - state = (1, - self.shape, - self.dtype, - self.flags.fnc, - (self._data.tolist() if is_obj else self._data.tobytes(cf)), - getmaskarray(self).tobytes(cf), - # getmaskarray(self).tolist(), - self._fill_value, - ) - return state + data_state = super(MaskedArray, self).__reduce__()[2] + return data_state + (getmaskarray(self).tobytes(cf), self._fill_value) def __setstate__(self, state): """Restore the internal state of the masked array, for