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,因此未使用 fixture。相反地,測試檔案包含繼承自 util.pyF2PyTest 類別的測試類別。

 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 函數呼叫子程式並測試其結果。