Skip to content

Commit 063295d

Browse files
authored
Merge pull request #21995 from eirrgang/mei-1468
BUG: Distinguish exact vs. equivalent dtype for C type aliases. Original NumPy Commit: 65c10c1cfecb2b3ebd0306ed1c63b103158f80d5
2 parents e157ccd + 233df4b commit 063295d

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import itertools
2+
3+
import numpy as np
4+
5+
6+
def test_dtype_identity():
7+
"""Confirm the intended behavior for ``asarray`` results.
8+
9+
The result of ``asarray()`` should have the dtype provided through the
10+
keyword argument, when used. This forces unique array handles to be
11+
produced for unique np.dtype objects, but (for equivalent dtypes), the
12+
underlying data (the base object) is shared with the original array object.
13+
14+
Ref https://github.com/numpy/numpy/issues/1468
15+
"""
16+
int_array = np.array([1, 2, 3], dtype='i')
17+
assert np.asarray(int_array) is int_array
18+
19+
# The character code resolves to the singleton dtype object provided
20+
# by the numpy package.
21+
assert np.asarray(int_array, dtype='i') is int_array
22+
23+
# Derive a dtype from n.dtype('i'), but add a metadata object to force
24+
# the dtype to be distinct.
25+
unequal_type = np.dtype('i', metadata={'spam': True})
26+
annotated_int_array = np.asarray(int_array, dtype=unequal_type)
27+
assert annotated_int_array is not int_array
28+
assert annotated_int_array.base is int_array
29+
# Create an equivalent descriptor with a new and distinct dtype instance.
30+
equivalent_requirement = np.dtype('i', metadata={'spam': True})
31+
annotated_int_array_alt = np.asarray(annotated_int_array,
32+
dtype=equivalent_requirement)
33+
assert unequal_type == equivalent_requirement
34+
assert unequal_type is not equivalent_requirement
35+
assert annotated_int_array_alt is not annotated_int_array
36+
assert annotated_int_array_alt.dtype is equivalent_requirement
37+
38+
# Check the same logic for a pair of C types whose equivalence may vary
39+
# between computing environments.
40+
# Find an equivalent pair.
41+
integer_type_codes = ('i', 'l', 'q')
42+
integer_dtypes = [np.dtype(code) for code in integer_type_codes]
43+
typeA = None
44+
typeB = None
45+
for typeA, typeB in itertools.permutations(integer_dtypes, r=2):
46+
if typeA == typeB:
47+
assert typeA is not typeB
48+
break
49+
assert isinstance(typeA, np.dtype) and isinstance(typeB, np.dtype)
50+
51+
# These ``asarray()`` calls may produce a new view or a copy,
52+
# but never the same object.
53+
long_int_array = np.asarray(int_array, dtype='l')
54+
long_long_int_array = np.asarray(int_array, dtype='q')
55+
assert long_int_array is not int_array
56+
assert long_long_int_array is not int_array
57+
assert np.asarray(long_int_array, dtype='q') is not long_int_array
58+
array_a = np.asarray(int_array, dtype=typeA)
59+
assert typeA == typeB
60+
assert typeA is not typeB
61+
assert array_a.dtype is typeA
62+
assert array_a is not np.asarray(array_a, dtype=typeB)
63+
assert np.asarray(array_a, dtype=typeB).dtype is typeB
64+
assert array_a is np.asarray(array_a, dtype=typeB).base

0 commit comments

Comments
 (0)