f2py import Fortran code in Python

2 minute read

Importing Fortran code in Python as a library/module is very straightforward. Here is a simple example of correctly specifying Fortran Intent() vis-à-vis Python f2py to consider for Fortran → Python projects.

Install f2py

f2py is part of numpy, so we install Numpy.

  • Linux / Windows Subsystem for Linux
    apt install gfortran
    conda install numpy     # or pip
    
  • Mac OS
    brew install gcc
    conda install numpy     # or pip
    

    Windows

    Windows is trickier in general, so it has it’s own section here.

Note: C:/Anaconda may be C:/Miniconda3 or the like. We recommend Miniconda3.

Tested on a 64-bit Windows 10 machine.

  1. install Numpy
    conda install numpy
    
  2. install MinGW-W64 to c:\mingw with:

    Architecture Threads Exception
    x86_64 posix seh
  3. Insert the mingw bin path to your system path permanently: Control Panel → Advanced System Settings → Environment Variables → System variables → Path. Add the path to gfortran.exe, such as:
    C:\mingw\mingw64\bin
    
  4. Tell Python to use MinGW: create file c:\Anaconda\Lib\distutils\distutils.cfg containing:
    [build]
    compiler=mingw32
    

    from PowerShell, this can be done by:

    echo "[build]`ncompiler=mingw32" > c:\Miniconda3\Lib\distutils\distutils.cfg
    

If you don’t like or can’t do the last step, you can instead do for each package you install:

python setup.py build_ext --inplace --compiler=mingw32

If you have problems using f2py or other development work on Windows, consider Windows Subsystem for Linux, which runs at full performance within a terminal window on Windows.

Test/fix

Try the lowtran7 code. Following the instructions there, you should get

  1. A lowtran7.pyd (on Windows) or lowtran7*.so (on Mac/Linux) file
  2. Running python DemoLowtran.py creates a plot of atmospheric loss
Lowtran atmospheric loss line plot
Lowtran atmospheric loss.

f2py does not allow inline comments for COMMON blocks

f2py does not allow inline comments for COMMON blocks for Fortran 77 .f code. This is because f2py works more strictly to Fortran specifications than most modern compilers.

Inline comments are not Fortran 77 standard, and will make f2py throw an error.

To fix this problem, just make the inline comment a full-line command with ! in column 1.

Fortran90 .f90 files won’t throw an f2py error due to inline comments on a line with a COMMON block: goodcomment.f90.

This will manifest itself two different ways, depending on whether you have implicit none or not:

COMMON inline comment error WITH implicit none

Example in badcomment_implicit.f

var2fixfortran: No typespec for argument “x ! bad for fortran77”. getctype: No C-type found in “{}”, assuming void. KeyError: ‘void’

Solution: Make inline comment a full-line comment with ! in column 1.

COMMON inline comment error WITHOUT implicit none

Example in badcomment.f

error: expected ‘;’, ‘,’ or ‘)’ before ‘!’ token

Solution: Make inline comment a full-line comment with ! in column 1: goodcomment.f.

Windows troubleshooting

Another solution is to use Windows Subsystem for Linux with Anaconda Python. However, with the techniques below, I’ve always gotten f2py to work on Windows 7 and Windows 10.


‘f2py’ is not recognized as an internal or external command, operable program or batch file.

  1. Ensure Numpy is installed
    conda install numpy
    
  2. (Windows) create a file <Anaconda Python install directory>/Scripts/f2py.bat with content
    python %~dp0/f2py.py %*
    

Error: No module named ‘numpy.distutils._msvccompiler’ in numpy.distutils; trying from distutils

is fixed by: create file c:\Anaconda\Lib\distutils\distutils.cfg containing:

[build]
compiler=mingw32

error LNK2001: unresolved external symbol _gfortran_st_write error LNK2001: unresolved external symbol _gfortran_st_read

and similar errors are typically from not having told f2py to use gfortran by: create file c:\Anaconda\Lib\distutils\distutils.cfg containing:

[build]
compiler=mingw32

Notes

Reference

Leave a comment