| title | First Wrapped Function |
|---|---|
| description | Build and call your first Fortran function as a Python extension |
| audience | users |
| prerequisites | installation, verification |
| related | first-wrapped-module.md, ../guide/wrapping-functions.md |
| status | maintained |
| publication | reviewed |
This example shows how to build a simple scalar Fortran function and call it from Python using the exact NumPy dtypes required by its contract.
Create scale.f90:
real(8) function scale(value, factor) result(output)
real(8), intent(in) :: value
real(8), intent(in) :: factor
output = value * factor
end function scalePreview the Python interface before building:
python3 -m prik generate --pyi scale.f90The generated semantic .pyi contains:
from prik.contracts import Addr, Arg, Float64, external, native_call
@external
@native_call([Addr(Arg(0)), Addr(Arg(1))])
def scale(
value: Float64,
factor: Float64
) -> Float64: ...Float64 means the function requires numpy.float64 scalar arguments and
returns the same scalar type. @external identifies a procedure outside a
Fortran module. @native_call(...) maps the two Python arguments to the native
call and passes each scalar by address.
This file is both the wrapper contract and an editable description of the Python interface. You can leave it unchanged for this example; later pages show useful edits in context.
From the directory containing scale.f90, run:
python3 -m prik scale.f90 --out-dir build/first-functionThis creates an importable scale extension module in the build/first-function directory.
prik creates NumPy-style docstrings from the same contract. Import the built extension and inspect the function:
import sys
sys.path.insert(0, "build/first-function")
import scale
print(scale.scale.__doc__)scale(value, factor) -> float64
Parameters
----------
value : float64
factor : float64
Returns
-------
result : float64
help(scale.scale) shows the same signature, parameter types, result, and
documented exceptions. Generated modules, classes, methods, and properties
also provide docstrings.
import numpy as np
result = scale.scale(np.float64(3.0), np.float64(2.5))
print(result) # 7.5
assert result == 7.5You must pass the exact NumPy scalar types:
# This will raise TypeError
scale.scale(3.0, 2.5)
# Correct way
scale.scale(np.float64(3.0), np.float64(2.5))Always convert at the call site for scalar arguments.
If the build fails, rerun it with --verbose.
- Continue with Your First Wrapped Module.
- For more function behavior, see Wrapping Functions.