f2py allows to convert Fortran subroutines to python functions. Therefore, when it tries to convert the Fortran functions to python callable objects it raises an error and crashes. If these functions were to be called from python, they would have to be rewritten as subroutines. However, as they only have to be called from one Fortran subroutine, there is no need for that.
The solution is to include the functions inside the subroutine, using contains. Below there is a working example, using the same structure as above:
subs.f
subroutine hello(a,b)
real(8), intent(in) :: a
real(8), intent(out) :: b
call newton(a, b)
end subroutine hello
subroutine newton (d,e)
real(8), intent(in) :: d
real(8), intent(out) :: e
e=q(d)
contains
real(8) function q(x)
real(8) :: x
q = h(x) + h(x-1)
end function
real(8) function h(x)
real(8) :: x
h = x*x-3*x+2
end function h
end subroutine newton
This file can be converted to a python callable using f2py, particularly, using the "quick way" explained in the f2py docs running f2py -c subs.f -m fsubs from the command line generates a callable shared object, which can be imported with import fsubs. This module has some help:
help(fsubs)
# Output
Help on module fsubs:
NAME
fsubs
DESCRIPTION
This module 'fsubs' is auto-generated with f2py (version:2).
Functions:
b = hello(a)
e = newton(d)
...
As it can be seen, the fsubs module contains 2 functions, hello and newton, the 2 subroutines. Now, we can call hello from python using fsubs.hello(4) which as expected, yields 8.