diff options
Diffstat (limited to 'numpy/f2py/tests/test_array_from_pyobj.py')
-rw-r--r-- | numpy/f2py/tests/test_array_from_pyobj.py | 81 |
1 files changed, 70 insertions, 11 deletions
diff --git a/numpy/f2py/tests/test_array_from_pyobj.py b/numpy/f2py/tests/test_array_from_pyobj.py index 5a084bc3e..2b8c8defc 100644 --- a/numpy/f2py/tests/test_array_from_pyobj.py +++ b/numpy/f2py/tests/test_array_from_pyobj.py @@ -6,11 +6,18 @@ import pytest import numpy as np -from numpy.core.multiarray import typeinfo +from numpy.testing import assert_, assert_equal +from numpy.core.multiarray import typeinfo as _typeinfo from . import util wrap = None +# Extend core typeinfo with CHARACTER to test dtype('c') +_ti = _typeinfo['STRING'] +typeinfo = dict( + CHARACTER=type(_ti)(('c', _ti.num, 8, _ti.alignment, _ti.type)), + **_typeinfo) + def setup_module(): """ @@ -56,6 +63,7 @@ def flags2names(flags): "NOTSWAPPED", "WRITEABLE", "WRITEBACKIFCOPY", + "UPDATEIFCOPY", "BEHAVED", "BEHAVED_RO", "CARRAY", @@ -116,6 +124,9 @@ _type_names = [ "FLOAT", "DOUBLE", "CFLOAT", + "STRING1", + "STRING5", + "CHARACTER", ] _cast_dict = {"BOOL": ["BOOL"]} @@ -139,6 +150,10 @@ _cast_dict["DOUBLE"] = _cast_dict["INT"] + ["UINT", "FLOAT", "DOUBLE"] _cast_dict["CFLOAT"] = _cast_dict["FLOAT"] + ["CFLOAT"] +_cast_dict['STRING1'] = ['STRING1'] +_cast_dict['STRING5'] = ['STRING5'] +_cast_dict['CHARACTER'] = ['CHARACTER'] + # 32 bit system malloc typically does not provide the alignment required by # 16 byte long double types this means the inout intent cannot be satisfied # and several tests fail as the alignment flag can be randomly true or fals @@ -184,14 +199,33 @@ class Type: def _init(self, name): self.NAME = name.upper() - info = typeinfo[self.NAME] - self.type_num = getattr(wrap, "NPY_" + self.NAME) + + if self.NAME == 'CHARACTER': + info = typeinfo[self.NAME] + self.type_num = getattr(wrap, 'NPY_STRING') + self.elsize = 1 + self.dtype = np.dtype('c') + elif self.NAME.startswith('STRING'): + info = typeinfo[self.NAME[:6]] + self.type_num = getattr(wrap, 'NPY_STRING') + self.elsize = int(self.NAME[6:] or 0) + self.dtype = np.dtype(f'S{self.elsize}') + else: + info = typeinfo[self.NAME] + self.type_num = getattr(wrap, 'NPY_' + self.NAME) + self.elsize = info.bits // 8 + self.dtype = np.dtype(info.type) + assert self.type_num == info.num - self.dtype = np.dtype(info.type) self.type = info.type - self.elsize = info.bits / 8 self.dtypechar = info.char + def __repr__(self): + return (f"Type({self.NAME})|type_num={self.type_num}," + f" dtype={self.dtype}," + f" type={self.type}, elsize={self.elsize}," + f" dtypechar={self.dtypechar}") + def cast_types(self): return [self.__class__(_m) for _m in _cast_dict[self.NAME]] @@ -226,6 +260,11 @@ class Type: class Array: + + def __repr__(self): + return (f'Array({self.type}, {self.dims}, {self.intent},' + f' {self.obj})|arr={self.arr}') + def __init__(self, typ, dims, intent, obj): self.type = typ self.dims = dims @@ -234,7 +273,9 @@ class Array: self.obj = obj # arr.dtypechar may be different from typ.dtypechar - self.arr = wrap.call(typ.type_num, dims, intent.flags, obj) + self.arr = wrap.call(typ.type_num, + typ.elsize, + dims, intent.flags, obj) assert isinstance(self.arr, np.ndarray) @@ -289,7 +330,9 @@ class Array: self.arr.tobytes(), self.pyarr.tobytes(), )) # strides - assert self.arr_attr[5][-2:] == self.pyarr_attr[5][-2:] # descr + assert self.arr_attr[5][-2:] == self.pyarr_attr[5][-2:], repr(( + self.arr_attr[5], self.pyarr_attr[5] + )) # descr assert self.arr_attr[6] == self.pyarr_attr[6], repr(( self.arr_attr[6], self.pyarr_attr[6], @@ -338,8 +381,6 @@ class TestIntent: class TestSharedMemory: - num2seq = [1, 2] - num23seq = [[1, 2, 3], [4, 5, 6]] @pytest.fixture(autouse=True, scope="class", params=_type_names) def setup_type(self, request): @@ -347,6 +388,21 @@ class TestSharedMemory: request.cls.array = lambda self, dims, intent, obj: Array( Type(request.param), dims, intent, obj) + @property + def num2seq(self): + if self.type.NAME.startswith('STRING'): + elsize = self.type.elsize + return ['1' * elsize, '2' * elsize] + return [1, 2] + + @property + def num23seq(self): + if self.type.NAME.startswith('STRING'): + elsize = self.type.elsize + return [['1' * elsize, '2' * elsize, '3' * elsize], + ['4' * elsize, '5' * elsize, '6' * elsize]] + return [[1, 2, 3], [4, 5, 6]] + def test_in_from_2seq(self): a = self.array([2], intent.in_, self.num2seq) assert not a.has_shared_memory() @@ -367,9 +423,9 @@ class TestSharedMemory: """Test if intent(in) array can be passed without copies""" seq = getattr(self, "num" + inp) obj = np.array(seq, dtype=self.type.dtype, order=order) - obj.setflags(write=(write == "w")) + obj.setflags(write=(write == 'w')) a = self.array(obj.shape, - ((order == "C" and intent.in_.c) or intent.in_), obj) + ((order == 'C' and intent.in_.c) or intent.in_), obj) assert a.has_shared_memory() def test_inout_2seq(self): @@ -496,6 +552,9 @@ class TestSharedMemory: def test_in_cache_from_2casttype_failure(self): for t in self.type.all_types(): + if t.NAME == 'STRING': + # string elsize is 0, so skipping the test + continue if t.elsize >= self.type.elsize: continue obj = np.array(self.num2seq, dtype=t.dtype) |