Skip to content

Commit

Permalink
Support character(len=*) Fortran syntax and add optional string tests
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel committed Dec 5, 2024
1 parent 63f3c48 commit ea739d0
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ list(APPEND tests
intent_out_size
string_array_input_f2py
type_check
optional_string
)

foreach(test ${tests})
Expand Down
1 change: 1 addition & 0 deletions examples/optional_string/Makefile.meson
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
include ../make.meson.inc

NAME := pywrapper
WRAPFLAGS += --type-check

test: build
$(PYTHON) test.py
14 changes: 14 additions & 0 deletions examples/optional_string/main.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module m_string_test
implicit none
private
public :: string_in
public :: string_in_array
public :: string_to_string
public :: string_to_string_array
public :: string_out
Expand All @@ -15,6 +16,19 @@ subroutine string_in(input)
character(len=*), intent(in) :: input
end subroutine

subroutine string_in_array(input)
character(len=6), intent(in) :: input(:)
integer :: i

if (input(1).ne."one ") then
call f90wrap_abort("First char input is incorrect, should be 'one', but is '" // input(1) // "'" )
endif

if (input(2).ne."two ") then
call f90wrap_abort("Second char input is incorrect, should be 'two', but is '" // input(2) // "'" )
endif
end subroutine

subroutine string_to_string(input,output)
character(len=*), intent(in) :: input
character(len=*), intent(out) :: output
Expand Down
38 changes: 38 additions & 0 deletions examples/optional_string/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,44 @@ def test_string_in_2(self):
def test_string_in_3(self):
m_string_test.string_in(np.bytes_('yo'))

def test_string_in_4(self):
with self.assertRaises(TypeError):
m_string_test.string_in(np.array(['yo']))

@unittest.skipIf(version.parse(np.version.version) > version.parse("1.23.5") , "This test is known to fail on numpy version newer than 1.23.5, dtype=c should not be used")
def test_string_in_array_deprecated(self):
in_array = np.array(['one ', 'two '], dtype='c')
m_string_test.string_in_array(in_array)

@unittest.skipIf(version.parse(np.version.version) > version.parse("1.23.5") , "This test is known to fail on numpy version newer than 1.23.5, dtype=c should not be used")
def test_string_in_array_2_deprecated(self):
in_array = np.array(['three ', 'two '], dtype='c')
with self.assertRaises(RuntimeError) as context:
m_string_test.string_in_array(in_array)

@unittest.skipIf(version.parse(np.version.version) > version.parse("1.23.5") , "This test is known to fail on numpy version newer than 1.23.5, dtype=c should not be used")
def test_string_in_array_3_deprecated(self):
in_array = np.array(['one ', 'four '], dtype='c')
with self.assertRaises(RuntimeError) as context:
m_string_test.string_in_array(in_array)

@unittest.skipIf(version.parse(np.version.version) < version.parse("1.24.0") , "This test is known to fail on numpy version older than 1.24.0")
def test_string_in_array(self):
in_array = np.array(['one ', 'two '], dtype='S6')
m_string_test.string_in_array(in_array)

@unittest.skipIf(version.parse(np.version.version) < version.parse("1.24.0") , "This test is known to fail on numpy version older than 1.24.0")
def test_string_in_array_2(self):
in_array = np.array(['three ', 'two '], dtype='S6')
with self.assertRaises(RuntimeError) as context:
m_string_test.string_in_array(in_array)

@unittest.skipIf(version.parse(np.version.version) < version.parse("1.24.0") , "This test is known to fail on numpy version older than 1.24.0")
def test_string_in_array_3(self):
in_array = np.array(['one ', 'four '], dtype='S6')
with self.assertRaises(RuntimeError) as context:
m_string_test.string_in_array(in_array)

def test_string_to_string(self):
in_string = 'yo'
out_string = m_string_test.string_to_string(in_string)
Expand Down
8 changes: 7 additions & 1 deletion f90wrap/fortran.py
Original file line number Diff line number Diff line change
Expand Up @@ -857,8 +857,14 @@ def split_type_kind(typename):
type*kind -> (type, kind)
type(kind) -> (type, kind)
type(kind=kind) -> (type, kind)
character(len=*) -> (character, *)
"""
if '*' in typename:

if typename.startswith('character'):
type = 'character'
kind = typename[len('character'):]
kind = kind.replace('len=', '')
elif '*' in typename:
type = typename[:typename.index('*')]
kind = typename[typename.index('*') + 1:]
elif '(' in typename:
Expand Down

0 comments on commit ea739d0

Please sign in to comment.