It is stated in a lot of places that F2PY does not "support derived types", however, it is unclear to me whether this means that either
- derived types may not be used as parameters to procedures wrapped by F2PY
- derived types may not even be used internally in procedures I want to wrap with F2PY
To my use case the first point is an inconvenience but the second rather a deal breaker.
As an example, consider this module that computes a vector sum:
module derived_types
implicit none
public :: point, add
type :: point
real :: x
real :: y
end type point
contains
type(point) function add(p1, p2)
type(point), intent(in) :: p1
type(point), intent(in) :: p2
add%x = p1%x + p2%x
add%y = p1%y + p2%y
end function add
end module derived_types
module expose
use derived_types, only: point, add
implicit none
contains
subroutine vector_sum(x1, y1, x2, y2, x3, y3)
real, intent(in) :: x1, y1, x2, y2
real, intent(out) :: x3, y3
type(point) :: p1, p2, p3
p1 = point(x1, y1)
p2 = point(x2, y2)
p3 = add(p1, p2)
x3 = p3%x
y3 = p3%y
end subroutine vector_sum
end module expose
Subroutine vector_sum
shall be exposed to Python. The derived type point
is not to be passed between Python and Fortran.
This works as plain Fortran program (with an appropriate program block added) but F2PY fails:
f2py -c ff.f90 only: vector_sum
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building extension "untitled" sources
f2py options: ['only:', 'vector_sum', ':']
f2py:> /tmp/tmpjdq8b9dq/src.linux-x86_64-3.8/untitledmodule.c
creating /tmp/tmpjdq8b9dq/src.linux-x86_64-3.8
Reading fortran codes...
Reading file 'ff.f90' (format:free)
Line #7 in ff.f90:"type :: point "
analyzeline: No name/args pattern found for line.
Post-processing...
Block: untitled
Block: derived_types
Block: unknown_type
Block: expose
Block: vector_sum
Block: run
Post-processing (stage 2)...
Block: untitled
Block: unknown_interface
Block: derived_types
Block: unknown_type
Block: expose
Block: vector_sum
Block: run
Building modules...
Building module "untitled"...
Constructing F90 module support for "derived_types"...
Variables: point add
getctype: No C-type found in "{'attrspec': ['public']}", assuming void.
Traceback (most recent call last):
File "/home/me/.pyenv/versions/anaconda3-2020.11/lib/python3.8/site-packages/numpy/f2py/f90mod_rules.py", line 143, in buildhooks
at = capi_maps.c2capi_map[ct]
KeyError: 'void'
Can such a thing be done using F2PY at all?