Scarab  v2.9.1
Project 8 C++ Utility Library
test_numpy_array.py
Go to the documentation of this file.
1 import pytest
2 from pybind11_tests import numpy_array as m
3 
4 pytestmark = pytest.requires_numpy
5 
6 with pytest.suppress(ImportError):
7  import numpy as np
8 
9 
11  # See issue #1328.
12  # - Platform-dependent sizes.
13  for size_check in m.get_platform_dtype_size_checks():
14  print(size_check)
15  assert size_check.size_cpp == size_check.size_numpy, size_check
16  # - Concrete sizes.
17  for check in m.get_concrete_dtype_checks():
18  print(check)
19  assert check.numpy == check.pybind11, check
20  if check.numpy.num != check.pybind11.num:
21  print("NOTE: typenum mismatch for {}: {} != {}".format(
22  check, check.numpy.num, check.pybind11.num))
23 
24 
25 @pytest.fixture(scope='function')
26 def arr():
27  return np.array([[1, 2, 3], [4, 5, 6]], '=u2')
28 
29 
31  a = np.array(0, 'f8')
32  assert m.ndim(a) == 0
33  assert all(m.shape(a) == [])
34  assert all(m.strides(a) == [])
35  with pytest.raises(IndexError) as excinfo:
36  m.shape(a, 0)
37  assert str(excinfo.value) == 'invalid axis: 0 (ndim = 0)'
38  with pytest.raises(IndexError) as excinfo:
39  m.strides(a, 0)
40  assert str(excinfo.value) == 'invalid axis: 0 (ndim = 0)'
41  assert m.writeable(a)
42  assert m.size(a) == 1
43  assert m.itemsize(a) == 8
44  assert m.nbytes(a) == 8
45  assert m.owndata(a)
46 
47  a = np.array([[1, 2, 3], [4, 5, 6]], 'u2').view()
48  a.flags.writeable = False
49  assert m.ndim(a) == 2
50  assert all(m.shape(a) == [2, 3])
51  assert m.shape(a, 0) == 2
52  assert m.shape(a, 1) == 3
53  assert all(m.strides(a) == [6, 2])
54  assert m.strides(a, 0) == 6
55  assert m.strides(a, 1) == 2
56  with pytest.raises(IndexError) as excinfo:
57  m.shape(a, 2)
58  assert str(excinfo.value) == 'invalid axis: 2 (ndim = 2)'
59  with pytest.raises(IndexError) as excinfo:
60  m.strides(a, 2)
61  assert str(excinfo.value) == 'invalid axis: 2 (ndim = 2)'
62  assert not m.writeable(a)
63  assert m.size(a) == 6
64  assert m.itemsize(a) == 2
65  assert m.nbytes(a) == 12
66  assert not m.owndata(a)
67 
68 
69 @pytest.mark.parametrize('args, ret', [([], 0), ([0], 0), ([1], 3), ([0, 1], 1), ([1, 2], 5)])
70 def test_index_offset(arr, args, ret):
71  assert m.index_at(arr, *args) == ret
72  assert m.index_at_t(arr, *args) == ret
73  assert m.offset_at(arr, *args) == ret * arr.dtype.itemsize
74  assert m.offset_at_t(arr, *args) == ret * arr.dtype.itemsize
75 
76 
78  for func in (m.index_at, m.index_at_t, m.offset_at, m.offset_at_t, m.data, m.data_t,
79  m.mutate_data, m.mutate_data_t):
80  with pytest.raises(IndexError) as excinfo:
81  func(arr, 1, 2, 3)
82  assert str(excinfo.value) == 'too many indices for an array: 3 (ndim = 2)'
83 
84 
85 @pytest.mark.parametrize('args, ret',
86  [([], [1, 2, 3, 4, 5, 6]),
87  ([1], [4, 5, 6]),
88  ([0, 1], [2, 3, 4, 5, 6]),
89  ([1, 2], [6])])
90 def test_data(arr, args, ret):
91  from sys import byteorder
92  assert all(m.data_t(arr, *args) == ret)
93  assert all(m.data(arr, *args)[(0 if byteorder == 'little' else 1)::2] == ret)
94  assert all(m.data(arr, *args)[(1 if byteorder == 'little' else 0)::2] == 0)
95 
96 
97 @pytest.mark.parametrize('dim', [0, 1, 3])
98 def test_at_fail(arr, dim):
99  for func in m.at_t, m.mutate_at_t:
100  with pytest.raises(IndexError) as excinfo:
101  func(arr, *([0] * dim))
102  assert str(excinfo.value) == 'index dimension mismatch: {} (ndim = 2)'.format(dim)
103 
104 
105 def test_at(arr):
106  assert m.at_t(arr, 0, 2) == 3
107  assert m.at_t(arr, 1, 0) == 4
108 
109  assert all(m.mutate_at_t(arr, 0, 2).ravel() == [1, 2, 4, 4, 5, 6])
110  assert all(m.mutate_at_t(arr, 1, 0).ravel() == [1, 2, 4, 5, 5, 6])
111 
112 
114  arr.flags.writeable = False
115  for func, args in (m.mutate_data, ()), (m.mutate_data_t, ()), (m.mutate_at_t, (0, 0)):
116  with pytest.raises(ValueError) as excinfo:
117  func(arr, *args)
118  assert str(excinfo.value) == 'array is not writeable'
119 
120 
122  assert all(m.mutate_data(arr).ravel() == [2, 4, 6, 8, 10, 12])
123  assert all(m.mutate_data(arr).ravel() == [4, 8, 12, 16, 20, 24])
124  assert all(m.mutate_data(arr, 1).ravel() == [4, 8, 12, 32, 40, 48])
125  assert all(m.mutate_data(arr, 0, 1).ravel() == [4, 16, 24, 64, 80, 96])
126  assert all(m.mutate_data(arr, 1, 2).ravel() == [4, 16, 24, 64, 80, 192])
127 
128  assert all(m.mutate_data_t(arr).ravel() == [5, 17, 25, 65, 81, 193])
129  assert all(m.mutate_data_t(arr).ravel() == [6, 18, 26, 66, 82, 194])
130  assert all(m.mutate_data_t(arr, 1).ravel() == [6, 18, 26, 67, 83, 195])
131  assert all(m.mutate_data_t(arr, 0, 1).ravel() == [6, 19, 27, 68, 84, 196])
132  assert all(m.mutate_data_t(arr, 1, 2).ravel() == [6, 19, 27, 68, 84, 197])
133 
134 
136  for func in (m.index_at, m.index_at_t, m.data, m.data_t,
137  m.mutate_data, m.mutate_data_t, m.at_t, m.mutate_at_t):
138  with pytest.raises(IndexError) as excinfo:
139  func(arr, 2, 0)
140  assert str(excinfo.value) == 'index 2 is out of bounds for axis 0 with size 2'
141  with pytest.raises(IndexError) as excinfo:
142  func(arr, 0, 4)
143  assert str(excinfo.value) == 'index 4 is out of bounds for axis 1 with size 3'
144 
145 
147  assert m.make_c_array().flags.c_contiguous
148  assert not m.make_c_array().flags.f_contiguous
149  assert m.make_f_array().flags.f_contiguous
150  assert not m.make_f_array().flags.c_contiguous
151 
152 
154  m.make_empty_shaped_array()
155 
156  # empty shape means numpy scalar, PEP 3118
157  assert m.scalar_int().ndim == 0
158  assert m.scalar_int().shape == ()
159  assert m.scalar_int() == 42
160 
161 
162 def test_wrap():
163  def assert_references(a, b, base=None):
164  from distutils.version import LooseVersion
165  if base is None:
166  base = a
167  assert a is not b
168  assert a.__array_interface__['data'][0] == b.__array_interface__['data'][0]
169  assert a.shape == b.shape
170  assert a.strides == b.strides
171  assert a.flags.c_contiguous == b.flags.c_contiguous
172  assert a.flags.f_contiguous == b.flags.f_contiguous
173  assert a.flags.writeable == b.flags.writeable
174  assert a.flags.aligned == b.flags.aligned
175  if LooseVersion(np.__version__) >= LooseVersion("1.14.0"):
176  assert a.flags.writebackifcopy == b.flags.writebackifcopy
177  else:
178  assert a.flags.updateifcopy == b.flags.updateifcopy
179  assert np.all(a == b)
180  assert not b.flags.owndata
181  assert b.base is base
182  if a.flags.writeable and a.ndim == 2:
183  a[0, 0] = 1234
184  assert b[0, 0] == 1234
185 
186  a1 = np.array([1, 2], dtype=np.int16)
187  assert a1.flags.owndata and a1.base is None
188  a2 = m.wrap(a1)
189  assert_references(a1, a2)
190 
191  a1 = np.array([[1, 2], [3, 4]], dtype=np.float32, order='F')
192  assert a1.flags.owndata and a1.base is None
193  a2 = m.wrap(a1)
194  assert_references(a1, a2)
195 
196  a1 = np.array([[1, 2], [3, 4]], dtype=np.float32, order='C')
197  a1.flags.writeable = False
198  a2 = m.wrap(a1)
199  assert_references(a1, a2)
200 
201  a1 = np.random.random((4, 4, 4))
202  a2 = m.wrap(a1)
203  assert_references(a1, a2)
204 
205  a1t = a1.transpose()
206  a2 = m.wrap(a1t)
207  assert_references(a1t, a2, a1)
208 
209  a1d = a1.diagonal()
210  a2 = m.wrap(a1d)
211  assert_references(a1d, a2, a1)
212 
213  a1m = a1[::-1, ::-1, ::-1]
214  a2 = m.wrap(a1m)
215  assert_references(a1m, a2, a1)
216 
217 
218 def test_numpy_view(capture):
219  with capture:
220  ac = m.ArrayClass()
221  ac_view_1 = ac.numpy_view()
222  ac_view_2 = ac.numpy_view()
223  assert np.all(ac_view_1 == np.array([1, 2], dtype=np.int32))
224  del ac
225  pytest.gc_collect()
226  assert capture == """
227  ArrayClass()
228  ArrayClass::numpy_view()
229  ArrayClass::numpy_view()
230  """
231  ac_view_1[0] = 4
232  ac_view_1[1] = 3
233  assert ac_view_2[0] == 4
234  assert ac_view_2[1] == 3
235  with capture:
236  del ac_view_1
237  del ac_view_2
238  pytest.gc_collect()
239  pytest.gc_collect()
240  assert capture == """
241  ~ArrayClass()
242  """
243 
244 
245 @pytest.unsupported_on_pypy
247  m.function_taking_uint64(123)
248  m.function_taking_uint64(np.uint64(123))
249 
250 
252  assert m.isinstance_untyped(np.array([1, 2, 3]), "not an array")
253  assert m.isinstance_typed(np.array([1.0, 2.0, 3.0]))
254 
255 
257  defaults = m.default_constructors()
258  for a in defaults.values():
259  assert a.size == 0
260  assert defaults["array"].dtype == np.array([]).dtype
261  assert defaults["array_t<int32>"].dtype == np.int32
262  assert defaults["array_t<double>"].dtype == np.float64
263 
264  results = m.converting_constructors([1, 2, 3])
265  for a in results.values():
266  np.testing.assert_array_equal(a, [1, 2, 3])
267  assert results["array"].dtype == np.int_
268  assert results["array_t<int32>"].dtype == np.int32
269  assert results["array_t<double>"].dtype == np.float64
270 
271 
273  # Exact overload matches:
274  assert m.overloaded(np.array([1], dtype='float64')) == 'double'
275  assert m.overloaded(np.array([1], dtype='float32')) == 'float'
276  assert m.overloaded(np.array([1], dtype='ushort')) == 'unsigned short'
277  assert m.overloaded(np.array([1], dtype='intc')) == 'int'
278  assert m.overloaded(np.array([1], dtype='longlong')) == 'long long'
279  assert m.overloaded(np.array([1], dtype='complex')) == 'double complex'
280  assert m.overloaded(np.array([1], dtype='csingle')) == 'float complex'
281 
282  # No exact match, should call first convertible version:
283  assert m.overloaded(np.array([1], dtype='uint8')) == 'double'
284 
285  with pytest.raises(TypeError) as excinfo:
286  m.overloaded("not an array")
287  assert msg(excinfo.value) == """
288  overloaded(): incompatible function arguments. The following argument types are supported:
289  1. (arg0: numpy.ndarray[float64]) -> str
290  2. (arg0: numpy.ndarray[float32]) -> str
291  3. (arg0: numpy.ndarray[int32]) -> str
292  4. (arg0: numpy.ndarray[uint16]) -> str
293  5. (arg0: numpy.ndarray[int64]) -> str
294  6. (arg0: numpy.ndarray[complex128]) -> str
295  7. (arg0: numpy.ndarray[complex64]) -> str
296 
297  Invoked with: 'not an array'
298  """
299 
300  assert m.overloaded2(np.array([1], dtype='float64')) == 'double'
301  assert m.overloaded2(np.array([1], dtype='float32')) == 'float'
302  assert m.overloaded2(np.array([1], dtype='complex64')) == 'float complex'
303  assert m.overloaded2(np.array([1], dtype='complex128')) == 'double complex'
304  assert m.overloaded2(np.array([1], dtype='float32')) == 'float'
305 
306  assert m.overloaded3(np.array([1], dtype='float64')) == 'double'
307  assert m.overloaded3(np.array([1], dtype='intc')) == 'int'
308  expected_exc = """
309  overloaded3(): incompatible function arguments. The following argument types are supported:
310  1. (arg0: numpy.ndarray[int32]) -> str
311  2. (arg0: numpy.ndarray[float64]) -> str
312 
313  Invoked with: """
314 
315  with pytest.raises(TypeError) as excinfo:
316  m.overloaded3(np.array([1], dtype='uintc'))
317  assert msg(excinfo.value) == expected_exc + repr(np.array([1], dtype='uint32'))
318  with pytest.raises(TypeError) as excinfo:
319  m.overloaded3(np.array([1], dtype='float32'))
320  assert msg(excinfo.value) == expected_exc + repr(np.array([1.], dtype='float32'))
321  with pytest.raises(TypeError) as excinfo:
322  m.overloaded3(np.array([1], dtype='complex'))
323  assert msg(excinfo.value) == expected_exc + repr(np.array([1. + 0.j]))
324 
325  # Exact matches:
326  assert m.overloaded4(np.array([1], dtype='double')) == 'double'
327  assert m.overloaded4(np.array([1], dtype='longlong')) == 'long long'
328  # Non-exact matches requiring conversion. Since float to integer isn't a
329  # save conversion, it should go to the double overload, but short can go to
330  # either (and so should end up on the first-registered, the long long).
331  assert m.overloaded4(np.array([1], dtype='float32')) == 'double'
332  assert m.overloaded4(np.array([1], dtype='short')) == 'long long'
333 
334  assert m.overloaded5(np.array([1], dtype='double')) == 'double'
335  assert m.overloaded5(np.array([1], dtype='uintc')) == 'unsigned int'
336  assert m.overloaded5(np.array([1], dtype='float32')) == 'unsigned int'
337 
338 
340  """Tests fix for #685 - ndarray shouldn't go to std::string overload"""
341 
342  assert m.issue685("abc") == "string"
343  assert m.issue685(np.array([97, 98, 99], dtype='b')) == "array"
344  assert m.issue685(123) == "other"
345 
346 
348  z1 = np.array([[1, 2], [3, 4]], dtype='float64')
349  m.proxy_add2(z1, 10)
350  assert np.all(z1 == [[11, 12], [13, 14]])
351 
352  with pytest.raises(ValueError) as excinfo:
353  m.proxy_add2(np.array([1., 2, 3]), 5.0)
354  assert msg(excinfo.value) == "array has incorrect number of dimensions: 1; expected 2"
355 
356  expect_c = np.ndarray(shape=(3, 3, 3), buffer=np.array(range(3, 30)), dtype='int')
357  assert np.all(m.proxy_init3(3.0) == expect_c)
358  expect_f = np.transpose(expect_c)
359  assert np.all(m.proxy_init3F(3.0) == expect_f)
360 
361  assert m.proxy_squared_L2_norm(np.array(range(6))) == 55
362  assert m.proxy_squared_L2_norm(np.array(range(6), dtype="float64")) == 55
363 
364  assert m.proxy_auxiliaries2(z1) == [11, 11, True, 2, 8, 2, 2, 4, 32]
365  assert m.proxy_auxiliaries2(z1) == m.array_auxiliaries2(z1)
366 
367 
369  z1 = np.array([[1, 2], [3, 4]], dtype='float64')
370  m.proxy_add2_dyn(z1, 10)
371  assert np.all(z1 == [[11, 12], [13, 14]])
372 
373  expect_c = np.ndarray(shape=(3, 3, 3), buffer=np.array(range(3, 30)), dtype='int')
374  assert np.all(m.proxy_init3_dyn(3.0) == expect_c)
375 
376  assert m.proxy_auxiliaries2_dyn(z1) == [11, 11, True, 2, 8, 2, 2, 4, 32]
377  assert m.proxy_auxiliaries2_dyn(z1) == m.array_auxiliaries2(z1)
378 
379 
381  with pytest.raises(ValueError) as excinfo:
382  m.array_fail_test()
383  assert str(excinfo.value) == 'cannot create a pybind11::array from a nullptr'
384 
385  with pytest.raises(ValueError) as excinfo:
386  m.array_t_fail_test()
387  assert str(excinfo.value) == 'cannot create a pybind11::array_t from a nullptr'
388 
389  with pytest.raises(ValueError) as excinfo:
390  m.array_fail_test_negative_size()
391  assert str(excinfo.value) == 'negative dimensions are not allowed'
392 
393 
395  assert m.array_initializer_list1().shape == (1,)
396  assert m.array_initializer_list2().shape == (1, 2)
397  assert m.array_initializer_list3().shape == (1, 2, 3)
398  assert m.array_initializer_list4().shape == (1, 2, 3, 4)
399 
400 
402  a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype='float64')
403  m.array_reshape2(a)
404  assert(a.size == 9)
405  assert(np.all(a == [[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
406 
407  # total size change should succced with refcheck off
408  m.array_resize3(a, 4, False)
409  assert(a.size == 64)
410  # ... and fail with refcheck on
411  try:
412  m.array_resize3(a, 3, True)
413  except ValueError as e:
414  assert(str(e).startswith("cannot resize an array"))
415  # transposed array doesn't own data
416  b = a.transpose()
417  try:
418  m.array_resize3(b, 3, False)
419  except ValueError as e:
420  assert(str(e).startswith("cannot resize this array: it does not own its data"))
421  # ... but reshape should be fine
422  m.array_reshape2(b)
423  assert(b.shape == (8, 8))
424 
425 
426 @pytest.unsupported_on_pypy
428  a = m.create_and_resize(2)
429  assert(a.size == 4)
430  assert(np.all(a == 42.))
431 
432 
433 @pytest.unsupported_on_py2
435  a = m.index_using_ellipsis(np.zeros((5, 6, 7)))
436  assert a.shape == (6,)
437 
438 
439 @pytest.unsupported_on_pypy
441  from sys import getrefcount
442  dtype = np.dtype(np.float_)
443  a = np.array([1], dtype=dtype)
444  before = getrefcount(dtype)
445  m.ndim(a)
446  after = getrefcount(dtype)
447  assert after == before
def test_array_resize(msg)
def test_dim_check_fail(arr)
auto format(const std::locale &loc, const CharT *fmt, const Streamable &tp) -> decltype(to_stream(std::declval< std::basic_ostream< CharT > &>(), fmt, tp), std::basic_string< CharT >
Definition: date.h:5663
def msg()
Definition: conftest.py:165
def test_numpy_view(capture)
def test_mutate_readonly(arr)
def test_greedy_string_overload()
def test_bounds_check(arr)
def test_make_empty_shaped_array()
str repr(handle h)
Definition: pytypes.h:1383
def test_array_unchecked_dyn_dims(msg)
def test_cast_numpy_int64_to_uint64()
return os str()
def test_at_fail(arr, dim)
def test_array_unchecked_fixed_dims(msg)
def test_index_offset(arr, args, ret)
def test_array_create_and_resize(msg)
def test_overload_resolution(msg)
void print(Args &&...args)
Definition: pybind11.h:1849
auto range
Definition: cast.h:455
def test_data(arr, args, ret)