Fortran to Python interface generator with derived type support for automated wrapper generation
—
Powerful transformation system for adapting Fortran AST to be suitable for Python wrapping, including type conversions, intent handling, code restructuring, and optimization for f2py compatibility.
High-level transformation functions that orchestrate the complete AST modification process.
def transform_to_generic_wrapper(tree, types, callbacks, constructors, destructors,
sizeof_fortran_t, string_lengths, init_lines,
abort_func, argument_name_map, move_methods,
shorten_routine_names, modules_for_type,
default_to_inout, comp_tuple_dtype):
"""Transform AST for generic wrapper generation."""
def transform_to_f90_wrapper(tree, types, callbacks, constructors, destructors,
sizeof_fortran_t, string_lengths, init_lines,
abort_func, argument_name_map, move_methods,
shorten_routine_names, modules_for_type,
default_to_inout, comp_tuple_dtype):
"""Transform AST for Fortran 90 wrapper generation."""
def transform_to_py_wrapper(tree, types):
"""Transform AST for Python wrapper generation."""Specialized transformer classes that perform specific AST modifications.
class AccessUpdater(FortranTransformer):
"""Update access control attributes (public/private)."""
class PrivateSymbolsRemover(FortranTransformer):
"""Remove private symbols that should not be wrapped."""
class UnwrappablesRemover(FortranTransformer):
"""Remove constructs that cannot be wrapped by f2py."""class StringLengthConverter(FortranVisitor):
"""Convert Fortran string length specifications."""
class ArrayDimensionConverter(FortranVisitor):
"""Convert array dimension specifications for Python compatibility."""
class NormaliseTypes(FortranVisitor):
"""Normalize Fortran type names and kind specifications."""class MethodFinder(FortranTransformer):
"""Identify and mark methods for object-oriented wrapping."""
class ConstructorExcessToClassMethod(FortranTransformer):
"""Convert excess constructor arguments to class methods."""
class FunctionToSubroutineConverter(FortranTransformer):
"""Convert functions to subroutines for easier wrapping."""
class IntentOutToReturnValues(FortranTransformer):
"""Convert intent(out) arguments to return values."""class RenameReservedWords(FortranVisitor):
"""Rename Fortran identifiers that conflict with Python keywords."""
class RenameArgumentsPython(FortranVisitor):
"""Rename arguments to follow Python naming conventions."""
class RenameInterfacesPython(FortranVisitor):
"""Rename interfaces for Python compatibility."""
class ReorderOptionalArgumentsPython(FortranVisitor):
"""Reorder optional arguments to match Python conventions."""class SetInterfaceProcedureCallNames(FortranVisitor):
"""Set procedure call names for interface resolution."""
class ResolveInterfacePrototypes(FortranTransformer):
"""Resolve procedure prototypes within interfaces."""
class ResolveBindingPrototypes(FortranTransformer):
"""Resolve type-bound procedure prototypes."""
class BindConstructorInterfaces(FortranTransformer):
"""Bind constructor procedures to interfaces."""class OnlyAndSkip(FortranTransformer):
"""Apply only/skip filters to select items for wrapping."""def remove_private_symbols(node, force_public=None):
"""Remove private symbols from AST nodes."""
def fix_subroutine_uses_clauses(tree, types):
"""Fix USE clauses in subroutine definitions."""
def fix_element_uses_clauses(tree, types):
"""Fix USE clauses for derived type elements."""def set_intent(attributes, intent):
"""Set intent specification for procedure arguments."""
def convert_derived_type_arguments(tree, init_lines, sizeof_fortran_t):
"""Convert derived type arguments to opaque handles."""
def convert_array_intent_out_to_intent_inout(tree):
"""Convert array intent(out) to intent(inout) for safety."""def collapse_single_interfaces(tree):
"""Collapse interfaces containing only one procedure."""
def add_missing_constructors(tree):
"""Add missing constructor routines for derived types."""
def add_missing_destructors(tree):
"""Add missing destructor routines for derived types."""
def create_super_types(tree, types):
"""Create super-type hierarchies for complex types."""def find_referenced_modules(mods, tree):
"""Find all modules referenced by the tree."""
def find_referenced_types(mods, tree):
"""Find all types referenced by the tree."""def append_type_dimension(tree, types):
"""Add dimension information to type definitions."""
def fix_subroutine_type_arrays(tree, types):
"""Fix array handling in subroutine signatures."""
def extract_dimensions_parameters(d, tree):
"""Extract dimension parameters from array specifications."""def shorten_long_name(name):
"""Shorten excessively long routine and type names."""from f90wrap.transform import transform_to_f90_wrapper
# Basic transformation for F90 wrapper
tree = parse_source_files(['source.f90'])
types = find_types(tree)
transform_to_f90_wrapper(tree, types, [], [], [],
sizeof_fortran_t, {}, [],
'f90wrap_abort', {}, False,
False, {}, False, False)from f90wrap.transform import (PrivateSymbolsRemover, RenameReservedWords,
IntentOutToReturnValues)
# Apply specific transformers
private_remover = PrivateSymbolsRemover()
private_remover.visit(tree)
rename_transformer = RenameReservedWords()
rename_transformer.visit(tree)
intent_transformer = IntentOutToReturnValues()
intent_transformer.visit(tree)from f90wrap.transform import (add_missing_constructors, add_missing_destructors,
create_super_types)
# Add missing constructors and destructors
add_missing_constructors(tree)
add_missing_destructors(tree)
# Create type hierarchies
types = find_types(tree)
create_super_types(tree, types)from f90wrap.transform import (convert_array_intent_out_to_intent_inout,
collapse_single_interfaces,
ReorderOptionalArgumentsPython)
# Convert array intents for safety
convert_array_intent_out_to_intent_inout(tree)
# Simplify interfaces
collapse_single_interfaces(tree)
# Reorder arguments for Python
reorder_transformer = ReorderOptionalArgumentsPython()
reorder_transformer.visit(tree)The typical transformation pipeline follows these stages:
The transformation system provides comprehensive error detection:
Install with Tessl CLI
npx tessl i tessl/pypi-f90wrap