Bart
Bart

Reputation: 10249

Reload import in IPython

I'm trying to access some Fortran subroutines using F2PY, but I've ran into the following problem during consecutive calls from IPython. Take this minimal Fortran code (hope that I didn't code anything stupid; my Fortran is a bit rusty..):

! test.f90
module mod
  integer i
contains
  subroutine foo
    i = i+1
    print*,i
  end subroutine foo
end module mod

If I compile this using F2PY (f2py3.5 -c -m test test.f90), import it in Python and call it twice:

# run.py
import test
test.mod.foo()
test.mod.foo()

The resulting output is:

$ python run.py 
           1
           2

So on every call of foo(), i is incremented, which is supposed to happen. But between different calls of run.py (either from the command line or IPython interpreter), everything should be "reset", i.e. the printed counter should start from 1 for every call. This happens when calling run.py from the command line, but if I call the script multiple times from IPython, i keeps increasing:

In [1]: run run.py
           1
           2

In [2]: run run.py
           3
           4

I know that there are lots of posts showing how to reload imports (using autoreload in IPython, importlib.reload(), ...), but none of them seem to work for this example. Is there a way to force a clean reload/import?

Some side notes: (1) The Fortran code that I'm trying to access is quite large, old and messy, so I'd prefer not to change anything in there; (2) I could easily do test.mod.i = something in between calls, but the real Fortran code is too complex for such solutions; (3) I'd really prefer a solution which I can put in the Python code over e.g. settings (autoreload, ..) which I have to manually put in the IPython interpreter (forget it once and ...)

Upvotes: 1

Views: 1170

Answers (1)

Ash Sharma
Ash Sharma

Reputation: 468

If you can slightly change your fortran code you may be able to reset without re-import (probably faster too).
The change is about introducing i as a common and resetting it from outside. Your changed fortran code will look this

      ! test.f90
      module mod
      common /set1/ i
      contains
      subroutine foo
      common /set1/ i
      i = i+1
      print*,i
      end subroutine foo
      end module mod

reset the variable i from python as below:

 import test
 test.mod.foo()
 test.mod.foo()
 test.set1.i = 0 #reset here
 test.mod.foo()

This should produce the result as follows:

  python run.py 
       1
       2
       1

Upvotes: 1

Related Questions