I have talked previously about building fast libraries for Python using Fortran. The key software that facilitates easy integration of Fortran code into Python is F2PY. The user can write fast Fortran code with F2PY specific comments and compile it using F2PY to produce a high-speed ready-to-use Python library.
F2PY Link to heading
F2PY is an open-source utilty tool that provides an easy connection between Python and Fortran languages. It was written in the late 90s by Dr. Pearu Peterson. The first version of this software was released in 1999 when it was called Fortran to Python Interface Generator (FPIG). It remained a stand-alone software till 2007 when it was moved to the NumPy project. F2PY is currently maintained by the NumPy developer team and users can install numpy to use it.
Current status Link to heading
F2PY’s codebase is a bit older than the rest of Numpy. It has not had any major releases since 2009 ever since it became feature complete for Fortran 77. Beginners browsing its codebase in the current state mightfind it a bit difficult to read, understand and contribute to. Recently, efforts have been made to modernise its CLI and backend compilation process. The F2PY you will get to use will be a more user-friendly and faster CLI.
Codebase Link to heading
If you explore the current directory numpy/f2py
you will open up a directory that looks likes this:-
|
|
crackfortran.py
file is the heart of f2py. It is responsible of reading Fortran code and extracting declaration information which is used to create .pyf
files. f2py2e.py
stands for F2PY Second edition. It is the CLI program that sits on top of crackfortran.py
and provides user interface.We will talk mostly about the test suite of F2PY in this blog which consists of the tests
directory.
Testing f2py Link to heading
The file tree of tests directory presents us with these:-
|
|
Files starting with test_
contain tests for various aspects of f2py from parsing Fortran files to checking modules' documentation. src
directory contains the Fortran source files upon which we do the testing. util.py
is an interesting file. It contains superclass for class based tests in f2py which we will talk about later.
Adding tests Link to heading
If you wander through the tests
folder snooping inside the files, you will find most tests are classes that inherit from util.F2PyTest
superclass. This superclass is present in util.py
file.
|
|
This superclass contains many helper functions responsible for parsing and compiling test source files. Its child classes can override its sources
data member to provide their own source files. This superclass will then compile the added source files upon object creation and their functions will be appended to self.module
data member. Thus, the child classes will be able to access the fortran functions specified in source file by calling self.module.[fortran_function_name]
.
Anyone looking to add more tests can follow the same strategy. The user can add new test classes to the appropriate file in tests
directory inheriting from util.F2PyTest
superclass and test the fortran function by calling self.module.[fortran_function_name]
.
Example Link to heading
Suppose you found this bug in f2py. You corrected it and now want to add tests for it. How do you do that?
Well, first of all you would have to identify the correct file to add the test. This bug was related to incorrect parsing of Fortran code where subroutines ending with endsubroutine
were not parsed correctly and therefore not compiled. Upon importing such subroutines, the user would encounter a missing attribute error. Since crackfortran.py
file is responsible for parsing, we add the test to test_crackfortran.py
file. The testing source file should also be created in numpy/f2py/tests/src/crackfortran/
directory. Similarly other tests can be added to already present test_
files based on user’s discretion.
First lets create a file my_source_file.f
containing subroutines ending with endsubroutine
. This file contains two self-explanatory Fortran subroutines :-
|
|
We will compile this Fortran code and test that it is working.
Open test_crackfortran.py
to add the test for the previously added Fortran file:-
|
|
We override the sources
data member to provide the source file. The source files are compiled and subroutines are attached to module data member when the class object is created. The test_module
function calls the subroutines and tests their results.
Conclusion Link to heading
The current test suite of F2PY is a bit old. Modern python programmers accustomed to pytest
might find its lack of fixtures, setups and tear downs little unappealing. However, once you get the hang of it, its easy to understand and improve. It is not an exhaustive test suite, but it is improving everyday. A new test suite for testing the CLI program f2py2e.py
is being developed with modern pytest
style testing and you can have a look at it here. F2PY and its test suite are sure to undergo heavy refactoring in the coming times.