Skip to content

Commit

Permalink
tests: add fortran test
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
  • Loading branch information
henryiii committed Nov 16, 2022
1 parent a421e7f commit 0297c50
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 1 deletion.
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ test = [
"build",
"cattrs >=22.2.0",
"distlib",
"numpy"
"pathspec",
"pybind11",
"pyproject-metadata",
Expand Down Expand Up @@ -119,6 +120,7 @@ testpaths = ["tests"]
markers = [
"compile: Compiles code",
"configure: Configures CMake code",
"fortran: Fortran code",
"integration: Full package build",
]

Expand Down Expand Up @@ -150,7 +152,7 @@ module = ["scikit_build_core.*"]
disallow_untyped_defs = true

[[tool.mypy.overrides]]
module = ["distlib.*", "pathspec"]
module = ["distlib.*", "pathspec", "numpy"]
ignore_missing_imports = true


Expand Down
46 changes: 46 additions & 0 deletions tests/packages/fortran_example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# setup project ###
cmake_minimum_required(VERSION 3.15...3.24)

project(
fibby
VERSION 1.0
DESCRIPTION "FIB module"
LANGUAGES C Fortran)

find_package(Python REQUIRED COMPONENTS Interpreter Development.Module NumPy)

# PyPy fix due to broken SOABI reporting
if(SKBUILD)
set(Python_SOABI "${SKBUILD_SOABI}")
endif()

# Grab the variables from a local Python installation F2PY headers
execute_process(
COMMAND "${Python_EXECUTABLE}" -c
"import numpy.f2py; print(numpy.f2py.get_include())"
OUTPUT_VARIABLE F2PY_INCLUDE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)

# Prepping the module
set(f2py_module_name "fibby")
set(fortran_src_file "${CMAKE_CURRENT_SOURCE_DIR}/fib1.f")
set(f2py_module_c "${f2py_module_name}module.c")

# Target for enforcing dependencies
add_custom_target(genpyf DEPENDS "${fortran_src_file}")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${f2py_module_c}"
COMMAND ${Python_EXECUTABLE} -m "numpy.f2py" "${fortran_src_file}" -m "fibby"
--lower # Important
DEPENDS fib1.f # Fortran source
)

python_add_library(${CMAKE_PROJECT_NAME} MODULE WITH_SOABI "${f2py_module_name}module.c"
"${F2PY_INCLUDE_DIR}/fortranobject.c" "${fortran_src_file}")

target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ${F2PY_INCLUDE_DIR})
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Python::NumPy)

add_dependencies(${CMAKE_PROJECT_NAME} genpyf)

install(TARGETS ${CMAKE_PROJECT_NAME} DESTINATION .)
18 changes: 18 additions & 0 deletions tests/packages/fortran_example/fib1.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
C FILE: FIB1.F
SUBROUTINE FIB(A,N)
C
C CALCULATE FIRST N FIBONACCI NUMBERS
C
INTEGER N
REAL*8 A(N)
DO I=1,N
IF (I.EQ.1) THEN
A(I) = 0.0D0
ELSEIF (I.EQ.2) THEN
A(I) = 1.0D0
ELSE
A(I) = A(I-1) + A(I-2)
ENDIF
ENDDO
END
C END FILE FIB1.F
13 changes: 13 additions & 0 deletions tests/packages/fortran_example/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[build-system]
requires = ["scikit-build-core", "numpy"]
build-backend = "scikit_build_core.build"

[project]
name = "fibby"
version = "0.0.1"
description = "a minimal example package (fortran version)"
requires-python = ">=3.7"
classifiers = [
"License :: OSI Approved :: BSD License",
]
dependencies = ["numpy"]
48 changes: 48 additions & 0 deletions tests/test_fortran.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import shutil
import sys
import zipfile
from pathlib import Path

import numpy as np
import pytest

from scikit_build_core.build import build_wheel

DIR = Path(__file__).parent.resolve()
FORTRAN_EXAMPLE = DIR / "packages/fortran_example"


@pytest.mark.compile
@pytest.mark.configure
@pytest.mark.fortran
def test_pep517_wheel(tmp_path, monkeypatch, virtualenv):
dist = tmp_path / "dist"
dist.mkdir()
monkeypatch.chdir(FORTRAN_EXAMPLE)
if Path("dist").is_dir():
shutil.rmtree("dist")
out = build_wheel(str(dist))
(wheel,) = dist.glob("fibby-0.0.1-*.whl")
assert wheel == dist / out

if sys.version_info >= (3, 8):
with wheel.open("rb") as f:
p = zipfile.Path(f)
file_names = [p.name for p in p.iterdir()]

assert len(file_names) == 2
assert "fibby-0.0.1.dist-info" in file_names
file_names.remove("fibby-0.0.1.dist-info")
(so_file,) = file_names

assert so_file.startswith("fibby")
print("SOFILE:", so_file)

virtualenv.run(f"python -m pip install {wheel}")

output = virtualenv.run(
"python -c 'import fibby; import numpy as np; a = np.zeros(9); fibby.fib(a); print(a)'",
capture=True,
)

assert output.strip() == str(np.array([0, 1, 1, 2, 3, 5, 8, 13, 21], dtype=float))

0 comments on commit 0297c50

Please sign in to comment.