Skip to content

Commit cdcbaa4

Browse files
committedOct 31, 2010
BUG: fix bug in dtype hash implementation for equivalent but different byte order character.
1 parent 6bcb36f commit cdcbaa4

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed
 

‎numpy/core/src/multiarray/hashdescr.c

+19-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,23 @@ static int _array_descr_walk(PyArray_Descr* descr, PyObject *l);
3030
static int _array_descr_walk_fields(PyObject* fields, PyObject* l);
3131
static int _array_descr_builtin(PyArray_Descr* descr, PyObject *l);
3232

33+
/*
34+
* normalize endian character: always return 'I', '<' or '>'
35+
*/
36+
static char _normalize_byteorder(char byteorder)
37+
{
38+
switch(byteorder) {
39+
case '=':
40+
if (PyArray_GetEndianness() == NPY_CPU_BIG) {
41+
return '>';
42+
} else {
43+
return '<';
44+
}
45+
default:
46+
return byteorder;
47+
}
48+
}
49+
3350
/*
3451
* Return true if descr is a builtin type
3552
*/
@@ -51,12 +68,13 @@ static int _array_descr_builtin(PyArray_Descr* descr, PyObject *l)
5168
{
5269
Py_ssize_t i;
5370
PyObject *t, *item;
71+
char nbyteorder = _normalize_byteorder(descr->byteorder);
5472

5573
/*
5674
* For builtin type, hash relies on : kind + byteorder + flags +
5775
* type_num + elsize + alignment
5876
*/
59-
t = Py_BuildValue("(cciiii)", descr->kind, descr->byteorder,
77+
t = Py_BuildValue("(cciiii)", descr->kind, nbyteorder,
6078
descr->flags, descr->type_num, descr->elsize,
6179
descr->alignment);
6280

‎numpy/core/tests/test_dtype.py

+13
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ def test_run(self):
99
dt = np.dtype(t)
1010
hash(dt)
1111

12+
def test_dtype(self):
13+
# Make sure equivalent byte order char hash the same (e.g. < and = on
14+
# little endian)
15+
for t in [np.int, np.float]:
16+
dt = np.dtype(t)
17+
dt2 = dt.newbyteorder("<")
18+
dt3 = dt.newbyteorder(">")
19+
if dt == dt2:
20+
self.assertTrue(dt.byteorder != dt2.byteorder, "bogus test")
21+
self.assertTrue(hash(dt) == hash(dt2), "equivalent bytorders do not hash the same")
22+
else:
23+
self.assertTrue(dt.byteorder != dt3.byteorder, "bogus test")
24+
self.assertTrue(hash(dt) == hash(dt3), "equivalent bytorders do not hash the same")
1225
class TestRecord(TestCase):
1326
def test_equivalent_record(self):
1427
"""Test whether equivalent record dtypes hash the same."""

0 commit comments

Comments
 (0)
Please sign in to comment.