Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
test_nditer.py3534 linesDownload Raw Back to tests
1import inspect
2import subprocess
3import sys
4import textwrap
5import warnings
6
7import pytest
8
9import numpy as np
10import numpy._core._multiarray_tests as _multiarray_tests
11import numpy._core.umath as ncu
12from numpy import all, arange, array, nditer
13from numpy.testing import (
14    HAS_REFCOUNT,
15    IS_64BIT,
16    IS_PYPY,
17    IS_WASM,
18    assert_,
19    assert_array_equal,
20    assert_equal,
21    assert_raises,
22)
23from numpy.testing._private.utils import requires_memory
24
25
26def iter_multi_index(i):
27    ret = []
28    while not i.finished:
29        ret.append(i.multi_index)
30        i.iternext()
31    return ret
32
33def iter_indices(i):
34    ret = []
35    while not i.finished:
36        ret.append(i.index)
37        i.iternext()
38    return ret
39
40def iter_iterindices(i):
41    ret = []
42    while not i.finished:
43        ret.append(i.iterindex)
44        i.iternext()
45    return ret
46
47@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
48def test_iter_refcount():
49    # Make sure the iterator doesn't leak
50
51    # Basic
52    a = arange(6)
53    dt = np.dtype('f4').newbyteorder()
54    rc_a = sys.getrefcount(a)
55    rc_dt = sys.getrefcount(dt)
56    with nditer(a, [],
57                [['readwrite', 'updateifcopy']],
58                casting='unsafe',
59                op_dtypes=[dt]) as it:
60        assert_(not it.iterationneedsapi)
61        assert_(sys.getrefcount(a) > rc_a)
62        assert_(sys.getrefcount(dt) > rc_dt)
63    # del 'it'
64    it = None
65    assert_equal(sys.getrefcount(a), rc_a)
66    assert_equal(sys.getrefcount(dt), rc_dt)
67
68    # With a copy
69    a = arange(6, dtype='f4')
70    dt = np.dtype('f4')
71    rc_a = sys.getrefcount(a)
72    rc_dt = sys.getrefcount(dt)
73    it = nditer(a, [],
74                [['readwrite']],
75                op_dtypes=[dt])
76    rc2_a = sys.getrefcount(a)
77    rc2_dt = sys.getrefcount(dt)
78    it2 = it.copy()
79    assert_(sys.getrefcount(a) > rc2_a)
80    if sys.version_info < (3, 13):
81        # np.dtype('f4') is immortal after Python 3.13
82        assert_(sys.getrefcount(dt) > rc2_dt)
83    it = None
84    assert_equal(sys.getrefcount(a), rc2_a)
85    assert_equal(sys.getrefcount(dt), rc2_dt)
86    it2 = None
87    assert_equal(sys.getrefcount(a), rc_a)
88    assert_equal(sys.getrefcount(dt), rc_dt)
89
90def test_iter_best_order():
91    # The iterator should always find the iteration order
92    # with increasing memory addresses
93
94    # Test the ordering for 1-D to 5-D shapes
95    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
96        a = arange(np.prod(shape))
97        # Test each combination of positive and negative strides
98        for dirs in range(2**len(shape)):
99            dirs_index = [slice(None)] * len(shape)
100            for bit in range(len(shape)):
101                if ((2**bit) & dirs):
102                    dirs_index[bit] = slice(None, None, -1)
103            dirs_index = tuple(dirs_index)
104
105            aview = a.reshape(shape)[dirs_index]
106            # C-order
107            i = nditer(aview, [], [['readonly']])
108            assert_equal(list(i), a)
109            # Fortran-order
110            i = nditer(aview.T, [], [['readonly']])
111            assert_equal(list(i), a)
112            # Other order
113            if len(shape) > 2:
114                i = nditer(aview.swapaxes(0, 1), [], [['readonly']])
115                assert_equal(list(i), a)
116
117def test_iter_c_order():
118    # Test forcing C order
119
120    # Test the ordering for 1-D to 5-D shapes
121    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
122        a = arange(np.prod(shape))
123        # Test each combination of positive and negative strides
124        for dirs in range(2**len(shape)):
125            dirs_index = [slice(None)] * len(shape)
126            for bit in range(len(shape)):
127                if ((2**bit) & dirs):
128                    dirs_index[bit] = slice(None, None, -1)
129            dirs_index = tuple(dirs_index)
130
131            aview = a.reshape(shape)[dirs_index]
132            # C-order
133            i = nditer(aview, order='C')
134            assert_equal(list(i), aview.ravel(order='C'))
135            # Fortran-order
136            i = nditer(aview.T, order='C')
137            assert_equal(list(i), aview.T.ravel(order='C'))
138            # Other order
139            if len(shape) > 2:
140                i = nditer(aview.swapaxes(0, 1), order='C')
141                assert_equal(list(i),
142                                    aview.swapaxes(0, 1).ravel(order='C'))
143
144def test_iter_f_order():
145    # Test forcing F order
146
147    # Test the ordering for 1-D to 5-D shapes
148    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
149        a = arange(np.prod(shape))
150        # Test each combination of positive and negative strides
151        for dirs in range(2**len(shape)):
152            dirs_index = [slice(None)] * len(shape)
153            for bit in range(len(shape)):
154                if ((2**bit) & dirs):
155                    dirs_index[bit] = slice(None, None, -1)
156            dirs_index = tuple(dirs_index)
157
158            aview = a.reshape(shape)[dirs_index]
159            # C-order
160            i = nditer(aview, order='F')
161            assert_equal(list(i), aview.ravel(order='F'))
162            # Fortran-order
163            i = nditer(aview.T, order='F')
164            assert_equal(list(i), aview.T.ravel(order='F'))
165            # Other order
166            if len(shape) > 2:
167                i = nditer(aview.swapaxes(0, 1), order='F')
168                assert_equal(list(i),
169                                    aview.swapaxes(0, 1).ravel(order='F'))
170
171def test_iter_c_or_f_order():
172    # Test forcing any contiguous (C or F) order
173
174    # Test the ordering for 1-D to 5-D shapes
175    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
176        a = arange(np.prod(shape))
177        # Test each combination of positive and negative strides
178        for dirs in range(2**len(shape)):
179            dirs_index = [slice(None)] * len(shape)
180            for bit in range(len(shape)):
181                if ((2**bit) & dirs):
182                    dirs_index[bit] = slice(None, None, -1)
183            dirs_index = tuple(dirs_index)
184
185            aview = a.reshape(shape)[dirs_index]
186            # C-order
187            i = nditer(aview, order='A')
188            assert_equal(list(i), aview.ravel(order='A'))
189            # Fortran-order
190            i = nditer(aview.T, order='A')
191            assert_equal(list(i), aview.T.ravel(order='A'))
192            # Other order
193            if len(shape) > 2:
194                i = nditer(aview.swapaxes(0, 1), order='A')
195                assert_equal(list(i),
196                                    aview.swapaxes(0, 1).ravel(order='A'))
197
198def test_nditer_multi_index_set():
199    # Test the multi_index set
200    a = np.arange(6).reshape(2, 3)
201    it = np.nditer(a, flags=['multi_index'])
202
203    # Removes the iteration on two first elements of a[0]
204    it.multi_index = (0, 2,)
205
206    assert_equal(list(it), [2, 3, 4, 5])
207
208@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
209def test_nditer_multi_index_set_refcount():
210    # Test if the reference count on index variable is decreased
211
212    index = 0
213    i = np.nditer(np.array([111, 222, 333, 444]), flags=['multi_index'])
214
215    start_count = sys.getrefcount(index)
216    i.multi_index = (index,)
217    end_count = sys.getrefcount(index)
218
219    assert_equal(start_count, end_count)
220
221def test_iter_best_order_multi_index_1d():
222    # The multi-indices should be correct with any reordering
223
224    a = arange(4)
225    # 1D order
226    i = nditer(a, ['multi_index'], [['readonly']])
227    assert_equal(iter_multi_index(i), [(0,), (1,), (2,), (3,)])
228    # 1D reversed order
229    i = nditer(a[::-1], ['multi_index'], [['readonly']])
230    assert_equal(iter_multi_index(i), [(3,), (2,), (1,), (0,)])
231
232def test_iter_best_order_multi_index_2d():
233    # The multi-indices should be correct with any reordering
234
235    a = arange(6)
236    # 2D C-order
237    i = nditer(a.reshape(2, 3), ['multi_index'], [['readonly']])
238    assert_equal(iter_multi_index(i), [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)])
239    # 2D Fortran-order
240    i = nditer(a.reshape(2, 3).copy(order='F'), ['multi_index'], [['readonly']])
241    assert_equal(iter_multi_index(i), [(0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2)])
242    # 2D reversed C-order
243    i = nditer(a.reshape(2, 3)[::-1], ['multi_index'], [['readonly']])
244    assert_equal(iter_multi_index(i), [(1, 0), (1, 1), (1, 2), (0, 0), (0, 1), (0, 2)])
245    i = nditer(a.reshape(2, 3)[:, ::-1], ['multi_index'], [['readonly']])
246    assert_equal(iter_multi_index(i), [(0, 2), (0, 1), (0, 0), (1, 2), (1, 1), (1, 0)])
247    i = nditer(a.reshape(2, 3)[::-1, ::-1], ['multi_index'], [['readonly']])
248    assert_equal(iter_multi_index(i), [(1, 2), (1, 1), (1, 0), (0, 2), (0, 1), (0, 0)])
249    # 2D reversed Fortran-order
250    i = nditer(a.reshape(2, 3).copy(order='F')[::-1], ['multi_index'], [['readonly']])
251    assert_equal(iter_multi_index(i), [(1, 0), (0, 0), (1, 1), (0, 1), (1, 2), (0, 2)])
252    i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1],
253                                                   ['multi_index'], [['readonly']])
254    assert_equal(iter_multi_index(i), [(0, 2), (1, 2), (0, 1), (1, 1), (0, 0), (1, 0)])
255    i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1],
256                                                   ['multi_index'], [['readonly']])
257    assert_equal(iter_multi_index(i), [(1, 2), (0, 2), (1, 1), (0, 1), (1, 0), (0, 0)])
258
259def test_iter_best_order_multi_index_3d():
260    # The multi-indices should be correct with any reordering
261
262    a = arange(12)
263    # 3D C-order
264    i = nditer(a.reshape(2, 3, 2), ['multi_index'], [['readonly']])
265    assert_equal(iter_multi_index(i),
266                            [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 0), (0, 2, 1),
267                             (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1), (1, 2, 0), (1, 2, 1)])
268    # 3D Fortran-order
269    i = nditer(a.reshape(2, 3, 2).copy(order='F'), ['multi_index'], [['readonly']])
270    assert_equal(iter_multi_index(i),
271                            [(0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0), (0, 2, 0), (1, 2, 0),
272                             (0, 0, 1), (1, 0, 1), (0, 1, 1), (1, 1, 1), (0, 2, 1), (1, 2, 1)])
273    # 3D reversed C-order
274    i = nditer(a.reshape(2, 3, 2)[::-1], ['multi_index'], [['readonly']])
275    assert_equal(iter_multi_index(i),
276                            [(1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1), (1, 2, 0), (1, 2, 1),
277                             (0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 0), (0, 2, 1)])
278    i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['multi_index'], [['readonly']])
279    assert_equal(iter_multi_index(i),
280                            [(0, 2, 0), (0, 2, 1), (0, 1, 0), (0, 1, 1), (0, 0, 0), (0, 0, 1),
281                             (1, 2, 0), (1, 2, 1), (1, 1, 0), (1, 1, 1), (1, 0, 0), (1, 0, 1)])
282    i = nditer(a.reshape(2, 3, 2)[:, :, ::-1], ['multi_index'], [['readonly']])
283    assert_equal(iter_multi_index(i),
284                            [(0, 0, 1), (0, 0, 0), (0, 1, 1), (0, 1, 0), (0, 2, 1), (0, 2, 0),
285                             (1, 0, 1), (1, 0, 0), (1, 1, 1), (1, 1, 0), (1, 2, 1), (1, 2, 0)])
286    # 3D reversed Fortran-order
287    i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1],
288                                                    ['multi_index'], [['readonly']])
289    assert_equal(iter_multi_index(i),
290                            [(1, 0, 0), (0, 0, 0), (1, 1, 0), (0, 1, 0), (1, 2, 0), (0, 2, 0),
291                             (1, 0, 1), (0, 0, 1), (1, 1, 1), (0, 1, 1), (1, 2, 1), (0, 2, 1)])
292    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1],
293                                                    ['multi_index'], [['readonly']])
294    assert_equal(iter_multi_index(i),
295                            [(0, 2, 0), (1, 2, 0), (0, 1, 0), (1, 1, 0), (0, 0, 0), (1, 0, 0),
296                             (0, 2, 1), (1, 2, 1), (0, 1, 1), (1, 1, 1), (0, 0, 1), (1, 0, 1)])
297    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, :, ::-1],
298                                                    ['multi_index'], [['readonly']])
299    assert_equal(iter_multi_index(i),
300                            [(0, 0, 1), (1, 0, 1), (0, 1, 1), (1, 1, 1), (0, 2, 1), (1, 2, 1),
301                             (0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0), (0, 2, 0), (1, 2, 0)])
302
303def test_iter_best_order_c_index_1d():
304    # The C index should be correct with any reordering
305
306    a = arange(4)
307    # 1D order
308    i = nditer(a, ['c_index'], [['readonly']])
309    assert_equal(iter_indices(i), [0, 1, 2, 3])
310    # 1D reversed order
311    i = nditer(a[::-1], ['c_index'], [['readonly']])
312    assert_equal(iter_indices(i), [3, 2, 1, 0])
313
314def test_iter_best_order_c_index_2d():
315    # The C index should be correct with any reordering
316
317    a = arange(6)
318    # 2D C-order
319    i = nditer(a.reshape(2, 3), ['c_index'], [['readonly']])
320    assert_equal(iter_indices(i), [0, 1, 2, 3, 4, 5])
321    # 2D Fortran-order
322    i = nditer(a.reshape(2, 3).copy(order='F'),
323                                    ['c_index'], [['readonly']])
324    assert_equal(iter_indices(i), [0, 3, 1, 4, 2, 5])
325    # 2D reversed C-order
326    i = nditer(a.reshape(2, 3)[::-1], ['c_index'], [['readonly']])
327    assert_equal(iter_indices(i), [3, 4, 5, 0, 1, 2])
328    i = nditer(a.reshape(2, 3)[:, ::-1], ['c_index'], [['readonly']])
329    assert_equal(iter_indices(i), [2, 1, 0, 5, 4, 3])
330    i = nditer(a.reshape(2, 3)[::-1, ::-1], ['c_index'], [['readonly']])
331    assert_equal(iter_indices(i), [5, 4, 3, 2, 1, 0])
332    # 2D reversed Fortran-order
333    i = nditer(a.reshape(2, 3).copy(order='F')[::-1],
334                                    ['c_index'], [['readonly']])
335    assert_equal(iter_indices(i), [3, 0, 4, 1, 5, 2])
336    i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1],
337                                    ['c_index'], [['readonly']])
338    assert_equal(iter_indices(i), [2, 5, 1, 4, 0, 3])
339    i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1],
340                                    ['c_index'], [['readonly']])
341    assert_equal(iter_indices(i), [5, 2, 4, 1, 3, 0])
342
343def test_iter_best_order_c_index_3d():
344    # The C index should be correct with any reordering
345
346    a = arange(12)
347    # 3D C-order
348    i = nditer(a.reshape(2, 3, 2), ['c_index'], [['readonly']])
349    assert_equal(iter_indices(i),
350                            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
351    # 3D Fortran-order
352    i = nditer(a.reshape(2, 3, 2).copy(order='F'),
353                                    ['c_index'], [['readonly']])
354    assert_equal(iter_indices(i),
355                            [0, 6, 2, 8, 4, 10, 1, 7, 3, 9, 5, 11])
356    # 3D reversed C-order
357    i = nditer(a.reshape(2, 3, 2)[::-1], ['c_index'], [['readonly']])
358    assert_equal(iter_indices(i),
359                            [6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5])
360    i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['c_index'], [['readonly']])
361    assert_equal(iter_indices(i),
362                            [4, 5, 2, 3, 0, 1, 10, 11, 8, 9, 6, 7])
363    i = nditer(a.reshape(2, 3, 2)[:, :, ::-1], ['c_index'], [['readonly']])
364    assert_equal(iter_indices(i),
365                            [1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10])
366    # 3D reversed Fortran-order
367    i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1],
368                                    ['c_index'], [['readonly']])
369    assert_equal(iter_indices(i),
370                            [6, 0, 8, 2, 10, 4, 7, 1, 9, 3, 11, 5])
371    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1],
372                                    ['c_index'], [['readonly']])
373    assert_equal(iter_indices(i),
374                            [4, 10, 2, 8, 0, 6, 5, 11, 3, 9, 1, 7])
375    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, :, ::-1],
376                                    ['c_index'], [['readonly']])
377    assert_equal(iter_indices(i),
378                            [1, 7, 3, 9, 5, 11, 0, 6, 2, 8, 4, 10])
379
380def test_iter_best_order_f_index_1d():
381    # The Fortran index should be correct with any reordering
382
383    a = arange(4)
384    # 1D order
385    i = nditer(a, ['f_index'], [['readonly']])
386    assert_equal(iter_indices(i), [0, 1, 2, 3])
387    # 1D reversed order
388    i = nditer(a[::-1], ['f_index'], [['readonly']])
389    assert_equal(iter_indices(i), [3, 2, 1, 0])
390
391def test_iter_best_order_f_index_2d():
392    # The Fortran index should be correct with any reordering
393
394    a = arange(6)
395    # 2D C-order
396    i = nditer(a.reshape(2, 3), ['f_index'], [['readonly']])
397    assert_equal(iter_indices(i), [0, 2, 4, 1, 3, 5])
398    # 2D Fortran-order
399    i = nditer(a.reshape(2, 3).copy(order='F'),
400                                    ['f_index'], [['readonly']])
401    assert_equal(iter_indices(i), [0, 1, 2, 3, 4, 5])
402    # 2D reversed C-order
403    i = nditer(a.reshape(2, 3)[::-1], ['f_index'], [['readonly']])
404    assert_equal(iter_indices(i), [1, 3, 5, 0, 2, 4])
405    i = nditer(a.reshape(2, 3)[:, ::-1], ['f_index'], [['readonly']])
406    assert_equal(iter_indices(i), [4, 2, 0, 5, 3, 1])
407    i = nditer(a.reshape(2, 3)[::-1, ::-1], ['f_index'], [['readonly']])
408    assert_equal(iter_indices(i), [5, 3, 1, 4, 2, 0])
409    # 2D reversed Fortran-order
410    i = nditer(a.reshape(2, 3).copy(order='F')[::-1],
411                                    ['f_index'], [['readonly']])
412    assert_equal(iter_indices(i), [1, 0, 3, 2, 5, 4])
413    i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1],
414                                    ['f_index'], [['readonly']])
415    assert_equal(iter_indices(i), [4, 5, 2, 3, 0, 1])
416    i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1],
417                                    ['f_index'], [['readonly']])
418    assert_equal(iter_indices(i), [5, 4, 3, 2, 1, 0])
419
420def test_iter_best_order_f_index_3d():
421    # The Fortran index should be correct with any reordering
422
423    a = arange(12)
424    # 3D C-order
425    i = nditer(a.reshape(2, 3, 2), ['f_index'], [['readonly']])
426    assert_equal(iter_indices(i),
427                            [0, 6, 2, 8, 4, 10, 1, 7, 3, 9, 5, 11])
428    # 3D Fortran-order
429    i = nditer(a.reshape(2, 3, 2).copy(order='F'),
430                                    ['f_index'], [['readonly']])
431    assert_equal(iter_indices(i),
432                            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
433    # 3D reversed C-order
434    i = nditer(a.reshape(2, 3, 2)[::-1], ['f_index'], [['readonly']])
435    assert_equal(iter_indices(i),
436                            [1, 7, 3, 9, 5, 11, 0, 6, 2, 8, 4, 10])
437    i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['f_index'], [['readonly']])
438    assert_equal(iter_indices(i),
439                            [4, 10, 2, 8, 0, 6, 5, 11, 3, 9, 1, 7])
440    i = nditer(a.reshape(2, 3, 2)[:, :, ::-1], ['f_index'], [['readonly']])
441    assert_equal(iter_indices(i),
442                            [6, 0, 8, 2, 10, 4, 7, 1, 9, 3, 11, 5])
443    # 3D reversed Fortran-order
444    i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1],
445                                    ['f_index'], [['readonly']])
446    assert_equal(iter_indices(i),
447                            [1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10])
448    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1],
449                                    ['f_index'], [['readonly']])
450    assert_equal(iter_indices(i),
451                            [4, 5, 2, 3, 0, 1, 10, 11, 8, 9, 6, 7])
452    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, :, ::-1],
453                                    ['f_index'], [['readonly']])
454    assert_equal(iter_indices(i),
455                            [6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5])
456
457def test_iter_no_inner_full_coalesce():
458    # Check no_inner iterators which coalesce into a single inner loop
459
460    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
461        size = np.prod(shape)
462        a = arange(size)
463        # Test each combination of forward and backwards indexing
464        for dirs in range(2**len(shape)):
465            dirs_index = [slice(None)] * len(shape)
466            for bit in range(len(shape)):
467                if ((2**bit) & dirs):
468                    dirs_index[bit] = slice(None, None, -1)
469            dirs_index = tuple(dirs_index)
470
471            aview = a.reshape(shape)[dirs_index]
472            # C-order
473            i = nditer(aview, ['external_loop'], [['readonly']])
474            assert_equal(i.ndim, 1)
475            assert_equal(i[0].shape, (size,))
476            # Fortran-order
477            i = nditer(aview.T, ['external_loop'], [['readonly']])
478            assert_equal(i.ndim, 1)
479            assert_equal(i[0].shape, (size,))
480            # Other order
481            if len(shape) > 2:
482                i = nditer(aview.swapaxes(0, 1),
483                                    ['external_loop'], [['readonly']])
484                assert_equal(i.ndim, 1)
485                assert_equal(i[0].shape, (size,))
486
487def test_iter_no_inner_dim_coalescing():
488    # Check no_inner iterators whose dimensions may not coalesce completely
489
490    # Skipping the last element in a dimension prevents coalescing
491    # with the next-bigger dimension
492    a = arange(24).reshape(2, 3, 4)[:, :, :-1]
493    i = nditer(a, ['external_loop'], [['readonly']])
494    assert_equal(i.ndim, 2)
495    assert_equal(i[0].shape, (3,))
496    a = arange(24).reshape(2, 3, 4)[:, :-1, :]
497    i = nditer(a, ['external_loop'], [['readonly']])
498    assert_equal(i.ndim, 2)
499    assert_equal(i[0].shape, (8,))
500    a = arange(24).reshape(2, 3, 4)[:-1, :, :]
501    i = nditer(a, ['external_loop'], [['readonly']])
502    assert_equal(i.ndim, 1)
503    assert_equal(i[0].shape, (12,))
504
505    # Even with lots of 1-sized dimensions, should still coalesce
506    a = arange(24).reshape(1, 1, 2, 1, 1, 3, 1, 1, 4, 1, 1)
507    i = nditer(a, ['external_loop'], [['readonly']])
508    assert_equal(i.ndim, 1)
509    assert_equal(i[0].shape, (24,))
510
511def test_iter_dim_coalescing():
512    # Check that the correct number of dimensions are coalesced
513
514    # Tracking a multi-index disables coalescing
515    a = arange(24).reshape(2, 3, 4)
516    i = nditer(a, ['multi_index'], [['readonly']])
517    assert_equal(i.ndim, 3)
518
519    # A tracked index can allow coalescing if it's compatible with the array
520    a3d = arange(24).reshape(2, 3, 4)
521    i = nditer(a3d, ['c_index'], [['readonly']])
522    assert_equal(i.ndim, 1)
523    i = nditer(a3d.swapaxes(0, 1), ['c_index'], [['readonly']])
524    assert_equal(i.ndim, 3)
525    i = nditer(a3d.T, ['c_index'], [['readonly']])
526    assert_equal(i.ndim, 3)
527    i = nditer(a3d.T, ['f_index'], [['readonly']])
528    assert_equal(i.ndim, 1)
529    i = nditer(a3d.T.swapaxes(0, 1), ['f_index'], [['readonly']])
530    assert_equal(i.ndim, 3)
531
532    # When C or F order is forced, coalescing may still occur
533    a3d = arange(24).reshape(2, 3, 4)
534    i = nditer(a3d, order='C')
535    assert_equal(i.ndim, 1)
536    i = nditer(a3d.T, order='C')
537    assert_equal(i.ndim, 3)
538    i = nditer(a3d, order='F')
539    assert_equal(i.ndim, 3)
540    i = nditer(a3d.T, order='F')
541    assert_equal(i.ndim, 1)
542    i = nditer(a3d, order='A')
543    assert_equal(i.ndim, 1)
544    i = nditer(a3d.T, order='A')
545    assert_equal(i.ndim, 1)
546
547def test_iter_broadcasting():
548    # Standard NumPy broadcasting rules
549
550    # 1D with scalar
551    i = nditer([arange(6), np.int32(2)], ['multi_index'], [['readonly']] * 2)
552    assert_equal(i.itersize, 6)
553    assert_equal(i.shape, (6,))
554
555    # 2D with scalar
556    i = nditer([arange(6).reshape(2, 3), np.int32(2)],
557                        ['multi_index'], [['readonly']] * 2)
558    assert_equal(i.itersize, 6)
559    assert_equal(i.shape, (2, 3))
560    # 2D with 1D
561    i = nditer([arange(6).reshape(2, 3), arange(3)],
562                        ['multi_index'], [['readonly']] * 2)
563    assert_equal(i.itersize, 6)
564    assert_equal(i.shape, (2, 3))
565    i = nditer([arange(2).reshape(2, 1), arange(3)],
566                        ['multi_index'], [['readonly']] * 2)
567    assert_equal(i.itersize, 6)
568    assert_equal(i.shape, (2, 3))
569    # 2D with 2D
570    i = nditer([arange(2).reshape(2, 1), arange(3).reshape(1, 3)],
571                        ['multi_index'], [['readonly']] * 2)
572    assert_equal(i.itersize, 6)
573    assert_equal(i.shape, (2, 3))
574
575    # 3D with scalar
576    i = nditer([np.int32(2), arange(24).reshape(4, 2, 3)],
577                        ['multi_index'], [['readonly']] * 2)
578    assert_equal(i.itersize, 24)
579    assert_equal(i.shape, (4, 2, 3))
580    # 3D with 1D
581    i = nditer([arange(3), arange(24).reshape(4, 2, 3)],
582                        ['multi_index'], [['readonly']] * 2)
583    assert_equal(i.itersize, 24)
584    assert_equal(i.shape, (4, 2, 3))
585    i = nditer([arange(3), arange(8).reshape(4, 2, 1)],
586                        ['multi_index'], [['readonly']] * 2)
587    assert_equal(i.itersize, 24)
588    assert_equal(i.shape, (4, 2, 3))
589    # 3D with 2D
590    i = nditer([arange(6).reshape(2, 3), arange(24).reshape(4, 2, 3)],
591                        ['multi_index'], [['readonly']] * 2)
592    assert_equal(i.itersize, 24)
593    assert_equal(i.shape, (4, 2, 3))
594    i = nditer([arange(2).reshape(2, 1), arange(24).reshape(4, 2, 3)],
595                        ['multi_index'], [['readonly']] * 2)
596    assert_equal(i.itersize, 24)
597    assert_equal(i.shape, (4, 2, 3))
598    i = nditer([arange(3).reshape(1, 3), arange(8).reshape(4, 2, 1)],
599                        ['multi_index'], [['readonly']] * 2)
600    assert_equal(i.itersize, 24)
601    assert_equal(i.shape, (4, 2, 3))
602    # 3D with 3D
603    i = nditer([arange(2).reshape(1, 2, 1), arange(3).reshape(1, 1, 3),
604                        arange(4).reshape(4, 1, 1)],
605                        ['multi_index'], [['readonly']] * 3)
606    assert_equal(i.itersize, 24)
607    assert_equal(i.shape, (4, 2, 3))
608    i = nditer([arange(6).reshape(1, 2, 3), arange(4).reshape(4, 1, 1)],
609                        ['multi_index'], [['readonly']] * 2)
610    assert_equal(i.itersize, 24)
611    assert_equal(i.shape, (4, 2, 3))
612    i = nditer([arange(24).reshape(4, 2, 3), arange(12).reshape(4, 1, 3)],
613                        ['multi_index'], [['readonly']] * 2)
614    assert_equal(i.itersize, 24)
615    assert_equal(i.shape, (4, 2, 3))
616
617def test_iter_itershape():
618    # Check that allocated outputs work with a specified shape
619    a = np.arange(6, dtype='i2').reshape(2, 3)
620    i = nditer([a, None], [], [['readonly'], ['writeonly', 'allocate']],
621                            op_axes=[[0, 1, None], None],
622                            itershape=(-1, -1, 4))
623    assert_equal(i.operands[1].shape, (2, 3, 4))
624    assert_equal(i.operands[1].strides, (24, 8, 2))
625
626    i = nditer([a.T, None], [], [['readonly'], ['writeonly', 'allocate']],
627                            op_axes=[[0, 1, None], None],
628                            itershape=(-1, -1, 4))
629    assert_equal(i.operands[1].shape, (3, 2, 4))
630    assert_equal(i.operands[1].strides, (8, 24, 2))
631
632    i = nditer([a.T, None], [], [['readonly'], ['writeonly', 'allocate']],
633                            order='F',
634                            op_axes=[[0, 1, None], None],
635                            itershape=(-1, -1, 4))
636    assert_equal(i.operands[1].shape, (3, 2, 4))
637    assert_equal(i.operands[1].strides, (2, 6, 12))
638
639    # If we specify 1 in the itershape, it shouldn't allow broadcasting
640    # of that dimension to a bigger value
641    assert_raises(ValueError, nditer, [a, None], [],
642                            [['readonly'], ['writeonly', 'allocate']],
643                            op_axes=[[0, 1, None], None],
644                            itershape=(-1, 1, 4))
645    # Test bug that for no op_axes but itershape, they are NULLed correctly
646    i = np.nditer([np.ones(2), None, None], itershape=(2,))
647
648def test_iter_broadcasting_errors():
649    # Check that errors are thrown for bad broadcasting shapes
650
651    # 1D with 1D
652    assert_raises(ValueError, nditer, [arange(2), arange(3)],
653                    [], [['readonly']] * 2)
654    # 2D with 1D
655    assert_raises(ValueError, nditer,
656                    [arange(6).reshape(2, 3), arange(2)],
657                    [], [['readonly']] * 2)
658    # 2D with 2D
659    assert_raises(ValueError, nditer,
660                    [arange(6).reshape(2, 3), arange(9).reshape(3, 3)],
661                    [], [['readonly']] * 2)
662    assert_raises(ValueError, nditer,
663                    [arange(6).reshape(2, 3), arange(4).reshape(2, 2)],
664                    [], [['readonly']] * 2)
665    # 3D with 3D
666    assert_raises(ValueError, nditer,
667                    [arange(36).reshape(3, 3, 4), arange(24).reshape(2, 3, 4)],
668                    [], [['readonly']] * 2)
669    assert_raises(ValueError, nditer,
670                    [arange(8).reshape(2, 4, 1), arange(24).reshape(2, 3, 4)],
671                    [], [['readonly']] * 2)
672
673    # Verify that the error message mentions the right shapes
674    try:
675        nditer([arange(2).reshape(1, 2, 1),
676                arange(3).reshape(1, 3),
677                arange(6).reshape(2, 3)],
678               [],
679               [['readonly'], ['readonly'], ['writeonly', 'no_broadcast']])
680        raise AssertionError('Should have raised a broadcast error')
681    except ValueError as e:
682        msg = str(e)
683        # The message should contain the shape of the 3rd operand
684        assert_(msg.find('(2,3)') >= 0,
685                f'Message "{msg}" doesn\'t contain operand shape (2,3)')
686        # The message should contain the broadcast shape
687        assert_(msg.find('(1,2,3)') >= 0,
688                f'Message "{msg}" doesn\'t contain broadcast shape (1,2,3)')
689
690    try:
691        nditer([arange(6).reshape(2, 3), arange(2)],
692               [],
693               [['readonly'], ['readonly']],
694               op_axes=[[0, 1], [0, np.newaxis]],
695               itershape=(4, 3))
696        raise AssertionError('Should have raised a broadcast error')
697    except ValueError as e:
698        msg = str(e)
699        # The message should contain "shape->remappedshape" for each operand
700        assert_(msg.find('(2,3)->(2,3)') >= 0,
701            f'Message "{msg}" doesn\'t contain operand shape (2,3)->(2,3)')
702        assert_(msg.find('(2,)->(2,newaxis)') >= 0,
703                ('Message "%s" doesn\'t contain remapped operand shape'
704                '(2,)->(2,newaxis)') % msg)
705        # The message should contain the itershape parameter
706        assert_(msg.find('(4,3)') >= 0,
707                f'Message "{msg}" doesn\'t contain itershape parameter (4,3)')
708
709    try:
710        nditer([np.zeros((2, 1, 1)), np.zeros((2,))],
711               [],
712               [['writeonly', 'no_broadcast'], ['readonly']])
713        raise AssertionError('Should have raised a broadcast error')
714    except ValueError as e:
715        msg = str(e)
716        # The message should contain the shape of the bad operand
717        assert_(msg.find('(2,1,1)') >= 0,
718            f'Message "{msg}" doesn\'t contain operand shape (2,1,1)')
719        # The message should contain the broadcast shape
720        assert_(msg.find('(2,1,2)') >= 0,
721                f'Message "{msg}" doesn\'t contain the broadcast shape (2,1,2)')
722
723def test_iter_flags_errors():
724    # Check that bad combinations of flags produce errors
725
726    a = arange(6)
727
728    # Not enough operands
729    assert_raises(ValueError, nditer, [], [], [])
730    # Bad global flag
731    assert_raises(ValueError, nditer, [a], ['bad flag'], [['readonly']])
732    # Bad op flag
733    assert_raises(ValueError, nditer, [a], [], [['readonly', 'bad flag']])
734    # Bad order parameter
735    assert_raises(ValueError, nditer, [a], [], [['readonly']], order='G')
736    # Bad casting parameter
737    assert_raises(ValueError, nditer, [a], [], [['readonly']], casting='noon')
738    # op_flags must match ops
739    assert_raises(ValueError, nditer, [a] * 3, [], [['readonly']] * 2)
740    # Cannot track both a C and an F index
741    assert_raises(ValueError, nditer, a,
742                ['c_index', 'f_index'], [['readonly']])
743    # Inner iteration and multi-indices/indices are incompatible
744    assert_raises(ValueError, nditer, a,
745                ['external_loop', 'multi_index'], [['readonly']])
746    assert_raises(ValueError, nditer, a,
747                ['external_loop', 'c_index'], [['readonly']])
748    assert_raises(ValueError, nditer, a,
749                ['external_loop', 'f_index'], [['readonly']])
750    # Must specify exactly one of readwrite/readonly/writeonly per operand
751    assert_raises(ValueError, nditer, a, [], [[]])
752    assert_raises(ValueError, nditer, a, [], [['readonly', 'writeonly']])
753    assert_raises(ValueError, nditer, a, [], [['readonly', 'readwrite']])
754    assert_raises(ValueError, nditer, a, [], [['writeonly', 'readwrite']])
755    assert_raises(ValueError, nditer, a,
756                [], [['readonly', 'writeonly', 'readwrite']])
757    # Python scalars are always readonly
758    assert_raises(TypeError, nditer, 1.5, [], [['writeonly']])
759    assert_raises(TypeError, nditer, 1.5, [], [['readwrite']])
760    # Array scalars are always readonly
761    assert_raises(TypeError, nditer, np.int32(1), [], [['writeonly']])
762    assert_raises(TypeError, nditer, np.int32(1), [], [['readwrite']])
763    # Check readonly array
764    a.flags.writeable = False
765    assert_raises(ValueError, nditer, a, [], [['writeonly']])
766    assert_raises(ValueError, nditer, a, [], [['readwrite']])
767    a.flags.writeable = True
768    # Multi-indices available only with the multi_index flag
769    i = nditer(arange(6), [], [['readonly']])
770    assert_raises(ValueError, lambda i: i.multi_index, i)
771    # Index available only with an index flag
772    assert_raises(ValueError, lambda i: i.index, i)
773    # GotoCoords and GotoIndex incompatible with buffering or no_inner
774
775    def assign_multi_index(i):
776        i.multi_index = (0,)
777
778    def assign_index(i):
779        i.index = 0
780
781    def assign_iterindex(i):
782        i.iterindex = 0
783
784    def assign_iterrange(i):
785        i.iterrange = (0, 1)
786    i = nditer(arange(6), ['external_loop'])
787    assert_raises(ValueError, assign_multi_index, i)
788    assert_raises(ValueError, assign_index, i)
789    assert_raises(ValueError, assign_iterindex, i)
790    assert_raises(ValueError, assign_iterrange, i)
791    i = nditer(arange(6), ['buffered'])
792    assert_raises(ValueError, assign_multi_index, i)
793    assert_raises(ValueError, assign_index, i)
794    assert_raises(ValueError, assign_iterrange, i)
795    # Can't iterate if size is zero
796    assert_raises(ValueError, nditer, np.array([]))
797
798def test_iter_slice():
799    a, b, c = np.arange(3), np.arange(3), np.arange(3.)
800    i = nditer([a, b, c], [], ['readwrite'])
801    with i:
802        i[0:2] = (3, 3)
803        assert_equal(a, [3, 1, 2])
804        assert_equal(b, [3, 1, 2])
805        assert_equal(c, [0, 1, 2])
806        i[1] = 12
807        assert_equal(i[0:2], [3, 12])
808
809def test_iter_assign_mapping():
810    a = np.arange(24, dtype='f8').reshape(2, 3, 4).T
811    it = np.nditer(a, [], [['readwrite', 'updateifcopy']],
812                       casting='same_kind', op_dtypes=[np.dtype('f4')])
813    with it:
814        it.operands[0][...] = 3
815        it.operands[0][...] = 14
816    assert_equal(a, 14)
817    it = np.nditer(a, [], [['readwrite', 'updateifcopy']],
818                       casting='same_kind', op_dtypes=[np.dtype('f4')])
819    with it:
820        x = it.operands[0][-1:1]
821        x[...] = 14
822        it.operands[0][...] = -1234
823    assert_equal(a, -1234)
824    # check for no warnings on dealloc
825    x = None
826    it = None
827
828def test_iter_nbo_align_contig():
829    # Check that byte order, alignment, and contig changes work
830
831    # Byte order change by requesting a specific dtype
832    a = np.arange(6, dtype='f4')
833    au = a.byteswap()
834    au = au.view(au.dtype.newbyteorder())
835    assert_(a.dtype.byteorder != au.dtype.byteorder)
836    i = nditer(au, [], [['readwrite', 'updateifcopy']],
837                        casting='equiv',
838                        op_dtypes=[np.dtype('f4')])
839    with i:
840        # context manager triggers WRITEBACKIFCOPY on i at exit
841        assert_equal(i.dtypes[0].byteorder, a.dtype.byteorder)
842        assert_equal(i.operands[0].dtype.byteorder, a.dtype.byteorder)
843        assert_equal(i.operands[0], a)
844        i.operands[0][:] = 2
845    assert_equal(au, [2] * 6)
846    del i  # should not raise a warning
847    # Byte order change by requesting NBO
848    a = np.arange(6, dtype='f4')
849    au = a.byteswap()
850    au = au.view(au.dtype.newbyteorder())
851    assert_(a.dtype.byteorder != au.dtype.byteorder)
852    with nditer(au, [], [['readwrite', 'updateifcopy', 'nbo']],
853                        casting='equiv') as i:
854        # context manager triggers UPDATEIFCOPY on i at exit
855        assert_equal(i.dtypes[0].byteorder, a.dtype.byteorder)
856        assert_equal(i.operands[0].dtype.byteorder, a.dtype.byteorder)
857        assert_equal(i.operands[0], a)
858        i.operands[0][:] = 12345
859        i.operands[0][:] = 2
860    assert_equal(au, [2] * 6)
861
862    # Unaligned input
863    a = np.zeros((6 * 4 + 1,), dtype='i1')[1:]
864    a = a.view('f4')
865    a[:] = np.arange(6, dtype='f4')
866    assert_(not a.flags.aligned)
867    # Without 'aligned', shouldn't copy
868    i = nditer(a, [], [['readonly']])
869    assert_(not i.operands[0].flags.aligned)
870    assert_equal(i.operands[0], a)
871    # With 'aligned', should make a copy
872    with nditer(a, [], [['readwrite', 'updateifcopy', 'aligned']]) as i:
873        assert_(i.operands[0].flags.aligned)
874        # context manager triggers UPDATEIFCOPY on i at exit
875        assert_equal(i.operands[0], a)
876        i.operands[0][:] = 3
877    assert_equal(a, [3] * 6)
878
879    # Discontiguous input
880    a = arange(12)
881    # If it is contiguous, shouldn't copy
882    i = nditer(a[:6], [], [['readonly']])
883    assert_(i.operands[0].flags.contiguous)
884    assert_equal(i.operands[0], a[:6])
885    # If it isn't contiguous, should buffer
886    i = nditer(a[::2], ['buffered', 'external_loop'],
887                        [['readonly', 'contig']],
888                        buffersize=10)
889    assert_(i[0].flags.contiguous)
890    assert_equal(i[0], a[::2])
891
892def test_iter_array_cast():
893    # Check that arrays are cast as requested
894
895    # No cast 'f4' -> 'f4'
896    a = np.arange(6, dtype='f4').reshape(2, 3)
897    i = nditer(a, [], [['readwrite']], op_dtypes=[np.dtype('f4')])
898    with i:
899        assert_equal(i.operands[0], a)
900        assert_equal(i.operands[0].dtype, np.dtype('f4'))
901
902    # Byte-order cast '<f4' -> '>f4'
903    a = np.arange(6, dtype='<f4').reshape(2, 3)
904    with nditer(a, [], [['readwrite', 'updateifcopy']],
905            casting='equiv',
906            op_dtypes=[np.dtype('>f4')]) as i:
907        assert_equal(i.operands[0], a)
908        assert_equal(i.operands[0].dtype, np.dtype('>f4'))
909
910    # Safe case 'f4' -> 'f8'
911    a = np.arange(24, dtype='f4').reshape(2, 3, 4).swapaxes(1, 2)
912    i = nditer(a, [], [['readonly', 'copy']],
913            casting='safe',
914            op_dtypes=[np.dtype('f8')])
915    assert_equal(i.operands[0], a)
916    assert_equal(i.operands[0].dtype, np.dtype('f8'))
917    # The memory layout of the temporary should match a (a is (48,4,16))
918    # except negative strides get flipped to positive strides.
919    assert_equal(i.operands[0].strides, (96, 8, 32))
920    a = a[::-1, :, ::-1]
921    i = nditer(a, [], [['readonly', 'copy']],
922            casting='safe',
923            op_dtypes=[np.dtype('f8')])
924    assert_equal(i.operands[0], a)
925    assert_equal(i.operands[0].dtype, np.dtype('f8'))
926    assert_equal(i.operands[0].strides, (96, 8, 32))
927
928    # Same-kind cast 'f8' -> 'f4' -> 'f8'
929    a = np.arange(24, dtype='f8').reshape(2, 3, 4).T
930    with nditer(a, [],
931            [['readwrite', 'updateifcopy']],
932            casting='same_kind',
933            op_dtypes=[np.dtype('f4')]) as i:
934        assert_equal(i.operands[0], a)
935        assert_equal(i.operands[0].dtype, np.dtype('f4'))
936        assert_equal(i.operands[0].strides, (4, 16, 48))
937        # Check that WRITEBACKIFCOPY is activated at exit
938        i.operands[0][2, 1, 1] = -12.5
939        assert_(a[2, 1, 1] != -12.5)
940    assert_equal(a[2, 1, 1], -12.5)
941
942    a = np.arange(6, dtype='i4')[::-2]
943    with nditer(a, [],
944            [['writeonly', 'updateifcopy']],
945            casting='unsafe',
946            op_dtypes=[np.dtype('f4')]) as i:
947        assert_equal(i.operands[0].dtype, np.dtype('f4'))
948        # Even though the stride was negative in 'a', it
949        # becomes positive in the temporary
950        assert_equal(i.operands[0].strides, (4,))
951        i.operands[0][:] = [1, 2, 3]
952    assert_equal(a, [1, 2, 3])
953
954def test_iter_array_cast_errors():
955    # Check that invalid casts are caught
956
957    # Need to enable copying for casts to occur
958    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
959                [['readonly']], op_dtypes=[np.dtype('f8')])
960    # Also need to allow casting for casts to occur
961    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
962                [['readonly', 'copy']], casting='no',
963                op_dtypes=[np.dtype('f8')])
964    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
965                [['readonly', 'copy']], casting='equiv',
966                op_dtypes=[np.dtype('f8')])
967    assert_raises(TypeError, nditer, arange(2, dtype='f8'), [],
968                [['writeonly', 'updateifcopy']],
969                casting='no',
970                op_dtypes=[np.dtype('f4')])
971    assert_raises(TypeError, nditer, arange(2, dtype='f8'), [],
972                [['writeonly', 'updateifcopy']],
973                casting='equiv',
974                op_dtypes=[np.dtype('f4')])
975    # '<f4' -> '>f4' should not work with casting='no'
976    assert_raises(TypeError, nditer, arange(2, dtype='<f4'), [],
977                [['readonly', 'copy']], casting='no',
978                op_dtypes=[np.dtype('>f4')])
979    # 'f4' -> 'f8' is a safe cast, but 'f8' -> 'f4' isn't
980    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
981                [['readwrite', 'updateifcopy']],
982                casting='safe',
983                op_dtypes=[np.dtype('f8')])
984    assert_raises(TypeError, nditer, arange(2, dtype='f8'), [],
985                [['readwrite', 'updateifcopy']],
986                casting='safe',
987                op_dtypes=[np.dtype('f4')])
988    # 'f4' -> 'i4' is neither a safe nor a same-kind cast
989    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
990                [['readonly', 'copy']],
991                casting='same_kind',
992                op_dtypes=[np.dtype('i4')])
993    assert_raises(TypeError, nditer, arange(2, dtype='i4'), [],
994                [['writeonly', 'updateifcopy']],
995                casting='same_kind',
996                op_dtypes=[np.dtype('f4')])
997
998def test_iter_scalar_cast():
999    # Check that scalars are cast as requested
1000
1001    # No cast 'f4' -> 'f4'
1002    i = nditer(np.float32(2.5), [], [['readonly']],
1003                    op_dtypes=[np.dtype('f4')])
1004    assert_equal(i.dtypes[0], np.dtype('f4'))
1005    assert_equal(i.value.dtype, np.dtype('f4'))
1006    assert_equal(i.value, 2.5)
1007    # Safe cast 'f4' -> 'f8'
1008    i = nditer(np.float32(2.5), [],
1009                    [['readonly', 'copy']],
1010                    casting='safe',
1011                    op_dtypes=[np.dtype('f8')])
1012    assert_equal(i.dtypes[0], np.dtype('f8'))
1013    assert_equal(i.value.dtype, np.dtype('f8'))
1014    assert_equal(i.value, 2.5)
1015    # Same-kind cast 'f8' -> 'f4'
1016    i = nditer(np.float64(2.5), [],
1017                    [['readonly', 'copy']],
1018                    casting='same_kind',
1019                    op_dtypes=[np.dtype('f4')])
1020    assert_equal(i.dtypes[0], np.dtype('f4'))
1021    assert_equal(i.value.dtype, np.dtype('f4'))
1022    assert_equal(i.value, 2.5)
1023    # Unsafe cast 'f8' -> 'i4'
1024    i = nditer(np.float64(3.0), [],
1025                    [['readonly', 'copy']],
1026                    casting='unsafe',
1027                    op_dtypes=[np.dtype('i4')])
1028    assert_equal(i.dtypes[0], np.dtype('i4'))
1029    assert_equal(i.value.dtype, np.dtype('i4'))
1030    assert_equal(i.value, 3)
1031    # Readonly scalars may be cast even without setting COPY or BUFFERED
1032    i = nditer(3, [], [['readonly']], op_dtypes=[np.dtype('f8')])
1033    assert_equal(i[0].dtype, np.dtype('f8'))
1034    assert_equal(i[0], 3.)
1035
1036def test_iter_scalar_cast_errors():
1037    # Check that invalid casts are caught
1038
1039    # Need to allow copying/buffering for write casts of scalars to occur
1040    assert_raises(TypeError, nditer, np.float32(2), [],
1041                [['readwrite']], op_dtypes=[np.dtype('f8')])
1042    assert_raises(TypeError, nditer, 2.5, [],
1043                [['readwrite']], op_dtypes=[np.dtype('f4')])
1044    # 'f8' -> 'f4' isn't a safe cast if the value would overflow
1045    assert_raises(TypeError, nditer, np.float64(1e60), [],
1046                [['readonly']],
1047                casting='safe',
1048                op_dtypes=[np.dtype('f4')])
1049    # 'f4' -> 'i4' is neither a safe nor a same-kind cast
1050    assert_raises(TypeError, nditer, np.float32(2), [],
1051                [['readonly']],
1052                casting='same_kind',
1053                op_dtypes=[np.dtype('i4')])
1054
1055def test_iter_object_arrays_basic():
1056    # Check that object arrays work
1057
1058    obj = {'a': 3, 'b': 'd'}
1059    a = np.array([[1, 2, 3], None, obj, None], dtype='O')
1060    if HAS_REFCOUNT:
1061        rc = sys.getrefcount(obj)
1062
1063    # Need to allow references for object arrays
1064    assert_raises(TypeError, nditer, a)
1065    if HAS_REFCOUNT:
1066        assert_equal(sys.getrefcount(obj), rc)
1067
1068    i = nditer(a, ['refs_ok'], ['readonly'])
1069    vals = [x_[()] for x_ in i]
1070    assert_equal(np.array(vals, dtype='O'), a)
1071    vals, i, x = [None] * 3
1072    if HAS_REFCOUNT:
1073        assert_equal(sys.getrefcount(obj), rc)
1074
1075    i = nditer(a.reshape(2, 2).T, ['refs_ok', 'buffered'],
1076                        ['readonly'], order='C')
1077    assert_(i.iterationneedsapi)
1078    vals = [x_[()] for x_ in i]
1079    assert_equal(np.array(vals, dtype='O'), a.reshape(2, 2).ravel(order='F'))
1080    vals, i, x = [None] * 3
1081    if HAS_REFCOUNT:
1082        assert_equal(sys.getrefcount(obj), rc)
1083
1084    i = nditer(a.reshape(2, 2).T, ['refs_ok', 'buffered'],
1085                        ['readwrite'], order='C')
1086    with i:
1087        for x in i:
1088            x[...] = None
1089        vals, i, x = [None] * 3
1090    if HAS_REFCOUNT:
1091        assert_(sys.getrefcount(obj) == rc - 1)
1092    assert_equal(a, np.array([None] * 4, dtype='O'))
1093
1094def test_iter_object_arrays_conversions():
1095    # Conversions to/from objects
1096    a = np.arange(6, dtype='O')
1097    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
1098                    casting='unsafe', op_dtypes='i4')
1099    with i:
1100        for x in i:
1101            x[...] += 1
1102    assert_equal(a, np.arange(6) + 1)
1103
1104    a = np.arange(6, dtype='i4')
1105    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
1106                    casting='unsafe', op_dtypes='O')
1107    with i:
1108        for x in i:
1109            x[...] += 1
1110    assert_equal(a, np.arange(6) + 1)
1111
1112    # Non-contiguous object array
1113    a = np.zeros((6,), dtype=[('p', 'i1'), ('a', 'O')])
1114    a = a['a']
1115    a[:] = np.arange(6)
1116    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
1117                    casting='unsafe', op_dtypes='i4')
1118    with i:
1119        for x in i:
1120            x[...] += 1
1121    assert_equal(a, np.arange(6) + 1)
1122
1123    # Non-contiguous value array
1124    a = np.zeros((6,), dtype=[('p', 'i1'), ('a', 'i4')])
1125    a = a['a']
1126    a[:] = np.arange(6) + 98172488
1127    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
1128                    casting='unsafe', op_dtypes='O')
1129    with i:
1130        ob = i[0][()]
1131        if HAS_REFCOUNT:
1132            rc = sys.getrefcount(ob)
1133        for x in i:
1134            x[...] += 1
1135        if HAS_REFCOUNT:
1136            newrc = sys.getrefcount(ob)
1137            assert_(newrc == rc - 1)
1138    assert_equal(a, np.arange(6) + 98172489)
1139
1140def test_iter_common_dtype():
1141    # Check that the iterator finds a common data type correctly
1142    # (some checks are somewhat duplicate after adopting NEP 50)
1143
1144    i = nditer([array([3], dtype='f4'), array([0], dtype='f8')],
1145                    ['common_dtype'],
1146                    [['readonly', 'copy']] * 2,
1147                    casting='safe')
1148    assert_equal(i.dtypes[0], np.dtype('f8'))
1149    assert_equal(i.dtypes[1], np.dtype('f8'))
1150    i = nditer([array([3], dtype='i4'), array([0], dtype='f4')],
1151                    ['common_dtype'],
1152                    [['readonly', 'copy']] * 2,
1153                    casting='safe')
1154    assert_equal(i.dtypes[0], np.dtype('f8'))
1155    assert_equal(i.dtypes[1], np.dtype('f8'))
1156    i = nditer([array([3], dtype='f4'), array(0, dtype='f8')],
1157                    ['common_dtype'],
1158                    [['readonly', 'copy']] * 2,
1159                    casting='same_kind')
1160    assert_equal(i.dtypes[0], np.dtype('f8'))
1161    assert_equal(i.dtypes[1], np.dtype('f8'))
1162    i = nditer([array([3], dtype='u4'), array(0, dtype='i4')],
1163                    ['common_dtype'],
1164                    [['readonly', 'copy']] * 2,
1165                    casting='safe')
1166    assert_equal(i.dtypes[0], np.dtype('i8'))
1167    assert_equal(i.dtypes[1], np.dtype('i8'))
1168    i = nditer([array([3], dtype='u4'), array(-12, dtype='i4')],
1169                    ['common_dtype'],
1170                    [['readonly', 'copy']] * 2,
1171                    casting='safe')
1172    assert_equal(i.dtypes[0], np.dtype('i8'))
1173    assert_equal(i.dtypes[1], np.dtype('i8'))
1174    i = nditer([array([3], dtype='u4'), array(-12, dtype='i4'),
1175                 array([2j], dtype='c8'), array([9], dtype='f8')],
1176                    ['common_dtype'],
1177                    [['readonly', 'copy']] * 4,
1178                    casting='safe')
1179    assert_equal(i.dtypes[0], np.dtype('c16'))
1180    assert_equal(i.dtypes[1], np.dtype('c16'))
1181    assert_equal(i.dtypes[2], np.dtype('c16'))
1182    assert_equal(i.dtypes[3], np.dtype('c16'))
1183    assert_equal(i.value, (3, -12, 2j, 9))
1184
1185    # When allocating outputs, other outputs aren't factored in
1186    i = nditer([array([3], dtype='i4'), None, array([2j], dtype='c16')], [],
1187                    [['readonly', 'copy'],
1188                     ['writeonly', 'allocate'],
1189                     ['writeonly']],
1190                    casting='safe')
1191    assert_equal(i.dtypes[0], np.dtype('i4'))
1192    assert_equal(i.dtypes[1], np.dtype('i4'))
1193    assert_equal(i.dtypes[2], np.dtype('c16'))
1194    # But, if common data types are requested, they are
1195    i = nditer([array([3], dtype='i4'), None, array([2j], dtype='c16')],
1196                    ['common_dtype'],
1197                    [['readonly', 'copy'],
1198                     ['writeonly', 'allocate'],
1199                     ['writeonly']],
1200                    casting='safe')

Showing the first 1,200 of 3534 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai