[f2py] Python Call Back in Fortran

Darren djaneczek at mirarco.org
Mon Jul 30 16:26:40 EEST 2012


Pearu Peterson <pearu at ...> writes:

> 
> 
> Hi,Here follows an example that illustrates how to handle this usage 
case:!foo.f90:subroutine sub1(python_callback)  !f2py intent(callback) 
python_callback   external python_callback
>   !f2py call python_callback(0,0,0) !define python_callback signature  call 
sub2(1,2,3)end subroutine sub1subroutine sub2(arg1,arg2,arg3)  integer arg1, 
arg2, arg3  external python_callback
>   call python_callback(arg1,arg2,arg3)  end subroutine sub2!eoff2py -c -m ex 
foo.f90>>> def cb(arg1, arg2, arg3):...     print 'calling python cb(%s, %s, 
%s)' % (arg1, arg2, arg3)
> ...     ...     >>> import ex>>> ex.sub1(cb)calling python cb(1, 2, 
3)HTH,Pearu
> On Sun, Feb 6, 2011 at 1:11 AM, Gaetan Kenway <kenway <at> utias.utoronto.ca> 
wrote:Hello I have a question about python callbacks in Fortran. I've been able 
to setup simple python call backs with no issue. The problem I'm having is I 
need a way to "store" the call back function handle in Fortran. I need to call 
the python callback from a Fortran function that I can't explicitly pass the 
python function handle to .  I need to have something like below. Subroutine 
sub1 is wrapped and sub2 has a fixed form that is actually called from and 
internal PETSc function and I can't change the sequence of arguments.subroutine 
sub1(python_callback)    external python_callbackend subroutine sub1subroutine 
sub2(arg1,arg2,arg3)external python_callback! I want to call python_callback 
here    call python_callback(arg1,arg2,arg3)end subroutine sub2It would be nice 
if you could just put the callback into a module and make that available in 
sub2. Is this possible in fortran? The code as above compiles, but when you try 
to import it into Python, python complains that python_callback is not defined. 
Is there a way to trick the compiler into using the callback defined in the pyf 
file?  Is there some way of telling f2py with an intent(callback) that the 
external python_callback in sub2 is actually defined as python callback?If 
anyone has any suggestions or know this is entirely impossible in fortran it 
would be greatly appreciated.Gaetan 
Kenway_______________________________________________
> f2py-users mailing listf2py-users-
Y4l6ocDipWCuvFJfX82//w at public.gmane.orghttp://cens.ioc.ee/mailman/listinfo/f2py-
users
> 
> 
> 
> 
> 
> _______________________________________________
> f2py-users mailing list
> f2py-users at ...
> http://cens.ioc.ee/mailman/listinfo/f2py-users
> 



I've been trying to retain a reference to a python callback reference in the 
Fortran memory space. 

To compile this fortran example, I am using mingw:
python C:\Python27\Scripts\f2py.py -c -m ex foo.f90

The example worked as defined, however I was hoping to achieve the added 
functionality of retaining the function reference/pointer for general use. What 
I found interesting and surprising when playing with your example was that when 
I manually set ex.python_callback through python, sub2 behaved slightly 
differently. See below.

>>> dir(ex)
['__doc__', '__file__', '__name__', '__package__', '__version__', 'sub1', 
'sub2']
>>> def callback(x,y,z):
...     print(x + y + z)
...
>>> callback(1,2,3)
6
>>> ex.sub1(callback)
6
>>> ex.sub2(1,2,3)
Call-back cb_python_callback_in_sub1__user__routines failed.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ex.error: cb: Callback python_callback not defined (as an argument or module ex 
attribute).

>>> ex.python_callback = callback
>>> ex.sub2(1,2,3)
capi_return is NULL
Call-back cb_python_callback_in_sub1__user__routines failed.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: callback() takes exactly 3 arguments (0 given)

Should anything like this be possible?

I've experimented with procedure pointers as shared (or module) variables. 
Unfortunately, Python only sees these as Float32 numpy objects. Attempts to set 
them aren't working out for me, and as such the calls to the pointed procedures 
crashes as one might expect with an incorrected pointed-to function.
 
Is there a way to permanently retain callback functions in f2py's current state?
If not, what would be required?

Thanks







More information about the f2py-users mailing list