Fortran to Python interface generator with derived type support for automated wrapper generation
—
Runtime classes and utilities that provide the foundation for generated wrapper code, handling derived type management, Fortran-Python interoperability, and memory management for f90wrap-generated Python extensions.
Core base classes that generated wrapper code inherits from to provide Fortran derived type functionality in Python.
class FortranDerivedType(object):
"""
Base class for all Fortran derived types in Python.
Provides memory management, copying, and handle-based access
to Fortran derived type instances.
"""
@classmethod
def from_handle(cls, handle, alloc=False):
"""
Create Python object from Fortran type handle.
Parameters:
- handle: int, opaque handle to Fortran type instance
- alloc: bool, whether to allocate new memory
Returns:
New instance of the derived type class
"""
def __copy__(self):
"""Create shallow copy of derived type instance."""
def copy(self):
"""Create deep copy of derived type instance."""class FortranDerivedTypeArray(object):
"""
Array container for Fortran derived types.
Provides Python sequence interface for arrays of Fortran derived types
with proper memory management and element access.
"""
def __init__(self, parent, getfunc, setfunc, lenfunc, doc, arraytype):
"""
Initialize derived type array.
Parameters:
- parent: parent object containing the array
- getfunc: function to get array element by index
- setfunc: function to set array element by index
- lenfunc: function to get array length
- doc: documentation string
- arraytype: type of array elements
"""
def iterindices(self):
"""Iterate over valid array indices."""
def items(self):
"""Iterate over (index, value) pairs."""
def __iter__(self):
"""Iterator protocol for array elements."""
def __len__(self):
"""Get array length."""
def __getitem__(self, i):
"""Get array element by index."""
def __setitem__(self, i, value):
"""Set array element by index."""
def __copy__(self):
"""Create shallow copy of array."""
def copy(self):
"""Create deep copy of array."""class FortranModule(object):
"""
Base class for Fortran modules in Python.
Provides namespace and organization for module-level procedures,
types, and parameters.
"""System for registering and looking up Fortran type classes at runtime.
class register_class(object):
"""
Decorator for registering Fortran type classes.
Parameters:
- cls_name: str, name of the class to register
Returns:
The registered class (for use as decorator)
"""
def __init__(self, cls_name):
"""Initialize the decorator with class name."""
def __call__(self, cls):
"""Register the class and return it."""
def lookup_class(cls_name):
"""
Look up registered Fortran type class by name.
Parameters:
- cls_name: str, name of the class to look up
Returns:
The registered class
Raises:
KeyError if class name not found
"""Runtime constants for Fortran type handle management.
sizeof_fortran_t = ... # Size in bytes of Fortran type handles
empty_handle = ... # Empty/null type handle value
empty_type = ... # Empty type instance for initializationMetaclass for implementing singleton pattern in Fortran module classes.
class Singleton(type):
"""Metaclass for creating singleton classes."""# Generated wrapper classes inherit from runtime base classes
from myfortrancode import MyType, MyModule
# Create instance using constructor
obj = MyType()
# Create from existing handle (advanced usage)
obj2 = MyType.from_handle(existing_handle)
# Copy instances
obj_copy = obj.copy()
obj_shallow = obj.__copy__()
# Access module-level functionality
result = MyModule.some_function(args)# Generated code creates arrays using FortranDerivedTypeArray
from myfortrancode import ContainerType
container = ContainerType()
# Access array elements (array property automatically created)
first_item = container.items[0]
container.items[1] = new_item
# Iterate over array
for item in container.items:
process(item)
# Get array length
count = len(container.items)
# Iterate with indices
for i, item in container.items.items():
print(f"Item {i}: {item}")from f90wrap.runtime import register_class, lookup_class
# Register custom type class
@register_class
class MyCustomType(FortranDerivedType):
# Custom implementation
pass
# Look up registered class
cls = lookup_class('MyCustomType')
if cls:
instance = cls()from f90wrap.runtime import FortranDerivedType
class CustomFortranType(FortranDerivedType):
def __init__(self, handle=None):
if handle is None:
# Call Fortran constructor
self._handle = _mymodule.create_custom_type()
else:
self._handle = handle
def __del__(self):
# Ensure cleanup
if hasattr(self, '_handle'):
_mymodule.destroy_custom_type(self._handle)
@property
def value(self):
"""Access Fortran component through getter."""
return _mymodule.get_custom_type_value(self._handle)
@value.setter
def value(self, val):
"""Set Fortran component through setter."""
_mymodule.set_custom_type_value(self._handle, val)The runtime classes provide automatic memory management for Fortran derived types:
Fortran derived types are accessed through opaque handles:
Special handling for arrays of derived types:
Runtime classes integrate with Python's exception system:
try:
obj = MyType()
obj.risky_operation()
except RuntimeError as e:
# Fortran runtime errors propagated as RuntimeError
print(f"Fortran error: {e}")The runtime system provides thread safety for:
The runtime classes integrate closely with NumPy:
import numpy as np
from myfortrancode import MyType
obj = MyType()
# Get NumPy view of Fortran array (if supported)
arr = obj.get_array_view()
print(f"Array shape: {arr.shape}, dtype: {arr.dtype}")
# Modify through NumPy (changes reflected in Fortran)
arr[0] = 42
# Create from NumPy array
obj.set_data_from_numpy(np.array([1, 2, 3, 4]))Install with Tessl CLI
npx tessl i tessl/pypi-f90wrap