ylikx / forpy

Forpy - use Python from Fortran

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Python function returning a list results in an empty list when converting to Forpy list

malkab opened this issue · comments

Hi,

most probably I'm missing something important, any light you can shed on this will be most welcomed.

A simple Python function:

def return_list:
    return [ 0, 1, 2 ]

I'm trying to wrap this function using Forpy. Excerpts of code, since module import and all preliminary operations work as expected, tested with functions that return simple data types as integers:

type(list) :: arr
type(object) :: out 
integer :: c

ierror = call_py(out, mymodule, "return_list")

ierror = list_create(arr, out)

ierror = arr%len(c)

and c happens to be -1, which I interprete as an empty list. What I'm doing wrong?

Thanks a lot.

Hi,
I think the problem is the following: The call to return_list fails, because in the Python code the parentheses are missing in what should be def return_list():.

The Fortran code is correct, list_create should create a copy of the list that is returned from return_list.

c = -1 indicates that the call to the len function failed, because arr does not contain a properly constructed list, because of the failed calls before.
For debugging you can insert call err_print statements to see error messages. Just note that err_print also clears the error state of the Python interpreter and therefore err_print statements can seem to fix errors in programs.

If you don't want to create a copy of the returned list, you can use ierror = cast(arr, out) instead of list_create.

Hi, many thanks for the kick response. Yes, def return_list() contained a typo in my report, it was right in code. Anyway, the call err_print worked like a charm, thanks for the hint. Finally the issue was that I was constructing an args tuple with more params that needed, err_print quickly pointed me in the right direction:

! Create the tuple to hold the parameters
pyfortestwrapper_error = tuple_create(params, 2)
pyfortestwrapper_error = params%setitem(0, a)

! Call and return output
pyfortestwrapper_error = call_py(out, pyfortest, "numpy_array", params)

I was defining the tuple with 2 parameters but was only defining one of them, and the target Python function expects only one, so there was the error. Working code:

! Create the tuple to hold the parameters
pyfortestwrapper_error = tuple_create(params, 1)
pyfortestwrapper_error = params%setitem(0, a)

! Call and return output
pyfortestwrapper_error = call_py(out, pyfortest, "numpy_array", params)

Now everything is working as expected, the cast to type(list) works flawlessly and I can access list items.

Thanks for your work, this module is amazingly useful.