CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-f90wrap

Fortran to Python interface generator with derived type support for automated wrapper generation

Pending
Overview
Eval results
Files

code-generation.mddocs/

Code Generation

Flexible code generation framework for producing both Fortran wrapper code and Python wrapper code with customizable formatting, structure, and output styles optimized for f2py compilation and Python integration.

Capabilities

Base Code Generator

Foundation class providing common code generation utilities and formatting capabilities.

class CodeGenerator(object):
    """Base code generation utility with formatting and output management."""
    
    def __init__(self, indent, max_length, continuation, comment):
        """
        Initialize code generator.
        
        Parameters:
        - indent: str, indentation string (spaces or tabs)
        - max_length: int, maximum line length before wrapping
        - continuation: str, line continuation character
        - comment: str, comment prefix character
        """
    
    def indent(self):
        """Increase current indentation level."""
    
    def dedent(self):
        """Decrease current indentation level."""
    
    def write(self, *args):
        """
        Write arbitrary string arguments to the instance's code, split by
        newline characters and implied newline after last arg.
        """
    
    def writelines(self, items, insert=None, level=None):
        """
        Write the given code lines to the instance's code.
        
        Parameters:
        - items: list of strings, code lines to be appended
        - insert: int or None, insert lines after index instead of appending
        - level: int or None, override current indent level
        
        Returns:
        int, index for next line to be added
        """
    
    def split_long_lines(self):
        """Split long lines using continuation characters."""
    
    def __str__(self):
        """Get generated code as formatted string."""

Fortran Wrapper Generator

Specialized generator for creating Fortran 90 wrapper code that interfaces with original Fortran code.

class F90WrapperGenerator(FortranVisitor, CodeGenerator):
    """Generate Fortran 90 wrapper code for f2py compilation."""

The F90WrapperGenerator creates simplified Fortran interfaces that:

  • Replace derived type arguments with opaque integer handles
  • Provide C-compatible procedure signatures
  • Handle string length parameters explicitly
  • Manage memory allocation for derived types
  • Enable exception handling through abort functions

Python Wrapper Generator

Specialized generator for creating high-level Python wrapper code that provides a Pythonic interface.

class PythonWrapperGenerator(FortranVisitor, CodeGenerator):
    """Generate Python wrapper code with object-oriented interface."""

The PythonWrapperGenerator creates Python classes and functions that:

  • Provide object-oriented interfaces for derived types
  • Handle automatic type conversion between Python and Fortran
  • Manage memory allocation and cleanup transparently
  • Offer Pythonic argument handling (keyword arguments, defaults)
  • Include comprehensive docstrings with type information

Python Wrapper Utilities

Utility functions supporting Python wrapper code generation.

def py_arg_value(arg):
    """Get Python argument value representation for wrapper functions."""

def normalise_class_name(name, name_map):
    """Normalize class names according to Python conventions."""

def format_call_signature(node):
    """Format procedure call signature for Python wrapper functions."""

def format_doc_string(node):
    """Format comprehensive docstrings from Fortran documentation."""

Usage Examples

Basic Code Generation

from f90wrap.codegen import CodeGenerator

# Create generator with custom formatting
generator = CodeGenerator(indent='    ', max_length=80, 
                         continuation='&', comment='!')

# Generate code with proper formatting
generator.write('subroutine example(x, y)')
generator.indent()
generator.write('real, intent(in) :: x')
generator.write('real, intent(out) :: y')
generator.write('y = x * 2.0')
generator.dedent()
generator.write('end subroutine example')

# Get formatted code
code = str(generator)
print(code)

Fortran Wrapper Generation

from f90wrap.f90wrapgen import F90WrapperGenerator
from f90wrap.fortran import walk_procedures

# Create F90 wrapper generator
f90_gen = F90WrapperGenerator(indent='  ', max_length=72,
                             continuation='&', comment='!')

# Generate wrappers for all procedures
for proc in walk_procedures(tree):
    f90_gen.visit(proc)

# Write to file
with open('f90wrap_module.f90', 'w') as f:
    f.write(str(f90_gen))

Python Wrapper Generation

from f90wrap.pywrapgen import PythonWrapperGenerator
from f90wrap.fortran import walk_modules

# Create Python wrapper generator  
py_gen = PythonWrapperGenerator(indent='    ', max_length=80,
                               continuation='\\', comment='#')

# Generate Python classes for modules
for module in walk_modules(tree):
    py_gen.visit(module)

# Write to file
with open('wrapper_module.py', 'w') as f:
    f.write(str(py_gen))

Custom Code Generation

from f90wrap.codegen import CodeGenerator
from f90wrap.fortran import FortranVisitor

class CustomGenerator(FortranVisitor, CodeGenerator):
    def __init__(self):
        CodeGenerator.__init__(self, '  ', 80, '&', '!')
    
    def visit_Subroutine(self, node):
        self.write(f'! Wrapper for {node.name}')
        self.write(f'subroutine wrap_{node.name}()')
        self.indent()
        # Custom wrapper logic
        self.write('! Custom code here')
        self.dedent()
        self.write('end subroutine')

# Use custom generator
gen = CustomGenerator()
gen.visit(tree)
print(str(gen))

Code Generation Features

Fortran Wrapper Features

Derived Type Handling:

  • Converts derived type arguments to opaque integer handles
  • Generates type construction and destruction wrappers
  • Manages type component access through getter/setter routines
  • Handles arrays of derived types with specialized wrappers

Memory Management:

  • Automatic allocation/deallocation of temporary variables
  • Proper handling of allocatable and pointer components
  • Memory leak prevention through systematic cleanup
  • Integration with Fortran's memory model

String Handling:

  • Explicit string length parameter management
  • Character array conversion for f2py compatibility
  • Support for both fixed-length and allocatable strings
  • Proper null-termination handling

Exception Handling:

  • Integration with f90wrap_abort() for error propagation
  • Proper cleanup on exception conditions
  • Error code translation to Python exceptions
  • Stack unwinding support

Python Wrapper Features

Object-Oriented Interface:

  • Classes for Fortran derived types with Python methods
  • Inheritance hierarchies reflecting Fortran type relationships
  • Property-based access to type components
  • Context manager support for resource management

Argument Handling:

  • Keyword argument support with defaults
  • Optional argument handling matching Fortran semantics
  • Automatic type conversion (numpy arrays, scalars)
  • Validation of argument types and shapes

Documentation Generation:

  • Comprehensive docstrings from Fortran comments
  • Parameter documentation with types and descriptions
  • Return value documentation
  • Usage examples in docstrings

Integration Features:

  • NumPy array integration with proper dtypes
  • Support for both C and Fortran array ordering
  • Automatic shape and type checking
  • Memory view support for efficient data transfer

Output File Organization

Fortran Wrapper Files

f90wrap_<module>.f90     # Main module wrapper
f90wrap_toplevel.f90     # Top-level procedure wrappers
f90wrap_types.f90        # Type-specific wrappers

Python Wrapper Files

<module>.py              # Main Python interface
<module>_types.py        # Type definitions and classes
__init__.py              # Package initialization

Customization Options

Formatting Control

  • Indentation: Spaces, tabs, or custom strings
  • Line Length: Maximum line width with automatic wrapping
  • Continuation: Line continuation characters and style
  • Comments: Comment prefixes and formatting

Naming Conventions

  • Prefix/Suffix: Custom prefixes and suffixes for generated names
  • Case Conversion: Automatic case conversion (snake_case, camelCase)
  • Reserved Words: Automatic renaming of language keywords
  • Namespace Management: Module and package name handling

Code Structure

  • Module Organization: Single file vs. multi-file output
  • Import Management: Automatic import statement generation
  • Dependency Tracking: Cross-module dependency resolution
  • Documentation Level: Detailed vs. minimal documentation generation

Integration with Build Systems

f2py Integration

Generated Fortran wrappers are designed for seamless f2py compilation:

f2py -c -m _module f90wrap_*.f90 original_objects.o

Meson Integration

Support for modern build systems through proper file organization:

# meson.build configuration
f2py_sources = ['f90wrap_module.f90', 'f90wrap_types.f90']

CMake Integration

Compatible with CMake-based Fortran projects:

# CMakeLists.txt configuration
set(F90WRAP_SOURCES f90wrap_module.f90 f90wrap_types.f90)

Install with Tessl CLI

npx tessl i tessl/pypi-f90wrap

docs

code-generation.md

command-line.md

index.md

parsing-ast.md

runtime.md

transformation.md

type-system.md

tile.json