From efcb0fbd138294fa362628ab1c8567255e374fd8 Mon Sep 17 00:00:00 2001 From: Alexander Heger <2sn@users.noreply.github.com> Date: Sun, 12 Feb 2023 00:26:42 +1100 Subject: [PATCH] BUG: fix for f2py string scalars (#23194) in previous version, any string scalar was converted to a string array of dimension len, i.e., a definition character(len=N) :: X effectively became character(len=NNN), dimension(NNN) :: X from the point of few of the numpy (python) interface: X.shape == (NNN,) X.dtype == '|SNNN' Closes gh-23192 --- numpy/f2py/capi_maps.py | 6 +++--- numpy/f2py/tests/src/string/scalar_string.f90 | 7 +++++++ numpy/f2py/tests/test_character.py | 20 +++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 numpy/f2py/tests/src/string/scalar_string.f90 diff --git a/numpy/f2py/capi_maps.py b/numpy/f2py/capi_maps.py index f07066a09b67..aaae3a8e0b15 100644 --- a/numpy/f2py/capi_maps.py +++ b/numpy/f2py/capi_maps.py @@ -342,9 +342,9 @@ def getstrlength(var): def getarrdims(a, var, verbose=0): ret = {} if isstring(var) and not isarray(var): - ret['dims'] = getstrlength(var) - ret['size'] = ret['dims'] - ret['rank'] = '1' + ret['size'] = getstrlength(var) + ret['rank'] = '0' + ret['dims'] = '' elif isscalar(var): ret['size'] = '1' ret['rank'] = '0' diff --git a/numpy/f2py/tests/src/string/scalar_string.f90 b/numpy/f2py/tests/src/string/scalar_string.f90 new file mode 100644 index 000000000000..d847668bbb7e --- /dev/null +++ b/numpy/f2py/tests/src/string/scalar_string.f90 @@ -0,0 +1,7 @@ +MODULE string_test + + character(len=8) :: string + + character(len=12), dimension(5,7) :: strarr + +END MODULE string_test diff --git a/numpy/f2py/tests/test_character.py b/numpy/f2py/tests/test_character.py index b54b4d981c67..a5cfffe0d196 100644 --- a/numpy/f2py/tests/test_character.py +++ b/numpy/f2py/tests/test_character.py @@ -568,3 +568,23 @@ def test_character_bc(self, state): assert_equal(len(a), 2) assert_raises(Exception, lambda: f(b'c')) + + +class TestStringScalarArr(util.F2PyTest): + sources = [util.getpath("tests", "src", "string", "scalar_string.f90")] + + @pytest.mark.slow + def test_char(self): + out = self.module.string_test.string + expected = () + assert out.shape == expected + expected = '|S8' + assert out.dtype == expected + + @pytest.mark.slow + def test_char_arr(self): + out = self.module.string_test.strarr + expected = (5,7) + assert out.shape == expected + expected = '|S12' + assert out.dtype == expected