F2PY test suite#
F2PY’s test suite is present in the directory numpy/f2py/tests. Its aim
is to ensure that Fortran language features are correctly translated to Python.
For example, the user can specify starting and ending indices of arrays in
Fortran. This behaviour is translated to the generated CPython library where
the arrays strictly start from 0 index.
The directory of the test suite looks like the following:
./tests/
├── __init__.py
├── src
│ ├── abstract_interface
│ ├── array_from_pyobj
│ ├── // ... several test folders
│ └── string
├── test_abstract_interface.py
├── test_array_from_pyobj.py
├── // ... several test files
├── test_symbolic.py
└── util.py
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 contains utility
functions for building and importing Fortran modules during test time using a
temporary location.
Adding a test#
F2PY’s current test suite predates pytest and therefore does not use fixtures.
Instead, the test files contain test classes that inherit from F2PyTest
class present in util.py.
1 backend = SimplifiedMesonBackend(
2 modulename=module_name,
3 sources=source_files,
4 extra_objects=kwargs.get("extra_objects", []),
5 build_dir=build_dir,
6 include_dirs=kwargs.get("include_dirs", []),
7 library_dirs=kwargs.get("library_dirs", []),
8 libraries=kwargs.get("libraries", []),
9 define_macros=kwargs.get("define_macros", []),
10 undef_macros=kwargs.get("undef_macros", []),
This class many helper functions 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].
New in version v2.0.0b1.
Each of the f2py tests should run without failure if no Fortran compilers
are present on the host machine. To facilitate this, the CompilerChecker is
used, essentially providing a meson dependent set of utilities namely
has_{c,f77,f90,fortran}_compiler().
For the CLI tests in test_f2py2e, flags which are expected to call meson
or otherwise depend on a compiler need to call compiler_check_f2pycli()
instead of f2pycli().
Example#
Consider the following subroutines, contained in a file named add-test.f
subroutine addb(k)
real(8), intent(inout) :: k(:)
k=k+1
endsubroutine
subroutine addc(w,k)
real(8), intent(in) :: w(:)
real(8), intent(out) :: k(size(w))
k=w+1
endsubroutine
The first routine addb simply takes an array and increases its elements by 1. The second subroutine addc assigns a new array k with elements greater that the elements of the input array w by 1.
A test can be implemented as follows:
class TestAdd(util.F2PyTest):
sources = [util.getpath("add-test.f")]
def test_module(self):
k = np.array([1, 2, 3], dtype=np.float64)
w = np.array([1, 2, 3], dtype=np.float64)
self.module.addb(k)
assert np.allclose(k, w + 1)
self.module.addc([w, k])
assert np.allclose(k, w + 1)
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.