summaryrefslogtreecommitdiff
path: root/ext/pybind11/tests/test_numpy_dtypes.py
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pybind11/tests/test_numpy_dtypes.py')
-rw-r--r--ext/pybind11/tests/test_numpy_dtypes.py139
1 files changed, 93 insertions, 46 deletions
diff --git a/ext/pybind11/tests/test_numpy_dtypes.py b/ext/pybind11/tests/test_numpy_dtypes.py
index 52ebe0ede..f63814f9d 100644
--- a/ext/pybind11/tests/test_numpy_dtypes.py
+++ b/ext/pybind11/tests/test_numpy_dtypes.py
@@ -1,27 +1,69 @@
import re
import pytest
+pytestmark = pytest.requires_numpy
+
with pytest.suppress(ImportError):
import numpy as np
@pytest.fixture(scope='module')
def simple_dtype():
- return np.dtype({'names': ['x', 'y', 'z'],
- 'formats': ['?', 'u4', 'f4'],
- 'offsets': [0, 4, 8]})
+ ld = np.dtype('longdouble')
+ return np.dtype({'names': ['bool_', 'uint_', 'float_', 'ldbl_'],
+ 'formats': ['?', 'u4', 'f4', 'f{}'.format(ld.itemsize)],
+ 'offsets': [0, 4, 8, (16 if ld.alignment > 4 else 12)]})
@pytest.fixture(scope='module')
def packed_dtype():
- return np.dtype([('x', '?'), ('y', 'u4'), ('z', 'f4')])
+ return np.dtype([('bool_', '?'), ('uint_', 'u4'), ('float_', 'f4'), ('ldbl_', 'g')])
+
+
+def dt_fmt():
+ from sys import byteorder
+ e = '<' if byteorder == 'little' else '>'
+ return ("{{'names':['bool_','uint_','float_','ldbl_'],"
+ " 'formats':['?','" + e + "u4','" + e + "f4','" + e + "f{}'],"
+ " 'offsets':[0,4,8,{}], 'itemsize':{}}}")
+
+
+def simple_dtype_fmt():
+ ld = np.dtype('longdouble')
+ simple_ld_off = 12 + 4 * (ld.alignment > 4)
+ return dt_fmt().format(ld.itemsize, simple_ld_off, simple_ld_off + ld.itemsize)
+
+
+def packed_dtype_fmt():
+ from sys import byteorder
+ return "[('bool_', '?'), ('uint_', '{e}u4'), ('float_', '{e}f4'), ('ldbl_', '{e}f{}')]".format(
+ np.dtype('longdouble').itemsize, e='<' if byteorder == 'little' else '>')
+
+
+def partial_ld_offset():
+ return 12 + 4 * (np.dtype('uint64').alignment > 4) + 8 + 8 * (
+ np.dtype('longdouble').alignment > 8)
+
+
+def partial_dtype_fmt():
+ ld = np.dtype('longdouble')
+ partial_ld_off = partial_ld_offset()
+ return dt_fmt().format(ld.itemsize, partial_ld_off, partial_ld_off + ld.itemsize)
+
+
+def partial_nested_fmt():
+ ld = np.dtype('longdouble')
+ partial_nested_off = 8 + 8 * (ld.alignment > 8)
+ partial_ld_off = partial_ld_offset()
+ partial_nested_size = partial_nested_off * 2 + partial_ld_off + ld.itemsize
+ return "{{'names':['a'], 'formats':[{}], 'offsets':[{}], 'itemsize':{}}}".format(
+ partial_dtype_fmt(), partial_nested_off, partial_nested_size)
def assert_equal(actual, expected_data, expected_dtype):
np.testing.assert_equal(actual, np.array(expected_data, dtype=expected_dtype))
-@pytest.requires_numpy
def test_format_descriptors():
from pybind11_tests import get_format_unbound, print_format_descriptors
@@ -29,33 +71,40 @@ def test_format_descriptors():
get_format_unbound()
assert re.match('^NumPy type info missing for .*UnboundStruct.*$', str(excinfo.value))
+ ld = np.dtype('longdouble')
+ ldbl_fmt = ('4x' if ld.alignment > 4 else '') + ld.char
+ ss_fmt = "T{?:bool_:3xI:uint_:f:float_:" + ldbl_fmt + ":ldbl_:}"
+ dbl = np.dtype('double')
+ partial_fmt = ("T{?:bool_:3xI:uint_:f:float_:" +
+ str(4 * (dbl.alignment > 4) + dbl.itemsize + 8 * (ld.alignment > 8)) +
+ "xg:ldbl_:}")
+ nested_extra = str(max(8, ld.alignment))
assert print_format_descriptors() == [
- "T{?:x:3xI:y:f:z:}",
- "T{?:x:=I:y:=f:z:}",
- "T{T{?:x:3xI:y:f:z:}:a:T{?:x:=I:y:=f:z:}:b:}",
- "T{?:x:3xI:y:f:z:12x}",
- "T{8xT{?:x:3xI:y:f:z:12x}:a:8x}",
+ ss_fmt,
+ "T{?:bool_:^I:uint_:^f:float_:^g:ldbl_:}",
+ "T{" + ss_fmt + ":a:T{?:bool_:^I:uint_:^f:float_:^g:ldbl_:}:b:}",
+ partial_fmt,
+ "T{" + nested_extra + "x" + partial_fmt + ":a:" + nested_extra + "x}",
"T{3s:a:3s:b:}",
'T{q:e1:B:e2:}'
]
-@pytest.requires_numpy
def test_dtype(simple_dtype):
from pybind11_tests import (print_dtypes, test_dtype_ctors, test_dtype_methods,
trailing_padding_dtype, buffer_to_dtype)
+ from sys import byteorder
+ e = '<' if byteorder == 'little' else '>'
assert print_dtypes() == [
- "{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':12}",
- "[('x', '?'), ('y', '<u4'), ('z', '<f4')]",
- "[('a', {'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8],"
- " 'itemsize':12}), ('b', [('x', '?'), ('y', '<u4'), ('z', '<f4')])]",
- "{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}",
- "{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4'],"
- " 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}",
+ simple_dtype_fmt(),
+ packed_dtype_fmt(),
+ "[('a', {}), ('b', {})]".format(simple_dtype_fmt(), packed_dtype_fmt()),
+ partial_dtype_fmt(),
+ partial_nested_fmt(),
"[('a', 'S3'), ('b', 'S3')]",
- "[('e1', '<i8'), ('e2', 'u1')]",
- "[('x', 'i1'), ('y', '<u8')]"
+ "[('e1', '" + e + "i8'), ('e2', 'u1')]",
+ "[('x', 'i1'), ('y', '" + e + "u8')]"
]
d1 = np.dtype({'names': ['a', 'b'], 'formats': ['int32', 'float64'],
@@ -70,13 +119,12 @@ def test_dtype(simple_dtype):
assert trailing_padding_dtype() == buffer_to_dtype(np.zeros(1, trailing_padding_dtype()))
-@pytest.requires_numpy
def test_recarray(simple_dtype, packed_dtype):
from pybind11_tests import (create_rec_simple, create_rec_packed, create_rec_nested,
print_rec_simple, print_rec_packed, print_rec_nested,
create_rec_partial, create_rec_partial_nested)
- elements = [(False, 0, 0.0), (True, 1, 1.5), (False, 2, 3.0)]
+ elements = [(False, 0, 0.0, -0.0), (True, 1, 1.5, -2.5), (False, 2, 3.0, -5.0)]
for func, dtype in [(create_rec_simple, simple_dtype), (create_rec_packed, packed_dtype)]:
arr = func(0)
@@ -91,15 +139,15 @@ def test_recarray(simple_dtype, packed_dtype):
if dtype == simple_dtype:
assert print_rec_simple(arr) == [
- "s:0,0,0",
- "s:1,1,1.5",
- "s:0,2,3"
+ "s:0,0,0,-0",
+ "s:1,1,1.5,-2.5",
+ "s:0,2,3,-5"
]
else:
assert print_rec_packed(arr) == [
- "p:0,0,0",
- "p:1,1,1.5",
- "p:0,2,3"
+ "p:0,0,0,-0",
+ "p:1,1,1.5,-2.5",
+ "p:0,2,3,-5"
]
nested_dtype = np.dtype([('a', simple_dtype), ('b', packed_dtype)])
@@ -110,18 +158,17 @@ def test_recarray(simple_dtype, packed_dtype):
arr = create_rec_nested(3)
assert arr.dtype == nested_dtype
- assert_equal(arr, [((False, 0, 0.0), (True, 1, 1.5)),
- ((True, 1, 1.5), (False, 2, 3.0)),
- ((False, 2, 3.0), (True, 3, 4.5))], nested_dtype)
+ assert_equal(arr, [((False, 0, 0.0, -0.0), (True, 1, 1.5, -2.5)),
+ ((True, 1, 1.5, -2.5), (False, 2, 3.0, -5.0)),
+ ((False, 2, 3.0, -5.0), (True, 3, 4.5, -7.5))], nested_dtype)
assert print_rec_nested(arr) == [
- "n:a=s:0,0,0;b=p:1,1,1.5",
- "n:a=s:1,1,1.5;b=p:0,2,3",
- "n:a=s:0,2,3;b=p:1,3,4.5"
+ "n:a=s:0,0,0,-0;b=p:1,1,1.5,-2.5",
+ "n:a=s:1,1,1.5,-2.5;b=p:0,2,3,-5",
+ "n:a=s:0,2,3,-5;b=p:1,3,4.5,-7.5"
]
arr = create_rec_partial(3)
- assert str(arr.dtype) == \
- "{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}"
+ assert str(arr.dtype) == partial_dtype_fmt()
partial_dtype = arr.dtype
assert '' not in arr.dtype.fields
assert partial_dtype.itemsize > simple_dtype.itemsize
@@ -129,16 +176,13 @@ def test_recarray(simple_dtype, packed_dtype):
assert_equal(arr, elements, packed_dtype)
arr = create_rec_partial_nested(3)
- assert str(arr.dtype) == \
- "{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4']," \
- " 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}"
+ assert str(arr.dtype) == partial_nested_fmt()
assert '' not in arr.dtype.fields
assert '' not in arr.dtype.fields['a'][0].fields
assert arr.dtype.itemsize > partial_dtype.itemsize
np.testing.assert_equal(arr['a'], create_rec_partial(3))
-@pytest.requires_numpy
def test_array_constructors():
from pybind11_tests import test_array_ctors
@@ -151,7 +195,6 @@ def test_array_constructors():
np.testing.assert_array_equal(test_array_ctors(40 + i), data)
-@pytest.requires_numpy
def test_string_array():
from pybind11_tests import create_string_array, print_string_array
@@ -170,13 +213,14 @@ def test_string_array():
assert dtype == arr.dtype
-@pytest.requires_numpy
def test_enum_array():
from pybind11_tests import create_enum_array, print_enum_array
+ from sys import byteorder
+ e = '<' if byteorder == 'little' else '>'
arr = create_enum_array(3)
dtype = arr.dtype
- assert dtype == np.dtype([('e1', '<i8'), ('e2', 'u1')])
+ assert dtype == np.dtype([('e1', e + 'i8'), ('e2', 'u1')])
assert print_enum_array(arr) == [
"e1=A,e2=X",
"e1=B,e2=Y",
@@ -187,14 +231,12 @@ def test_enum_array():
assert create_enum_array(0).dtype == dtype
-@pytest.requires_numpy
def test_signature(doc):
from pybind11_tests import create_rec_nested
assert doc(create_rec_nested) == "create_rec_nested(arg0: int) -> numpy.ndarray[NestedStruct]"
-@pytest.requires_numpy
def test_scalar_conversion():
from pybind11_tests import (create_rec_simple, f_simple,
create_rec_packed, f_packed,
@@ -216,10 +258,15 @@ def test_scalar_conversion():
assert 'incompatible function arguments' in str(excinfo.value)
-@pytest.requires_numpy
def test_register_dtype():
from pybind11_tests import register_dtype
with pytest.raises(RuntimeError) as excinfo:
register_dtype()
assert 'dtype is already registered' in str(excinfo.value)
+
+
+@pytest.requires_numpy
+def test_compare_buffer_info():
+ from pybind11_tests import compare_buffer_info
+ assert all(compare_buffer_info())