test_numpy_dtypes.py revision 11986:c12e4625ab56
1import re 2import pytest 3 4with pytest.suppress(ImportError): 5 import numpy as np 6 7 8@pytest.fixture(scope='module') 9def simple_dtype(): 10 return np.dtype({'names': ['x', 'y', 'z'], 11 'formats': ['?', 'u4', 'f4'], 12 'offsets': [0, 4, 8]}) 13 14 15@pytest.fixture(scope='module') 16def packed_dtype(): 17 return np.dtype([('x', '?'), ('y', 'u4'), ('z', 'f4')]) 18 19 20def assert_equal(actual, expected_data, expected_dtype): 21 np.testing.assert_equal(actual, np.array(expected_data, dtype=expected_dtype)) 22 23 24@pytest.requires_numpy 25def test_format_descriptors(): 26 from pybind11_tests import get_format_unbound, print_format_descriptors 27 28 with pytest.raises(RuntimeError) as excinfo: 29 get_format_unbound() 30 assert re.match('^NumPy type info missing for .*UnboundStruct.*$', str(excinfo.value)) 31 32 assert print_format_descriptors() == [ 33 "T{?:x:3xI:y:f:z:}", 34 "T{?:x:=I:y:=f:z:}", 35 "T{T{?:x:3xI:y:f:z:}:a:T{?:x:=I:y:=f:z:}:b:}", 36 "T{?:x:3xI:y:f:z:12x}", 37 "T{8xT{?:x:3xI:y:f:z:12x}:a:8x}", 38 "T{3s:a:3s:b:}", 39 'T{q:e1:B:e2:}' 40 ] 41 42 43@pytest.requires_numpy 44def test_dtype(simple_dtype): 45 from pybind11_tests import (print_dtypes, test_dtype_ctors, test_dtype_methods, 46 trailing_padding_dtype, buffer_to_dtype) 47 48 assert print_dtypes() == [ 49 "{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':12}", 50 "[('x', '?'), ('y', '<u4'), ('z', '<f4')]", 51 "[('a', {'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8]," 52 " 'itemsize':12}), ('b', [('x', '?'), ('y', '<u4'), ('z', '<f4')])]", 53 "{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}", 54 "{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4']," 55 " 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}", 56 "[('a', 'S3'), ('b', 'S3')]", 57 "[('e1', '<i8'), ('e2', 'u1')]", 58 "[('x', 'i1'), ('y', '<u8')]" 59 ] 60 61 d1 = np.dtype({'names': ['a', 'b'], 'formats': ['int32', 'float64'], 62 'offsets': [1, 10], 'itemsize': 20}) 63 d2 = np.dtype([('a', 'i4'), ('b', 'f4')]) 64 assert test_dtype_ctors() == [np.dtype('int32'), np.dtype('float64'), 65 np.dtype('bool'), d1, d1, np.dtype('uint32'), d2] 66 67 assert test_dtype_methods() == [np.dtype('int32'), simple_dtype, False, True, 68 np.dtype('int32').itemsize, simple_dtype.itemsize] 69 70 assert trailing_padding_dtype() == buffer_to_dtype(np.zeros(1, trailing_padding_dtype())) 71 72 73@pytest.requires_numpy 74def test_recarray(simple_dtype, packed_dtype): 75 from pybind11_tests import (create_rec_simple, create_rec_packed, create_rec_nested, 76 print_rec_simple, print_rec_packed, print_rec_nested, 77 create_rec_partial, create_rec_partial_nested) 78 79 elements = [(False, 0, 0.0), (True, 1, 1.5), (False, 2, 3.0)] 80 81 for func, dtype in [(create_rec_simple, simple_dtype), (create_rec_packed, packed_dtype)]: 82 arr = func(0) 83 assert arr.dtype == dtype 84 assert_equal(arr, [], simple_dtype) 85 assert_equal(arr, [], packed_dtype) 86 87 arr = func(3) 88 assert arr.dtype == dtype 89 assert_equal(arr, elements, simple_dtype) 90 assert_equal(arr, elements, packed_dtype) 91 92 if dtype == simple_dtype: 93 assert print_rec_simple(arr) == [ 94 "s:0,0,0", 95 "s:1,1,1.5", 96 "s:0,2,3" 97 ] 98 else: 99 assert print_rec_packed(arr) == [ 100 "p:0,0,0", 101 "p:1,1,1.5", 102 "p:0,2,3" 103 ] 104 105 nested_dtype = np.dtype([('a', simple_dtype), ('b', packed_dtype)]) 106 107 arr = create_rec_nested(0) 108 assert arr.dtype == nested_dtype 109 assert_equal(arr, [], nested_dtype) 110 111 arr = create_rec_nested(3) 112 assert arr.dtype == nested_dtype 113 assert_equal(arr, [((False, 0, 0.0), (True, 1, 1.5)), 114 ((True, 1, 1.5), (False, 2, 3.0)), 115 ((False, 2, 3.0), (True, 3, 4.5))], nested_dtype) 116 assert print_rec_nested(arr) == [ 117 "n:a=s:0,0,0;b=p:1,1,1.5", 118 "n:a=s:1,1,1.5;b=p:0,2,3", 119 "n:a=s:0,2,3;b=p:1,3,4.5" 120 ] 121 122 arr = create_rec_partial(3) 123 assert str(arr.dtype) == \ 124 "{'names':['x','y','z'], 'formats':['?','<u4','<f4'], 'offsets':[0,4,8], 'itemsize':24}" 125 partial_dtype = arr.dtype 126 assert '' not in arr.dtype.fields 127 assert partial_dtype.itemsize > simple_dtype.itemsize 128 assert_equal(arr, elements, simple_dtype) 129 assert_equal(arr, elements, packed_dtype) 130 131 arr = create_rec_partial_nested(3) 132 assert str(arr.dtype) == \ 133 "{'names':['a'], 'formats':[{'names':['x','y','z'], 'formats':['?','<u4','<f4']," \ 134 " 'offsets':[0,4,8], 'itemsize':24}], 'offsets':[8], 'itemsize':40}" 135 assert '' not in arr.dtype.fields 136 assert '' not in arr.dtype.fields['a'][0].fields 137 assert arr.dtype.itemsize > partial_dtype.itemsize 138 np.testing.assert_equal(arr['a'], create_rec_partial(3)) 139 140 141@pytest.requires_numpy 142def test_array_constructors(): 143 from pybind11_tests import test_array_ctors 144 145 data = np.arange(1, 7, dtype='int32') 146 for i in range(8): 147 np.testing.assert_array_equal(test_array_ctors(10 + i), data.reshape((3, 2))) 148 np.testing.assert_array_equal(test_array_ctors(20 + i), data.reshape((3, 2))) 149 for i in range(5): 150 np.testing.assert_array_equal(test_array_ctors(30 + i), data) 151 np.testing.assert_array_equal(test_array_ctors(40 + i), data) 152 153 154@pytest.requires_numpy 155def test_string_array(): 156 from pybind11_tests import create_string_array, print_string_array 157 158 arr = create_string_array(True) 159 assert str(arr.dtype) == "[('a', 'S3'), ('b', 'S3')]" 160 assert print_string_array(arr) == [ 161 "a='',b=''", 162 "a='a',b='a'", 163 "a='ab',b='ab'", 164 "a='abc',b='abc'" 165 ] 166 dtype = arr.dtype 167 assert arr['a'].tolist() == [b'', b'a', b'ab', b'abc'] 168 assert arr['b'].tolist() == [b'', b'a', b'ab', b'abc'] 169 arr = create_string_array(False) 170 assert dtype == arr.dtype 171 172 173@pytest.requires_numpy 174def test_enum_array(): 175 from pybind11_tests import create_enum_array, print_enum_array 176 177 arr = create_enum_array(3) 178 dtype = arr.dtype 179 assert dtype == np.dtype([('e1', '<i8'), ('e2', 'u1')]) 180 assert print_enum_array(arr) == [ 181 "e1=A,e2=X", 182 "e1=B,e2=Y", 183 "e1=A,e2=X" 184 ] 185 assert arr['e1'].tolist() == [-1, 1, -1] 186 assert arr['e2'].tolist() == [1, 2, 1] 187 assert create_enum_array(0).dtype == dtype 188 189 190@pytest.requires_numpy 191def test_signature(doc): 192 from pybind11_tests import create_rec_nested 193 194 assert doc(create_rec_nested) == "create_rec_nested(arg0: int) -> numpy.ndarray[NestedStruct]" 195 196 197@pytest.requires_numpy 198def test_scalar_conversion(): 199 from pybind11_tests import (create_rec_simple, f_simple, 200 create_rec_packed, f_packed, 201 create_rec_nested, f_nested, 202 create_enum_array) 203 204 n = 3 205 arrays = [create_rec_simple(n), create_rec_packed(n), 206 create_rec_nested(n), create_enum_array(n)] 207 funcs = [f_simple, f_packed, f_nested] 208 209 for i, func in enumerate(funcs): 210 for j, arr in enumerate(arrays): 211 if i == j and i < 2: 212 assert [func(arr[k]) for k in range(n)] == [k * 10 for k in range(n)] 213 else: 214 with pytest.raises(TypeError) as excinfo: 215 func(arr[0]) 216 assert 'incompatible function arguments' in str(excinfo.value) 217 218 219@pytest.requires_numpy 220def test_register_dtype(): 221 from pybind11_tests import register_dtype 222 223 with pytest.raises(RuntimeError) as excinfo: 224 register_dtype() 225 assert 'dtype is already registered' in str(excinfo.value) 226