diff options
author | Matti Picus <matti.picus@gmail.com> | 2019-07-07 07:57:59 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-07 07:57:59 -0700 |
commit | 95c243221da5bedb7230e9ff229748f50acaf869 (patch) | |
tree | f39e58bec6eca9168f1e0ebe3ffc95d6a4ba71e7 | |
parent | 07555c841feb03683ce01d49762fe9b7053a5626 (diff) | |
parent | f723325b6f36868dfa483ff777e0447c229ffc42 (diff) | |
download | numpy-95c243221da5bedb7230e9ff229748f50acaf869.tar.gz |
Merge pull request #13907 from stestagg/master
BUG: handle weird bytestrings in dtype() (#13902)
-rw-r--r-- | numpy/core/src/multiarray/arraytypes.c.src | 12 | ||||
-rw-r--r-- | numpy/core/src/multiarray/descriptor.c | 3 | ||||
-rw-r--r-- | numpy/core/tests/test_dtype.py | 30 |
3 files changed, 43 insertions, 2 deletions
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src index 3b986ed04..c586a0b1d 100644 --- a/numpy/core/src/multiarray/arraytypes.c.src +++ b/numpy/core/src/multiarray/arraytypes.c.src @@ -4414,7 +4414,17 @@ PyArray_DescrFromType(int type) { PyArray_Descr *ret = NULL; - if (type < NPY_NTYPES) { + if (type < 0) { + /* + * It's not valid for type to be less than 0. + * If that happens, then no other branch of + * this if/else chain should be followed. + * This is effectively a no-op that ensures + * the default error is raised. + */ + ret = NULL; + } + else if (type < NPY_NTYPES) { ret = _builtin_descrs[type]; } else if (type == NPY_NOTYPE) { diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index 82d1ef4c9..ff85c3fcb 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -1546,7 +1546,8 @@ PyArray_DescrConverter(PyObject *obj, PyArray_Descr **at) /* A typecode like 'd' */ if (len == 1) { - check_num = type[0]; + /* Python byte string characters are unsigned */ + check_num = (unsigned char) type[0]; } /* A kind + size like 'f8' */ else { diff --git a/numpy/core/tests/test_dtype.py b/numpy/core/tests/test_dtype.py index bc5c23caf..f60eab696 100644 --- a/numpy/core/tests/test_dtype.py +++ b/numpy/core/tests/test_dtype.py @@ -88,6 +88,36 @@ class TestBuiltin(object): assert_raises(TypeError, np.dtype, 'q8') assert_raises(TypeError, np.dtype, 'Q8') + @pytest.mark.parametrize( + 'value', + ['m8', 'M8', 'datetime64', 'timedelta64', + 'i4, (2,3)f8, f4', 'a3, 3u8, (3,4)a10', + '>f', '<f', '=f', '|f', + ]) + def test_dtype_bytes_str_equivalence(self, value): + bytes_value = value.encode('ascii') + from_bytes = np.dtype(bytes_value) + from_str = np.dtype(value) + assert_dtype_equal(from_bytes, from_str) + + def test_dtype_from_bytes(self): + # Empty bytes object + assert_raises(TypeError, np.dtype, b'') + # Byte order indicator, but no type + assert_raises(TypeError, np.dtype, b'|') + + # Single character with ordinal < NPY_NTYPES returns + # type by index into _builtin_descrs + assert_dtype_equal(np.dtype(bytes([0])), np.dtype('bool')) + assert_dtype_equal(np.dtype(bytes([17])), np.dtype(object)) + + # Single character where value is a valid type code + assert_dtype_equal(np.dtype(b'f'), np.dtype('float32')) + + # Bytes with non-ascii values raise errors + assert_raises(TypeError, np.dtype, b'\xff') + assert_raises(TypeError, np.dtype, b's\xff') + def test_bad_param(self): # Can't give a size that's too small assert_raises(ValueError, np.dtype, |