pyifb
Python bindings for Fortran's ISO_Fortran_binding.h descriptors (CFI_cdesc_t).
pyifb provides:
- A low-level extension module (
pyifb.ifb) exposing C descriptor structs, constants, and CFI helper functions. - A high-level Python wrapper (
pyifb.CFI_cdesc) that makes descriptor allocation and array exchange feel NumPy-native.
This is useful when interoperating with Fortran code that uses bind(C) and assumed-shape/descriptor-based interfaces.
Features
- Wraps
CFI_cdesc_tandCFI_dim_tfromISO_Fortran_binding.h - Exposes CFI constants/macros (for example:
CFI_SUCCESS,CFI_type_int,CFI_MAX_RANK) - Supports creating, serializing, and deserializing descriptors
- Supports descriptor operations such as allocation, deallocation, sectioning, pointer setup, and contiguity checks
- Includes a high-level
CFI_cdesc.valueproperty for exchanging data with NumPy arrays
Requirements
- Python 3.10+
- NumPy (installed automatically as a dependency)
- A C compiler toolchain for building the extension
- A Fortran runtime available at link/runtime
- Default build path targets GNU Fortran runtime (
libgfortran) - Alternative compiler/runtime behavior is handled in
setup.py
- Default build path targets GNU Fortran runtime (
Install
Install from source:
python -m pip install .
For editable development install:
python -m pip install -e .
Build
Build wheel/sdist:
python -m build
Quick Start
High-level descriptor wrapper
import numpy as np
import pyifb
# Create rank-2 descriptor
cdesc = pyifb.CFI_cdesc(rank=2)
# Assign NumPy data (allocates descriptor storage if needed)
cdesc.value = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.int32)
print(cdesc.rank) # 2
print(cdesc.shape) # (2, 3)
print(cdesc.elem_len) # 4
# Round-trip back to NumPy
arr = cdesc.value
print(arr)
Low-level API access
import pyifb
# Access raw constants and structs from the extension
print(pyifb.ifb.CFI_MAX_RANK)
print(pyifb.ifb.CFI_SUCCESS)
cdesc_t = pyifb.ifb.CFI_cdesc_t(rank=1)
status = cdesc_t.allocate([0], [9], 4)
print(status == pyifb.ifb.CFI_SUCCESS)
Using pyifb With Fortran Code
pyifb is designed to work with Fortran procedures exposed through
bind(C). The typical workflow is:
- Write a
bind(C)Fortran routine. - Build it as a shared library (
.so/.dylib/.dll). - Create a
CFI_cdescin Python and pass its serialized descriptor to the Fortran routine withctypes.
Fortran side (bind(C) + assumed-shape)
module finterop
use iso_c_binding
implicit none
contains
integer(c_int) function sum_desc(x) bind(C, name="sum_desc")
integer(c_int), intent(in) :: x(:)
integer(c_int) :: i
sum_desc = 0
do i = 1, size(x)
sum_desc = sum_desc + x(i)
end do
end function sum_desc
end module finterop
Build a shared library (GNU example):
gfortran -shared -fPIC -O2 finterop.f90 -o libfinterop.so
Python side (pyifb + ctypes)
import ctypes
import numpy as np
import pyifb
lib = ctypes.CDLL("./libfinterop.so")
sum_desc = lib.sum_desc
sum_desc.restype = ctypes.c_int
sum_desc.argtypes = [ctypes.c_void_p]
# Build a rank-1 descriptor and populate from NumPy.
cdesc = pyifb.CFI_cdesc(rank=1)
cdesc.value = np.array([10, 20, 30], dtype=np.int32)
# Pass descriptor bytes by pointer.
raw = cdesc.to_bytes()
buf = ctypes.create_string_buffer(raw, len(raw))
result = sum_desc(buf)
print(result) # 60
Notes and pitfalls
- Use Fortran interoperable kinds (
integer(c_int),real(c_double), etc.) fromiso_c_binding. - Match NumPy dtype to Fortran kind (for example,
np.int32<->integer(c_int)). CFI_cdesc.valuestores arrays in Fortran (column-major) order.- For scalar descriptors, use
CFI_cdesc(rank=0)and assign a scalar NumPy value. - For routines that expect allocatable/pointer dummy arguments, descriptor
attributes must also match (
CFI_attribute_allocatable/CFI_attribute_pointer).
Testing
The test suite builds a small Fortran shared library in tests/ (via CMake) and then runs pytest.
Run tests:
pytest
Or use the helper script:
./build_and_test.sh
Development
Useful scripts in the repository root:
build.shbuild_and_test.shlint.shcoverage.sh
Optional dependency groups (from pyproject.toml):
testcoveragedevperfomance
Install development extras (example):
python -m pip install -e ".[dev,test]"
Compilers
By default we compile with gcc/gfortran and that is the version shipped in PyPI. We support other compiliers:
- Intel ICC/IFX
- Clang
These must be built locally, to do set the environement variables:
export CC=icx
export FC=ifx
or
export CC=clang
export FC=flang
Then install the package
python -m pip install -e .
Other compilers can be support on request, if they have a publicly readable ISO_Fortran_Bindings.h file. Please open a bug request for a new compiler.
License
GPL-2.0-or-later. See COPYING.txt.
Metadata
Release files for pyifb 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyifb-0.2.0.tar.gz | 45.6 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| pyifb-0.2.0-cp310-abi3-musllinux_1_2_x86_64.whl | CPython 3.10 | abi3 | Linux musl 1.2+ x86-64 | Details |
| pyifb-0.2.0-cp310-abi3-musllinux_1_2_aarch64.whl | CPython 3.10 | abi3 | Linux musl 1.2+ ARM64 | Details |
| pyifb-0.2.0-cp310-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| pyifb-0.2.0-cp310-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ ARM64, Linux glibc 2.27+ ARM64 | Details |
| pyifb-0.2.0-cp310-abi3-macosx_14_0_arm64.whl | CPython 3.10 | abi3 | macOS 14.0+ ARM64 | Details |
Total release size: 4.5 MB
Release files / pyifb-0.2.0.tar.gz
| Download URL | pyifb-0.2.0.tar.gz |
|---|---|
| Size | 45.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
25f533e450c43f34764fd4de945e74be505df6c966c17aafee4f910357017bf8
|
|
BLAKE2b-256 checksum How to use checksums |
756ae43cae9445f98aa592dda9d96859037959456b00cba8381f302f0317f02f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 25, 2026.
Transparency logRelease files / pyifb-0.2.0-cp310-abi3-musllinux_1_2_x86_64.whl
| Download URL | pyifb-0.2.0-cp310-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.10 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
fc915488e77a904f00a704a6185f668a7da9f63ad05a8a9002c69b767ae95aa4
|
|
BLAKE2b-256 checksum How to use checksums |
c5165c4ddb888450f8b7535788ac08c21f09b9e8e8eced1e7e7f833ace98859d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 25, 2026.
Transparency logRelease files / pyifb-0.2.0-cp310-abi3-musllinux_1_2_aarch64.whl
| Download URL | pyifb-0.2.0-cp310-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 652.3 kB |
| Tags | CPython 3.10 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
58912144db03b663e9f3238f10ebea8262dec813f48ef748b42bf8c24a5c2b13
|
|
BLAKE2b-256 checksum How to use checksums |
8b9ffa330eb6b8cf02400b875a1d4c0ef207dd053799d3987290c96ecc6e16bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 25, 2026.
Transparency logRelease files / pyifb-0.2.0-cp310-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pyifb-0.2.0-cp310-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.1 MB |
| Tags | CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
39571acf83621e15c1f90fa839b29153aac529fca06c20612a07efb7a2e9448b
|
|
BLAKE2b-256 checksum How to use checksums |
63b819ccf0cdbf50df502fa2e7c9f9ee4cd7d9d3bae16f26913e798cc6653dd1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 25, 2026.
Transparency logRelease files / pyifb-0.2.0-cp310-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
| Download URL | pyifb-0.2.0-cp310-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 511.4 kB |
| Tags | CPython 3.10 Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
bfd2f3bccdda09ed3f7efb4f0459b033e3dc16552a26cd2785ccea4d77e9de9e
|
|
BLAKE2b-256 checksum How to use checksums |
43d6d1bfaf7a26389b7e45a559fb3fab76e3bacf1e80735b99079974b67bca01
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 25, 2026.
Transparency logRelease files / pyifb-0.2.0-cp310-abi3-macosx_14_0_arm64.whl
| Download URL | pyifb-0.2.0-cp310-abi3-macosx_14_0_arm64.whl |
|---|---|
| Size | 749.0 kB |
| Tags | CPython 3.10 abi3 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
9dde595c619d90d4578c387add966edd308c048efde6e59d74a09f4df5bfb7ae
|
|
BLAKE2b-256 checksum How to use checksums |
2314b9f21095c2fe6e19fde82363141be1801c882bd528052586542164373a2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 25, 2026.
Transparency log