summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2017-02-22 11:07:55 +0000
committerEric Wieser <wieser.eric@gmail.com>2017-03-03 12:47:08 +0000
commit02f33887b751d288ec2238143aa8048a74f731f2 (patch)
treebf334e48d9ba49ecc94fd5356ffac5ccc7d5be4f
parent96c3e66179b6bbd71d7ae4c16c5130179dd683c3 (diff)
downloadnumpy-02f33887b751d288ec2238143aa8048a74f731f2.tar.gz
BUG: Preserve identity of dtypes in make_mask_descr
Partially addresses #8666
-rw-r--r--numpy/ma/core.py17
-rw-r--r--numpy/ma/tests/test_core.py20
2 files changed, 30 insertions, 7 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index ea4a1d85f..ad67c582a 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -1297,14 +1297,19 @@ def _recursive_make_descr(datatype, newtype=bool_):
# Prepend the title to the name
name = (field[-1], name)
descr.append((name, _recursive_make_descr(field[0], newtype)))
- return descr
# Is this some kind of composite a la (np.float,2)
elif datatype.subdtype:
- mdescr = list(datatype.subdtype)
- mdescr[0] = _recursive_make_descr(datatype.subdtype[0], newtype)
- return tuple(mdescr)
+ descr = list(datatype.subdtype)
+ descr[0] = _recursive_make_descr(datatype.subdtype[0], newtype)
+ descr = tuple(descr)
else:
- return newtype
+ descr = newtype
+
+ new_dtype = np.dtype(descr)
+ if new_dtype == datatype:
+ new_dtype = datatype
+
+ return new_dtype
def make_mask_descr(ndtype):
@@ -1340,7 +1345,7 @@ def make_mask_descr(ndtype):
# Make sure we do have a dtype
if not isinstance(ndtype, np.dtype):
ndtype = np.dtype(ndtype)
- return np.dtype(_recursive_make_descr(ndtype, np.bool))
+ return _recursive_make_descr(ndtype, np.bool)
def getmask(a):
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index ca1ef16c4..93898c4d0 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -4000,32 +4000,50 @@ class TestMaskedArrayFunctions(TestCase):
self.assertTrue(c.flags['C'])
def test_make_mask_descr(self):
- # Test make_mask_descr
# Flexible
ntype = [('a', np.float), ('b', np.float)]
test = make_mask_descr(ntype)
assert_equal(test, [('a', np.bool), ('b', np.bool)])
+ assert_(test is make_mask_descr(test))
+
# Standard w/ shape
ntype = (np.float, 2)
test = make_mask_descr(ntype)
assert_equal(test, (np.bool, 2))
+ assert_(test is make_mask_descr(test))
+
# Standard standard
ntype = np.float
test = make_mask_descr(ntype)
assert_equal(test, np.dtype(np.bool))
+ assert_(test is make_mask_descr(test))
+
# Nested
ntype = [('a', np.float), ('b', [('ba', np.float), ('bb', np.float)])]
test = make_mask_descr(ntype)
control = np.dtype([('a', 'b1'), ('b', [('ba', 'b1'), ('bb', 'b1')])])
assert_equal(test, control)
+ assert_(test is make_mask_descr(test))
+
# Named+ shape
ntype = [('a', (np.float, 2))]
test = make_mask_descr(ntype)
assert_equal(test, np.dtype([('a', (np.bool, 2))]))
+ assert_(test is make_mask_descr(test))
+
# 2 names
ntype = [(('A', 'a'), float)]
test = make_mask_descr(ntype)
assert_equal(test, np.dtype([(('A', 'a'), bool)]))
+ assert_(test is make_mask_descr(test))
+
+ # nested boolean types should preserve identity
+ base_type = np.dtype([('a', int, 3)])
+ base_mtype = make_mask_descr(base_type)
+ sub_type = np.dtype([('a', int), ('b', base_mtype)])
+ test = make_mask_descr(sub_type)
+ assert_equal(test, np.dtype([('a', bool), ('b', [('a', bool, 3)])]))
+ assert_(test.fields['b'][0] is base_mtype)
def test_make_mask(self):
# Test make_mask