summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2019-07-07 07:57:59 -0700
committerGitHub <noreply@github.com>2019-07-07 07:57:59 -0700
commit95c243221da5bedb7230e9ff229748f50acaf869 (patch)
treef39e58bec6eca9168f1e0ebe3ffc95d6a4ba71e7
parent07555c841feb03683ce01d49762fe9b7053a5626 (diff)
parentf723325b6f36868dfa483ff777e0447c229ffc42 (diff)
downloadnumpy-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.src12
-rw-r--r--numpy/core/src/multiarray/descriptor.c3
-rw-r--r--numpy/core/tests/test_dtype.py30
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,