F2PY 测试套件#
F2PY 的测试套件位于 numpy/f2py/tests
目录中。其目的是确保 Fortran 语言特性被正确地转换为 Python。例如,用户可以在 Fortran 中指定数组的起始和结束索引。这种行为会被转换到生成的 CPython 库中,其中数组严格从 0 索引开始。
测试套件目录结构如下
./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
以 test_
开头的文件包含 F2PY 各方面的测试,从解析 Fortran 文件到检查模块文档。 src
目录包含我们进行测试所用的 Fortran 源文件。 util.py
包含在测试时使用临时位置构建和导入 Fortran 模块的实用函数。
添加测试#
F2PY 当前的测试套件早于 pytest
,因此不使用 fixtures。相反,测试文件包含继承自 util.py
中 F2PyTest
类的测试类。
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", []),
此类别提供了许多用于解析和编译测试源文件的辅助函数。其子类可以重写其 sources
数据成员以提供自己的源文件。该超类将在对象创建时编译添加的源文件,并且其函数将附加到 self.module
数据成员。因此,子类将能够通过调用 self.module.[fortran_function_name]
来访问源文件中指定的 Fortran 函数。
v2.0.0b1 版本新增。
如果主机上没有 Fortran 编译器,每个 f2py
测试都应能无故障运行。为方便起见,使用了 CompilerChecker
,它本质上提供了一组依赖于 meson
的实用程序,即 has_{c,f77,f90,fortran}_compiler()
。
对于 test_f2py2e
中的 CLI 测试,预期调用 meson
或依赖于编译器的标志需要调用 compiler_check_f2pycli()
而不是 f2pycli()
。
示例#
考虑以下子程序,它们包含在一个名为 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
第一个例程 addb 只是接受一个数组并将其元素增加 1。第二个子程序 addc 分配一个新的数组 k,其元素比输入数组 w 的元素大 1。
测试可以按如下方式实现
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)
我们重写 sources
数据成员以提供源文件。当类对象被创建时,源文件会被编译,子程序会附加到模块数据成员。 test_module
函数调用子程序并测试其结果。