# -*- coding: utf-8 -*- # Copyright (C) 2018 Nexedi SA and Contributors. # Kirill Smelkov # # This program is free software: you can Use, Study, Modify and Redistribute # it under the terms of the GNU General Public License version 3, or (at your # option) any later version, as published by the Free Software Foundation. # # You can also Link and Combine this program with other software covered by # the terms of any of the Free Software licenses or any of the Open Source # Initiative approved licenses and Convey the resulting work. Corresponding # source of such a combination shall include the source code for all other # software used. # # This program is distributed WITHOUT ANY WARRANTY; without even the implied # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # See COPYING file for full licensing terms. # See https://www.nexedi.com/licensing for rationale and options. from numpy import ndarray, arange, dtype, int32 from numpy.lib.stride_tricks import DummyArray from wendelin.lib.xnumpy import structured from pytest import raises # xbase returns original object from which arr was _as_strided viewed. def xbase(arr): b = arr.base # arr -> typed view | DummyArray if type(b) is not DummyArray: b = b.base # it was typed view -> DummyArray assert type(b) is DummyArray b = b.base # -> origin return b # verifies xnumpy.structured() def test_structured(): dtxy = dtype([('x', int32), ('y', int32)]) # C order a = arange(4*3, dtype=int32).reshape((4,3)) # 0 1 2 # 3 4 5 # 6 7 8 # 9 10 11 with raises(ValueError, match="minor-axis is not C-contiguous: stride \(-4\) < 0"): structured(a[:3,:2][:,::-1], dtxy) with raises(ValueError, match="minor-axis is not C-contiguous: stride \(8\) != itemsize \(4\)"): structured(a[:,::2], dtxy) with raises(ValueError, match="dtype.itemsize \(8\) != sizeof\(minor-axis\) \(12\)"): structured(a, dtxy) b = a[:3,:2] bxy = structured(b, dtxy) assert xbase(bxy) is b assert bxy.dtype == dtxy assert bxy.shape == (3,) assert bxy[0]['x'] == 0 assert bxy[0]['y'] == 1 assert bxy[1]['x'] == 3 assert bxy[1]['y'] == 4 assert bxy[2]['x'] == 6 assert bxy[2]['y'] == 7 bxy['x'][0] = 100 assert bxy[0]['x'] == 100 assert b[0,0] == 100 assert a[0,0] == 100 bxy['y'][2] = 200 assert bxy[2]['y'] == 200 assert b[2,1] == 200 assert a[2,1] == 200 # C contigous in minor; reverse in major a = arange(4*3, dtype=int32).reshape((4,3)) # 0 1 2 # 3 4 5 # 6 7 8 # 9 10 11 b = a[:3,:2][::-1,:] bxy = structured(b, dtxy) assert xbase(bxy) is b assert bxy.dtype == dtxy assert bxy.shape == (3,) assert bxy[0]['x'] == 6 assert bxy[0]['y'] == 7 assert bxy[1]['x'] == 3 assert bxy[1]['y'] == 4 assert bxy[2]['x'] == 0 assert bxy[2]['y'] == 1 bxy['x'][0] = 100 assert bxy[0]['x'] == 100 assert b[0,0] == 100 assert a[2,0] == 100 bxy['y'][2] = 200 assert bxy[2]['y'] == 200 assert b[2,1] == 200 assert a[0,1] == 200 # F order a = arange(4*3, dtype=int32).reshape((4,3), order='F') # 0 4 8 # 1 5 9 # 2 6 10 # 3 7 11 b = a[:2,:3] bxy = structured(b, dtxy) assert xbase(bxy) is b assert bxy.dtype == dtxy assert bxy.shape == (3,) assert bxy[0]['x'] == 0 assert bxy[0]['y'] == 1 assert bxy[1]['x'] == 4 assert bxy[1]['y'] == 5 assert bxy[2]['x'] == 8 assert bxy[2]['y'] == 9 bxy['x'][0] = 100 assert bxy[0]['x'] == 100 assert b[0,0] == 100 assert a[0,0] == 100 bxy['y'][2] = 200 assert bxy[2]['y'] == 200 assert b[1,2] == 200 assert a[1,2] == 200 # custom class class MyArray(ndarray): pass a = arange(4*3, dtype=int32).reshape((4,3)) # 0 1 2 # 3 4 5 # 6 7 8 # 9 10 11 a = a.view(type=MyArray) b = a[:3,:2] bxy = structured(b, dtxy) assert xbase(bxy) is b assert bxy.dtype == dtxy assert bxy.shape == (3,) assert type(bxy) is MyArray