test_numpy_array.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 import pytest
3 
4 import env # noqa: F401
5 
6 from pybind11_tests import numpy_array as m
7 
8 np = pytest.importorskip("numpy")
9 
10 
12  # See issue #1328.
13  # - Platform-dependent sizes.
14  for size_check in m.get_platform_dtype_size_checks():
15  print(size_check)
16  assert size_check.size_cpp == size_check.size_numpy, size_check
17  # - Concrete sizes.
18  for check in m.get_concrete_dtype_checks():
19  print(check)
20  assert check.numpy == check.pybind11, check
21  if check.numpy.num != check.pybind11.num:
22  print("NOTE: typenum mismatch for {}: {} != {}".format(
23  check, check.numpy.num, check.pybind11.num))
24 
25 
26 @pytest.fixture(scope='function')
27 def arr():
28  return np.array([[1, 2, 3], [4, 5, 6]], '=u2')
29 
30 
32  a = np.array(0, 'f8')
33  assert m.ndim(a) == 0
34  assert all(m.shape(a) == [])
35  assert all(m.strides(a) == [])
36  with pytest.raises(IndexError) as excinfo:
37  m.shape(a, 0)
38  assert str(excinfo.value) == 'invalid axis: 0 (ndim = 0)'
39  with pytest.raises(IndexError) as excinfo:
40  m.strides(a, 0)
41  assert str(excinfo.value) == 'invalid axis: 0 (ndim = 0)'
42  assert m.writeable(a)
43  assert m.size(a) == 1
44  assert m.itemsize(a) == 8
45  assert m.nbytes(a) == 8
46  assert m.owndata(a)
47 
48  a = np.array([[1, 2, 3], [4, 5, 6]], 'u2').view()
49  a.flags.writeable = False
50  assert m.ndim(a) == 2
51  assert all(m.shape(a) == [2, 3])
52  assert m.shape(a, 0) == 2
53  assert m.shape(a, 1) == 3
54  assert all(m.strides(a) == [6, 2])
55  assert m.strides(a, 0) == 6
56  assert m.strides(a, 1) == 2
57  with pytest.raises(IndexError) as excinfo:
58  m.shape(a, 2)
59  assert str(excinfo.value) == 'invalid axis: 2 (ndim = 2)'
60  with pytest.raises(IndexError) as excinfo:
61  m.strides(a, 2)
62  assert str(excinfo.value) == 'invalid axis: 2 (ndim = 2)'
63  assert not m.writeable(a)
64  assert m.size(a) == 6
65  assert m.itemsize(a) == 2
66  assert m.nbytes(a) == 12
67  assert not m.owndata(a)
68 
69 
70 @pytest.mark.parametrize('args, ret', [([], 0), ([0], 0), ([1], 3), ([0, 1], 1), ([1, 2], 5)])
71 def test_index_offset(arr, args, ret):
72  assert m.index_at(arr, *args) == ret
73  assert m.index_at_t(arr, *args) == ret
74  assert m.offset_at(arr, *args) == ret * arr.dtype.itemsize
75  assert m.offset_at_t(arr, *args) == ret * arr.dtype.itemsize
76 
77 
79  for func in (m.index_at, m.index_at_t, m.offset_at, m.offset_at_t, m.data, m.data_t,
80  m.mutate_data, m.mutate_data_t):
81  with pytest.raises(IndexError) as excinfo:
82  func(arr, 1, 2, 3)
83  assert str(excinfo.value) == 'too many indices for an array: 3 (ndim = 2)'
84 
85 
86 @pytest.mark.parametrize('args, ret',
87  [([], [1, 2, 3, 4, 5, 6]),
88  ([1], [4, 5, 6]),
89  ([0, 1], [2, 3, 4, 5, 6]),
90  ([1, 2], [6])])
91 def test_data(arr, args, ret):
92  from sys import byteorder
93  assert all(m.data_t(arr, *args) == ret)
94  assert all(m.data(arr, *args)[(0 if byteorder == 'little' else 1)::2] == ret)
95  assert all(m.data(arr, *args)[(1 if byteorder == 'little' else 0)::2] == 0)
96 
97 
98 @pytest.mark.parametrize('dim', [0, 1, 3])
99 def test_at_fail(arr, dim):
100  for func in m.at_t, m.mutate_at_t:
101  with pytest.raises(IndexError) as excinfo:
102  func(arr, *([0] * dim))
103  assert str(excinfo.value) == 'index dimension mismatch: {} (ndim = 2)'.format(dim)
104 
105 
106 def test_at(arr):
107  assert m.at_t(arr, 0, 2) == 3
108  assert m.at_t(arr, 1, 0) == 4
109 
110  assert all(m.mutate_at_t(arr, 0, 2).ravel() == [1, 2, 4, 4, 5, 6])
111  assert all(m.mutate_at_t(arr, 1, 0).ravel() == [1, 2, 4, 5, 5, 6])
112 
113 
115  arr.flags.writeable = False
116  for func, args in (m.mutate_data, ()), (m.mutate_data_t, ()), (m.mutate_at_t, (0, 0)):
117  with pytest.raises(ValueError) as excinfo:
118  func(arr, *args)
119  assert str(excinfo.value) == 'array is not writeable'
120 
121 
123  assert all(m.mutate_data(arr).ravel() == [2, 4, 6, 8, 10, 12])
124  assert all(m.mutate_data(arr).ravel() == [4, 8, 12, 16, 20, 24])
125  assert all(m.mutate_data(arr, 1).ravel() == [4, 8, 12, 32, 40, 48])
126  assert all(m.mutate_data(arr, 0, 1).ravel() == [4, 16, 24, 64, 80, 96])
127  assert all(m.mutate_data(arr, 1, 2).ravel() == [4, 16, 24, 64, 80, 192])
128 
129  assert all(m.mutate_data_t(arr).ravel() == [5, 17, 25, 65, 81, 193])
130  assert all(m.mutate_data_t(arr).ravel() == [6, 18, 26, 66, 82, 194])
131  assert all(m.mutate_data_t(arr, 1).ravel() == [6, 18, 26, 67, 83, 195])
132  assert all(m.mutate_data_t(arr, 0, 1).ravel() == [6, 19, 27, 68, 84, 196])
133  assert all(m.mutate_data_t(arr, 1, 2).ravel() == [6, 19, 27, 68, 84, 197])
134 
135 
137  for func in (m.index_at, m.index_at_t, m.data, m.data_t,
138  m.mutate_data, m.mutate_data_t, m.at_t, m.mutate_at_t):
139  with pytest.raises(IndexError) as excinfo:
140  func(arr, 2, 0)
141  assert str(excinfo.value) == 'index 2 is out of bounds for axis 0 with size 2'
142  with pytest.raises(IndexError) as excinfo:
143  func(arr, 0, 4)
144  assert str(excinfo.value) == 'index 4 is out of bounds for axis 1 with size 3'
145 
146 
148  assert m.make_c_array().flags.c_contiguous
149  assert not m.make_c_array().flags.f_contiguous
150  assert m.make_f_array().flags.f_contiguous
151  assert not m.make_f_array().flags.c_contiguous
152 
153 
155  m.make_empty_shaped_array()
156 
157  # empty shape means numpy scalar, PEP 3118
158  assert m.scalar_int().ndim == 0
159  assert m.scalar_int().shape == ()
160  assert m.scalar_int() == 42
161 
162 
163 def test_wrap():
164  def assert_references(a, b, base=None):
165  from distutils.version import LooseVersion
166  if base is None:
167  base = a
168  assert a is not b
169  assert a.__array_interface__['data'][0] == b.__array_interface__['data'][0]
170  assert a.shape == b.shape
171  assert a.strides == b.strides
172  assert a.flags.c_contiguous == b.flags.c_contiguous
173  assert a.flags.f_contiguous == b.flags.f_contiguous
174  assert a.flags.writeable == b.flags.writeable
175  assert a.flags.aligned == b.flags.aligned
176  if LooseVersion(np.__version__) >= LooseVersion("1.14.0"):
177  assert a.flags.writebackifcopy == b.flags.writebackifcopy
178  else:
179  assert a.flags.updateifcopy == b.flags.updateifcopy
180  assert np.all(a == b)
181  assert not b.flags.owndata
182  assert b.base is base
183  if a.flags.writeable and a.ndim == 2:
184  a[0, 0] = 1234
185  assert b[0, 0] == 1234
186 
187  a1 = np.array([1, 2], dtype=np.int16)
188  assert a1.flags.owndata and a1.base is None
189  a2 = m.wrap(a1)
190  assert_references(a1, a2)
191 
192  a1 = np.array([[1, 2], [3, 4]], dtype=np.float32, order='F')
193  assert a1.flags.owndata and a1.base is None
194  a2 = m.wrap(a1)
195  assert_references(a1, a2)
196 
197  a1 = np.array([[1, 2], [3, 4]], dtype=np.float32, order='C')
198  a1.flags.writeable = False
199  a2 = m.wrap(a1)
200  assert_references(a1, a2)
201 
202  a1 = np.random.random((4, 4, 4))
203  a2 = m.wrap(a1)
204  assert_references(a1, a2)
205 
206  a1t = a1.transpose()
207  a2 = m.wrap(a1t)
208  assert_references(a1t, a2, a1)
209 
210  a1d = a1.diagonal()
211  a2 = m.wrap(a1d)
212  assert_references(a1d, a2, a1)
213 
214  a1m = a1[::-1, ::-1, ::-1]
215  a2 = m.wrap(a1m)
216  assert_references(a1m, a2, a1)
217 
218 
219 def test_numpy_view(capture):
220  with capture:
221  ac = m.ArrayClass()
222  ac_view_1 = ac.numpy_view()
223  ac_view_2 = ac.numpy_view()
224  assert np.all(ac_view_1 == np.array([1, 2], dtype=np.int32))
225  del ac
226  pytest.gc_collect()
227  assert capture == """
228  ArrayClass()
229  ArrayClass::numpy_view()
230  ArrayClass::numpy_view()
231  """
232  ac_view_1[0] = 4
233  ac_view_1[1] = 3
234  assert ac_view_2[0] == 4
235  assert ac_view_2[1] == 3
236  with capture:
237  del ac_view_1
238  del ac_view_2
239  pytest.gc_collect()
240  pytest.gc_collect()
241  assert capture == """
242  ~ArrayClass()
243  """
244 
245 
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[numpy.float64]) -> str
290  2. (arg0: numpy.ndarray[numpy.float32]) -> str
291  3. (arg0: numpy.ndarray[numpy.int32]) -> str
292  4. (arg0: numpy.ndarray[numpy.uint16]) -> str
293  5. (arg0: numpy.ndarray[numpy.int64]) -> str
294  6. (arg0: numpy.ndarray[numpy.complex128]) -> str
295  7. (arg0: numpy.ndarray[numpy.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[numpy.int32]) -> str
311  2. (arg0: numpy.ndarray[numpy.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.mark.xfail("env.PYPY")
428  a = m.create_and_resize(2)
429  assert(a.size == 4)
430  assert(np.all(a == 42.))
431 
432 
434  a = m.index_using_ellipsis(np.zeros((5, 6, 7)))
435  assert a.shape == (6,)
436 
437 
438 @pytest.mark.parametrize("forcecast", [False, True])
439 @pytest.mark.parametrize("contiguity", [None, 'C', 'F'])
440 @pytest.mark.parametrize("noconvert", [False, True])
441 @pytest.mark.filterwarnings(
442  "ignore:Casting complex values to real discards the imaginary part:numpy.ComplexWarning"
443 )
444 def test_argument_conversions(forcecast, contiguity, noconvert):
445  function_name = "accept_double"
446  if contiguity == 'C':
447  function_name += "_c_style"
448  elif contiguity == 'F':
449  function_name += "_f_style"
450  if forcecast:
451  function_name += "_forcecast"
452  if noconvert:
453  function_name += "_noconvert"
454  function = getattr(m, function_name)
455 
456  for dtype in [np.dtype('float32'), np.dtype('float64'), np.dtype('complex128')]:
457  for order in ['C', 'F']:
458  for shape in [(2, 2), (1, 3, 1, 1), (1, 1, 1), (0,)]:
459  if not noconvert:
460  # If noconvert is not passed, only complex128 needs to be truncated and
461  # "cannot be safely obtained". So without `forcecast`, the argument shouldn't
462  # be accepted.
463  should_raise = dtype.name == 'complex128' and not forcecast
464  else:
465  # If noconvert is passed, only float64 and the matching order is accepted.
466  # If at most one dimension has a size greater than 1, the array is also
467  # trivially contiguous.
468  trivially_contiguous = sum(1 for d in shape if d > 1) <= 1
469  should_raise = (
470  dtype.name != 'float64' or
471  (contiguity is not None and
472  contiguity != order and
473  not trivially_contiguous)
474  )
475 
476  array = np.zeros(shape, dtype=dtype, order=order)
477  if not should_raise:
478  function(array)
479  else:
480  with pytest.raises(TypeError, match="incompatible function arguments"):
481  function(array)
482 
483 
484 @pytest.mark.xfail("env.PYPY")
486  from sys import getrefcount
487  dtype = np.dtype(np.float_)
488  a = np.array([1], dtype=dtype)
489  before = getrefcount(dtype)
490  m.ndim(a)
491  after = getrefcount(dtype)
492  assert after == before
void print(const Matrix &A, const string &s, ostream &stream)
Definition: Matrix.cpp:155
def test_array_resize(msg)
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set view
def test_dim_check_fail(arr)
def test_numpy_view(capture)
def test_mutate_readonly(arr)
def test_greedy_string_overload()
def test_bounds_check(arr)
Definition: pytypes.h:928
const mpreal sum(const mpreal tab[], const unsigned long int n, int &status, mp_rnd_t mode=mpreal::get_default_rnd())
Definition: mpreal.h:2381
def test_make_empty_shaped_array()
def test_array_unchecked_dyn_dims(msg)
object getattr(handle obj, handle name)
Definition: pytypes.h:419
def test_cast_numpy_int64_to_uint64()
def test_at_fail(arr, dim)
def test_argument_conversions(forcecast, contiguity, noconvert)
def test_array_unchecked_fixed_dims(msg)
def test_index_offset(arr, args, ret)
str repr(handle h)
Definition: pytypes.h:1536
def test_array_create_and_resize(msg)
def test_overload_resolution(msg)
def test_data(arr, args, ret)


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:46:03