question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

f2py fails for functions returning character(len=len(input_string))

See original GitHub issue

I’ve written simple toupper() and tolower() functions in Fortran that start like this:

pure function toupper(str)
  character(len=*) intent(in) :: str
  character(len=len(str)) :: toupper
  ...

When wrapping these with f2py, I get an error looking like this:

/tmp/tmpmrZ5Ra/src.linux-x86_64-2.7/RMCfunctionsmodule.c: In function ‘f2py_rout_RMCfunctions_mod_functions_toupper’: /tmp/tmpmrZ5Ra/src.linux-x86_64-2.7/RMCfunctionsmodule.c:926:23: error: ‘str_Dims’ undeclared (first use in this function)

slen(toupper) = len(str);
                      ^

I guess the len(str) needs to be replaced by slen(str).

This problem occurs with both f2py-2.7 and f2py-3.3 It does not depend on the name of the variable str - I tried a couple of other names.

Issue Analytics

  • State:closed
  • Created 10 years ago
  • Comments:6 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
pearucommented, May 31, 2021

My first reaction (without looking at code) is that f2py should be fixed by replacing len(..) call with slen(..) when len is used in the context of character len specification. Note that there are three kinds of length functions involved here: slen and len defined by f2py and to be used withing .pyf files, and len that is Fortran intrinsic. f2py len should be used in the context of arrays while f2py slen in the context of character types.

0reactions
melissawmcommented, May 13, 2021

Here’s what I’ve managed to get so far:

  1. Wrapping the following:
  pure function test(str)
    character(len=*), intent(in) :: str
    character(len=len(str)) :: test
    integer :: i

    test(1:1) = 'A'
    do i = 2, len(str)
       test(i:i) = str(i:i)
    enddo
    
  end function test

I get:

/tmp/tmpdg8zrhbc/src.linux-x86_64-3.9/stringsmodule.c: In function 'f2py_rout_strings_strings_test':
/tmp/tmpdg8zrhbc/src.linux-x86_64-3.9/stringsmodule.c:279:20: error: 'str_Dims' undeclared (first use in this function)
  279 |   slen(test) = len(str);
      |                    ^~~
  1. I tried using a subroutine, with the following signature file:
python module strings ! in 
    interface  ! in :strings
        module strings ! in :strings:strings.f90
            subroutine test(str, a) ! in :strings:strings.f90:strings
                character*(*) intent(in) :: str
                character*len(str) intent(out) :: a
            end subroutine test
        end module strings
    end interface 
end python module strings

Running $ f2py -c strings.f90 strings.pyf compiles fine, but

>>> import strings
>>> print(strings.strings.test.__doc__)  # should return a as output, but returns
test(str,a)

Wrapper for ``test``.

Parameters
----------
str : input string(len=-1)
a : input string(len=1)

(note the incorrect intent for a)

  1. Changing strings.pyf to use character(len=slen(str)), intent(out) :: a runs fine and works.

So the problem seems to be when using a function but not a subroutine.

When inspecting the code, IIUC the problem comes from the fact that we need to use slen for the C function wrapper, but len for the fortran function wrapper (both generated by f2py).

My question to @pearu is if we should require the use of the slen expression in the pyf file in this case, or try to fix this from f2py itself, considering the two separate cases of the fortran and C function wrappers.

Read more comments on GitHub >

github_iconTop Results From Across the Web

f2py fails if a function argument passed to another function
Here is my Fortran code !WRONG function fun1(myfun1) implicit none real(8) :: fun1 real(8),external :: myfun1 fun1 = myfun1(1) return end ...
Read more >
F2PY Users Guide and Reference Manual
The purpose of the F2PY –Fortran to Python interface generator– project is to provide a connection between. Python and Fortran languages.
Read more >
Using F2PY bindings in Python — NumPy v1.24 Manual
In general, a scalar argument for a F2PY generated wrapper function can be an ... b : in/output rank-0 array(string(len=5),'c') c : input...
Read more >
NumPy User Guide
To create sequences of numbers, NumPy provides the arange function which is analogous to the Python built-in range, but returns an array.
Read more >
Using F2PY bindings in Python — NumPy v1.9 Manual
Such CObjects can be used as an callback argument of F2PY generated functions to bypass Python C/API layer of calling Python functions from...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found