├── .github └── workflows │ ├── build-wheels.yml │ └── python-package.yml ├── .gitignore ├── LICENSE ├── README.md ├── docs ├── Makefile ├── api.rst ├── apidocs │ ├── f90wrap.codegen.rst │ ├── f90wrap.f90wrapgen.rst │ ├── f90wrap.fortran.rst │ ├── f90wrap.fortrantype.rst │ ├── f90wrap.latex.rst │ ├── f90wrap.parser.rst │ ├── f90wrap.pywrapgen.rst │ ├── f90wrap.rst │ ├── f90wrap.transform.rst │ └── modules.rst ├── conf.py ├── index.rst ├── tutorials │ ├── WCPM_logo_text.png │ ├── ase-calculators.png │ ├── boron-crack-100dpi.png │ ├── f90wrap-demo.ipynb │ ├── f90wrap.png │ ├── kermode-csc-warwick-nov-2015.ipynb │ ├── multiscale.png │ ├── scipy-stack.png │ ├── si-vac.gpw │ └── warwick-logo.png └── usage.rst ├── examples ├── CMakeLists.txt ├── Makefile ├── arrayderivedtypes │ ├── Makefile │ ├── Makefile.meson │ ├── kind_map │ ├── test.f90 │ └── tests.py ├── arrays │ ├── Makefile │ ├── Makefile.meson │ ├── README.md │ ├── kind_map │ ├── library.f90 │ ├── memory_profile.py │ ├── parameters.f90 │ └── tests.py ├── arrays_fixed │ ├── Makefile │ ├── Makefile.meson │ ├── README.md │ ├── kind_map │ ├── library.f │ ├── memory_profile.py │ ├── parameters.f │ └── tests.py ├── arrays_in_derived_types_issue50 │ ├── Makefile │ ├── Makefile.meson │ ├── kind_map │ ├── test.f90 │ └── tests.py ├── auto_raise_error │ ├── Makefile │ ├── Makefile.meson │ ├── main.f90 │ └── tests.py ├── callback_print_function_issue93 │ ├── Makefile │ ├── Makefile.meson │ ├── README.md │ ├── callback_print_output_python.ipynb │ ├── caller.f90 │ ├── cback.f90 │ ├── kind_map │ └── tests.py ├── class_names │ ├── Makefile │ ├── Makefile.meson │ ├── class_names.json │ ├── kind_map │ ├── test.f90 │ └── tests.py ├── cylinder │ ├── DNAD.f90 │ ├── DNADHeaders.h │ ├── Makefile │ ├── Makefile.meson │ ├── README │ ├── cyldnad.f90 │ ├── cylinder.ipynb │ ├── kind_map │ └── tests.py ├── default_i8 │ ├── Makefile │ ├── Makefile.meson │ ├── kind_map │ ├── test.f90 │ └── tests.py ├── derived-type-aliases │ ├── Makefile │ ├── Makefile.meson │ ├── kind_map │ ├── mytype_mod.f90 │ ├── othertype_mod.f90 │ └── tests.py ├── derivedtypes │ ├── Makefile │ ├── Makefile.meson │ ├── README.md │ ├── datatypes.f90 │ ├── kind_map │ ├── library.f90 │ ├── memory_profile.py │ ├── parameters.f90 │ ├── tests.py │ └── tests_pkg.py ├── derivedtypes_procedure │ ├── Makefile │ ├── Makefile.meson │ ├── library.f90 │ └── tests.py ├── docstring │ ├── Makefile │ ├── Makefile.meson │ ├── docstring_test.py │ └── main.f90 ├── elemental │ ├── Makefile │ ├── Makefile.meson │ ├── elemental_module.f90 │ ├── kind_map │ └── test.py ├── errorbinding │ ├── Makefile │ ├── Makefile.meson │ ├── README.md │ ├── datatypes.f90 │ ├── kind_map │ └── parameters.f90 ├── example2 │ ├── ExampleMakefiles │ │ ├── Makefile │ │ └── Makefile_py │ ├── Makefile │ ├── Makefile.meson │ ├── README │ ├── Source │ │ ├── BasicDefs │ │ │ ├── aa0_typelist.F90 │ │ │ ├── aa1_modules.F90 │ │ │ ├── aa2_defineAllProperties.F90 │ │ │ └── assign_constants.F90 │ │ └── HeliSrc │ │ │ └── set_defaults.F90 │ ├── kind_map │ ├── test_module.py │ └── test_package.py ├── extends │ ├── Makefile │ ├── Makefile.meson │ └── testextends.f90 ├── fixed_1D_derived_type_array_argument │ ├── Makefile │ ├── Makefile.meson │ ├── dummy.file │ ├── functions.f90 │ └── tests.py ├── fortran_oo │ ├── Makefile │ ├── Makefile.meson │ ├── base_poly.f90 │ ├── kind.map │ ├── main-oo.f90 │ └── oowrap_test.py ├── intent_out_size │ ├── Makefile │ ├── Makefile.meson │ ├── main.f90 │ └── tests.py ├── interface │ ├── Makefile │ ├── Makefile.meson │ ├── README.md │ ├── example.f90 │ ├── test.py │ └── test_pkg.py ├── issue105_function_definition_with_empty_lines │ ├── Makefile │ ├── Makefile.meson │ ├── main.f90 │ └── run.py ├── issue206_subroutine_oldstyle │ ├── Makefile │ ├── Makefile.meson │ ├── run.py │ └── subroutine_oldstyle.f ├── issue227_allocatable │ ├── Makefile │ ├── Makefile.meson │ ├── alloc_output.f90 │ └── run.py ├── issue235_allocatable_classes │ ├── Makefile │ ├── Makefile.meson │ ├── myclass.f90 │ ├── myclass_factory.f90 │ ├── mytype.f90 │ └── run.py ├── issue254_getter │ ├── .f2py_f2cmap │ ├── KIMDispersionEquation.f90 │ ├── KIMDispersion_Horton.f90 │ ├── Makefile │ ├── Makefile.meson │ └── run.py ├── issue258_derived_type_attributes │ ├── Makefile │ ├── dta_cc.f90 │ ├── dta_ct.f90 │ ├── dta_tc.f90 │ ├── dta_tt.f90 │ └── test.py ├── issue32 │ ├── Makefile │ ├── Makefile.meson │ ├── kind_map │ └── test.f90 ├── issue41_abstract_classes │ ├── Makefile │ ├── Makefile.meson │ ├── main.f90 │ ├── myclass_base.f90 │ ├── myclass_factory.f90 │ ├── myclass_impl.f90 │ ├── myclass_impl2.f90 │ ├── run.py │ └── test_parser_abstract_iface.py ├── keyword_renaming_issue160 │ ├── Makefile │ ├── Makefile.meson │ ├── kind_map │ ├── rename.f90 │ └── tests.py ├── kind_map_default │ ├── Makefile │ ├── Makefile.meson │ ├── kind.map │ ├── main.f90 │ └── tests.py ├── long_subroutine_name │ ├── Makefile │ ├── Makefile.meson │ ├── main.f90 │ └── test.py ├── make.meson.inc ├── meson.build.template ├── mockderivetype │ ├── Makefile │ ├── Makefile.ifort │ ├── Makefile.meson │ ├── define.f90 │ ├── fwrap.f90 │ ├── kind_map │ ├── leveltwomod.f90 │ ├── readme.rst │ ├── test.py │ └── testpkg.py ├── mod_arg_clash │ ├── Makefile │ ├── Makefile.meson │ ├── test.f90 │ └── tests.py ├── optional_args_issue53 │ ├── Makefile │ ├── Makefile.meson │ ├── main.f90 │ └── run.py ├── optional_derived_arrays │ ├── Makefile │ ├── Makefile.meson │ └── test.f90 ├── optional_string │ ├── Makefile │ ├── Makefile.meson │ ├── main.f90 │ └── test.py ├── output_kind │ ├── Makefile │ ├── Makefile.meson │ ├── kind.map │ ├── main.f90 │ └── test.py ├── passbyreference │ ├── Makefile.meson │ ├── example_mymodule.py │ ├── makefile │ └── mycode.F90 ├── recursive_type │ ├── Makefile │ ├── Makefile.meson │ ├── README.md │ ├── kind_map │ ├── tests.py │ └── tree.f90 ├── recursive_type_array │ ├── Makefile │ ├── Makefile.meson │ ├── kind_map │ ├── test.f90 │ └── tests.py ├── remove_pointer_arg │ ├── Makefile │ ├── Makefile.meson │ ├── main.f90 │ └── tests.py ├── return_array │ ├── Makefile │ ├── Makefile.meson │ ├── main.f90 │ └── test.py ├── string_array_input_f2py │ ├── Makefile │ ├── Makefile.meson │ ├── main.f90 │ ├── tests_no_sign.py │ └── tests_sign.py ├── strings │ ├── Makefile │ ├── Makefile.meson │ ├── README.md │ ├── kind_map │ ├── string_io.f90 │ └── tests.py ├── subroutine_args │ ├── Makefile │ ├── Makefile.meson │ ├── kind_map │ ├── subroutine_mod.f90 │ └── tests.py ├── subroutine_contains_issue101 │ ├── Makefile │ ├── Makefile.meson │ ├── run.py │ └── test.f90 ├── type_bn │ ├── Makefile │ ├── Makefile.meson │ ├── README.md │ ├── test.py │ └── type_bn.f90 └── type_check │ ├── Makefile │ ├── Makefile.meson │ ├── kind.map │ ├── main.f90 │ └── type_check_test.py ├── f90wrap ├── __init__.py ├── __main__.py ├── arraydatamodule.c ├── codegen.py ├── f90wrapgen.py ├── fortran.py ├── fortrantype.py ├── latex.py ├── meson.build ├── parser.py ├── pywrapgen.py ├── runtime.py ├── scripts │ ├── __init__.py │ ├── f2py_f90wrap.py │ ├── f90doc.py │ └── main.py ├── six.py ├── sizeoffortran.f90 └── transform.py ├── get_version.py ├── meson.build ├── pyproject.toml ├── requirements.txt ├── test ├── .gitignore ├── __init__.py ├── samples │ ├── circle.f90 │ └── test_circle.f90 ├── test_parser.py └── test_transform.py └── tools ├── openblas_support.py └── wheels ├── cibw_before_all_cp38_macosx_arm64.sh └── release-wheels.sh /.github/workflows/python-package.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests with a variety of Python versions 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: Python package 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | # Allows you to run this workflow manually from the Actions tab 13 | workflow_dispatch: 14 | 15 | jobs: 16 | build: 17 | 18 | runs-on: ubuntu-latest 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | python-version: ['3.9', '3.10', '3.11'] 23 | 24 | steps: 25 | - uses: actions/checkout@v2 26 | - name: Set up Python ${{ matrix.python-version }} 27 | uses: actions/setup-python@v2 28 | with: 29 | python-version: ${{ matrix.python-version }} 30 | - name: Install dependencies 31 | run: | 32 | python -m pip install --upgrade pip 33 | python -m pip install flake8 pytest 34 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 35 | - name: Build and install 36 | run: | 37 | sudo apt-get update -y 38 | sudo apt-get install gfortran 39 | pip install . 40 | - name: Run tests 41 | run: | 42 | cd examples 43 | make test 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build 3 | *~ 4 | *.fpp 5 | *.o 6 | *.mod 7 | *.a 8 | *.so 9 | *.x 10 | f90wrap*.f90 11 | *.pyc 12 | .pydevproject 13 | examples/mockderivetype/mockdt.py 14 | define_a_type.py 15 | leveltwomod.py 16 | use_a_type.py 17 | org.eclipse.core.resources.prefs 18 | docs/_build 19 | src.* 20 | .f2py_f2cmap 21 | .ipynb_checkpoints 22 | .idea/ 23 | *.swp 24 | itest/ 25 | -------------------------------------------------------------------------------- /docs/api.rst: -------------------------------------------------------------------------------- 1 | === 2 | API 3 | === 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | api_docs/fortran 9 | api_docs/parser 10 | api_docs/transform 11 | api_docs/codegen 12 | api_docs/f90wrapgen 13 | api_docs/pywrapgen 14 | api_docs/fortrantype 15 | -------------------------------------------------------------------------------- /docs/apidocs/f90wrap.codegen.rst: -------------------------------------------------------------------------------- 1 | f90wrap.codegen module 2 | ====================== 3 | 4 | .. automodule:: f90wrap.codegen 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/apidocs/f90wrap.f90wrapgen.rst: -------------------------------------------------------------------------------- 1 | f90wrap.f90wrapgen module 2 | ========================= 3 | 4 | .. automodule:: f90wrap.f90wrapgen 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/apidocs/f90wrap.fortran.rst: -------------------------------------------------------------------------------- 1 | f90wrap.fortran module 2 | ====================== 3 | 4 | .. automodule:: f90wrap.fortran 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/apidocs/f90wrap.fortrantype.rst: -------------------------------------------------------------------------------- 1 | f90wrap.fortrantype module 2 | ========================== 3 | 4 | .. automodule:: f90wrap.fortrantype 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/apidocs/f90wrap.latex.rst: -------------------------------------------------------------------------------- 1 | f90wrap.latex module 2 | ==================== 3 | 4 | .. automodule:: f90wrap.latex 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/apidocs/f90wrap.parser.rst: -------------------------------------------------------------------------------- 1 | f90wrap.parser module 2 | ===================== 3 | 4 | .. automodule:: f90wrap.parser 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/apidocs/f90wrap.pywrapgen.rst: -------------------------------------------------------------------------------- 1 | f90wrap.pywrapgen module 2 | ======================== 3 | 4 | .. automodule:: f90wrap.pywrapgen 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/apidocs/f90wrap.rst: -------------------------------------------------------------------------------- 1 | f90wrap package 2 | =============== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | 9 | f90wrap.codegen 10 | f90wrap.f90wrapgen 11 | f90wrap.fortran 12 | f90wrap.fortrantype 13 | f90wrap.latex 14 | f90wrap.parser 15 | f90wrap.pywrapgen 16 | f90wrap.transform 17 | 18 | Module contents 19 | --------------- 20 | 21 | .. automodule:: f90wrap 22 | :members: 23 | :undoc-members: 24 | :show-inheritance: 25 | -------------------------------------------------------------------------------- /docs/apidocs/f90wrap.transform.rst: -------------------------------------------------------------------------------- 1 | f90wrap.transform module 2 | ======================== 3 | 4 | .. automodule:: f90wrap.transform 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/apidocs/modules.rst: -------------------------------------------------------------------------------- 1 | f90wrap 2 | ======= 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | f90wrap 8 | -------------------------------------------------------------------------------- /docs/tutorials/WCPM_logo_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/WCPM_logo_text.png -------------------------------------------------------------------------------- /docs/tutorials/ase-calculators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/ase-calculators.png -------------------------------------------------------------------------------- /docs/tutorials/boron-crack-100dpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/boron-crack-100dpi.png -------------------------------------------------------------------------------- /docs/tutorials/f90wrap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/f90wrap.png -------------------------------------------------------------------------------- /docs/tutorials/multiscale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/multiscale.png -------------------------------------------------------------------------------- /docs/tutorials/scipy-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/scipy-stack.png -------------------------------------------------------------------------------- /docs/tutorials/si-vac.gpw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/si-vac.gpw -------------------------------------------------------------------------------- /docs/tutorials/warwick-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/warwick-logo.png -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | project(test_f90wrap) 3 | enable_testing() 4 | include(CTest) 5 | 6 | list(APPEND tests 7 | arrayderivedtypes 8 | arrays 9 | arrays_fixed 10 | arrays_in_derived_types_issue50 11 | class_names 12 | cylinder 13 | derivedtypes 14 | elemental 15 | example2 16 | extends 17 | interface 18 | issue105_function_definition_with_empty_lines 19 | issue32 20 | mockderivetype 21 | mod_arg_clash 22 | optional_args_issue53 23 | optional_derived_arrays 24 | passbyreference 25 | strings 26 | subroutine_contains_issue101 27 | type_bn 28 | kind_map_default 29 | docstring 30 | return_array 31 | intent_out_size 32 | string_array_input_f2py 33 | type_check 34 | optional_string 35 | long_subroutine_name 36 | output_kind 37 | remove_pointer_arg 38 | fortran_oo 39 | issue206_subroutine_oldstyle 40 | issue227_allocatable 41 | issue235_allocatable_classes 42 | auto_raise_error 43 | ) 44 | 45 | foreach(test ${tests}) 46 | message(STATUS "Adding test ${test}") 47 | add_test( 48 | NAME ${test} 49 | COMMAND make 50 | WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/${test}" 51 | ) 52 | endforeach() 53 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | EXAMPLES = arrayderivedtypes \ 2 | arrays \ 3 | arrays_fixed \ 4 | arrays_in_derived_types_issue50 \ 5 | class_names \ 6 | cylinder \ 7 | derivedtypes \ 8 | elemental \ 9 | example2 \ 10 | extends \ 11 | interface \ 12 | issue105_function_definition_with_empty_lines \ 13 | issue32 \ 14 | keyword_renaming_issue160 \ 15 | mockderivetype \ 16 | mod_arg_clash \ 17 | optional_args_issue53 \ 18 | optional_derived_arrays \ 19 | passbyreference \ 20 | strings \ 21 | subroutine_contains_issue101 \ 22 | type_bn \ 23 | docstring \ 24 | type_check \ 25 | derivedtypes_procedure \ 26 | return_array \ 27 | string_array_input_f2py \ 28 | optional_string \ 29 | long_subroutine_name \ 30 | kind_map_default \ 31 | intent_out_size \ 32 | output_kind \ 33 | remove_pointer_arg \ 34 | fortran_oo \ 35 | issue206_subroutine_oldstyle \ 36 | issue227_allocatable \ 37 | issue235_allocatable_classes \ 38 | auto_raise_error 39 | 40 | PYTHON = python 41 | 42 | all: test 43 | 44 | test: 45 | for example in ${EXAMPLES}; do \ 46 | echo "" ; \ 47 | echo "" ; \ 48 | echo "" ; \ 49 | echo "# ---------------------------------------------------" ; \ 50 | echo "running make test in $$example" ; \ 51 | make -C $$example PYTHON=$(PYTHON) test || exit ; \ 52 | done 53 | 54 | clean: 55 | for example in ${EXAMPLES}; do \ 56 | echo "running make test in $$example" ; \ 57 | make -C $$example clean || exit ; \ 58 | done 59 | 60 | test_meson: 61 | for example in ${EXAMPLES}; do \ 62 | echo "" ; \ 63 | echo "" ; \ 64 | echo "" ; \ 65 | echo "# ---------------------------------------------------" ; \ 66 | echo "running make test in $$example" ; \ 67 | make -C $$example -f Makefile.meson PYTHON=$(PYTHON) test || exit ; \ 68 | done 69 | 70 | clean_meson: 71 | for example in ${EXAMPLES}; do \ 72 | echo "running make test in $$example" ; \ 73 | make -C $$example -f Makefile.meson clean || exit ; \ 74 | done 75 | -------------------------------------------------------------------------------- /examples/arrayderivedtypes/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := arrayderivedtype 4 | WRAPFLAGS += -k kind_map 5 | 6 | test: build 7 | $(PYTHON) tests.py 8 | -------------------------------------------------------------------------------- /examples/arrayderivedtypes/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': {'': 'float', 3 | '8': 'double', 4 | 'dp': 'double', 5 | 'idp':'double'}, 6 | 'complex' : {'': 'complex_float', 7 | '8' : 'complex_double', 8 | '16': 'complex_long_double', 9 | 'dp': 'complex_double'}, 10 | 'integer' : {'4': 'int', 11 | '8': 'long_long', 12 | 'dp': 'long_long' }, 13 | 'character' : {'': 'char'} 14 | } 15 | -------------------------------------------------------------------------------- /examples/arrayderivedtypes/test.f90: -------------------------------------------------------------------------------- 1 | module module_calcul 2 | type type_ptmes 3 | integer :: y 4 | end type type_ptmes 5 | 6 | type array_type 7 | type(type_ptmes) :: x(2) 8 | end type array_type 9 | 10 | type(array_type), dimension(10), target :: xarr 11 | 12 | contains 13 | subroutine recup_point(x) 14 | type(array_type) :: x 15 | return 16 | end subroutine recup_point 17 | end module module_calcul 18 | -------------------------------------------------------------------------------- /examples/arrayderivedtypes/tests.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | import arrayderivedtype 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/arrays/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := ExampleArray_pkg 4 | NAME2 := ExampleArray_relative 5 | NAME3 := ExampleArray_top 6 | WRAPFLAGS += -k kind_map -P 7 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 8 | 9 | test: build2 10 | $(PYTHON) tests.py 11 | 12 | build2_pre: build 13 | $(eval WRAPFLAGS += --relative) 14 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS)" 15 | 16 | build2: build2_pre 17 | mkdir ${NAME3} 18 | mv ${NAME2}/ _${NAME2}.*so ${NAME3}/ 19 | touch ${NAME3}/__init__.py 20 | 21 | clean: 22 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 23 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 24 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME3) 25 | -------------------------------------------------------------------------------- /examples/arrays/README.md: -------------------------------------------------------------------------------- 1 | example-arrays 2 | ============== 3 | 4 | Simple example with a wrapped subroutine that contains input and output arrays. 5 | It simply shows how to access and interact with an array that is being 6 | initiated in Python, and manipulated by a Fortran subroutine. 7 | 8 | This example has been tested with ```gfortran``` and ```ifort``` on Linux 64bit. 9 | 10 | To build and wrap with f90wrap, use the included ```Makefile```: 11 | 12 | ``` 13 | make 14 | ``` 15 | 16 | and before rebuilding, clean-up with: 17 | 18 | ``` 19 | make clean 20 | ``` 21 | 22 | A simple unittest is included in ```tests.py```. 23 | 24 | A sample memory profiling script is included in ```memory_profile.py```. 25 | To profile, run: 26 | 27 | ``` 28 | python2 -m memory_profiler memory_profile.py 29 | ``` 30 | 31 | 32 | Author 33 | ------ 34 | 35 | David Verelst: 36 | 37 | -------------------------------------------------------------------------------- /examples/arrays/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': {'': 'float', 3 | '8': 'double', 4 | 'dp': 'double', 5 | 'idp':'double'}, 6 | 'complex' : {'': 'complex_float', 7 | '8' : 'complex_double', 8 | '16': 'complex_long_double', 9 | 'dp': 'complex_double'}, 10 | 'integer' : {'4': 'int', 11 | '8': 'long_long', 12 | 'dp': 'long_long' }, 13 | 'character' : {'': 'char'} 14 | } 15 | -------------------------------------------------------------------------------- /examples/arrays/library.f90: -------------------------------------------------------------------------------- 1 | module library 2 | 3 | use parameters, only: idp, isp 4 | implicit none 5 | private 6 | public :: do_array_stuff, only_manipulate, return_array, ia, iarray 7 | integer(4) :: ia 8 | integer(4) :: iarray(3) 9 | 10 | contains 11 | 12 | subroutine do_array_stuff(n,x,y,br,co) 13 | INTEGER, INTENT(in) :: n 14 | REAL(kind=idp), INTENT(in) :: x(n) 15 | REAL(kind=idp), INTENT(in) :: y(n) 16 | REAL(kind=idp), INTENT(out) :: br(n) 17 | REAL(kind=idp), INTENT(out) :: co(4,n) 18 | 19 | INTEGER :: i,j 20 | DO j=1,n 21 | br(j) = x(j) / ( y(j) + 1.0_idp ) 22 | DO i=1,4 23 | co(i,j) = x(j)*y(j) + x(j) 24 | ENDDO 25 | ENDDO 26 | end subroutine do_array_stuff 27 | 28 | subroutine only_manipulate(n,array) 29 | INTEGER, INTENT(in) :: n 30 | REAL(kind=idp), INTENT(inout) :: array(4,n) 31 | 32 | INTEGER :: i,j 33 | DO j=1,n 34 | DO i=1,4 35 | array(i,j) = array(i,j)*array(i,j) 36 | ENDDO 37 | ENDDO 38 | end subroutine only_manipulate 39 | 40 | subroutine return_array(m, n, output) 41 | INTEGER, INTENT(in) :: m, n 42 | INTEGER, INTENT(out) :: output(m,n) 43 | INTEGER :: i,j 44 | DO i=1,m 45 | DO j=1,n 46 | output(i,j) = i*j + j 47 | ENDDO 48 | ENDDO 49 | end subroutine return_array 50 | 51 | end module library 52 | 53 | -------------------------------------------------------------------------------- /examples/arrays/memory_profile.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | # -*- coding: utf-8 -*- 24 | """ 25 | Created on Tue Jul 28 15:19:03 2015 26 | 27 | @author: David Verelst 28 | """ 29 | 30 | from __future__ import print_function 31 | 32 | import numpy as np 33 | 34 | import ExampleArray as lib 35 | 36 | @profile 37 | def do_array_stuff(ndata): 38 | xdata = np.arange(ndata) 39 | fdata = np.arange(ndata) 40 | breakarr = np.zeros((ndata,), order='F', dtype=np.float64) 41 | cscoef = np.zeros((4, ndata), order='F', dtype=np.float64) 42 | 43 | lib.library.do_array_stuff(n=ndata, x=xdata, y=fdata, 44 | br=breakarr, co=cscoef) 45 | 46 | cscoef_np = np.zeros((4, ndata), order='F', dtype=np.float64) 47 | for k in range(4): 48 | cscoef_np[k,:] = xdata*fdata + xdata 49 | breakarr_np = np.zeros((ndata), order='F', dtype=np.float64) 50 | breakarr_np[:] = xdata/(fdata+1.0) 51 | 52 | print(np.allclose(breakarr_np, breakarr)) 53 | print(np.allclose(cscoef_np, cscoef)) 54 | p2 = breakarr 55 | 56 | lib.library.only_manipulate(n=ndata, array=cscoef) 57 | p3 = cscoef 58 | 59 | do_array_stuff(1e6) 60 | -------------------------------------------------------------------------------- /examples/arrays/parameters.f90: -------------------------------------------------------------------------------- 1 | module parameters 2 | 3 | implicit none 4 | private 5 | !public :: idp, isp, do_array_stuff 6 | public :: idp, isp 7 | 8 | INTEGER, PARAMETER :: idp=kind(1d0) 9 | INTEGER, PARAMETER :: isp=kind(1e0) 10 | 11 | contains 12 | subroutine do_array_stuff() 13 | end subroutine do_array_stuff 14 | 15 | end module parameters 16 | 17 | -------------------------------------------------------------------------------- /examples/arrays_fixed/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := ExampleArray 4 | NAME2 := ExampleArray_pkg 5 | WRAPFLAGS += -k kind_map 6 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 7 | 8 | test: build2 9 | $(PYTHON) tests.py 10 | 11 | build2: build 12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P" 13 | 14 | clean: 15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 17 | -------------------------------------------------------------------------------- /examples/arrays_fixed/README.md: -------------------------------------------------------------------------------- 1 | example-arrays 2 | ============== 3 | 4 | Simple example with a wrapped subroutine that contains input and output arrays. 5 | It simply shows how to access and interact with an array that is being 6 | initiated in Python, and manipulated by a Fortran subroutine. 7 | 8 | This example has been tested with ```gfortran``` and ```ifort``` on Linux 64bit. 9 | 10 | To build and wrap with f90wrap, use the included ```Makefile```: 11 | 12 | ``` 13 | make 14 | ``` 15 | 16 | and before rebuilding, clean-up with: 17 | 18 | ``` 19 | make clean 20 | ``` 21 | 22 | A simple unittest is included in ```tests.py```. 23 | 24 | A sample memory profiling script is included in ```memory_profile.py```. 25 | To profile, run: 26 | 27 | ``` 28 | python2 -m memory_profiler memory_profile.py 29 | ``` 30 | 31 | 32 | Author 33 | ------ 34 | 35 | David Verelst: 36 | 37 | -------------------------------------------------------------------------------- /examples/arrays_fixed/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': {'': 'float', 3 | '8': 'double', 4 | 'dp': 'double', 5 | 'idp':'double'}, 6 | 'complex' : {'': 'complex_float', 7 | '8' : 'complex_double', 8 | '16': 'complex_long_double', 9 | 'dp': 'complex_double'}, 10 | 'integer' : {'4': 'int', 11 | '8': 'long_long', 12 | 'dp': 'long_long' }, 13 | 'character' : {'': 'char'} 14 | } 15 | -------------------------------------------------------------------------------- /examples/arrays_fixed/library.f: -------------------------------------------------------------------------------- 1 | module library 2 | 3 | use parameters, only: idp, isp 4 | implicit none 5 | private 6 | public :: do_array_stuff, only_manipulate, return_array 7 | 8 | contains 9 | 10 | subroutine do_array_stuff(n, 11 | & x,y,br,co) 12 | c----------------------------------------------------------------------- 13 | INTEGER, INTENT(in) :: n 14 | REAL(kind=idp), INTENT(in) :: x(n) 15 | REAL(kind=idp), INTENT(in) :: y(n) 16 | REAL(kind=idp), INTENT(out) :: br(n) 17 | REAL(kind=idp), INTENT(out) :: co(4,n) 18 | 19 | INTEGER :: i,j 20 | DO j=1,n 21 | br(j) = x(j) / ( y(j) + 1.0_idp ) 22 | DO i=1,4 23 | co(i,j) = x(j)*y(j) + x(j) 24 | ENDDO 25 | ENDDO 26 | end subroutine do_array_stuff 27 | 28 | subroutine only_manipulate(n,array) 29 | INTEGER, INTENT(in) :: n 30 | REAL(kind=idp), INTENT(inout) :: array(4,n) 31 | 32 | INTEGER :: i,j 33 | DO j=1,n 34 | DO i=1,4 35 | array(i,j) = array(i,j)*array(i,j) 36 | ENDDO 37 | ENDDO 38 | end subroutine only_manipulate 39 | 40 | subroutine return_array(m, n, output) 41 | INTEGER, INTENT(in) :: m, n 42 | INTEGER, INTENT(out) :: output(m,n) 43 | INTEGER :: i,j 44 | DO i=1,m 45 | DO j=1,n 46 | output(i,j) = i*j + j 47 | ENDDO 48 | ENDDO 49 | end subroutine return_array 50 | 51 | end module library 52 | 53 | -------------------------------------------------------------------------------- /examples/arrays_fixed/memory_profile.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | # -*- coding: utf-8 -*- 24 | """ 25 | Created on Tue Jul 28 15:19:03 2015 26 | 27 | @author: David Verelst 28 | """ 29 | 30 | from __future__ import print_function 31 | 32 | import numpy as np 33 | 34 | import ExampleArray as lib 35 | 36 | @profile 37 | def do_array_stuff(ndata): 38 | xdata = np.arange(ndata) 39 | fdata = np.arange(ndata) 40 | breakarr = np.zeros((ndata,), order='F', dtype=np.float64) 41 | cscoef = np.zeros((4, ndata), order='F', dtype=np.float64) 42 | 43 | lib.library.do_array_stuff(n=ndata, x=xdata, y=fdata, 44 | br=breakarr, co=cscoef) 45 | 46 | cscoef_np = np.zeros((4, ndata), order='F', dtype=np.float64) 47 | for k in range(4): 48 | cscoef_np[k,:] = xdata*fdata + xdata 49 | breakarr_np = np.zeros((ndata), order='F', dtype=np.float64) 50 | breakarr_np[:] = xdata/(fdata+1.0) 51 | 52 | print(np.allclose(breakarr_np, breakarr)) 53 | print(np.allclose(cscoef_np, cscoef)) 54 | p2 = breakarr 55 | 56 | lib.library.only_manipulate(n=ndata, array=cscoef) 57 | p3 = cscoef 58 | 59 | do_array_stuff(1e6) 60 | -------------------------------------------------------------------------------- /examples/arrays_fixed/parameters.f: -------------------------------------------------------------------------------- 1 | module parameters 2 | 3 | implicit none 4 | private 5 | public :: idp, isp 6 | 7 | INTEGER, PARAMETER :: idp=kind(1d0) 8 | INTEGER, PARAMETER :: isp=kind(1e0) 9 | 10 | contains 11 | 12 | end module parameters 13 | 14 | -------------------------------------------------------------------------------- /examples/arrays_in_derived_types_issue50/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := issue50 4 | 5 | test: build 6 | $(PYTHON) tests.py 7 | -------------------------------------------------------------------------------- /examples/arrays_in_derived_types_issue50/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': {'': 'float', 3 | '4': 'float', 4 | '8': 'double', 5 | 'dp': 'double', 6 | 'idp':'double'}, 7 | 'complex' : {'': 'complex_float', 8 | '8' : 'complex_double', 9 | '16': 'complex_long_double', 10 | 'dp': 'complex_double'}, 11 | 'integer' : {'4': 'int', 12 | '8': 'long_long', 13 | 'dp': 'long_long' }, 14 | 'character' : {'': 'char'} 15 | } 16 | -------------------------------------------------------------------------------- /examples/arrays_in_derived_types_issue50/test.f90: -------------------------------------------------------------------------------- 1 | module module_test 2 | 3 | type real_array 4 | real, dimension(6) :: item 5 | end type real_array 6 | 7 | contains 8 | 9 | subroutine testf(x) 10 | implicit none 11 | type(real_array) :: x 12 | 13 | print*, "This is received in fortran : ", x%item 14 | x%item(4) = 4 15 | print*, "This is sent back to python : ", x%item 16 | end subroutine testf 17 | 18 | end module module_test -------------------------------------------------------------------------------- /examples/arrays_in_derived_types_issue50/tests.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | from issue50 import module_test as tp 24 | from numpy import zeros, ones, float32, abs, max 25 | 26 | a = tp.real_array() 27 | print("This is the freshly allocated array : " + str(a.item)) 28 | a.item = ones(6, dtype=float32) 29 | print("This is sent to fortran : " + str(a.item)) 30 | tp.testf(a) 31 | print("This is received by python : " + str(a.item)) 32 | 33 | assert max(abs(a.item - [1.0, 1.0, 1.0, 4.0, 1.0, 1.0])) < 1e-6 34 | -------------------------------------------------------------------------------- /examples/auto_raise_error/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | CC = gcc 6 | F90 = gfortran 7 | PYTHON = python 8 | CFLAGS = -fPIC 9 | F90FLAGS = -fPIC 10 | PY_MOD = pywrapper 11 | F90_SRC = main.f90 12 | OBJ = $(F90_SRC:.f90=.o) 13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC}) 14 | WRAPFLAGS = -v --auto-raise-error ierr,errmsg 15 | F2PYFLAGS = --build-dir build 16 | F90WRAP = f90wrap 17 | F2PY = f2py-f90wrap 18 | .PHONY: all clean 19 | 20 | all: test 21 | 22 | clean: 23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/ 24 | 25 | main.o: ${F90_SRC} 26 | ${F90} ${F90FLAGS} -c $< -o $@ 27 | 28 | %.o: %.f90 29 | ${F90} ${F90FLAGS} -c $< -o $@ 30 | 31 | ${F90WRAP_SRC}: ${OBJ} 32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC} 33 | 34 | f2py: ${F90WRAP_SRC} 35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o 36 | 37 | test: f2py 38 | ${PYTHON} tests.py 39 | -------------------------------------------------------------------------------- /examples/auto_raise_error/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper 4 | WRAPFLAGS += --auto-raise-error ierr,errmsg 5 | 6 | test: build 7 | $(PYTHON) tests.py 8 | -------------------------------------------------------------------------------- /examples/auto_raise_error/main.f90: -------------------------------------------------------------------------------- 1 | module m_error 2 | implicit none 3 | private 4 | 5 | public :: auto_raise,auto_no_raise 6 | public :: auto_raise_optional,auto_no_raise_optional 7 | public :: no_error_var 8 | 9 | contains 10 | 11 | subroutine auto_raise(ierr,errmsg) 12 | 13 | implicit none 14 | integer, intent(out) :: ierr 15 | character(len=*), intent(out) :: errmsg 16 | 17 | ierr=1 18 | write(errmsg,'(a)') 'auto raise error' 19 | return 20 | 21 | end subroutine 22 | 23 | subroutine auto_raise_optional(ierr,errmsg) 24 | 25 | implicit none 26 | integer,optional, intent(out) :: ierr 27 | character(len=*),optional, intent(out) :: errmsg 28 | 29 | ierr=1 30 | write(errmsg,'(a)') 'auto raise error optional' 31 | return 32 | 33 | end subroutine 34 | 35 | subroutine auto_no_raise(ierr,errmsg) 36 | 37 | implicit none 38 | integer, intent(out) :: ierr 39 | character(len=*), intent(out) :: errmsg 40 | 41 | ierr=0 42 | write(errmsg,'(a)') '' 43 | return 44 | 45 | end subroutine 46 | 47 | subroutine auto_no_raise_optional(ierr,errmsg) 48 | 49 | implicit none 50 | integer,optional, intent(out) :: ierr 51 | character(len=*),optional, intent(out) :: errmsg 52 | 53 | ierr=0 54 | write(errmsg,'(a)') '' 55 | return 56 | 57 | end subroutine 58 | 59 | subroutine no_error_var(a_num,a_string) 60 | 61 | implicit none 62 | integer, intent(out) :: a_num 63 | character(len=*), intent(out) :: a_string 64 | 65 | a_num=1 66 | write(a_string,'(a)') 'a string' 67 | return 68 | 69 | end subroutine 70 | 71 | 72 | 73 | end module m_error 74 | -------------------------------------------------------------------------------- /examples/auto_raise_error/tests.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | 4 | from pywrapper import m_error 5 | 6 | class TestError(unittest.TestCase): 7 | 8 | def test_raise(self): 9 | with self.assertRaises(RuntimeError) as context: 10 | m_error.auto_raise() 11 | self.assertEqual(str(context.exception).strip(), 'auto raise error') 12 | 13 | def test_raise_optional(self): 14 | with self.assertRaises(RuntimeError) as context: 15 | m_error.auto_raise_optional() 16 | self.assertEqual(str(context.exception).strip(), 'auto raise error optional') 17 | 18 | def test_no_raise(self): 19 | m_error.auto_no_raise() 20 | # Check that Error handling argument are correctly removed from interface 21 | with self.assertRaises(TypeError): 22 | ierr, errmsg = m_error.auto_no_raise() 23 | 24 | def test_no_raise_optional(self): 25 | m_error.auto_no_raise_optional() 26 | # Check that Error handling argument are correctly removed from interface 27 | with self.assertRaises(TypeError): 28 | ierr=1 29 | errmsg='error' 30 | m_error.auto_no_raise_optional(ierr, errmsg) 31 | 32 | def test_no_error_var(self): 33 | a_number, a_string = m_error.no_error_var() 34 | self.assertEqual(a_number, 1) 35 | self.assertEqual(a_string, b'a string') 36 | 37 | if __name__ == '__main__': 38 | 39 | unittest.main() 40 | -------------------------------------------------------------------------------- /examples/callback_print_function_issue93/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := CBF 4 | NAME2 := CBF_pkg 5 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 6 | 7 | test: build2 8 | $(PYTHON) tests.py 9 | 10 | build2: build 11 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P" 12 | 13 | clean: 14 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 16 | -------------------------------------------------------------------------------- /examples/callback_print_function_issue93/README.md: -------------------------------------------------------------------------------- 1 | python function callback 2 | ============== 3 | 4 | This example illustrate how to set up an external callback so that a python function can be called, namely to capture messages for display in a Jupyter notebook (or passed to a log, etc.). 5 | 6 | As of 2019-11 there is nothing specific to f90wrap in the content of this folder (f2py should handle it to). Finding how to set up a callback function registration was a day-long pain for yours truly. This example is written in the hope this will ease the pain for others. 7 | 8 | ## Related resources 9 | 10 | 11 | * [Call-back arguments in f2py](https://numpy.org/devdocs/f2py/python-usage.html#call-back-arguments) 12 | * Callback registration to e.g. trap C++ exceptions and report through R, Python, etc. [here](https://github.com/csiro-hydroinformatics/moirai/blob/master/src/reference_handle_map_export.cpp) 13 | 14 | 15 | ## Build 16 | 17 | This example has been tested with ```gfortran``` on Linux 64bit. 18 | 19 | To build and wrap with f90wrap, use the included ```Makefile```: 20 | 21 | ```sh 22 | make 23 | ``` 24 | 25 | and before rebuilding, clean-up with: 26 | 27 | ```sh 28 | make clean 29 | ``` 30 | 31 | A simple unittest is included in ```tests.py```. 32 | 33 | Author 34 | ------ 35 | 36 | Jean-Michel Perraud: 37 | 38 | 39 | -------------------------------------------------------------------------------- /examples/callback_print_function_issue93/caller.f90: -------------------------------------------------------------------------------- 1 | 2 | module caller 3 | use cback 4 | implicit none 5 | 6 | public 7 | 8 | contains 9 | 10 | subroutine test_write_msg() 11 | call write_message("from test_write_msg") 12 | return 13 | end 14 | 15 | subroutine test_write_msg_2() 16 | call write_message("from test_write_msg_2") 17 | return 18 | end 19 | 20 | ! character(len=20) function test_return_msg() 21 | ! test_return_msg = return_message("from test_return_msg") 22 | ! end 23 | 24 | ! character(len=20) function test_return_msg_2() 25 | ! test_return_msg_2 = return_message("from test_return_msg_2") 26 | ! end 27 | 28 | end module -------------------------------------------------------------------------------- /examples/callback_print_function_issue93/cback.f90: -------------------------------------------------------------------------------- 1 | 2 | module cback 3 | implicit none 4 | 5 | public 6 | 7 | contains 8 | 9 | subroutine write_message(msg) 10 | !f2py intent(callback, hide) pyfunc_print 11 | external pyfunc_print 12 | character(len= *) :: msg 13 | call pyfunc_print(msg) 14 | end 15 | 16 | ! TODO cannot seem to make it work. Leads to "error: ‘PyStringObject’ undeclared" 17 | ! character(len=20) function return_message(msg) 18 | ! !f2py intent(callback, hide) pyfunc_return 19 | ! external pyfunc_return 20 | ! character(len=20) pyfunc_return 21 | ! !f2py character(len=20) y,x 22 | ! !f2py y = py_func(x) 23 | ! character(len= *) :: msg 24 | ! character(len=20) :: returned_msg 25 | ! write(returned_msg,*)msg 26 | ! returned_msg = pyfunc_return(msg) 27 | ! return_message = returned_msg(1:20) 28 | ! end 29 | 30 | end module -------------------------------------------------------------------------------- /examples/callback_print_function_issue93/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': {'': 'float', 3 | '8': 'double', 4 | 'dp': 'double', 5 | 'idp':'double'}, 6 | 'integer' : {'4': 'int', 7 | '8': 'long_long', 8 | 'dp': 'long_long' } 9 | } 10 | -------------------------------------------------------------------------------- /examples/callback_print_function_issue93/tests.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | # -*- coding: utf-8 -*- 24 | """ 25 | Created on Tue Jan 25 2018 26 | 27 | @author: Gaetan Kenway 28 | """ 29 | 30 | from __future__ import print_function 31 | 32 | import unittest 33 | 34 | import numpy as np 35 | 36 | import CBF 37 | 38 | class TestExample(unittest.TestCase): 39 | 40 | def setUp(self): 41 | 42 | pass 43 | 44 | def test_basic(self): 45 | print(CBF._CBF.cback.write_message.__doc__) 46 | def f(msg): 47 | print("Yo! " + msg) 48 | CBF._CBF.pyfunc_print = f 49 | # We need to prime the callback with a call "under the hood", not sure why. 50 | CBF._CBF.cback.write_message('blah') 51 | # Subsequently other calls to higher level functions work. 52 | CBF.caller.test_write_msg() 53 | CBF.caller.test_write_msg() 54 | CBF.caller.test_write_msg_2() 55 | # TODO? 56 | # CBF.caller.test_return_msg() 57 | # CBF.caller.test_return_msg() 58 | # CBF.caller.test_return_msg_2() 59 | 60 | if __name__ == '__main__': 61 | unittest.main() 62 | -------------------------------------------------------------------------------- /examples/class_names/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := classnames 4 | WRAPFLAGS += -k kind_map --class-names class_names.json 5 | 6 | test: build 7 | $(PYTHON) tests.py 8 | -------------------------------------------------------------------------------- /examples/class_names/class_names.json: -------------------------------------------------------------------------------- 1 | { 2 | "module_snake_mod": "ModuleSnake", 3 | "array_type": "ArrayType", 4 | "ceci_ne_pas_un_chameau": "IAmACamel" 5 | } 6 | -------------------------------------------------------------------------------- /examples/class_names/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': {'': 'float', 3 | '8': 'double', 4 | 'dp': 'double', 5 | 'idp':'double'}, 6 | 'complex' : {'': 'complex_float', 7 | '8' : 'complex_double', 8 | '16': 'complex_long_double', 9 | 'dp': 'complex_double'}, 10 | 'integer' : {'4': 'int', 11 | '8': 'long_long', 12 | 'dp': 'long_long' }, 13 | 'character' : {'': 'char'} 14 | } 15 | -------------------------------------------------------------------------------- /examples/class_names/test.f90: -------------------------------------------------------------------------------- 1 | module module_snake_mod 2 | type ceci_ne_pas_un_chameau 3 | integer :: y 4 | end type ceci_ne_pas_un_chameau 5 | 6 | type array_type 7 | type(ceci_ne_pas_un_chameau) :: x(2) 8 | end type array_type 9 | 10 | type(array_type), dimension(10), target :: xarr 11 | 12 | contains 13 | subroutine recup_point(x) 14 | type(array_type) :: x 15 | return 16 | end subroutine recup_point 17 | end module module_snake_mod 18 | -------------------------------------------------------------------------------- /examples/class_names/tests.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | import classnames 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/cylinder/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := Example 4 | NAME2 := Example_pkg 5 | WRAPFLAGS += -k kind_map 6 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 7 | 8 | test: build 9 | $(PYTHON) tests.py 10 | 11 | build2: build 12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P" 13 | 14 | clean: 15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 17 | -------------------------------------------------------------------------------- /examples/cylinder/README: -------------------------------------------------------------------------------- 1 | Contributed by James Orr 2 | 3 | Note that operator overloading is not yet supported, so not many features 4 | of the DNAD library are available from Python. Contributions welcome! 5 | -------------------------------------------------------------------------------- /examples/cylinder/cyldnad.f90: -------------------------------------------------------------------------------- 1 | MODULE mcyldnad 2 | CONTAINS 3 | !> Computes cylinder volume from 2 input variables (radius, height) 4 | SUBROUTINE cyldnad(vol, radius, height) 5 | 6 | USE Dual_Num_Auto_Diff 7 | TYPE (DUAL_NUM), PARAMETER:: PI=DUAL_NUM(3.141592653589793D0,0.D0) 8 | TYPE (DUAL_NUM), INTENT(out):: vol 9 | TYPE (DUAL_NUM), INTENT(in) :: radius, height 10 | 11 | vol = PI * radius**2 * height 12 | 13 | END SUBROUTINE cyldnad 14 | END MODULE mcyldnad 15 | 16 | -------------------------------------------------------------------------------- /examples/cylinder/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': { '' : 'float', 3 | '4' : 'float', 4 | 'isp' : 'float', 5 | '8' : 'double', 6 | 'dp' : 'double', 7 | 'idp' : 'double', 8 | 'sng_ad' : 'float', 9 | 'dbl_ad' : 'double'}, 10 | 'complex' : { '' : 'complex_float', 11 | '8' : 'complex_double', 12 | '16' : 'complex_long_double', 13 | 'dp' : 'complex_double'}, 14 | 'integer' : { '2' : 'int', 15 | '4' : 'int', 16 | '8' : 'long_long', 17 | 'dp' : 'long_long' }, 18 | 'character' : {'' : 'char', 19 | '1' : 'char' } 20 | } 21 | -------------------------------------------------------------------------------- /examples/cylinder/tests.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | 24 | from __future__ import print_function 25 | 26 | import unittest 27 | 28 | import numpy as np 29 | 30 | import Example 31 | 32 | 33 | class TestExample(unittest.TestCase): 34 | 35 | def setUp(self): 36 | pass 37 | 38 | def test_auto_diff(self): 39 | d1 = Example.Dual_Num_Auto_Diff.DUAL_NUM() 40 | d2 = Example.Dual_Num_Auto_Diff.DUAL_NUM() 41 | d3 = Example.Mcyldnad.cyldnad(d1, d2) 42 | 43 | if __name__ == '__main__': 44 | unittest.main() 45 | -------------------------------------------------------------------------------- /examples/default_i8/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := testmodule 4 | F90FLAGS += -fdefault-integer-8 5 | WRAPFLAGS += -k kind_map -P 6 | 7 | test: build 8 | $(PYTHON) tests.py 9 | -------------------------------------------------------------------------------- /examples/default_i8/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': {'': 'float', 3 | '8': 'double', 4 | 'dp': 'double', 5 | 'idp':'double'}, 6 | 'complex' : {'': 'complex_float', 7 | '8' : 'complex_double', 8 | '16': 'complex_long_double', 9 | 'dp': 'complex_double'}, 10 | 'integer' : { '' : 'long_long', 11 | '4' : 'int', 12 | '8' : 'long_long', 13 | 'dp': 'long_long' }, 14 | 'character' : {'': 'char'} 15 | } 16 | -------------------------------------------------------------------------------- /examples/default_i8/test.f90: -------------------------------------------------------------------------------- 1 | module my_module 2 | implicit none 3 | 4 | type mytype 5 | integer :: n=0,m=0 6 | real(8), allocatable :: y(:,:) 7 | end type mytype 8 | 9 | contains 10 | 11 | subroutine allocit(x,n,m) 12 | implicit none 13 | integer, intent(in) :: n,m 14 | type(mytype), intent(inout) :: x 15 | integer i,j 16 | 17 | write(6,*) 'allocit> n,m=',n,m 18 | 19 | x%n = n; x%m = m 20 | allocate(x%y(n,m)) 21 | 22 | do i = 1, n 23 | do j = 1, m 24 | x%y(i,j) = real(i+j)/real(n+m) 25 | end do 26 | end do 27 | 28 | end subroutine allocit 29 | 30 | end module my_module 31 | -------------------------------------------------------------------------------- /examples/default_i8/tests.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | # -*- coding: utf-8 -*- 24 | """ 25 | Created on Tue Jul 28 15:19:03 2015 26 | 27 | @author: David Verelst 28 | """ 29 | 30 | from __future__ import print_function 31 | 32 | import unittest 33 | 34 | import numpy as np 35 | 36 | import testmodule as lib 37 | 38 | 39 | class TestExample(unittest.TestCase): 40 | 41 | def setUp(self): 42 | pass 43 | 44 | def do_array_stuff(self, n=3, m=4): 45 | 46 | print("n,m=",n,m) 47 | x = lib.my_module.mytype() 48 | lib.my_module.allocit(x,n,m) 49 | 50 | sum = 0.0 51 | for k in range(n): 52 | for j in range(m): 53 | sum += x.y[k,j] 54 | print("sum = %20.10f .... x.y[%d,%d] = %20.10f \n" % ( sum, n,m,x.y[n-1,m-1] ) ) 55 | 56 | def test_basic(self): 57 | self.do_array_stuff(1,2) 58 | 59 | def test_normal_array(self): 60 | self.do_array_stuff(10,20) 61 | 62 | def test_verybig_array(self): 63 | self.do_array_stuff(50,99) 64 | 65 | if __name__ == '__main__': 66 | 67 | unittest.main() 68 | -------------------------------------------------------------------------------- /examples/derived-type-aliases/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := mytype 4 | NAME2 := othertype 5 | WRAPFLAGS += -k kind_map 6 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 7 | 8 | test: build2 9 | $(PYTHON) tests.py 10 | 11 | build1: 12 | $(eval LIBSRC_WRAP_FILES := mytype_mod.f90) 13 | @ rm -rf f90wrap_*.f90 14 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME) WRAPFLAGS="$(WRAPFLAGS)" LIBSRC_WRAP_FILES=$(LIBSRC_WRAP_FILES) 15 | 16 | build2: build1 17 | $(eval LIBSRC_WRAP_FILES := othertype_mod.f90) 18 | @ rm -rf f90wrap_*.f90 19 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS)" LIBSRC_WRAP_FILES=$(LIBSRC_WRAP_FILES) 20 | 21 | clean: 22 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 23 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 24 | -------------------------------------------------------------------------------- /examples/derived-type-aliases/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': { '' : 'float', 3 | '4' : 'float', 4 | 'isp' : 'float', 5 | '8' : 'double', 6 | 'dp' : 'double', 7 | 'idp' : 'double'}, 8 | 'complex' : { '' : 'complex_float', 9 | '8' : 'complex_double', 10 | '16' : 'complex_long_double', 11 | 'dp' : 'complex_double'}, 12 | 'integer' : { '4' : 'int', 13 | '8' : 'long_long', 14 | 'dp' : 'long_long' } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /examples/derived-type-aliases/mytype_mod.f90: -------------------------------------------------------------------------------- 1 | module mytype_mod 2 | 3 | implicit none 4 | 5 | type mytype 6 | integer :: a 7 | end type mytype 8 | 9 | contains 10 | 11 | function constructor() result(obj) 12 | type(mytype) :: obj 13 | 14 | obj%a = 2 15 | end function constructor 16 | 17 | subroutine plus_b(obj, b, c) 18 | type(mytype) :: obj 19 | integer, intent(in) :: b 20 | integer, intent(out) :: c 21 | 22 | c = obj%a + b 23 | end subroutine plus_b 24 | 25 | end module mytype_mod 26 | -------------------------------------------------------------------------------- /examples/derived-type-aliases/othertype_mod.f90: -------------------------------------------------------------------------------- 1 | module othertype_mod 2 | 3 | implicit none 4 | 5 | type othertype 6 | integer :: a 7 | end type othertype 8 | 9 | contains 10 | 11 | function constructor() result(obj) 12 | type(othertype) :: obj 13 | 14 | obj%a = 5 15 | end function constructor 16 | 17 | subroutine plus_b(obj, b, c) 18 | type(othertype) :: obj 19 | integer, intent(in) :: b 20 | integer, intent(out) :: c 21 | 22 | c = obj%a + b 23 | end subroutine plus_b 24 | 25 | end module othertype_mod 26 | -------------------------------------------------------------------------------- /examples/derived-type-aliases/tests.py: -------------------------------------------------------------------------------- 1 | from mytype import mytype_mod 2 | 3 | mine = mytype_mod.constructor() 4 | assert mine.a == 2 5 | c = mytype_mod.plus_b(mine, b=3) 6 | assert c == 5 7 | 8 | from othertype import othertype_mod 9 | 10 | other = othertype_mod.constructor() 11 | assert other.a == 5 12 | d = othertype_mod.plus_b(other, b=4) 13 | assert d == 9 14 | -------------------------------------------------------------------------------- /examples/derivedtypes/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := ExampleDerivedTypes 4 | NAME2 := ExampleDerivedTypes_pkg 5 | WRAPFLAGS += -k kind_map 6 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 7 | 8 | test: build2 9 | ${PYTHON} tests.py 10 | ${PYTHON} tests_pkg.py 11 | 12 | build2: build 13 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P" 14 | 15 | clean: 16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 17 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 18 | -------------------------------------------------------------------------------- /examples/derivedtypes/README.md: -------------------------------------------------------------------------------- 1 | example-derived-types 2 | ===================== 3 | 4 | Example with a set of subroutines, functions, arrays and derived types. 5 | This extends the ```example-array``` example. 6 | It is shown how to access and interact in Python with the Fortran based 7 | derived types and arrays. The example has been tested with both ```ifort``` 8 | and ```gfortran```. The compiler can be set in the ```Makefile```. 9 | 10 | To build and wrap with f90wrap, use the included ```Makefile```: 11 | 12 | ``` 13 | make 14 | ``` 15 | 16 | and before rebuilding, clean-up with: 17 | 18 | ``` 19 | make clean 20 | ``` 21 | 22 | Simple unittest test cases are included in ```tests.py```. 23 | 24 | A sample memory profiling script is included in ```memory_profile.py```. 25 | To profile, run (you will need to have the Python module ```memory_profiler``` 26 | installed): 27 | 28 | ``` 29 | python2 -m memory_profiler memory_profile.py 30 | ``` 31 | 32 | 33 | Author 34 | ------ 35 | 36 | David Verelst: 37 | 38 | -------------------------------------------------------------------------------- /examples/derivedtypes/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': { '' : 'float', 3 | '4' : 'float', 4 | 'isp' : 'float', 5 | '8' : 'double', 6 | 'dp' : 'double', 7 | 'idp' : 'double'}, 8 | 'complex' : { '' : 'complex_float', 9 | '8' : 'complex_double', 10 | '16' : 'complex_long_double', 11 | 'dp' : 'complex_double'}, 12 | 'integer' : { '4' : 'int', 13 | '8' : 'long_long', 14 | 'dp' : 'long_long' }, 15 | 'character' : {'' : 'char', 16 | '1' : 'char' } 17 | } 18 | -------------------------------------------------------------------------------- /examples/derivedtypes/memory_profile.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | # -*- coding: utf-8 -*- 24 | """ 25 | Created on Tue Jul 28 15:19:03 2015 26 | 27 | @author: David Verelst 28 | """ 29 | 30 | from __future__ import print_function 31 | 32 | import numpy as np 33 | 34 | import ExampleArray as lib 35 | 36 | @profile 37 | def do_array_stuff(ndata): 38 | xdata = np.arange(ndata) 39 | fdata = np.arange(ndata) 40 | breakarr = np.zeros((ndata,), order='F', dtype=np.float64) 41 | cscoef = np.zeros((4, ndata), order='F', dtype=np.float64) 42 | 43 | lib.library.do_array_stuff(n=ndata, x=xdata, y=fdata, 44 | br=breakarr, co=cscoef) 45 | 46 | cscoef_np = np.zeros((4, ndata), order='F', dtype=np.float64) 47 | for k in range(4): 48 | cscoef_np[k,:] = xdata*fdata + xdata 49 | breakarr_np = np.zeros((ndata), order='F', dtype=np.float64) 50 | breakarr_np[:] = xdata/(fdata+1.0) 51 | 52 | print(np.allclose(breakarr_np, breakarr)) 53 | print(np.allclose(cscoef_np, cscoef)) 54 | p2 = breakarr 55 | 56 | lib.library.only_manipulate(n=ndata, array=cscoef) 57 | p3 = cscoef 58 | 59 | do_array_stuff(1e6) 60 | -------------------------------------------------------------------------------- /examples/derivedtypes/parameters.f90: -------------------------------------------------------------------------------- 1 | module parameters 2 | 3 | implicit none 4 | private 5 | public :: idp, isp 6 | 7 | INTEGER, PARAMETER :: idp=kind(1d0) ! double precision, np.float64 equivalent 8 | INTEGER, PARAMETER :: isp=kind(1e0) ! single precision, np.float32 equivalent 9 | 10 | contains 11 | 12 | end module parameters 13 | 14 | -------------------------------------------------------------------------------- /examples/derivedtypes/tests_pkg.py: -------------------------------------------------------------------------------- 1 | tests.py -------------------------------------------------------------------------------- /examples/derivedtypes_procedure/Makefile: -------------------------------------------------------------------------------- 1 | FC = gfortran 2 | CFLAGS = -fPIC 3 | PYTHON = python 4 | 5 | all: test 6 | 7 | %.o : %.f90 8 | ${FC} ${CFLAGS} -c $< -o $@ 9 | 10 | library.o: library.f90 11 | 12 | tests.py: library.o 13 | python -m f90wrap -m library library.f90 -v 14 | python -m f90wrap --f2py-f90wrap -c -m _library f90wrap_*.f90 library.o 15 | 16 | test: tests.py 17 | $(PYTHON) tests.py 18 | 19 | clean: 20 | -rm -f *.o f90wrap*.f90 *.so *.mod *.pyc 21 | -rm -rf __pycache__ 22 | -rm -f library.py 23 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 24 | -------------------------------------------------------------------------------- /examples/derivedtypes_procedure/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := library 4 | 5 | test: build 6 | $(PYTHON) tests.py 7 | -------------------------------------------------------------------------------- /examples/derivedtypes_procedure/library.f90: -------------------------------------------------------------------------------- 1 | module test 2 | implicit none 3 | 4 | private 5 | public atype, btype 6 | public :: create, asum 7 | public :: asum_class 8 | 9 | type :: atype 10 | integer, allocatable :: array(:) 11 | contains 12 | procedure :: p_create => create_class 13 | procedure :: p_asum => asum_class 14 | procedure :: p_asum_2 => asum_class 15 | procedure :: asum_class 16 | procedure :: p_reset => assignment_value 17 | generic :: assignment(=) => p_reset 18 | end type atype 19 | 20 | type :: btype 21 | integer :: array(3) 22 | contains 23 | procedure :: p_asum => bsum_class 24 | end type btype 25 | 26 | contains 27 | 28 | subroutine create(self, n) 29 | implicit none 30 | type(atype),intent(inout) :: self 31 | integer :: n 32 | ! 33 | if (allocated(self%array)) deallocate(self%array) 34 | allocate(self%array(n)) 35 | ! 36 | end subroutine 37 | 38 | subroutine create_class(self, n) 39 | implicit none 40 | class(atype),intent(inout) :: self 41 | integer :: n 42 | ! 43 | call create(self, n) 44 | ! 45 | end subroutine 46 | 47 | function asum(self) 48 | implicit none 49 | type(atype),intent(in) :: self 50 | real :: asum 51 | ! 52 | asum = sum(self%array) 53 | ! 54 | end function 55 | 56 | function asum_class(self) 57 | implicit none 58 | class(atype),intent(in) :: self 59 | real :: asum_class 60 | ! 61 | asum_class = asum(self) 62 | ! 63 | end function 64 | 65 | subroutine assignment_value(self, value) 66 | implicit none 67 | class(atype),intent(inout) :: self 68 | integer,intent(in) :: value 69 | ! 70 | self%array(:) = value 71 | ! 72 | end subroutine 73 | 74 | function bsum_class(self) 75 | implicit none 76 | class(btype),intent(in) :: self 77 | real :: bsum_class 78 | ! 79 | bsum_class = sum(self%array) 80 | ! 81 | end function 82 | 83 | end module 84 | -------------------------------------------------------------------------------- /examples/derivedtypes_procedure/tests.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import library 3 | lib = library.test 4 | 5 | 6 | class TestExample(unittest.TestCase): 7 | 8 | def setUp(self): 9 | pass 10 | 11 | def test_create(self): 12 | data = lib.atype() 13 | lib.create(data, 10) 14 | self.assertEqual(len(data.array), 10) 15 | 16 | def test_type_create(self): 17 | data = lib.atype() 18 | data.p_create(10) 19 | self.assertEqual(len(data.array), 10) 20 | 21 | def test_asum(self): 22 | data = lib.atype() 23 | lib.create(data, 10) 24 | data.array[:] = 1 25 | a = lib.asum(data) 26 | self.assertEqual(a, 10) 27 | a = lib.asum_class(data) 28 | self.assertEqual(a, 10) 29 | 30 | def test_type_asum(self): 31 | data = lib.atype() 32 | data.p_create(10) 33 | data.array[:] = 1 34 | a = data.p_asum() 35 | self.assertEqual(a, 10) 36 | a2 = data.asum_class() 37 | self.assertEqual(a2, 10) 38 | a3 = data.p_asum_2() 39 | self.assertEqual(a3, 10) 40 | 41 | def test_type_asum_b(self): 42 | data = lib.atype() 43 | data.p_create(10) 44 | data.array[:] = 1 45 | a = data.p_asum() 46 | self.assertEqual(a, 10) 47 | data2 = lib.btype() 48 | data2.array[:] = 1 49 | b = data2.p_asum() 50 | self.assertEqual(b, 3) 51 | 52 | def test_type_assignment(self): 53 | data = lib.atype() 54 | data.p_create(10) 55 | data.array[:] = 1 56 | data.p_reset(2) 57 | a = data.p_asum() 58 | self.assertEqual(a, 20) 59 | 60 | 61 | if __name__ == '__main__': 62 | 63 | unittest.main() 64 | -------------------------------------------------------------------------------- /examples/docstring/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | CC = gcc 6 | F90 = gfortran 7 | PYTHON = python 8 | CFLAGS = -fPIC 9 | F90FLAGS = -fPIC 10 | PY_MOD = pywrapper 11 | F90_SRC = main.f90 12 | OBJ = $(F90_SRC:.f90=.o) 13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC}) 14 | WRAPFLAGS = -v 15 | F2PYFLAGS = --build-dir build 16 | F90WRAP = f90wrap 17 | F2PY = f2py-f90wrap 18 | .PHONY: all clean 19 | 20 | all: test 21 | 22 | clean: 23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/ 24 | 25 | main.o: ${F90_SRC} 26 | ${F90} ${F90FLAGS} -c $< -o $@ 27 | 28 | %.o: %.f90 29 | ${F90} ${F90FLAGS} -c $< -o $@ 30 | 31 | ${F90WRAP_SRC}: ${OBJ} 32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC} 33 | 34 | f2py: ${F90WRAP_SRC} 35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o 36 | 37 | test: f2py 38 | python docstring_test.py 39 | -------------------------------------------------------------------------------- /examples/docstring/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper 4 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 5 | 6 | LIBSRC_WRAP_FPP_FILES := main.f90 7 | 8 | test: build1 9 | $(PYTHON) docstring_test.py 10 | 11 | build1: 12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME) LIBSRC_WRAP_FPP_FILES=$(LIBSRC_WRAP_FPP_FILES) 13 | 14 | -------------------------------------------------------------------------------- /examples/elemental/Makefile: -------------------------------------------------------------------------------- 1 | PYTHON = python 2 | 3 | all: 4 | f90wrap -m elmod elemental_module.f90 -v -k kind_map 5 | f2py-f90wrap --fcompiler=gfortran -I. --build-dir . -c -m _elmod elemental_module.f90 f90wrap*.f90 6 | 7 | clean: 8 | -rm *.o *.mod elmod.py* _elmod*.so f90wrap_elemental_module.* 9 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 10 | 11 | test: all 12 | $(PYTHON) test.py 13 | -------------------------------------------------------------------------------- /examples/elemental/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := elmod 4 | WRAPFLAGS += -k kind_map 5 | 6 | test: build 7 | $(PYTHON) test.py 8 | -------------------------------------------------------------------------------- /examples/elemental/elemental_module.f90: -------------------------------------------------------------------------------- 1 | module elemental_module 2 | implicit none 3 | contains 4 | elemental real(kind=8) function sinc(x) 5 | real(kind=8), intent(in) :: x 6 | if(abs(x).gt.1d-5) then 7 | sinc = sin(x)/x 8 | else 9 | sinc = 1.0d0 10 | endif 11 | return 12 | end function sinc 13 | end module elemental_module -------------------------------------------------------------------------------- /examples/elemental/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': { '' : 'float', 3 | '4' : 'float', 4 | 'isp' : 'float', 5 | '8' : 'double', 6 | 'dp' : 'double', 7 | 'idp' : 'double'}, 8 | 'complex' : { '' : 'complex_float', 9 | '8' : 'complex_double', 10 | '16' : 'complex_long_double', 11 | 'dp' : 'complex_double'}, 12 | 'integer' : { '4' : 'int', 13 | '8' : 'long_long', 14 | 'dp' : 'long_long' }, 15 | 'character' : {'' : 'char', 16 | '1' : 'char' } 17 | } 18 | -------------------------------------------------------------------------------- /examples/elemental/test.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | import elmod 24 | from math import pi 25 | 26 | assert elmod.Elemental_Module.sinc(pi/2) == 2.0/pi -------------------------------------------------------------------------------- /examples/errorbinding/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := ExampleDerivedTypes 4 | NAME2 := ExampleDerivedTypes_pkg 5 | WRAPFLAGS += -k kind_map 6 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 7 | 8 | test: build2 9 | #${PYTHON} tests.py 10 | #${PYTHON} tests_pkg.py 11 | 12 | build2: build 13 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P" 14 | 15 | clean: 16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 17 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 18 | -------------------------------------------------------------------------------- /examples/errorbinding/README.md: -------------------------------------------------------------------------------- 1 | Error by absent Binding 2 | ===================== 3 | 4 | Minimal example to reproduce error due to absense of import Bindining 5 | in "parser.py" script. Created from a copy of example derivedtype. 6 | 7 | In previous version of f90wrap (version 0.2.2 dos not give this issue) 8 | I used to write by myself the procedure where class is replaced by 9 | tpye and in the example derivedtype. 10 | 11 | 12 | To generate the error use the included ```Makefile```: 13 | 14 | ``` 15 | make 16 | ``` 17 | 18 | Author 19 | ------ 20 | 21 | Enrico Facca: 22 | 23 | -------------------------------------------------------------------------------- /examples/errorbinding/datatypes.f90: -------------------------------------------------------------------------------- 1 | ! ============================================================================== 2 | module datatypes 3 | use parameters, only: idp, isp 4 | implicit none 5 | private 6 | public :: typewithprocedure, constructor_typewithprocedure, info_typewithprocedure 7 | type :: typewithprocedure 8 | REAL(idp) :: a 9 | INTEGER(4) :: n 10 | contains 11 | procedure, public :: init => init_procedure 12 | procedure, public :: info => info_procedure 13 | end type typewithprocedure 14 | contains 15 | 16 | subroutine init_procedure(this, a, n) 17 | class(typewithprocedure), intent(inout) :: this 18 | REAL(idp), intent(in ) :: a 19 | INTEGER(4), INTENT(in) :: n 20 | 21 | this%a = a 22 | this%n = n 23 | end subroutine init_procedure 24 | 25 | subroutine info_procedure(this, lun) 26 | class(typewithprocedure), intent(inout) :: this 27 | INTEGER(4), INTENT(in) :: lun 28 | 29 | write(lun,*) ' a = ', this%a, 'n = ', this%n 30 | end subroutine info_procedure 31 | 32 | subroutine constructor_typewithprocedure(this, a, n) 33 | type(typewithprocedure), intent(inout) :: this 34 | REAL(idp), intent(in ) :: a 35 | INTEGER(4), INTENT(in) :: n 36 | 37 | call this%init(a,n) 38 | end subroutine constructor_typewithprocedure 39 | 40 | 41 | subroutine info_typewithprocedure(this, lun) 42 | type(typewithprocedure), intent(inout) :: this 43 | INTEGER(4), INTENT(in) :: lun 44 | 45 | call this%info(lun) 46 | end subroutine info_typewithprocedure 47 | 48 | end module datatypes 49 | -------------------------------------------------------------------------------- /examples/errorbinding/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': { '' : 'float', 3 | '4' : 'float', 4 | 'isp' : 'float', 5 | '8' : 'double', 6 | 'dp' : 'double', 7 | 'idp' : 'double'}, 8 | 'complex' : { '' : 'complex_float', 9 | '8' : 'complex_double', 10 | '16' : 'complex_long_double', 11 | 'dp' : 'complex_double'}, 12 | 'integer' : { '4' : 'int', 13 | '8' : 'long_long', 14 | 'dp' : 'long_long' }, 15 | 'character' : {'' : 'char', 16 | '1' : 'char' } 17 | } 18 | -------------------------------------------------------------------------------- /examples/errorbinding/parameters.f90: -------------------------------------------------------------------------------- 1 | module parameters 2 | 3 | implicit none 4 | private 5 | public :: idp, isp 6 | 7 | INTEGER, PARAMETER :: idp=kind(1d0) ! double precision, np.float64 equivalent 8 | INTEGER, PARAMETER :: isp=kind(1e0) ! single precision, np.float32 equivalent 9 | 10 | contains 11 | 12 | end module parameters 13 | 14 | -------------------------------------------------------------------------------- /examples/example2/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := mockdt 4 | NAME2 := mockdtpkg 5 | WRAPFLAGS += -k kind_map 6 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 7 | 8 | LIBSRC_WRAP_FILES := $(shell find ./ -name '*.F90') 9 | 10 | test: build2 11 | $(PYTHON) test_module.py 12 | $(PYTHON) test_package.py 13 | 14 | build2: 15 | @ rm -rf f90wrap_*.f90 16 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME) WRAPFLAGS="$(WRAPFLAGS)" LIBSRC_WRAP_FILES="$(LIBSRC_WRAP_FILES)" 17 | @ rm -rf f90wrap_*.f90 18 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P" LIBSRC_WRAP_FILES="$(LIBSRC_WRAP_FILES)" 19 | 20 | clean: 21 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 22 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 23 | -------------------------------------------------------------------------------- /examples/example2/README: -------------------------------------------------------------------------------- 1 | Example code contributed by Ananth Sridharan , 2 | University of Maryland. 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/example2/Source/BasicDefs/aa0_typelist.F90: -------------------------------------------------------------------------------- 1 | !====================================================================== 2 | ! Original author Shreyas Ananthan 3 | ! Modified by Ananth Sridharan 4 | !====================================================================== 5 | module precision 6 | !Kind parameters for real variables 7 | ! integer, parameter :: float =kind(1.e0) ! single precision 8 | ! integer, parameter :: double=kind(1.D0) ! double precision 9 | 10 | !Uncomment lines below to enable switching.. right now, using rdp=double 11 | ! #ifdef USE_SINGLE_PRECISION 12 | ! integer, parameter :: rdp=4 13 | ! zero = 0.0 14 | ! #else 15 | 16 | !must specify # bytes integer explicitly here for f2c and f2py 17 | integer, parameter :: rdp=8 18 | ! #endif 19 | real(kind=rdp) :: ZERO,ONE,HALF,TWO,THREE,FOUR,SIX, & 20 | EIGHT,PI,TWOPI, D2R, R2D, XK2FPS, & 21 | LB2N, FTLB2NM, ONE80,FT2M, GSI, GFPS, & 22 | Three60, IN2FT, FIVE 23 | 24 | end module precision 25 | -------------------------------------------------------------------------------- /examples/example2/Source/HeliSrc/set_defaults.F90: -------------------------------------------------------------------------------- 1 | !>====================================================================== 2 | !! This subroutine is used to set the default values of 3 | !! various switches at the beginning of program 4 | !!====================================================================== 5 | 6 | subroutine set_defaults(Solver) 7 | 8 | use defineAllProperties 9 | implicit none 10 | 11 | !======================================================================= 12 | ! EXECUTABLE CODE 13 | !======================================================================= 14 | 15 | type(SolverOptionsDef), intent(inout) :: Solver 16 | 17 | !======================================================================= 18 | ! Solver option defaults 19 | !======================================================================= 20 | 21 | Solver % AirframeVib = .true. 22 | Solver % FET_qddot = .false. 23 | Solver % FET_Response = .false. 24 | Solver % FusHarm = .false. 25 | Solver % STore_FET_ResponseJac = .false. 26 | 27 | !======================================================================= 28 | ! End of operations 29 | !======================================================================= 30 | 31 | return 32 | end subroutine set_defaults 33 | -------------------------------------------------------------------------------- /examples/example2/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': { '': 'float', 3 | '8': 'double', 4 | 'rdp': 'double'}, 5 | 'complex' : { '': 'complex_float', 6 | '8': 'complex_double', 7 | 'rdp': 'complex_double'}, 8 | 'integer' : { '': 'int', 9 | '8': 'long_long', 10 | 'dp': 'long_long' } 11 | } 12 | -------------------------------------------------------------------------------- /examples/extends/Makefile: -------------------------------------------------------------------------------- 1 | FPP=gfortran 2 | #FPP=ifort 3 | FFLAGS=-fPIC 4 | PYTHON = python 5 | 6 | %.o : %.f90 7 | ${FPP} ${FFLAGS} -c $< -o $@ 8 | 9 | all: testextends.o 10 | f90wrap -m testextends testextends.f90 11 | f2py-f90wrap -c -m _testextends f90wrap_*.f90 12 | 13 | test: all 14 | $(PYTHON) testextends.py 15 | 16 | clean: 17 | -rm -f *.o f90wrap*.f90 *.so *.mod testextends.py 18 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 19 | 20 | -------------------------------------------------------------------------------- /examples/extends/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := testextends 4 | 5 | test: build 6 | $(PYTHON) testextends.py 7 | -------------------------------------------------------------------------------- /examples/extends/testextends.f90: -------------------------------------------------------------------------------- 1 | 2 | module testextends_mod 3 | 4 | 5 | PUBLIC 6 | 7 | ! ----------------------------------------------- 8 | type Superclass 9 | ! IN: Ask subroutine to stop in the middle. 10 | integer :: stop_at = -1 ! -1 --> don't stop 11 | end type Superclass 12 | 13 | type, extends(Superclass) :: Subclass1 14 | integer :: nl 15 | end type 16 | 17 | type, extends(Superclass) :: Subclass2 18 | integer :: nl 19 | end type 20 | 21 | end module 22 | -------------------------------------------------------------------------------- /examples/fixed_1D_derived_type_array_argument/Makefile: -------------------------------------------------------------------------------- 1 | PYTHON = python 2 | 3 | test : clean functions.o wrap python 4 | $(PYTHON) tests.py 5 | functions.o : functions.f90 6 | gfortran -c -O3 -fPIC functions.f90 7 | wrap : 8 | f90wrap --default-to-inout -m test_python functions.f90 9 | python : 10 | f2py-f90wrap -c -m _test_python f90wrap_functions.f90 *.o 11 | clean : 12 | rm -f *.o *.mod *.so f90wrap* test_python.py 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/fixed_1D_derived_type_array_argument/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := test_python 4 | WRAPFLAGS += --default-to-inout 5 | 6 | test: build 7 | $(PYTHON) tests.py 8 | -------------------------------------------------------------------------------- /examples/fixed_1D_derived_type_array_argument/dummy.file: -------------------------------------------------------------------------------- 1 | x 2 | -------------------------------------------------------------------------------- /examples/fixed_1D_derived_type_array_argument/functions.f90: -------------------------------------------------------------------------------- 1 | module test_module 2 | 3 | integer, parameter :: m=5 4 | integer, parameter :: n=3 5 | type test_type2 6 | real, dimension(m) :: y 7 | end type test_type2 8 | 9 | contains 10 | 11 | subroutine test_routine4(x1, x2, x3, x4, x5, x6) 12 | real, dimension(m) :: x1 13 | type(test_type2), dimension(n) :: x2 14 | ! another dimension(n) array, to see if the wrapper creates two super types on not (it should not) 15 | type(test_type2), dimension(n) :: x3 16 | ! another array of the same type, but different dimension : should lead to a different super-type 17 | type(test_type2), dimension(m) :: x4 18 | ! "normal" array of types 19 | type(test_type2), dimension(5) :: x5 20 | ! x6 is completely implicit : should be real, and will be treated as intent(in) unless the command-line flag --default-to-intent-inout is used 21 | 22 | x1(1) = 42 23 | x2(2)%y(2) = 42 24 | x3(3)%y(3) = 42 25 | x4(4)%y(4) = 42 26 | x5(5)%y(5) = 42 27 | x6 = x6 + 1 28 | 29 | end subroutine test_routine4 30 | 31 | 32 | end module test_module 33 | 34 | -------------------------------------------------------------------------------- /examples/fixed_1D_derived_type_array_argument/tests.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | import test_python 24 | import numpy 25 | 26 | a = numpy.ones(test_python.test_module.m, dtype=numpy.float32) 27 | b = test_python.test_module.Test_Type2_Xn_Array() 28 | c = test_python.test_module.Test_Type2_Xn_Array() 29 | d = test_python.test_module.Test_Type2_Xm_Array() 30 | e = test_python.test_module.Test_Type2_X5_Array() 31 | f = numpy.ones(1) 32 | 33 | test_python.test_module.test_routine4(a, b, c, d, e, f) 34 | 35 | print(a) 36 | print(list(b.items[i].y for i in range(len(b.items)))) 37 | print(list(c.items[i].y for i in range(len(c.items)))) 38 | print(list(d.items[i].y for i in range(len(d.items)))) 39 | print(list(e.items[i].y for i in range(len(e.items)))) 40 | print(f) 41 | 42 | 43 | assert(all(a == numpy.array([42, 1, 1, 1, 1], dtype=numpy.float32))) 44 | assert(b.items[1].y[1] == 42) 45 | assert(c.items[2].y[2] == 42) 46 | assert(d.items[3].y[3] == 42) 47 | assert(e.items[4].y[4] == 42) 48 | assert(f == 2) 49 | -------------------------------------------------------------------------------- /examples/fortran_oo/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | CC = gcc 6 | F90 = gfortran 7 | PYTHON = python 8 | CFLAGS = -fPIC 9 | F90FLAGS = -fPIC 10 | PY_MOD = pywrapper 11 | F90_SRC = main-oo.f90 base_poly.f90 12 | OBJ = $(F90_SRC:.f90=.o) 13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC}) 14 | WRAPFLAGS = -v --type-check --kind-map kind.map 15 | F2PYFLAGS = --build-dir build 16 | F90WRAP = f90wrap 17 | F2PY = f2py-f90wrap 18 | .PHONY: all clean 19 | 20 | all: test 21 | clean: 22 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/ 23 | 24 | main-oo.o: main-oo.f90 base_poly.o 25 | ${F90} ${F90FLAGS} -c $< -o $@ 26 | 27 | %.o: %.f90 28 | ${F90} ${F90FLAGS} -c $< -o $@ 29 | 30 | ${F90WRAP_SRC}: ${OBJ} 31 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC} 32 | 33 | f2py: ${F90WRAP_SRC} 34 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o 35 | 36 | test: f2py 37 | ${PYTHON} oowrap_test.py 38 | -------------------------------------------------------------------------------- /examples/fortran_oo/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper 4 | WRAPFLAGS += --type-check --kind-map kind.map 5 | 6 | test: build 7 | $(PYTHON) oowrap_test.py 8 | -------------------------------------------------------------------------------- /examples/fortran_oo/base_poly.f90: -------------------------------------------------------------------------------- 1 | module m_base_poly 2 | implicit none 3 | private 4 | 5 | type, public, abstract :: Polygone 6 | contains 7 | procedure :: is_polygone => polygone_is_polygone 8 | end type Polygone 9 | contains 10 | function polygone_is_polygone(this) result(is_polygone) 11 | class(Polygone), intent(in) :: this 12 | integer :: is_polygone 13 | is_polygone = 1 14 | end function polygone_is_polygone 15 | end module m_base_poly 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/fortran_oo/kind.map: -------------------------------------------------------------------------------- 1 | {'complex':{'':'complex_float', '4':'complex_float', '8':'complex_double'},\ 2 | 'integer':{'':'int', '1':'signed_char', '2':'short','4':'int', 'c_int':'int', '8':'long_long', 'c_int64_t':'long_long'},\ 3 | 'real':{'': 'float', '4': 'float', 'c_float':'float', '8': 'double'},\ 4 | 'logical':{'': 'bool'},\ 5 | } 6 | -------------------------------------------------------------------------------- /examples/intent_out_size/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | CC = gcc 6 | F90 = gfortran 7 | PYTHON = python 8 | CFLAGS = -fPIC 9 | F90FLAGS = -fPIC 10 | PY_MOD = pywrapper 11 | F90_SRC = main.f90 12 | OBJ = $(F90_SRC:.f90=.o) 13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC}) 14 | WRAPFLAGS = -v 15 | F2PYFLAGS = --build-dir build 16 | F90WRAP = f90wrap 17 | F2PY = f2py-f90wrap 18 | .PHONY: all clean 19 | 20 | all: test 21 | 22 | clean: 23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/ 24 | 25 | main.o: ${F90_SRC} 26 | ${F90} ${F90FLAGS} -c $< -o $@ 27 | 28 | %.o: %.f90 29 | ${F90} ${F90FLAGS} -c $< -o $@ 30 | 31 | ${F90WRAP_SRC}: ${OBJ} 32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC} 33 | 34 | f2py: ${F90WRAP_SRC} 35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o 36 | 37 | test: f2py 38 | ${PYTHON} tests.py 39 | -------------------------------------------------------------------------------- /examples/intent_out_size/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper 4 | 5 | test: build 6 | $(PYTHON) tests.py 7 | -------------------------------------------------------------------------------- /examples/intent_out_size/main.f90: -------------------------------------------------------------------------------- 1 | module m_intent_out 2 | 3 | implicit none 4 | public 5 | 6 | contains 7 | 8 | subroutine interpolation(n1,n2,a1,a2,output) 9 | ! 10 | integer, intent(in) :: n1,n2 11 | real,dimension(n1,n2), intent(in) :: a1,a2 12 | real,dimension(n1,n2), intent(out) :: output 13 | 14 | integer :: i,j 15 | 16 | do j=1,n2 17 | do i=1,n1 18 | output(i,j)=(a1(i,j)+a2(i,j))/2 19 | enddo 20 | enddo 21 | 22 | end subroutine interpolation 23 | 24 | end module m_intent_out 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/intent_out_size/tests.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | 4 | from pywrapper import m_intent_out 5 | 6 | class TestIntentOut(unittest.TestCase): 7 | 8 | def test_intent_out_size(self): 9 | 10 | a1 = np.array([[1,2], [3,4]], dtype=np.float32, order='F') 11 | a2 = np.array([[2,4], [6,8]], dtype=np.float32, order='F') 12 | output = np.zeros((2,2), dtype=np.float32, order='F') 13 | n1 = 2 14 | n2 = 2 15 | 16 | m_intent_out.interpolation(n1,n2,a1,a2,output) 17 | 18 | ref_out = np.array([[1.5,3.], [4.5,6.]], dtype=np.float32, order='F') 19 | 20 | np.testing.assert_array_equal(output, ref_out) 21 | 22 | if __name__ == '__main__': 23 | 24 | unittest.main() 25 | -------------------------------------------------------------------------------- /examples/interface/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | F90 = gfortran 3 | FPP = gfortran -E 4 | F90FLAGS = -x f95-cpp-input -fPIC 5 | CFLAGS = -fPIC 6 | PYTHON = python 7 | 8 | all: test 9 | 10 | example.o: example.f90 11 | $(F90) $(F90FLAGS) -c $< 12 | 13 | mod: example.o 14 | f90wrap -m example ./example.f90 15 | f2py-f90wrap -c -m _example f90wrap_example.f90 example.o 16 | 17 | package: example.o 18 | f90wrap -P -m examplepkg ./example.f90 19 | f2py-f90wrap -c -m _examplepkg f90wrap_example.f90 example.o 20 | 21 | test: mod package 22 | $(PYTHON) test.py 23 | $(PYTHON) test_pkg.py 24 | 25 | clean: 26 | -rm -r examplepkg 27 | -rm example.py 28 | -rm f90wrap*.f90 *.o *.pyc *.mod 29 | -rm _example*.so _examplepkg*.so 30 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 31 | 32 | -------------------------------------------------------------------------------- /examples/interface/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := example 4 | NAME2 := examplepkg 5 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 6 | 7 | test: build2 8 | $(PYTHON) test.py 9 | $(PYTHON) test_pkg.py 10 | 11 | build2: build 12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS=-P 13 | 14 | clean: 15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 17 | -------------------------------------------------------------------------------- /examples/interface/README.md: -------------------------------------------------------------------------------- 1 | Test case for issue #32 2 | -------------------------------------------------------------------------------- /examples/interface/example.f90: -------------------------------------------------------------------------------- 1 | !-*-f90-*- 2 | module class_example 3 | 4 | implicit none 5 | private 6 | public :: Example, return_example 7 | 8 | interface return_example 9 | module procedure return_example_first, return_example_second, return_example_third 10 | end interface return_example 11 | 12 | type Example 13 | integer :: first 14 | integer :: second 15 | integer :: third 16 | end type Example 17 | 18 | ! singleton 19 | type(Example) :: this 20 | 21 | contains 22 | 23 | !------------------------------------------------------------------------------------! 24 | 25 | function return_example_first(first) result(instance) 26 | 27 | implicit none 28 | integer :: first 29 | type(Example) :: instance 30 | 31 | this%first = first 32 | instance = this 33 | 34 | return 35 | 36 | end function return_example_first 37 | 38 | !------------------------------------------------------------------------------------! 39 | 40 | function return_example_second(first,second) result(instance) 41 | 42 | implicit none 43 | integer :: first 44 | integer :: second 45 | type(Example) :: instance 46 | 47 | this%first = first 48 | this%second = second 49 | 50 | instance = this 51 | return 52 | 53 | end function return_example_second 54 | 55 | !------------------------------------------------------------------------------------! 56 | 57 | function return_example_third(first,second,third) result(instance) 58 | 59 | implicit none 60 | integer :: first 61 | integer :: second 62 | integer :: third 63 | type(Example) :: instance 64 | 65 | this%first = first 66 | this%second = second 67 | this%third = third 68 | 69 | instance = this 70 | return 71 | 72 | end function return_example_third 73 | 74 | !------------------------------------------------------------------------------------! 75 | end module class_example -------------------------------------------------------------------------------- /examples/interface/test.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | import example 24 | 25 | example.class_example.return_example(1) 26 | example.class_example.return_example(1,2) 27 | example.class_example.return_example(1,2,3) 28 | 29 | -------------------------------------------------------------------------------- /examples/interface/test_pkg.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | import examplepkg 24 | 25 | examplepkg.class_example.return_example(1) 26 | examplepkg.class_example.return_example(1,2) 27 | examplepkg.class_example.return_example(1,2,3) 28 | -------------------------------------------------------------------------------- /examples/issue105_function_definition_with_empty_lines/Makefile: -------------------------------------------------------------------------------- 1 | FC = gfortran 2 | #FPP = ifort 3 | FCFLAGS = -fPIC 4 | PYTHON = python 5 | 6 | %.o : %.f90 7 | ${FC} ${FCFLAGS} -c $< -o $@ 8 | 9 | all: main.o 10 | f90wrap -m itest -P main.f90 -v 11 | f2py-f90wrap --fcompiler=$(FC) --build-dir . -c -m _itest f90wrap_main.f90 main.o 12 | 13 | test: all 14 | $(PYTHON) run.py 15 | 16 | clean: 17 | rm -f *.o f90wrap*.f90 *.so *.mod 18 | rm -rf src.*/ 19 | rm -rf itest/ 20 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 21 | -------------------------------------------------------------------------------- /examples/issue105_function_definition_with_empty_lines/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := itest 4 | 5 | test: build 6 | $(PYTHON) run.py 7 | -------------------------------------------------------------------------------- /examples/issue105_function_definition_with_empty_lines/main.f90: -------------------------------------------------------------------------------- 1 | module itestit 2 | 3 | implicit none 4 | 5 | private 6 | 7 | public :: testit1 8 | public :: testit2 9 | 10 | contains 11 | 12 | subroutine testit1( & 13 | x & 14 | ) 15 | 16 | implicit none 17 | 18 | real, dimension(:), intent(inout) :: x 19 | 20 | x = 1.*x 21 | 22 | end subroutine testit1 23 | 24 | subroutine testit2( & 25 | x & 26 | 27 | ) 28 | 29 | implicit none 30 | 31 | real, dimension(:), intent(inout) :: x 32 | 33 | x = 2.*x 34 | 35 | end subroutine testit2 36 | 37 | end module itestit 38 | -------------------------------------------------------------------------------- /examples/issue105_function_definition_with_empty_lines/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import division, absolute_import, print_function 3 | 4 | import numpy as np 5 | import itest 6 | 7 | a = np.arange(10, dtype=np.float32) 8 | itest.itestit.testit1(a) 9 | print(a) 10 | 11 | itest.itestit.testit2(a) 12 | print(a) 13 | -------------------------------------------------------------------------------- /examples/issue206_subroutine_oldstyle/Makefile: -------------------------------------------------------------------------------- 1 | FC = gfortran 2 | #FPP = ifort 3 | FCFLAGS = -fPIC 4 | PYTHON = python 5 | 6 | %.o : %.f 7 | ${FC} ${FCFLAGS} -c $< -o $@ 8 | 9 | all: subroutine_oldstyle.o 10 | f90wrap -m itest -P subroutine_oldstyle.f -v 11 | f2py-f90wrap --build-dir . -c -m _itest f90wrap_toplevel.f90 subroutine_oldstyle.o 12 | 13 | test: all 14 | $(PYTHON) run.py 15 | 16 | clean: 17 | rm -f *.o f90wrap*.f *.so *.mod 18 | rm -rf src.*/ 19 | rm -rf itest/ 20 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 21 | -------------------------------------------------------------------------------- /examples/issue206_subroutine_oldstyle/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := itest 4 | 5 | test: build 6 | $(PYTHON) run.py 7 | -------------------------------------------------------------------------------- /examples/issue206_subroutine_oldstyle/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import itest 3 | 4 | # Does nothing, but doesn't fail either 5 | itest.routine_with_oldstyle_asterisk() 6 | -------------------------------------------------------------------------------- /examples/issue206_subroutine_oldstyle/subroutine_oldstyle.f: -------------------------------------------------------------------------------- 1 | subroutine routine_with_oldstyle_asterisk(a,b,c, 2 | *d) 3 | 4 | implicit none 5 | 6 | integer :: a,b 7 | external c,d 8 | 9 | end subroutine routine_with_oldstyle_asterisk 10 | -------------------------------------------------------------------------------- /examples/issue227_allocatable/Makefile: -------------------------------------------------------------------------------- 1 | FC = gfortran 2 | FCFLAGS = -fPIC 3 | PYTHON = python 4 | 5 | %.o : %.f90 6 | ${FC} ${FCFLAGS} -c $< -o $@ 7 | 8 | all: alloc_output.o 9 | f90wrap -m itest -P alloc_output.f90 -v 10 | f2py-f90wrap --build-dir . -c -m _itest f90wrap_alloc_output.f90 alloc_output.o 11 | 12 | test: all 13 | $(PYTHON) run.py 14 | 15 | clean: 16 | rm -f *.o f90wrap*.f90 *.so *.mod 17 | rm -rf src.*/ 18 | rm -rf itest/ 19 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 20 | -------------------------------------------------------------------------------- /examples/issue227_allocatable/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := itest 4 | 5 | test: build 6 | $(PYTHON) run.py 7 | -------------------------------------------------------------------------------- /examples/issue227_allocatable/alloc_output.f90: -------------------------------------------------------------------------------- 1 | module alloc_output 2 | implicit none 3 | 4 | type :: alloc_output_type 5 | real :: a 6 | end type alloc_output_type 7 | 8 | contains 9 | 10 | ! This should be used by the wrapper generator 11 | function alloc_output_type_func(val) result(out) 12 | real, intent(in) :: val 13 | type(alloc_output_type), allocatable :: out 14 | allocate(out) 15 | out%a = val 16 | end function alloc_output_type_func 17 | 18 | 19 | ! This should be discarded by the wrapper generator 20 | function alloc_output_intrinsic_func(val) result(out) 21 | real, intent(in) :: val 22 | real, allocatable :: out 23 | allocate(out) 24 | out = val 25 | end function alloc_output_intrinsic_func 26 | 27 | 28 | ! This should be discarded by the wrapper generator 29 | function alloc_output_array_func(val) result(out) 30 | real, intent(in) :: val(:) 31 | real, allocatable :: out(:) 32 | allocate(out(size(val))) 33 | out(:) = val 34 | end function alloc_output_array_func 35 | 36 | 37 | subroutine noalloc_output_subroutine(val, out) 38 | real, intent(in) :: val 39 | type(alloc_output_type), intent(inout) :: out 40 | out%a = val 41 | end subroutine noalloc_output_subroutine 42 | 43 | end module alloc_output 44 | -------------------------------------------------------------------------------- /examples/issue227_allocatable/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import unittest 3 | import gc 4 | import tracemalloc 5 | 6 | import itest 7 | 8 | VAL = 10.0 9 | TOL = 1e-13 10 | 11 | class TestAllocOutput(unittest.TestCase): 12 | 13 | def test_type_output_is_wrapped(self): 14 | self.assertTrue(hasattr(itest.alloc_output, 'alloc_output_type_func')) 15 | 16 | def test_intrinsic_output_is_not_wrapped(self): 17 | self.assertFalse(hasattr(itest.alloc_output, 'alloc_output_intrinsic_func')) 18 | 19 | def test_array_output_is_not_wrapped(self): 20 | self.assertFalse(hasattr(itest.alloc_output, 'alloc_output_array_func')) 21 | 22 | def test_type_output_wrapper(self): 23 | t = itest.alloc_output.alloc_output_type_func(VAL) 24 | self.assertAlmostEqual(t.a, VAL, delta=TOL) 25 | 26 | def test_memory_leak(self): 27 | gc.collect() 28 | t = [] 29 | tracemalloc.start() 30 | start_snapshot = tracemalloc.take_snapshot() 31 | for i in range(8192): 32 | t.append(itest.alloc_output.alloc_output_type_func(VAL)) 33 | del t 34 | gc.collect() 35 | end_snapshot = tracemalloc.take_snapshot() 36 | tracemalloc.stop() 37 | stats = end_snapshot.compare_to(start_snapshot, 'lineno') 38 | self.assertLess(sum(stat.size_diff for stat in stats), 4096) 39 | 40 | if __name__ == '__main__': 41 | unittest.main() 42 | -------------------------------------------------------------------------------- /examples/issue235_allocatable_classes/Makefile: -------------------------------------------------------------------------------- 1 | FC = gfortran 2 | FCFLAGS = -fPIC 3 | PYTHON = python 4 | 5 | all: test 6 | 7 | test: wrapper 8 | $(PYTHON) run.py 9 | 10 | wrapper: f90wrapper mytype.o myclass.o myclass_factory.o 11 | $(PYTHON) -m f90wrap --f2py-f90wrap --build-dir . -c -m _itest --opt="-O0 -g" \ 12 | f90wrap_mytype.f90 f90wrap_myclass.f90 f90wrap_myclass_factory.f90 \ 13 | mytype.o myclass.o myclass_factory.o --lower 14 | 15 | f90wrapper: mytype.f90 myclass.f90 myclass_factory.f90 16 | $(PYTHON) -m f90wrap -m itest mytype.f90 myclass.f90 myclass_factory.f90 -v 17 | 18 | %.o : %.f90 19 | $(FC) $(FCFLAGS) -c -g -O0 $< -o $@ 20 | 21 | clean: 22 | rm -f *.o f90wrap*.f90 *.so *.mod 23 | rm -rf src.*/ 24 | rm -rf itest.py 25 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 26 | -------------------------------------------------------------------------------- /examples/issue235_allocatable_classes/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := itest 4 | 5 | test: build 6 | $(PYTHON) run.py 7 | -------------------------------------------------------------------------------- /examples/issue235_allocatable_classes/myclass.f90: -------------------------------------------------------------------------------- 1 | module myclass 2 | 3 | implicit none 4 | 5 | integer :: create_count = 0 6 | integer :: destroy_count = 0 7 | 8 | type :: myclass_t 9 | real :: val 10 | contains 11 | procedure :: get_val => myclass_get_val 12 | procedure :: set_val => myclass_set_val 13 | final :: myclass_destroy 14 | end type myclass_t 15 | 16 | contains 17 | 18 | subroutine myclass_get_val(self, val) 19 | class(myclass_t), intent(in) :: self 20 | real, intent(out) :: val 21 | 22 | val = self%val 23 | end subroutine myclass_get_val 24 | 25 | subroutine myclass_set_val(self, val) 26 | class(myclass_t), intent(inout) :: self 27 | real, intent(in) :: val 28 | 29 | self%val = val 30 | end subroutine myclass_set_val 31 | 32 | subroutine myclass_destroy(self) 33 | type(myclass_t), intent(inout) :: self 34 | 35 | destroy_count = destroy_count + 1 36 | print *, 'Destroying class_t with val = ', self%val 37 | end subroutine myclass_destroy 38 | 39 | end module myclass 40 | -------------------------------------------------------------------------------- /examples/issue235_allocatable_classes/myclass_factory.f90: -------------------------------------------------------------------------------- 1 | module myclass_factory 2 | 3 | use myclass, only: myclass_t, create_count 4 | implicit none 5 | 6 | contains 7 | 8 | function myclass_create(val) result(myobject) 9 | class(myclass_t), allocatable :: myobject 10 | real, intent(in) :: val 11 | 12 | allocate(myclass_t :: myobject) 13 | call myobject%set_val(val) 14 | create_count = create_count + 1 15 | 16 | end function myclass_create 17 | 18 | end module myclass_factory 19 | -------------------------------------------------------------------------------- /examples/issue235_allocatable_classes/mytype.f90: -------------------------------------------------------------------------------- 1 | module mytype 2 | 3 | implicit none 4 | 5 | integer :: create_count = 0 6 | integer :: destroy_count = 0 7 | 8 | type :: mytype_t 9 | real :: val 10 | contains 11 | final :: mytype_destroy 12 | end type mytype_t 13 | 14 | contains 15 | 16 | function mytype_create(val) result(self) 17 | type(mytype_t) :: self 18 | real, intent(in) :: val 19 | 20 | self%val = val 21 | create_count = create_count + 1 22 | end function mytype_create 23 | 24 | subroutine mytype_destroy(self) 25 | type(mytype_t), intent(inout) :: self 26 | 27 | destroy_count = destroy_count + 1 28 | print *, 'Destroying mytype_t with val = ', self%val 29 | end subroutine mytype_destroy 30 | 31 | end module mytype 32 | -------------------------------------------------------------------------------- /examples/issue235_allocatable_classes/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import unittest 3 | from itest import mytype, myclass, myclass_factory 4 | 5 | REF = 3.1415 6 | TOL = 1.0e-6 7 | 8 | class TestMyType(unittest.TestCase): 9 | 10 | def test_create_destroy_type_object(self): 11 | """Object creation and destruction should happen only once.""" 12 | mytype.create_count = 0 13 | mytype.destroy_count = 0 14 | 15 | obj = mytype.mytype_create(REF) 16 | 17 | self.assertEqual(mytype.create_count, 1) 18 | 19 | self.assertTrue(abs(obj.val - REF) < TOL) 20 | 21 | del obj 22 | 23 | self.assertEqual(mytype.create_count, 1) 24 | self.assertGreaterEqual(mytype.destroy_count, 1) 25 | 26 | def test_type_member_access(self): 27 | """Direct access of member variables.""" 28 | obj = mytype.mytype_create(REF) 29 | 30 | self.assertTrue(abs(obj.val - REF) < TOL) 31 | 32 | obj.val = 2.0 * REF 33 | 34 | self.assertTrue(abs(obj.val - 2.0 * REF) < TOL) 35 | 36 | del obj 37 | 38 | 39 | class TestMyClass(unittest.TestCase): 40 | 41 | def test_create_destroy_class_object(self): 42 | """Object creation and destruction should happen only once.""" 43 | myclass.create_count = 0 44 | myclass.destroy_count = 0 45 | 46 | obj = myclass_factory.myclass_create(REF) 47 | 48 | self.assertEqual(myclass.create_count, 1) 49 | 50 | self.assertTrue(abs(obj.get_val() - REF) < TOL) 51 | 52 | del obj 53 | 54 | self.assertEqual(myclass.create_count, 1) 55 | self.assertGreaterEqual(myclass.destroy_count, 1) 56 | 57 | def test_class_getter_setter(self): 58 | """Getters and setters defined in Fortran should work.""" 59 | obj = myclass_factory.myclass_create(REF) 60 | 61 | self.assertTrue(abs(obj.get_val() - REF) < TOL) 62 | 63 | obj.set_val(2.0 * REF) 64 | 65 | self.assertTrue(abs(obj.get_val() - 2.0 * REF) < TOL) 66 | 67 | del obj 68 | 69 | def test_class_member_access(self): 70 | """Direct access of member variables.""" 71 | obj = myclass_factory.myclass_create(REF) 72 | 73 | self.assertTrue(abs(obj.val - REF) < TOL) 74 | 75 | obj.val = 2.0 * REF 76 | 77 | self.assertTrue(abs(obj.val - 2.0 * REF) < TOL) 78 | 79 | del obj 80 | 81 | 82 | if __name__ == "__main__": 83 | unittest.main() 84 | -------------------------------------------------------------------------------- /examples/issue254_getter/.f2py_f2cmap: -------------------------------------------------------------------------------- 1 | {'complex': {'4': 'complex_float', 2 | '8': 'complex_double', 3 | 'complex_kind': 'complex_double', 4 | 'dp': 'complex_double', 5 | 'kind1.d0': 'complex_double', 6 | 'kind1d0': 'complex_double'}, 7 | 'real': {'4': 'float', 8 | '8': 'double', 9 | 'dp': 'double', 10 | 'kind1.d0': 'double', 11 | 'kind1d0': 'double', 12 | 'real_kind': 'double', 13 | 'sp': 'float'}} 14 | -------------------------------------------------------------------------------- /examples/issue254_getter/KIMDispersionEquation.f90: -------------------------------------------------------------------------------- 1 | module KIMDispersionEquation_module 2 | implicit none 3 | 4 | ! Type for options 5 | type :: OptionsType 6 | real(8) :: omega 7 | ! Add other fields as needed 8 | end type OptionsType 9 | 10 | ! Abstract base type 11 | type, abstract :: KIMDispersionEquation 12 | contains 13 | procedure(initialize_interface), deferred :: initialize 14 | end type KIMDispersionEquation 15 | 16 | ! Abstract interface for the initialize method 17 | abstract interface 18 | subroutine initialize_interface(this, options) 19 | import :: KIMDispersionEquation, OptionsType 20 | class(KIMDispersionEquation), intent(inout) :: this 21 | type(OptionsType), intent(in) :: options 22 | end subroutine initialize_interface 23 | end interface 24 | 25 | end module KIMDispersionEquation_module 26 | -------------------------------------------------------------------------------- /examples/issue254_getter/KIMDispersion_Horton.f90: -------------------------------------------------------------------------------- 1 | module KIMDispersion_Horton_module 2 | use KIMDispersionEquation_module 3 | implicit none 4 | 5 | type, extends(KIMDispersionEquation) :: KIMDispersion_Horton 6 | type(OptionsType) :: options 7 | contains 8 | procedure :: initialize => initialize_KIMDispersion_Horton 9 | end type KIMDispersion_Horton 10 | 11 | contains 12 | 13 | subroutine initialize_KIMDispersion_Horton(this, options) 14 | class(KIMDispersion_Horton), intent(inout) :: this 15 | type(OptionsType), intent(in) :: options 16 | 17 | this%options = options 18 | end subroutine initialize_KIMDispersion_Horton 19 | 20 | end module KIMDispersion_Horton_module 21 | -------------------------------------------------------------------------------- /examples/issue254_getter/Makefile: -------------------------------------------------------------------------------- 1 | FC = gfortran 2 | FCFLAGS = -fPIC 3 | PYTHON = python 4 | 5 | %.o : %.f90 6 | ${FC} ${FCFLAGS} -c $< -o $@ 7 | 8 | all: KIMDispersionEquation.o KIMDispersion_Horton.o 9 | f90wrap -m itest -k .f2py_f2cmap -P KIMDispersionEquation.f90 KIMDispersion_Horton.f90 -v 10 | f2py-f90wrap --build-dir . -c -m _itest --f2cmap .f2py_f2cmap \ 11 | KIMDispersionEquation.o KIMDispersion_Horton.o \ 12 | f90wrap_KIMDispersionEquation.f90 f90wrap_KIMDispersion_Horton.f90 13 | 14 | test: all 15 | $(PYTHON) run.py 16 | 17 | clean: 18 | rm -f *.o f90wrap*.f90 *.so *.mod 19 | rm -rf src.*/ 20 | rm -rf itest/ 21 | -rm -rf src.*/ .libs/ __pycache__/ 22 | 23 | 24 | .PHONY: all clean 25 | -------------------------------------------------------------------------------- /examples/issue254_getter/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := itest 4 | 5 | test: build 6 | $(PYTHON) run.py 7 | -------------------------------------------------------------------------------- /examples/issue254_getter/run.py: -------------------------------------------------------------------------------- 1 | import itest 2 | 3 | options = itest.kimdispersionequation_module.OptionsType() 4 | options.omega = 0.5 5 | 6 | obj = itest.kimdispersion_horton_module.KIMDispersion_Horton() 7 | obj.initialize(options) 8 | 9 | assert(abs(obj.options.omega - 0.5) < 1e-13) 10 | -------------------------------------------------------------------------------- /examples/issue258_derived_type_attributes/Makefile: -------------------------------------------------------------------------------- 1 | FC = gfortran 2 | FCFLAGS = -fPIC 3 | PYTHON = python 4 | 5 | all: test 6 | 7 | test: wrapper 8 | $(PYTHON) test.py 9 | 10 | wrapper: wrap-dta_tt wrap-dta_tc wrap-dta_ct wrap-dta_cc 11 | 12 | wrap-%: f90wrap_%.f90 %.o 13 | f2py-f90wrap --build-dir . -c -m _$* --opt="-O0 -g" f90wrap_$*.f90 $*.o 14 | 15 | f90wrap_%.f90 %.py: %.o %.f90 16 | f90wrap -m $* $*.f90 -v 17 | 18 | %.o: %.f90 19 | $(FC) $(FCFLAGS) -c -g -O0 $< -o $@ 20 | 21 | clean: 22 | rm -f *.o f90wrap*.f90 *.so *.mod *.x .f2py_f2cmap 23 | rm -rf src.*/ .libs/ __pycache__/ 24 | rm -rf dta_*.py 25 | -------------------------------------------------------------------------------- /examples/issue258_derived_type_attributes/dta_cc.f90: -------------------------------------------------------------------------------- 1 | module dta_cc 2 | implicit none 3 | 4 | type :: t_inner 5 | integer :: value 6 | contains 7 | procedure :: print => t_inner_print 8 | end type t_inner 9 | 10 | type :: t_outer 11 | integer :: value 12 | type(t_inner) :: inner 13 | contains 14 | procedure :: print => t_outer_print 15 | end type t_outer 16 | 17 | interface t_inner 18 | module procedure new_inner 19 | end interface t_inner 20 | 21 | interface t_outer 22 | module procedure new_outer 23 | end interface t_outer 24 | 25 | contains 26 | 27 | function new_inner(value) result(inner) 28 | type(t_inner) :: inner 29 | integer, intent(in) :: value 30 | 31 | inner%value = value 32 | end function new_inner 33 | 34 | function new_outer(value, inner) result(node) 35 | type(t_outer) :: node 36 | integer, intent(in) :: value 37 | type(t_inner), intent(in) :: inner 38 | 39 | node%inner = inner 40 | node%value = value 41 | end function new_outer 42 | 43 | subroutine t_inner_print(inner) 44 | class(t_inner), intent(in) :: inner 45 | 46 | write(*,*) "value:", inner%value 47 | end subroutine t_inner_print 48 | 49 | subroutine t_outer_print(outer) 50 | class(t_outer), intent(in) :: outer 51 | 52 | write(*,*) "value:", outer%value, " inner value:", outer%inner%value 53 | end subroutine t_outer_print 54 | 55 | function get_outer_inner(outer) result(inner) 56 | type(t_outer), intent(in) :: outer 57 | type(t_inner) :: inner 58 | 59 | inner = outer%inner 60 | end function get_outer_inner 61 | 62 | end module dta_cc 63 | -------------------------------------------------------------------------------- /examples/issue258_derived_type_attributes/dta_ct.f90: -------------------------------------------------------------------------------- 1 | module dta_ct 2 | implicit none 3 | 4 | type :: t_inner 5 | integer :: value 6 | end type t_inner 7 | 8 | type :: t_outer 9 | integer :: value 10 | type(t_inner) :: inner 11 | contains 12 | procedure :: print => t_outer_print 13 | end type t_outer 14 | 15 | interface t_inner 16 | module procedure new_inner 17 | end interface t_inner 18 | 19 | interface t_outer 20 | module procedure new_outer 21 | end interface t_outer 22 | 23 | contains 24 | 25 | function new_inner(value) result(inner) 26 | type(t_inner) :: inner 27 | integer, intent(in) :: value 28 | 29 | inner%value = value 30 | end function new_inner 31 | 32 | function new_outer(value, inner) result(node) 33 | type(t_outer) :: node 34 | integer, intent(in) :: value 35 | type(t_inner), intent(in) :: inner 36 | 37 | node%inner = inner 38 | node%value = value 39 | end function new_outer 40 | 41 | subroutine t_outer_print(outer) 42 | class(t_outer), intent(in) :: outer 43 | 44 | write(*,*) "value:", outer%value, " inner value:", outer%inner%value 45 | end subroutine t_outer_print 46 | 47 | function get_outer_inner(outer) result(inner) 48 | type(t_outer), intent(in) :: outer 49 | type(t_inner) :: inner 50 | 51 | inner = outer%inner 52 | end function get_outer_inner 53 | 54 | end module dta_ct 55 | -------------------------------------------------------------------------------- /examples/issue258_derived_type_attributes/dta_tc.f90: -------------------------------------------------------------------------------- 1 | module dta_tc 2 | implicit none 3 | 4 | type :: t_inner 5 | integer :: value 6 | contains 7 | procedure :: print => t_inner_print 8 | end type t_inner 9 | 10 | type :: t_outer 11 | integer :: value 12 | type(t_inner) :: inner 13 | end type t_outer 14 | 15 | interface t_inner 16 | module procedure new_inner 17 | end interface t_inner 18 | 19 | interface t_outer 20 | module procedure new_outer 21 | end interface t_outer 22 | 23 | contains 24 | 25 | function new_inner(value) result(inner) 26 | type(t_inner) :: inner 27 | integer, intent(in) :: value 28 | 29 | inner%value = value 30 | end function new_inner 31 | 32 | function new_outer(value, inner) result(node) 33 | type(t_outer) :: node 34 | integer, intent(in) :: value 35 | type(t_inner), intent(in) :: inner 36 | 37 | node%inner = inner 38 | node%value = value 39 | end function new_outer 40 | 41 | subroutine t_inner_print(inner) 42 | class(t_inner), intent(in) :: inner 43 | 44 | write(*,*) "value:", inner%value 45 | end subroutine t_inner_print 46 | 47 | function get_outer_inner(outer) result(inner) 48 | type(t_outer), intent(in) :: outer 49 | type(t_inner) :: inner 50 | 51 | inner = outer%inner 52 | end function get_outer_inner 53 | 54 | end module dta_tc 55 | -------------------------------------------------------------------------------- /examples/issue258_derived_type_attributes/dta_tt.f90: -------------------------------------------------------------------------------- 1 | module dta_tt 2 | implicit none 3 | 4 | type :: t_inner 5 | integer :: value 6 | end type t_inner 7 | 8 | type :: t_outer 9 | integer :: value 10 | type(t_inner) :: inner 11 | end type t_outer 12 | 13 | interface t_inner 14 | module procedure new_inner 15 | end interface t_inner 16 | 17 | interface t_outer 18 | module procedure new_outer 19 | end interface t_outer 20 | 21 | contains 22 | 23 | function new_inner(value) result(inner) 24 | type(t_inner) :: inner 25 | integer, intent(in) :: value 26 | 27 | inner%value = value 28 | end function new_inner 29 | 30 | function new_outer(value, inner) result(node) 31 | type(t_outer) :: node 32 | integer, intent(in) :: value 33 | type(t_inner), intent(in) :: inner 34 | 35 | node%inner = inner 36 | node%value = value 37 | end function new_outer 38 | 39 | function get_outer_inner(outer) result(inner) 40 | type(t_outer), intent(in) :: outer 41 | type(t_inner) :: inner 42 | 43 | inner = outer%inner 44 | end function get_outer_inner 45 | 46 | end module dta_tt 47 | -------------------------------------------------------------------------------- /examples/issue258_derived_type_attributes/test.py: -------------------------------------------------------------------------------- 1 | """Test derived type as attributes of other derived types. 2 | 3 | Check all combinations of type / class (polymorphic derived type) for the outer and intner derived types.""" 4 | import dta_tt 5 | import dta_ct 6 | import dta_tc 7 | import dta_cc 8 | 9 | for mod, o, i in [ 10 | (dta_tt.dta_tt, "t", "t"), 11 | (dta_ct.dta_ct, "c", "t"), 12 | (dta_tc.dta_tc, "t", "c"), 13 | (dta_cc.dta_cc, "c", "c"), 14 | ]: 15 | print("Testing module:", mod) 16 | inner1 = mod.t_inner(1) 17 | assert inner1.value == 1 18 | inner2 = mod.t_inner(2) 19 | assert inner2.value == 2 20 | if i == "c": 21 | inner1.print() 22 | inner2.print() 23 | 24 | outer = mod.t_outer(10, inner1) 25 | assert outer.value == 10 26 | assert outer.inner.value == 1 27 | 28 | outer.inner = inner2 29 | assert outer.inner.value == 2 30 | if o == "c": 31 | outer.print() 32 | 33 | -------------------------------------------------------------------------------- /examples/issue32/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | F90 = gfortran 3 | FPP = gfortran -E 4 | F90FLAGS = -x f95-cpp-input -fPIC 5 | CFLAGS = -fPIC 6 | PYTHON = python 7 | 8 | all: test 9 | 10 | test.o: test.f90 11 | $(F90) $(F90FLAGS) -c $< 12 | 13 | mod: test.o 14 | f90wrap -m test ./test.f90 15 | f2py-f90wrap -c -m _test f90wrap_toplevel.f90 test.o 16 | 17 | test: mod 18 | $(PYTHON) -c 'import test; test.foo(1.0, 2)' 19 | 20 | clean: 21 | -rm test.py 22 | -rm f90wrap*.f90 *.o *.pyc *.mod 23 | -rm _test*.so _testpkg*.so 24 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 25 | 26 | -------------------------------------------------------------------------------- /examples/issue32/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := test 4 | 5 | test: build 6 | $(PYTHON) -c 'import test; test.foo(1.0, 2)' 7 | -------------------------------------------------------------------------------- /examples/issue32/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': {'': 'float', 3 | '8': 'double'} 4 | } 5 | -------------------------------------------------------------------------------- /examples/issue32/test.f90: -------------------------------------------------------------------------------- 1 | subroutine foo(a,b) 2 | real(kind=8), intent(in) :: a 3 | integer :: b 4 | print *, a, b, a*b 5 | end subroutine foo 6 | -------------------------------------------------------------------------------- /examples/issue41_abstract_classes/Makefile: -------------------------------------------------------------------------------- 1 | FC = gfortran 2 | FCFLAGS = -fPIC 3 | PYTHON = python 4 | 5 | all: test test_abstract_classes.x 6 | 7 | test: wrapper 8 | $(PYTHON) run.py 9 | 10 | test_abstract_classes.x: main.f90 myclass_base.o myclass_impl.o myclass_impl2.o myclass_factory.o 11 | $(FC) $(FCFLAGS) -o $@ $^ 12 | 13 | wrapper: myclass_base.o myclass_impl.o myclass_impl2.o myclass_factory.o 14 | f90wrap -m itest -P myclass_base.f90 myclass_impl.f90 myclass_impl2.f90 myclass_factory.f90 -v 15 | f2py-f90wrap --build-dir . -c -m _itest --opt="-O0 -g" \ 16 | f90wrap_myclass_base.f90 f90wrap_myclass_impl.f90 f90wrap_myclass_impl2.f90 f90wrap_myclass_factory.f90 \ 17 | myclass_base.o myclass_impl.o myclass_impl2.o myclass_factory.o 18 | 19 | %.o : %.f90 20 | $(FC) $(FCFLAGS) -c -g -O0 $< -o $@ 21 | 22 | clean: 23 | rm -f *.o f90wrap*.f90 *.so *.mod *.x 24 | rm -rf src.*/ 25 | rm -rf itest/ 26 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 27 | -------------------------------------------------------------------------------- /examples/issue41_abstract_classes/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := itest 4 | 5 | test: build 6 | $(PYTHON) run.py 7 | -------------------------------------------------------------------------------- /examples/issue41_abstract_classes/main.f90: -------------------------------------------------------------------------------- 1 | program main 2 | use myclass_factory, only: create_myclass 3 | use myclass_base, only: myclass_t 4 | implicit none 5 | 6 | print *, "Start" 7 | 8 | call test() 9 | 10 | print *, "Done" 11 | 12 | contains 13 | 14 | subroutine test 15 | real :: x 16 | class(myclass_t), allocatable :: myobject 17 | 18 | myobject = create_myclass("impl") 19 | call myobject%get_value(x) 20 | 21 | print *, "Value: ", x 22 | end subroutine test 23 | 24 | end program main 25 | -------------------------------------------------------------------------------- /examples/issue41_abstract_classes/myclass_base.f90: -------------------------------------------------------------------------------- 1 | module myclass_base 2 | implicit none 3 | 4 | type, abstract :: myclass_t 5 | contains 6 | procedure(get_value_i), deferred :: get_value 7 | end type myclass_t 8 | 9 | abstract interface 10 | subroutine get_value_i(self, value) 11 | import myclass_t 12 | class(myclass_t), intent(in) :: self 13 | real, intent(out) :: value 14 | end subroutine get_value_i 15 | end interface 16 | 17 | end module myclass_base 18 | -------------------------------------------------------------------------------- /examples/issue41_abstract_classes/myclass_factory.f90: -------------------------------------------------------------------------------- 1 | module myclass_factory 2 | 3 | use myclass_base, only: myclass_t 4 | use myclass_impl, only: myclass_impl_t 5 | use myclass_impl2, only: myclass_impl2_t 6 | implicit none 7 | 8 | contains 9 | 10 | function create_myclass(impl_type) result(myobject) 11 | class(myclass_t), allocatable :: myobject 12 | 13 | character(*), intent(in) :: impl_type 14 | 15 | select case(impl_type) 16 | case("impl") 17 | allocate(myclass_impl_t :: myobject) 18 | case("impl2") 19 | allocate(myclass_impl2_t :: myobject) 20 | case default 21 | print *, "create_field_can: Unknown implementation: ", impl_type 22 | error stop 23 | end select 24 | end function create_myclass 25 | 26 | end module myclass_factory 27 | -------------------------------------------------------------------------------- /examples/issue41_abstract_classes/myclass_impl.f90: -------------------------------------------------------------------------------- 1 | module myclass_impl 2 | 3 | use myclass_base, only: myclass_t 4 | implicit none 5 | 6 | type, extends(myclass_t) :: myclass_impl_t 7 | contains 8 | procedure :: get_value => get_value_impl 9 | final :: myclass_impl_destroy 10 | end type myclass_impl_t 11 | 12 | contains 13 | 14 | subroutine get_value_impl(self, value) 15 | class(myclass_impl_t), intent(in) :: self 16 | real, intent(out) :: value 17 | 18 | value = 1.0 19 | end subroutine get_value_impl 20 | 21 | subroutine myclass_impl_destroy(self) 22 | type(myclass_impl_t), intent(inout) :: self 23 | 24 | print *, "Finalising myclass_impl_t" 25 | end subroutine myclass_impl_destroy 26 | 27 | end module myclass_impl 28 | -------------------------------------------------------------------------------- /examples/issue41_abstract_classes/myclass_impl2.f90: -------------------------------------------------------------------------------- 1 | module myclass_impl2 2 | 3 | use myclass_base, only: myclass_t 4 | implicit none 5 | 6 | type, extends(myclass_t) :: myclass_impl2_t 7 | contains 8 | procedure :: get_value => get_value_impl2 9 | final :: myclass_impl2_destroy 10 | end type myclass_impl2_t 11 | 12 | contains 13 | 14 | subroutine get_value_impl2(self, value) 15 | class(myclass_impl2_t), intent(in) :: self 16 | real, intent(out) :: value 17 | 18 | value = 2.0 19 | end subroutine get_value_impl2 20 | 21 | subroutine myclass_impl2_destroy(self) 22 | type(myclass_impl2_t), intent(inout) :: self 23 | 24 | print *, "Finalising myclass_impl2_t" 25 | end subroutine myclass_impl2_destroy 26 | 27 | end module myclass_impl2 28 | -------------------------------------------------------------------------------- /examples/issue41_abstract_classes/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import itest 3 | 4 | REF = 1.0 5 | TOL = 1.0e-6 6 | 7 | obj = itest.myclass_factory.create_myclass("impl") 8 | 9 | output = obj.get_value() 10 | assert(abs(output-REF). 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | # -*- coding: utf-8 -*- 24 | """ 25 | @author: Caoxiang Zhu 26 | """ 27 | 28 | from __future__ import print_function 29 | 30 | import unittest 31 | 32 | import numpy as np 33 | 34 | import keywordr_rename as lib 35 | 36 | 37 | def test(): 38 | a = 3 39 | # normal type 40 | assert lib.global_.abc == 0 41 | # rename keyword in normal types 42 | assert lib.global_.lambda_ == 1 43 | # rename keyword in derived types 44 | y = lib.global_.class2() 45 | assert y.x == 456 46 | # rename keyword in array 47 | assert len(lib.global_.with_) == 9 48 | # rename keyword in subroutine 49 | lib.global_.is_(a) 50 | assert lib.global_.abc == a 51 | # rename keyword in function 52 | assert lib.in_(a) == a + 1 53 | 54 | 55 | if __name__ == "__main__": 56 | test() 57 | -------------------------------------------------------------------------------- /examples/kind_map_default/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | CC = gcc 6 | F90 = gfortran 7 | PYTHON = python 8 | CFLAGS = -fPIC 9 | F90FLAGS = -fPIC 10 | PY_MOD = pywrapper 11 | F90_SRC = main.f90 12 | OBJ = $(F90_SRC:.f90=.o) 13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC}) 14 | WRAPFLAGS = -v --kind-map kind.map 15 | F2PYFLAGS = --build-dir build 16 | F90WRAP = f90wrap 17 | F2PY = f2py-f90wrap 18 | .PHONY: all clean 19 | 20 | all: test 21 | 22 | clean: 23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/ 24 | 25 | main.o: ${F90_SRC} 26 | ${F90} ${F90FLAGS} -c $< -o $@ 27 | 28 | %.o: %.f90 29 | ${F90} ${F90FLAGS} -c $< -o $@ 30 | 31 | ${F90WRAP_SRC}: ${OBJ} 32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC} 33 | 34 | f2py: ${F90WRAP_SRC} 35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o 36 | 37 | test: f2py 38 | ${PYTHON} tests.py 39 | -------------------------------------------------------------------------------- /examples/kind_map_default/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper 4 | WRAPFLAGS += --kind-map kind.map 5 | 6 | test: build 7 | $(PYTHON) tests.py 8 | -------------------------------------------------------------------------------- /examples/kind_map_default/kind.map: -------------------------------------------------------------------------------- 1 | {\ 2 | 'real':{'8':'double'},\ 3 | } 4 | -------------------------------------------------------------------------------- /examples/kind_map_default/main.f90: -------------------------------------------------------------------------------- 1 | program main 2 | 3 | end program 4 | 5 | module m_test 6 | 7 | implicit none 8 | public 9 | 10 | contains 11 | 12 | function test_real(in_real) result(out_int) 13 | real :: in_real 14 | integer :: out_int 15 | out_int = 1 16 | end function test_real 17 | 18 | function test_real4(in_real) result(out_int) 19 | real(kind=4) :: in_real 20 | integer :: out_int 21 | out_int = 2 22 | end function test_real4 23 | 24 | function test_real8(in_real) result(out_int) 25 | real(kind=8) :: in_real 26 | integer :: out_int 27 | out_int = 3 28 | end function test_real8 29 | 30 | end module m_test 31 | -------------------------------------------------------------------------------- /examples/kind_map_default/tests.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from pywrapper import m_test 4 | 5 | class TestKindMap(unittest.TestCase): 6 | 7 | def test_real(self): 8 | _ = m_test.test_real(1.) 9 | 10 | def test_real4(self): 11 | _ = m_test.test_real4(2.) 12 | 13 | def test_real8(self): 14 | _ = m_test.test_real8(3.) 15 | 16 | if __name__ == '__main__': 17 | unittest.main() 18 | -------------------------------------------------------------------------------- /examples/long_subroutine_name/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | CC = gcc 6 | F90 = gfortran 7 | PYTHON = python 8 | CFLAGS = -fPIC 9 | F90FLAGS = -fPIC 10 | PY_MOD = pywrapper 11 | F90_SRC = main.f90 12 | OBJ = $(F90_SRC:.f90=.o) 13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC}) 14 | WRAPFLAGS = -v 15 | F2PYFLAGS = --build-dir build 16 | F90WRAP = f90wrap 17 | F2PY = f2py-f90wrap 18 | .PHONY: all clean 19 | 20 | all: test 21 | 22 | clean: 23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/ 24 | 25 | main.o: ${F90_SRC} 26 | ${F90} ${F90FLAGS} -c $< -o $@ 27 | 28 | %.o: %.f90 29 | ${F90} ${F90FLAGS} -c $< -o $@ 30 | 31 | ${F90WRAP_SRC}: ${OBJ} 32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC} 33 | 34 | f2py: ${F90WRAP_SRC} 35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o 36 | 37 | test: f2py 38 | ${PYTHON} test.py 39 | -------------------------------------------------------------------------------- /examples/long_subroutine_name/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper 4 | 5 | test: build 6 | $(PYTHON) test.py 7 | -------------------------------------------------------------------------------- /examples/long_subroutine_name/main.f90: -------------------------------------------------------------------------------- 1 | module m_long_subroutine_name 2 | 3 | implicit none 4 | 5 | integer :: m_long_subroutine_name_integer 6 | 7 | type m_long_subroutine_name_type 8 | 9 | integer :: m_long_subroutine_name_type_integer 10 | integer, dimension(10) :: m_long_subroutine_name_type_integer_array 11 | 12 | end type m_long_subroutine_name_type 13 | 14 | type m_long_subroutine_name_type_2 15 | 16 | type(m_long_subroutine_name_type), dimension(10) :: m_long_subroutine_name_type_2_type_array 17 | 18 | end type m_long_subroutine_name_type_2 19 | 20 | contains 21 | 22 | subroutine m_long_subroutine_name_subroutine() 23 | end subroutine m_long_subroutine_name_subroutine 24 | 25 | end module m_long_subroutine_name -------------------------------------------------------------------------------- /examples/long_subroutine_name/test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from pywrapper import m_long_subroutine_name 4 | 5 | class TestLongSubroutineName(unittest.TestCase): 6 | 7 | def test_long_subroutine_name(self): 8 | 9 | m_long_subroutine_name.m_long_subroutine_name_integer = 42 10 | 11 | typ = m_long_subroutine_name.m_long_subroutine_name_type() 12 | typ.m_long_subroutine_name_type_name_integer = 42 13 | typ.m_long_subroutine_name_type_name_integer_array = 42 14 | 15 | typ2 = m_long_subroutine_name.m_long_subroutine_name_type_2() 16 | typ2.m_long_subroutine_name_type_2_type_array[0].m_long_subroutine_name_type_integer = 42 17 | typ2.m_long_subroutine_name_type_2_type_array[0].m_long_subroutine_name_type_integer_array = 42 18 | 19 | m_long_subroutine_name.m_long_subroutine_name_subroutine() 20 | 21 | if __name__ == '__main__': 22 | 23 | unittest.main() 24 | -------------------------------------------------------------------------------- /examples/make.meson.inc: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | F90 = gfortran 3 | F90FLAGS = -fPIC -xf95-cpp-input 4 | FPP = gfortran -E 5 | PYTHON = python 6 | #NAME = name 7 | WRAPFLAGS := -v 8 | F2PYFLAGS := --lower 9 | 10 | .SUFFIXES: .f90 .fpp .f 11 | 12 | .PHONY: all clean 13 | 14 | all: test 15 | 16 | UNAME = $(shell uname) 17 | ifeq (${UNAME}, Darwin) 18 | SEDI := gsed -i 19 | else 20 | SEDI := sed -i 21 | endif 22 | SEDA := "/additional_flags/a add_project_arguments('$$item', language: 'fortran')" 23 | 24 | LIBSRC_WRAP_FILES := $(filter-out f90wrap_%.f90, $(wildcard *.f90 *.f *.F90)) 25 | LIBSRC_WRAP_FPP_FILES := $(LIBSRC_WRAP_FILES:%.f90=%.fpp) 26 | 27 | 28 | .f90.fpp: 29 | ${FPP} ${F90FLAGS} $< -o $@ 30 | .f.fpp: 31 | ${FPP} ${F90FLAGS} $< -o $@ 32 | 33 | 34 | extension: ${LIBSRC_WRAP_FPP_FILES} 35 | ${PYTHON} -m f90wrap -m ${NAME} ${LIBSRC_WRAP_FPP_FILES} ${WRAPFLAGS} 36 | ${PYTHON} -m f90wrap --f2py-f90wrap -m _${NAME} f90wrap_*.f90 ${F2PYFLAGS} 37 | 38 | build: extension 39 | @echo 'Using via meson...' 40 | @cp ../meson.build.template meson.build 41 | ${SEDI} "s/\$${name}/'_${NAME}'/" meson.build 42 | ${SEDI} "s@\$${source}@'${LIBSRC_WRAP_FILES} $(shell ls f90wrap_*.f90)'@" meson.build 43 | for item in ${F90FLAGS}; do \ 44 | ${SEDI} ${SEDA} meson.build; done 45 | meson setup --wipe _build_dir 46 | meson compile -C _build_dir 47 | mv _build_dir/_${NAME}*.so . 48 | 49 | clean: 50 | -rm -f f90wrap_*.f90 *.o *.mod *.fpp *.a 51 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 52 | -rm -rf _${NAME}* ${NAME}*/ ${NAME}.py 53 | -rm -rf _build_dir 54 | -rm -f meson.build* 55 | -------------------------------------------------------------------------------- /examples/meson.build.template: -------------------------------------------------------------------------------- 1 | project('fib', 2 | ['c', 'fortran'], 3 | version : '0.1', 4 | meson_version: '>= 1.1.0', 5 | default_options : [ 6 | 'warning_level=1', 7 | 'buildtype=release' 8 | ]) 9 | 10 | add_languages('fortran', native: false) 11 | ff = meson.get_compiler('fortran') 12 | if ff.has_argument('-Wno-conversion') 13 | add_project_arguments('-Wno-conversion', language: 'fortran') 14 | endif 15 | 16 | py = import('python').find_installation(pure: false) 17 | py_dep = py.dependency() 18 | 19 | incdir_numpy = run_command(py, 20 | ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'], 21 | check : true 22 | ).stdout().strip() 23 | 24 | incdir_f2py = run_command(py, 25 | ['-c', 'import os; os.chdir(".."); import numpy.f2py; print(numpy.f2py.get_include())'], 26 | check : true 27 | ).stdout().strip() 28 | 29 | fortranobject_c = incdir_f2py / 'fortranobject.c' 30 | inc_np = include_directories(incdir_numpy, incdir_f2py) 31 | quadmath_dep = ff.find_library('quadmath', required: false) 32 | 33 | name = ${name} 34 | source = ${source} 35 | source = source.split() 36 | source += [ name+'module.c', fortranobject_c] 37 | 38 | # additional_flags 39 | 40 | py.extension_module(name, 41 | source, 42 | include_directories: inc_np, 43 | dependencies : [py_dep, quadmath_dep], 44 | install : true 45 | ) 46 | -------------------------------------------------------------------------------- /examples/mockderivetype/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | F90 = gfortran 3 | FPP = gfortran -E 4 | F90FLAGS = -x f95-cpp-input -fPIC 5 | CFLAGS = -fPIC 6 | PYTHON = python 7 | 8 | UNAME = $(shell uname) 9 | 10 | ifeq (${UNAME}, Darwin) 11 | LIBTOOL = libtool -static -o 12 | else 13 | LIBTOOL = ar src 14 | endif 15 | 16 | LIBSRC_SOURCES = leveltwomod define fwrap 17 | 18 | LIBSRC_FILES = $(addsuffix .f90,${LIBSRC_SOURCES}) 19 | LIBSRC_OBJECTS = $(addsuffix .o,${LIBSRC_SOURCES}) 20 | LIBSRC_FPP_FILES = $(addsuffix .fpp,${LIBSRC_SOURCES}) 21 | 22 | .SUFFIXES: .f90 .fpp 23 | 24 | .PHONY: all clean test 25 | 26 | all: test 27 | 28 | clean: 29 | -rm -f ${LIBSRC_OBJECTS} libsrc.a _mockdt*.so _mockdtpkg*.so *.mod f90wrap*.* *.fpp 30 | -rm -rf mockdtpkg/ 31 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 32 | 33 | .f90.o: 34 | ${F90} ${F90FLAGS} -c $< -o $@ 35 | 36 | .c.o: 37 | ${CC} ${CFLAGS} -c $< -o $@ 38 | 39 | .f90.fpp: 40 | ${FPP} ${F90FLAGS} $< -o $@ 41 | 42 | libsrc.a: ${LIBSRC_OBJECTS} 43 | ${LIBTOOL} $@ $? 44 | 45 | _mockdt.so: libsrc.a ${LIBSRC_FPP_FILES} 46 | f90wrap -m mockdt ${LIBSRC_FPP_FILES} -k kind_map -v 47 | f2py-f90wrap --build-dir . -c -m _mockdt -L. -lsrc f90wrap*.f90 48 | 49 | _mockdtpkg.so: libsrc.a ${LIBSRC_FPP_FILES} 50 | f90wrap -m mockdtpkg ${LIBSRC_FPP_FILES} -k kind_map -v -P 51 | f2py-f90wrap --build-dir . -c -m _mockdtpkg -L. -lsrc f90wrap*.f90 52 | 53 | test: _mockdt.so _mockdtpkg.so 54 | $(PYTHON) test.py 55 | 56 | -------------------------------------------------------------------------------- /examples/mockderivetype/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := mockdt 4 | WRAPFLAGS += -k kind_map 5 | 6 | test: build 7 | $(PYTHON) test.py 8 | -------------------------------------------------------------------------------- /examples/mockderivetype/define.f90: -------------------------------------------------------------------------------- 1 | module define_a_type 2 | use leveltwomod 3 | 4 | !% This type will be wrapped as it is used. 5 | type atype 6 | logical :: bool 7 | integer :: integ 8 | real(8) :: rl 9 | real(8) :: vec(10) 10 | type(leveltwo) :: dtype 11 | end type atype 12 | 13 | real(8) :: a_set_real = 4.d0 14 | logical :: a_set_bool = .true. 15 | 16 | !% This type will also be wrapped 17 | type unused_type 18 | real(8) :: rl = 3.d0 19 | end type 20 | 21 | contains 22 | 23 | subroutine use_set_vars() 24 | if(a_set_bool)then 25 | call top_level(a_set_real,a_set_real) 26 | a_set_bool = .false. 27 | endif 28 | end subroutine use_set_vars 29 | 30 | function return_a_type_func() result(a) 31 | type(atype) :: a 32 | 33 | a%bool = .true. 34 | a%integ = 42 35 | 36 | end function return_a_type_func 37 | 38 | subroutine return_a_type_sub(a) 39 | type(atype), intent(out) :: a 40 | 41 | a%bool = .true. 42 | a%integ = 42 43 | 44 | end subroutine return_a_type_sub 45 | 46 | end module 47 | 48 | !% Example of a top-level subroutine. 49 | subroutine top_level(in, out) 50 | real(8), intent(in) :: in 51 | real(8), intent(out) :: out 52 | out = 85.d0*in 53 | end subroutine top_level 54 | 55 | !% Another module, defining a horrible type 56 | module horrible 57 | use leveltwomod 58 | real(8) :: a_real 59 | type horrible_type 60 | real(8), allocatable :: x(:,:,:) 61 | end type 62 | end module 63 | 64 | -------------------------------------------------------------------------------- /examples/mockderivetype/fwrap.f90: -------------------------------------------------------------------------------- 1 | !% This file contains a single module with several module-level vars 2 | !% with one of them a derived type, which is defined in the 'base library'. 3 | 4 | #define type(x) TYPE(x), target 5 | 6 | module use_a_type 7 | use define_a_type !% This is the module which defines the type 'atype' 8 | type(atype) :: P !% A variable with this type. NB: target attribute needed to allow access from Python 9 | type(atype), allocatable :: P_array(:) !% Array of derived types, also wrapped 10 | real(8), allocatable :: vector(:) !% It also contains allocatable arrays 11 | 12 | !% For simplicity, P has a variable of each of several base types. 13 | !% That is, a logical, real, integer, real array, and a 14 | !% derived type from a different module. 15 | 16 | contains 17 | 18 | !% Here's a routine that does something 19 | subroutine do_stuff(factor,out) 20 | real(8), intent(in) :: factor 21 | real(8), intent(out):: out 22 | 23 | integer :: i 24 | 25 | if (allocated(vector)) deallocate(vector) 26 | allocate(vector(P%integ)) 27 | 28 | ! This construct uses the real, integer and logical vars of P 29 | if (P%bool)then 30 | do i=1,P%integ 31 | out = factor*P%rl 32 | P%rl = out 33 | end do 34 | else 35 | do i=1,P%integ 36 | out = P%rl/factor 37 | P%rl = out 38 | end do 39 | end if 40 | 41 | ! This construct fills out the allocatable module vector 42 | do i=1,P%integ 43 | vector(i) = out/(i*factor) 44 | end do 45 | 46 | !This construct uses the array and derived type vars of P 47 | do i=1,size(P%vec) 48 | P%vec(i) = P%dtype%rl*i 49 | end do 50 | 51 | ! allocate P_array and copy data into it from P 52 | if (allocated(P_array)) deallocate(P_array) 53 | allocate(P_array(3)) 54 | do i=1,3 55 | P_array(i) = P 56 | end do 57 | 58 | call use_set_vars() 59 | 60 | end subroutine do_stuff 61 | 62 | subroutine not_used(x,y) 63 | real(8), intent(in) :: x 64 | real(8), intent(out) :: y 65 | type(unused_type) :: T 66 | 67 | y = P%rl * x 68 | y = T%rl * y 69 | end subroutine 70 | 71 | end module 72 | -------------------------------------------------------------------------------- /examples/mockderivetype/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': {'': 'float', 3 | '8': 'double', 4 | 'dp': 'double'}, 5 | 'complex' : {'': 'complex_float', 6 | '8': 'complex_double', 7 | 'dp': 'complex_double'}, 8 | 'integer' : {'': 'int', 9 | '8': 'long_long', 10 | 'dp': 'long_long' } 11 | } 12 | -------------------------------------------------------------------------------- /examples/mockderivetype/leveltwomod.f90: -------------------------------------------------------------------------------- 1 | module leveltwomod 2 | implicit none 3 | !% Define a type which is referenced by the primary used type, to make 4 | !% sure it is also wrapped (and we can access its elements). 5 | type leveltwo 6 | real(8) :: rl 7 | end type leveltwo 8 | 9 | end module leveltwomod 10 | -------------------------------------------------------------------------------- /examples/mockderivetype/readme.rst: -------------------------------------------------------------------------------- 1 | mockderivetype 2 | -------------- 3 | 4 | This example contains a number of "tests" of f90wrap's functionality. To run 5 | the tests, simply type "make" ("make clean" to restart). 6 | 7 | The tests that it contains include: 8 | * wrap a module containing a module-level variable which is a defined type 9 | * this defined type is defined in a separate, used, module. 10 | * the defined type itself references another defined type defined in another 11 | separate, used module. 12 | * the defined type also contain a logical, integer, real and vector. 13 | * tests that subroutines not explicitly provided are not wrapped. 14 | * tests that top-level subroutines are wrapped properly if provided. 15 | * tests that module-level variables in used modules are accessible 16 | * running "python test.py" after making the example tests the pythonic wrapper. 17 | 18 | -------------------------------------------------------------------------------- /examples/mod_arg_clash/Makefile: -------------------------------------------------------------------------------- 1 | FPP=gfortran 2 | #FPP=ifort 3 | FFLAGS=-fPIC 4 | PYTHON = python 5 | 6 | %.o : %.f90 7 | ${FPP} ${FFLAGS} -c $< -o $@ 8 | 9 | all: test.o 10 | f90wrap -m test -P test.f90 11 | f2py-f90wrap -c -m _test f90wrap_test.f90 test.o 12 | 13 | test: all 14 | $(PYTHON) tests.py 15 | 16 | clean: 17 | -rm *.o f90wrap*.f90 *.so *.mod 18 | -rm -r test/ 19 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 20 | 21 | -------------------------------------------------------------------------------- /examples/mod_arg_clash/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := test 4 | WRAPFLAGS += -P 5 | 6 | test: build 7 | $(PYTHON) tests.py 8 | -------------------------------------------------------------------------------- /examples/mod_arg_clash/test.f90: -------------------------------------------------------------------------------- 1 | 2 | module cell 3 | 4 | implicit none 5 | 6 | private 7 | 8 | type, public::unit_cell 9 | integer ::num_species 10 | character(len=8)::species_symbol 11 | end type unit_cell 12 | 13 | public::cell_dosomething 14 | 15 | contains 16 | 17 | subroutine cell_dosomething(cell, num_species, species_symbol) 18 | 19 | implicit none 20 | 21 | type(unit_cell), intent(inout) ::cell 22 | integer, intent(in) ::num_species 23 | character(len=8), intent(in) ::species_symbol 24 | 25 | cell%num_species=num_species 26 | cell%species_symbol=species_symbol 27 | 28 | return 29 | 30 | end subroutine cell_dosomething 31 | 32 | end module 33 | -------------------------------------------------------------------------------- /examples/mod_arg_clash/tests.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | from __future__ import print_function 24 | import test.cell 25 | 26 | c = test.cell.unit_cell() 27 | test.cell.cell_dosomething(c, 1, 'Si') 28 | print(c) 29 | -------------------------------------------------------------------------------- /examples/optional_args_issue53/Makefile: -------------------------------------------------------------------------------- 1 | FPP=gfortran 2 | #FPP=ifort 3 | FFLAGS=-fPIC 4 | PYTHON = python 5 | 6 | %.o : %.f90 7 | ${FPP} ${FFLAGS} -c $< -o $@ 8 | 9 | all: main.o 10 | f90wrap -m test -P main.f90 11 | f2py-f90wrap -c -m _test f90wrap_toplevel.f90 main.o 12 | 13 | test: all 14 | $(PYTHON) run.py 15 | 16 | clean: 17 | -rm *.o f90wrap*.f90 *.so *.mod 18 | -rm -r test/ 19 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 20 | 21 | -------------------------------------------------------------------------------- /examples/optional_args_issue53/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := test 4 | 5 | test: build 6 | $(PYTHON) run.py 7 | -------------------------------------------------------------------------------- /examples/optional_args_issue53/main.f90: -------------------------------------------------------------------------------- 1 | subroutine wrap(opt, def) 2 | implicit none 3 | 4 | integer :: def 5 | integer, optional :: opt 6 | 7 | print *, 'present(opt) = ', present(opt) 8 | print *, 'def = ', def 9 | 10 | if (present(opt)) print *, 'opt = ', opt 11 | 12 | end subroutine 13 | -------------------------------------------------------------------------------- /examples/optional_args_issue53/run.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | import test 24 | 25 | test.wrap(1) # default only 26 | test.wrap(1, 2) # default and optional 27 | test.wrap(def_=1, opt=3) # kwarg form -------------------------------------------------------------------------------- /examples/optional_derived_arrays/Makefile: -------------------------------------------------------------------------------- 1 | #FPP=ifort 2 | FPP=gfortran 3 | FFLAGS=-fPIC 4 | PYTHON = python 5 | 6 | %.o : %.f90 7 | ${FPP} ${FFLAGS} -c $< -o $@ 8 | 9 | all: test.o 10 | f90wrap -m test -P test.f90 11 | f2py-f90wrap -c -m _test f90wrap_test.f90 test.o 12 | 13 | clean: 14 | -rm *.o f90wrap*.f90 *.so *.mod 15 | -rm -r test/ 16 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 17 | 18 | test: all 19 | $(PYTHON) -c 'import test' 20 | -------------------------------------------------------------------------------- /examples/optional_derived_arrays/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := test 4 | 5 | test: build 6 | $(PYTHON) -c 'import test' 7 | -------------------------------------------------------------------------------- /examples/optional_derived_arrays/test.f90: -------------------------------------------------------------------------------- 1 | 2 | module io 3 | 4 | implicit none 5 | 6 | private 7 | 8 | type, public :: keyword 9 | character(len=10) :: key 10 | character(len=3) :: typ 11 | character(len=10) :: description 12 | end type keyword 13 | 14 | public :: io_freeform_open 15 | 16 | contains 17 | 18 | subroutine io_freeform_open(filename,keywords) 19 | 20 | implicit none 21 | 22 | character(len=*), intent(in) :: filename 23 | !type(keyword), intent(in) :: keywords 24 | type(keyword), optional ,dimension(:), intent(in) :: keywords 25 | 26 | 27 | return 28 | 29 | end subroutine io_freeform_open 30 | 31 | end module 32 | -------------------------------------------------------------------------------- /examples/optional_string/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | CC = gcc 6 | F90 = gfortran 7 | PYTHON = python 8 | CFLAGS = -fPIC 9 | F90FLAGS = -fPIC 10 | PY_MOD = pywrapper 11 | F90_SRC = main.f90 12 | OBJ = $(F90_SRC:.f90=.o) 13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC}) 14 | WRAPFLAGS = -v --type-check 15 | F2PYFLAGS = --build-dir build 16 | F90WRAP = f90wrap 17 | F2PY = f2py-f90wrap 18 | .PHONY: all clean 19 | 20 | all: test 21 | 22 | clean: 23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/ 24 | 25 | main.o: ${F90_SRC} 26 | ${F90} ${F90FLAGS} -c $< -o $@ 27 | 28 | %.o: %.f90 29 | ${F90} ${F90FLAGS} -c $< -o $@ 30 | 31 | ${F90WRAP_SRC}: ${OBJ} 32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC} 33 | 34 | f2py: ${F90WRAP_SRC} 35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o 36 | 37 | test: f2py 38 | ${PYTHON} test.py 39 | -------------------------------------------------------------------------------- /examples/optional_string/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper 4 | WRAPFLAGS += --type-check 5 | 6 | test: build 7 | $(PYTHON) test.py 8 | -------------------------------------------------------------------------------- /examples/optional_string/main.f90: -------------------------------------------------------------------------------- 1 | 2 | module m_string_test 3 | implicit none 4 | private 5 | public :: string_in 6 | public :: string_in_array 7 | public :: string_to_string 8 | public :: string_to_string_array 9 | public :: string_out 10 | public :: string_out_optional 11 | public :: string_out_optional_array 12 | 13 | contains 14 | 15 | subroutine string_in(input) 16 | character(len=*), intent(in) :: input 17 | end subroutine 18 | 19 | subroutine string_in_array(input) 20 | character(len=6), intent(in) :: input(:) 21 | integer :: i 22 | 23 | if (input(1).ne."one ") then 24 | call f90wrap_abort("First char input is incorrect, should be 'one', but is '" // input(1) // "'" ) 25 | endif 26 | 27 | if (input(2).ne."two ") then 28 | call f90wrap_abort("Second char input is incorrect, should be 'two', but is '" // input(2) // "'" ) 29 | endif 30 | end subroutine 31 | 32 | subroutine string_to_string(input,output) 33 | character(len=*), intent(in) :: input 34 | character(len=*), intent(out) :: output 35 | output=input 36 | end subroutine string_to_string 37 | 38 | subroutine string_to_string_array(input,output) 39 | character(len=*), intent(in) :: input(:) 40 | character(len=*), intent(out) :: output(:) 41 | output=input 42 | end subroutine string_to_string_array 43 | 44 | subroutine string_out(output) 45 | character(len=13), intent(out) :: output 46 | output = "output string" 47 | end subroutine 48 | 49 | subroutine string_out_optional(output) 50 | character(len=13), optional, intent(out) :: output 51 | if (present(output)) then 52 | output = "output string" 53 | endif 54 | end subroutine 55 | 56 | subroutine string_out_optional_array(output) 57 | character(len=13), optional, intent(out) :: output(:) 58 | if (present(output)) then 59 | output = "output string" 60 | endif 61 | end subroutine 62 | 63 | end module m_string_test 64 | 65 | -------------------------------------------------------------------------------- /examples/output_kind/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | CC = gcc 6 | F90 = gfortran 7 | PYTHON = python 8 | CFLAGS = -fPIC 9 | F90FLAGS = -fPIC 10 | PY_MOD = pywrapper 11 | F90_SRC = main.f90 12 | OBJ = $(F90_SRC:.f90=.o) 13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC}) 14 | WRAPFLAGS = -v --type-check --kind-map kind.map 15 | F2PYFLAGS = --build-dir build 16 | F90WRAP = f90wrap 17 | F2PY = f2py-f90wrap 18 | .PHONY: all clean 19 | 20 | all: test 21 | 22 | clean: 23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/ 24 | 25 | main.o: ${F90_SRC} 26 | ${F90} ${F90FLAGS} -c $< -o $@ 27 | 28 | %.o: %.f90 29 | ${F90} ${F90FLAGS} -c $< -o $@ 30 | 31 | ${F90WRAP_SRC}: ${OBJ} 32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC} 33 | 34 | f2py: ${F90WRAP_SRC} 35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o 36 | 37 | test: f2py 38 | ${PYTHON} test.py 39 | -------------------------------------------------------------------------------- /examples/output_kind/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper 4 | WRAPFLAGS += --type-check --kind-map kind.map 5 | 6 | test: build 7 | $(PYTHON) test.py 8 | -------------------------------------------------------------------------------- /examples/output_kind/kind.map: -------------------------------------------------------------------------------- 1 | {'integer':{'1':'signed_char', '2':'short', '4':'int', '8':'long'},\ 2 | 'real':{'4': 'float', '8': 'double'},\ 3 | } 4 | -------------------------------------------------------------------------------- /examples/output_kind/main.f90: -------------------------------------------------------------------------------- 1 | 2 | module m_out_test 3 | implicit none 4 | private 5 | 6 | public :: out_scalar_int1,out_scalar_int2 7 | public :: out_scalar_int4,out_scalar_int8 8 | public :: out_scalar_real4,out_scalar_real8 9 | public :: out_array_int4,out_array_int8 10 | public :: out_array_real4,out_array_real8 11 | 12 | contains 13 | 14 | function out_scalar_int1() result(output) 15 | integer(kind=1) :: output 16 | output=1 17 | end function 18 | 19 | function out_scalar_int2() result(output) 20 | integer(kind=2) :: output 21 | output=2 22 | end function 23 | 24 | function out_scalar_int4() result(output) 25 | integer(kind=4) :: output 26 | output=4 27 | end function 28 | 29 | function out_scalar_int8() result(output) 30 | integer(kind=8) :: output 31 | output=8 32 | end function 33 | 34 | function out_scalar_real4() result(output) 35 | real(kind=4) :: output 36 | output=4 37 | end function 38 | 39 | function out_scalar_real8() result(output) 40 | real(kind=8) :: output 41 | output=8 42 | end function 43 | 44 | function out_array_int4() result(output) 45 | integer(kind=4) :: output(1) 46 | output=4 47 | end function 48 | 49 | function out_array_int8() result(output) 50 | integer(kind=8) :: output(1) 51 | output=8 52 | end function 53 | 54 | function out_array_real4() result(output) 55 | real(kind=4) :: output(1) 56 | output=4 57 | end function 58 | 59 | function out_array_real8() result(output) 60 | real(kind=8) :: output(1) 61 | output=8 62 | end function 63 | 64 | end module m_out_test 65 | 66 | 67 | -------------------------------------------------------------------------------- /examples/output_kind/test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | 4 | from pywrapper import m_out_test 5 | 6 | class TestTypeCheck(unittest.TestCase): 7 | def test_out_scalar_int1(self): 8 | out = m_out_test.out_scalar_int1() 9 | self.assertEqual(1,out) 10 | self.assertIsInstance(out, int) 11 | 12 | def test_out_scalar_int2(self): 13 | out = m_out_test.out_scalar_int2() 14 | self.assertEqual(2,out) 15 | self.assertIsInstance(out, int) 16 | 17 | def test_out_scalar_int4(self): 18 | out = m_out_test.out_scalar_int4() 19 | self.assertEqual(4,out) 20 | self.assertIsInstance(out, int) 21 | 22 | def test_out_scalar_int8(self): 23 | out = m_out_test.out_scalar_int8() 24 | self.assertEqual(8,out) 25 | self.assertIsInstance(out, int) 26 | 27 | def test_out_scalar_real4(self): 28 | out = m_out_test.out_scalar_real4() 29 | self.assertEqual(4.,out) 30 | self.assertIsInstance(out, float) 31 | 32 | def test_out_scalar_real8(self): 33 | out = m_out_test.out_scalar_real8() 34 | self.assertEqual(8.,out) 35 | self.assertIsInstance(out, float) 36 | 37 | def test_out_array_int4(self): 38 | out = m_out_test.out_array_int4() 39 | self.assertEqual(4,out[0]) 40 | self.assertIsInstance(out, np.ndarray) 41 | self.assertIsInstance(out[0], np.intc) 42 | self.assertIsInstance(out[0], np.int32) 43 | 44 | def test_out_array_int8(self): 45 | out = m_out_test.out_array_int8() 46 | self.assertEqual(8,out[0]) 47 | self.assertIsInstance(out, np.ndarray) 48 | self.assertIsInstance(out[0], np.int_) 49 | self.assertIsInstance(out[0], np.int64) 50 | self.assertNotIsInstance(out[0], np.longlong) 51 | 52 | def test_out_array_real4(self): 53 | out = m_out_test.out_array_real4() 54 | self.assertEqual(4.,out[0]) 55 | self.assertIsInstance(out, np.ndarray) 56 | self.assertIsInstance(out[0], np.single) 57 | self.assertIsInstance(out[0], np.float32) 58 | 59 | def test_out_array_real8(self): 60 | out = m_out_test.out_array_real8() 61 | self.assertEqual(8.,out[0]) 62 | self.assertIsInstance(out, np.ndarray) 63 | self.assertIsInstance(out[0], np.double) 64 | self.assertIsInstance(out[0], np.float64) 65 | 66 | if __name__ == '__main__': 67 | 68 | unittest.main() 69 | -------------------------------------------------------------------------------- /examples/passbyreference/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := mymodule 4 | 5 | test: build 6 | $(PYTHON) example_mymodule.py 7 | -------------------------------------------------------------------------------- /examples/passbyreference/example_mymodule.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | from __future__ import print_function 24 | import mymodule 25 | import numpy as np 26 | 27 | tt = mymodule.Mymodule.mytype() 28 | tt.val = 17 29 | b=np.array(17) 30 | 31 | print('********* BEFORE') 32 | print('b=',b) 33 | print('tt=',tt) 34 | mymodule.mymodule.mysubroutine(4,b,tt) 35 | print('********* AFTER') 36 | print('b=',b) 37 | print('tt=',tt) 38 | -------------------------------------------------------------------------------- /examples/passbyreference/makefile: -------------------------------------------------------------------------------- 1 | PYTHON = python 2 | 3 | all: mymodule.so 4 | 5 | mymodule.so : f90wrap_mycode.f90 mycode.o 6 | f2py-f90wrap -c -m _mymodule mycode.o f90wrap_mycode.f90 7 | 8 | f90wrap_mycode.f90 : mycode.F90 9 | f90wrap -m mymodule mycode.F90 10 | 11 | mycode.o : mycode.F90 12 | gfortran -c -fPIC mycode.F90 13 | 14 | clean: 15 | -rm *.o *.so f90wrap* mymodule.py 16 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 17 | 18 | test: mymodule.so 19 | $(PYTHON) example_mymodule.py 20 | -------------------------------------------------------------------------------- /examples/passbyreference/mycode.F90: -------------------------------------------------------------------------------- 1 | 2 | 3 | module mymodule 4 | 5 | implicit none 6 | 7 | type mytype 8 | double precision :: val 9 | end type mytype 10 | 11 | contains 12 | 13 | subroutine mysubroutine(a, b, tt) 14 | implicit none 15 | type(mytype) :: tt 16 | double precision, intent(in) :: a 17 | double precision, intent(inout) :: b 18 | 19 | print *,'Running mysubroutine' 20 | b = a*2 21 | tt%val = a*3 22 | 23 | end subroutine mysubroutine 24 | 25 | end module mymodule 26 | -------------------------------------------------------------------------------- /examples/recursive_type/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := ExampleRecursive 4 | NAME2 := ExampleRecursive_pkg 5 | WRAPFLAGS += -k kind_map 6 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 7 | 8 | test: build2 9 | $(PYTHON) tests.py 10 | 11 | build2: build 12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P" 13 | 14 | clean: 15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 17 | -------------------------------------------------------------------------------- /examples/recursive_type/README.md: -------------------------------------------------------------------------------- 1 | recursive_type 2 | ============== 3 | 4 | Simple example of a recursive derived type definition; that is the 5 | dervied type contains a pointer to the same type. This is common in 6 | linked lists or tree structures. 7 | 8 | This example has been tested with ```gfortran``` on Linux 64bit. 9 | 10 | To build and wrap with f90wrap, use the included ```Makefile```: 11 | 12 | ``` 13 | make 14 | ``` 15 | 16 | and before rebuilding, clean-up with: 17 | 18 | ``` 19 | make clean 20 | ``` 21 | 22 | A simple unittest is included in ```tests.py```. 23 | 24 | 25 | Author 26 | ------ 27 | 28 | Gaetan Kenway: 29 | -------------------------------------------------------------------------------- /examples/recursive_type/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': {'': 'float', 3 | '8': 'double', 4 | 'dp': 'double', 5 | 'idp':'double'}, 6 | 'complex' : {'': 'complex_float', 7 | '8' : 'complex_double', 8 | '16': 'complex_long_double', 9 | 'dp': 'complex_double'}, 10 | 'integer' : {'4': 'int', 11 | '8': 'long_long', 12 | 'dp': 'long_long' }, 13 | 'character' : {'': 'char'} 14 | } 15 | -------------------------------------------------------------------------------- /examples/recursive_type/tests.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | # -*- coding: utf-8 -*- 24 | """ 25 | Created on Tue Jan 25 2018 26 | 27 | @author: Gaetan Kenway 28 | """ 29 | 30 | from __future__ import print_function 31 | 32 | import unittest 33 | 34 | import numpy as np 35 | 36 | import ExampleRecursive as lib 37 | 38 | 39 | class TestExample(unittest.TestCase): 40 | 41 | def setUp(self): 42 | 43 | pass 44 | 45 | 46 | def test_basic(self): 47 | tree = lib.Tree.node() 48 | print (tree) 49 | del tree 50 | 51 | 52 | 53 | if __name__ == '__main__': 54 | 55 | unittest.main() 56 | -------------------------------------------------------------------------------- /examples/recursive_type/tree.f90: -------------------------------------------------------------------------------- 1 | module tree 2 | implicit none 3 | type node 4 | type(node), pointer :: left=>null() 5 | type(node), pointer :: right=>null() 6 | 7 | end type node 8 | 9 | contains 10 | 11 | subroutine treeAllocate(root) 12 | implicit none 13 | 14 | type(node) :: root 15 | allocate(root%left) 16 | allocate(root%right) 17 | 18 | end subroutine treeAllocate 19 | 20 | subroutine treedeallocate(root) 21 | implicit none 22 | 23 | type(node) :: root 24 | deallocate(root%left, root%right) 25 | 26 | end subroutine treedeallocate 27 | 28 | 29 | end module tree 30 | -------------------------------------------------------------------------------- /examples/recursive_type_array/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := recursive_type_array 4 | WRAPFLAGS += -k kind_map 5 | 6 | test: build 7 | $(PYTHON) tests.py 8 | -------------------------------------------------------------------------------- /examples/recursive_type_array/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': {'': 'float', 3 | '8': 'double', 4 | 'dp': 'double', 5 | 'idp':'double'}, 6 | 'complex' : {'': 'complex_float', 7 | '8' : 'complex_double', 8 | '16': 'complex_long_double', 9 | 'dp': 'complex_double'}, 10 | 'integer' : {'4': 'int', 11 | '8': 'long_long', 12 | 'dp': 'long_long' }, 13 | 'character' : {'': 'char'} 14 | } 15 | -------------------------------------------------------------------------------- /examples/recursive_type_array/test.f90: -------------------------------------------------------------------------------- 1 | module mod_recursive_type_array 2 | implicit none 3 | type t_node 4 | type(t_node),dimension(:),allocatable :: node 5 | end type t_node 6 | 7 | contains 8 | 9 | subroutine allocate_node(root,N_node) 10 | type(t_node) :: root 11 | integer :: N_node 12 | 13 | allocate(root%node(N_node)) 14 | 15 | end subroutine allocate_node 16 | 17 | subroutine deallocate_node(root) 18 | type(t_node) :: root 19 | 20 | if (allocated(root%node)) deallocate(root%node) 21 | 22 | end subroutine 23 | end module mod_recursive_type_array 24 | -------------------------------------------------------------------------------- /examples/recursive_type_array/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created on Mon Oct 12, 2020 3 | 4 | @author: Bernardo Pacini 5 | """ 6 | import unittest 7 | import numpy as np 8 | 9 | from recursive_type_array import Mod_Recursive_Type_Array as recursive_type_array 10 | 11 | class Test_recursive_type_array(unittest.TestCase): 12 | def setUp(self): 13 | self.N_node = 3 14 | 15 | self.root = recursive_type_array.t_node() 16 | 17 | recursive_type_array.allocate_node(self.root,self.N_node) 18 | 19 | def tearDown(self): 20 | recursive_type_array.deallocate_node(self.root) 21 | 22 | def test_allocate(self): 23 | self.assertEqual( 24 | len(self.root.node), 25 | self.N_node 26 | ) 27 | 28 | def test_deallocate(self): 29 | recursive_type_array.deallocate_node(self.root) 30 | self.assertEqual( 31 | len(self.root.node), 32 | 0 33 | ) 34 | 35 | if __name__ == "__main__": 36 | unittest.main() 37 | -------------------------------------------------------------------------------- /examples/remove_pointer_arg/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | CC = gcc 6 | F90 = gfortran 7 | PYTHON = python 8 | CFLAGS = -fPIC 9 | F90FLAGS = -fPIC 10 | PY_MOD = pywrapper 11 | F90_SRC = main.f90 12 | OBJ = $(F90_SRC:.f90=.o) 13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC}) 14 | WRAPFLAGS = -v 15 | F2PYFLAGS = --build-dir build 16 | F90WRAP = f90wrap 17 | F2PY = f2py-f90wrap 18 | .PHONY: all clean 19 | 20 | all: test 21 | 22 | clean: 23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/ 24 | 25 | main.o: ${F90_SRC} 26 | ${F90} ${F90FLAGS} -c $< -o $@ 27 | 28 | %.o: %.f90 29 | ${F90} ${F90FLAGS} -c $< -o $@ 30 | 31 | ${F90WRAP_SRC}: ${OBJ} 32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC} 33 | 34 | f2py: ${F90WRAP_SRC} 35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o 36 | 37 | test: f2py 38 | ${PYTHON} tests.py 39 | -------------------------------------------------------------------------------- /examples/remove_pointer_arg/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper 4 | 5 | test: build 6 | $(PYTHON) tests.py 7 | -------------------------------------------------------------------------------- /examples/remove_pointer_arg/main.f90: -------------------------------------------------------------------------------- 1 | program main 2 | 3 | end program 4 | 5 | module m_test 6 | 7 | implicit none 8 | public 9 | 10 | contains 11 | 12 | function to_be_ignored_1() result(ptr) 13 | real,pointer :: ptr(:,:) 14 | ptr => null() 15 | end function to_be_ignored_1 16 | 17 | function to_be_ignored_2() result(ptr) 18 | real,pointer,contiguous :: ptr(:,:) 19 | ptr => null() 20 | end function to_be_ignored_2 21 | 22 | function not_to_be_ignored() result(out_int) 23 | integer :: out_int 24 | out_int = 1 25 | end function not_to_be_ignored 26 | 27 | end module m_test 28 | -------------------------------------------------------------------------------- /examples/remove_pointer_arg/tests.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from pywrapper import m_test 4 | 5 | class TestReturnArray(unittest.TestCase): 6 | 7 | def test_not_ignored(self): 8 | _ = m_test.not_to_be_ignored() 9 | 10 | def test_ignored_1(self): 11 | with self.assertRaises(AttributeError): 12 | _ = m_test.to_be_ignored_1() 13 | 14 | def test_ignored_2(self): 15 | with self.assertRaises(AttributeError): 16 | _ = m_test.to_be_ignored_2() 17 | 18 | if __name__ == '__main__': 19 | unittest.main() 20 | -------------------------------------------------------------------------------- /examples/return_array/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | CC = gcc 6 | F90 = gfortran 7 | PYTHON = python 8 | CFLAGS = -fPIC 9 | F90FLAGS = -fPIC 10 | PY_MOD = pywrapper 11 | F90_SRC = main.f90 12 | OBJ = $(F90_SRC:.f90=.o) 13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC}) 14 | WRAPFLAGS = -v 15 | F2PYFLAGS = --build-dir build 16 | F90WRAP = f90wrap 17 | F2PY = f2py-f90wrap 18 | .PHONY: all clean 19 | 20 | all: test 21 | 22 | clean: 23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/ 24 | 25 | main.o: ${F90_SRC} 26 | ${F90} ${F90FLAGS} -c $< -o $@ 27 | 28 | %.o: %.f90 29 | ${F90} ${F90FLAGS} -c $< -o $@ 30 | 31 | ${F90WRAP_SRC}: ${OBJ} 32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC} 33 | 34 | f2py: ${F90WRAP_SRC} 35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o 36 | 37 | test: f2py 38 | ${PYTHON} test.py 39 | -------------------------------------------------------------------------------- /examples/return_array/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper 4 | 5 | test: build 6 | $(PYTHON) test.py 7 | -------------------------------------------------------------------------------- /examples/string_array_input_f2py/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | F90 = gfortran 6 | PYTHON = python3 7 | CFLAGS = -fPIC 8 | F90FLAGS = -fPIC 9 | PY_MOD = pywrapper 10 | F90_SRC = main.f90 11 | OBJ = $(F90_SRC:.f90=.o) 12 | SIGNATURES = _signatures.pyf 13 | F2PYFLAGS = --build-dir build 14 | F2PY = f2py 15 | LINK = -lgfortran 16 | .PHONY: all clean 17 | 18 | all: test 19 | 20 | clean: 21 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}_*.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}_*/ ${SIGNATURES} 22 | 23 | %.o: %.f90 24 | ${F90} ${F90FLAGS} -c $< -o $@ 25 | 26 | ${SIGNATURES}: ${F90_SRC} 27 | ${F2PY} ${F90_SRC} -m _${PY_MOD}_sign -h ${SIGNATURES} 28 | 29 | f2py: ${OBJ} ${SIGNATURES} 30 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD}_sign ${F2PYFLAGS} ${LINK} ${OBJ} ${SIGNATURES} 31 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD}_no_sign ${F2PYFLAGS} ${F90_SRC} 32 | 33 | test: f2py 34 | ${PYTHON} tests_sign.py 35 | ${PYTHON} tests_no_sign.py 36 | -------------------------------------------------------------------------------- /examples/string_array_input_f2py/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper_sign 4 | NAME2 := pywrapper_no_sign 5 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 6 | SIGNATURES = _signatures.pyf 7 | F2PY = f2py 8 | 9 | test: extension 10 | ${PYTHON} tests_sign.py 11 | ${PYTHON} tests_no_sign.py 12 | 13 | ${SIGNATURES}: ${LIBSRC_WRAP_FILES} 14 | ${F2PY} ${LIBSRC_WRAP_FILES} -m _${NAME} -h ${SIGNATURES} 15 | 16 | extension: ${SIGNATURES} 17 | ${F2PY} -c -m _${NAME} ${LIBSRC_WRAP_FILES} ${SIGNATURES} 18 | ${F2PY} -c -m _${NAME2} ${LIBSRC_WRAP_FILES} 19 | 20 | 21 | clean: 22 | -rm -f f90wrap_*.f90 *.o *.mod *.fpp *.a 23 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 24 | -rm -rf _${NAME}* ${NAME}*/ ${NAME}.py 25 | -rm -rf _build_dir 26 | -rm -f meson.build* 27 | -rm -f ${SIGNATURES} 28 | -------------------------------------------------------------------------------- /examples/string_array_input_f2py/main.f90: -------------------------------------------------------------------------------- 1 | subroutine string_in_array(n0, input, output) 2 | implicit none 3 | 4 | integer :: n0 5 | !f2py intent(hide), depend(input) :: n0 = shape(input,0) 6 | character*(*), intent(in), dimension(n0) :: input 7 | integer, intent(out) :: output 8 | 9 | if(input(1) .eq. "one" .and. input(2) .eq. "two") then 10 | output=0 11 | else 12 | output=1 13 | endif 14 | end subroutine string_in_array 15 | 16 | subroutine string_in_array_optional(n0, input, output) 17 | implicit none 18 | 19 | integer :: n0 20 | !f2py intent(hide), depend(input) :: n0 = shape(input,0) 21 | character*(*), intent(in), optional, dimension(n0) :: input 22 | integer, intent(out) :: output 23 | 24 | output=2 25 | if(present(input)) then 26 | if(input(1) .eq. "one" .and. input(2) .eq. "two") then 27 | output=0 28 | else 29 | output=1 30 | endif 31 | endif 32 | end subroutine string_in_array_optional 33 | -------------------------------------------------------------------------------- /examples/string_array_input_f2py/tests_no_sign.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | from packaging import version 4 | 5 | import _pywrapper_no_sign 6 | 7 | class TestWithoutSignature(unittest.TestCase): 8 | 9 | @unittest.skipIf(version.parse(np.version.version) < version.parse("1.24.0") , "This test is known to fail on numpy version older than 1.24.0, dtype=S# does not work") 10 | def test_string_in_array(self): 11 | in_array = np.array(['one', 'two'], dtype='S3') 12 | output = _pywrapper_no_sign.string_in_array(in_array) 13 | self.assertEqual(output, 0) 14 | 15 | @unittest.skipIf(version.parse(np.version.version) < version.parse("1.24.0") , "This test is known to fail on numpy version older than 1.24.0, dtype=S# does not work") 16 | def test_string_in_array_optional_present(self): 17 | in_array = np.array(['one', 'two'], dtype='S3') 18 | output = _pywrapper_no_sign.string_in_array_optional(in_array) 19 | self.assertEqual(output, 0) 20 | 21 | def test_string_in_array_optional_not_present(self): 22 | with self.assertRaises((SystemError, ValueError)): 23 | _ = _pywrapper_no_sign.string_in_array_optional() 24 | 25 | class TestWithoutSignatureWithCDtype(unittest.TestCase): 26 | 27 | @unittest.skipIf(version.parse(np.version.version) > version.parse("1.23.5") , "This test is known to fail on numpy version newer than 1.23.5, dtype=c should not be used") 28 | def test_string_in_array(self): 29 | in_array = np.array(['one', 'two'], dtype='c') 30 | output = _pywrapper_no_sign.string_in_array(in_array) 31 | self.assertEqual(output, 0) 32 | 33 | @unittest.skipIf(version.parse(np.version.version) > version.parse("1.23.5") , "This test is known to fail on numpy version newer than 1.23.5, dtype=c should not be used") 34 | def test_string_in_array_optional_present(self): 35 | in_array = np.array(['one', 'two'], dtype='c') 36 | output = _pywrapper_no_sign.string_in_array_optional(in_array) 37 | self.assertEqual(output, 0) 38 | 39 | def test_string_in_array_optional_not_present(self): 40 | with self.assertRaises((SystemError, ValueError)): 41 | _ = _pywrapper_no_sign.string_in_array_optional() 42 | 43 | if __name__ == '__main__': 44 | 45 | unittest.main() 46 | -------------------------------------------------------------------------------- /examples/string_array_input_f2py/tests_sign.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | from packaging import version 4 | 5 | import _pywrapper_sign 6 | 7 | class TestWithSignature(unittest.TestCase): 8 | 9 | @unittest.skipIf(version.parse(np.version.version) < version.parse("1.24.0") , "f2py bug solved https://github.com/numpy/numpy/issues/24706") 10 | def test_string_in_array(self): 11 | in_array = np.array(['one', 'two'], dtype='S3') 12 | output = _pywrapper_sign.string_in_array(in_array) 13 | self.assertEqual(output, 0) 14 | 15 | @unittest.skipIf(version.parse(np.version.version) < version.parse("1.24.0") , "f2py bug solved https://github.com/numpy/numpy/issues/24706") 16 | def test_string_in_array_optional_present(self): 17 | in_array = np.array(['one', 'two'], dtype='S3') 18 | output = _pywrapper_sign.string_in_array_optional(in_array) 19 | self.assertEqual(output, 0) 20 | 21 | def test_string_in_array_optional_not_present(self): 22 | with self.assertRaises((SystemError, ValueError)): 23 | _ = _pywrapper_sign.string_in_array_optional() 24 | 25 | 26 | if __name__ == '__main__': 27 | 28 | unittest.main() 29 | -------------------------------------------------------------------------------- /examples/strings/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := ExampleStrings 4 | NAME2 := ExampleStrings_pkg 5 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 6 | 7 | test: build2 8 | $(PYTHON) tests.py 9 | 10 | build2: build 11 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P" 12 | 13 | clean: 14 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 16 | -------------------------------------------------------------------------------- /examples/strings/README.md: -------------------------------------------------------------------------------- 1 | example-strings 2 | =================== 3 | 4 | When excluding the character/char mapping in ```kind_map```, strings can be 5 | passed between Fortran and Python in a straightforward manner. 6 | 7 | To build and wrap with f90wrap, use the included ```Makefile```: 8 | 9 | ``` 10 | make 11 | ``` 12 | 13 | and before rebuilding, clean-up with: 14 | 15 | ``` 16 | make clean 17 | ``` 18 | 19 | Simple unittests are included in ```tests.py```. 20 | 21 | 22 | Author 23 | ------ 24 | 25 | David Verelst: 26 | -------------------------------------------------------------------------------- /examples/strings/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': { '' : 'float', 3 | '4' : 'float', 4 | 'isp' : 'float', 5 | '8' : 'double', 6 | 'dp' : 'double', 7 | 'idp' : 'double'}, 8 | 'complex' : { '' : 'complex_float', 9 | '8' : 'complex_double', 10 | '16' : 'complex_long_double', 11 | 'dp' : 'complex_double'}, 12 | 'integer' : { '4' : 'int', 13 | '8' : 'long_long', 14 | 'dp' : 'long_long' } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /examples/strings/string_io.f90: -------------------------------------------------------------------------------- 1 | module string_io 2 | 3 | implicit none 4 | 5 | CHARACTER(512) global_string 6 | 7 | contains 8 | 9 | function func_generate_string(n) result(stringout) 10 | INTEGER(4) i, j, n, k 11 | CHARACTER(n) stringout 12 | DO i=1,n 13 | j = i + 1 14 | k = i + 33 15 | stringout(i:j) = achar(k) 16 | ENDDO 17 | end function func_generate_string 18 | 19 | function func_return_string() result(stringout) 20 | CHARACTER(51) stringout 21 | stringout = '-_-::this is a string with ASCII, / and 123...::-_-' 22 | end function func_return_string 23 | 24 | subroutine generate_string(n, stringout) 25 | INTEGER(4) i, j, k 26 | INTEGER(4), INTENT(in) :: n 27 | CHARACTER(n), INTENT(out) :: stringout 28 | DO i=1,n 29 | j = i + 1 30 | k = i + 33 31 | stringout(i:j) = achar(k) 32 | ENDDO 33 | end subroutine generate_string 34 | 35 | subroutine return_string(stringout) 36 | CHARACTER(51), INTENT(out) :: stringout 37 | stringout = '-_-::this is a string with ASCII, / and 123...::-_-' 38 | end subroutine return_string 39 | 40 | subroutine set_global_string(n, newstring) 41 | INTEGER(4), INTENT(in) :: n 42 | CHARACTER(n), INTENT(in) :: newstring 43 | global_string = newstring 44 | end subroutine set_global_string 45 | 46 | subroutine inout_string(n, stringinout) 47 | INTEGER(4) i, j 48 | INTEGER(4), INTENT(in) :: n 49 | CHARACTER(n), INTENT(inout) :: stringinout 50 | DO i=1,n 51 | j = i + 1 52 | stringinout(i:j) = 'Z' 53 | ENDDO 54 | end subroutine inout_string 55 | 56 | end module string_io 57 | 58 | -------------------------------------------------------------------------------- /examples/subroutine_args/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := subroutine_mod 4 | NAME2 := subroutine_mod_pkg 5 | WRAPFLAGS += -k kind_map 6 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 7 | 8 | test: build2 9 | $(PYTHON) tests.py 10 | 11 | build2: build 12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P" 13 | 14 | clean: 15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME) 16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2) 17 | -------------------------------------------------------------------------------- /examples/subroutine_args/kind_map: -------------------------------------------------------------------------------- 1 | { 2 | 'real': { '' : 'float', 3 | '4' : 'float', 4 | 'isp' : 'float', 5 | '8' : 'double', 6 | 'dp' : 'double', 7 | 'idp' : 'double'}, 8 | 'complex' : { '' : 'complex_float', 9 | '8' : 'complex_double', 10 | '16' : 'complex_long_double', 11 | 'dp' : 'complex_double'}, 12 | 'integer' : { '4' : 'int', 13 | '8' : 'long_long', 14 | 'dp' : 'long_long' } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /examples/subroutine_args/subroutine_mod.f90: -------------------------------------------------------------------------------- 1 | module subroutine_mod 2 | 3 | implicit none 4 | 5 | contains 6 | 7 | subroutine routine_with_simple_args(a, b, c, d) 8 | integer, intent(in) :: a, b 9 | integer, intent(out) :: c, d 10 | 11 | c = a + b 12 | d = a * b 13 | 14 | end subroutine routine_with_simple_args 15 | 16 | subroutine routine_with_multiline_args(& 17 | & a, b, c, d) 18 | integer, intent(in) :: a, b 19 | integer, intent(out) :: c, d 20 | 21 | c = a + b 22 | d = a * b 23 | 24 | end subroutine routine_with_multiline_args 25 | 26 | subroutine routine_with_commented_args(& 27 | ! Some arbitrary comment... 28 | & a, b, & 29 | ! ... to highlight Fortran line continuation. 30 | & c, d) 31 | integer, intent(in) :: a, b 32 | integer, intent(out) :: c, d 33 | 34 | c = a + b 35 | d = a * b 36 | 37 | end subroutine routine_with_commented_args 38 | 39 | subroutine routine_with_more_commented_args(& 40 | ! Some additional commenting... 41 | & a, b, & 42 | ! ... to highlight the true ... 43 | ! ... beauty of the FORTRAN language. 44 | & c, d) 45 | integer, intent(in) :: a, b 46 | integer, intent(out) :: c, d 47 | 48 | c = a + b 49 | d = a * b 50 | 51 | end subroutine routine_with_more_commented_args 52 | 53 | end module subroutine_mod 54 | -------------------------------------------------------------------------------- /examples/subroutine_args/tests.py: -------------------------------------------------------------------------------- 1 | 2 | import subroutine_mod 3 | 4 | mod = subroutine_mod.Subroutine_Mod 5 | 6 | c, d = mod.routine_with_simple_args(2, 3) 7 | assert c == 5 and d == 6 8 | 9 | c, d = mod.routine_with_multiline_args(2, 3) 10 | assert c == 5 and d == 6 11 | 12 | c, d = mod.routine_with_commented_args(2, 3) 13 | assert c == 5 and d == 6 14 | 15 | c, d = mod.routine_with_more_commented_args(2, 3) 16 | assert c == 5 and d == 6 17 | -------------------------------------------------------------------------------- /examples/subroutine_contains_issue101/Makefile: -------------------------------------------------------------------------------- 1 | FC = gfortran 2 | CFLAGS = -fPIC 3 | PYTHON = python 4 | 5 | all: test 6 | 7 | %.o : %.f90 8 | ${FC} ${CFLAGS} -c $< -o $@ 9 | 10 | test.o: test.f90 11 | 12 | test.py: test.o 13 | f90wrap -m test test.f90 14 | f2py-f90wrap -c -m _test f90wrap_toplevel.f90 test.o 15 | 16 | test: test.py 17 | $(PYTHON) run.py 18 | 19 | clean: 20 | -rm -f *.o f90wrap*.f90 *.so *.mod *.pyc 21 | -rm -rf __pycache__ 22 | -rm -f test.py 23 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 24 | -------------------------------------------------------------------------------- /examples/subroutine_contains_issue101/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := test 4 | 5 | test: build 6 | $(PYTHON) run.py 7 | -------------------------------------------------------------------------------- /examples/subroutine_contains_issue101/run.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2020 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | import test 24 | 25 | assert hasattr(test, 'routine_member_procedures') 26 | assert not hasattr(test, 'member_procedure') 27 | assert not hasattr(test, 'member_function') 28 | 29 | out1, out2 = test.routine_member_procedures(1, 2) 30 | assert out1 == 7 # 5*1+2 31 | assert out2 == 23 # 3*out1+2 32 | 33 | assert hasattr(test, 'routine_member_procedures2') 34 | assert not hasattr(test, 'member_procedure2') 35 | assert not hasattr(test, 'member_function2') 36 | 37 | out12, out22 = test.routine_member_procedures2(1, 2) 38 | assert out12 == 28 # (out2-10)*2+2 39 | assert out22 == 84 # out12*3 40 | -------------------------------------------------------------------------------- /examples/type_bn/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | F90 = gfortran 3 | FPP = gfortran -E 4 | F90FLAGS = -x f95-cpp-input -fPIC 5 | CFLAGS = -fPIC 6 | PYTHON = python 7 | 8 | UNAME = $(shell uname) 9 | 10 | ifeq (${UNAME}, Darwin) 11 | LIBTOOL = libtool -static -o 12 | else 13 | LIBTOOL = ar src 14 | endif 15 | 16 | .PHONY: all clean test 17 | 18 | all: test 19 | 20 | clean: 21 | -rm -f _type_bn*.so *.mod f90wrap*.f90 *.fpp *.o *.pyc 22 | -rm -f type_bn.py 23 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/ 24 | 25 | _type_bn.so: type_bn.f90 26 | f90wrap -m type_bn type_bn.f90 -v 27 | gfortran -c type_bn.f90 28 | f2py-f90wrap --build-dir . -c -m _type_bn type_bn.o f90wrap*.f90 29 | 30 | test: _type_bn.so 31 | $(PYTHON) test.py 32 | 33 | -------------------------------------------------------------------------------- /examples/type_bn/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := type_bn 4 | 5 | test: build 6 | $(PYTHON) test.py 7 | -------------------------------------------------------------------------------- /examples/type_bn/README.md: -------------------------------------------------------------------------------- 1 | Regression test case for issue Github #30 2 | 3 | https://github.com/jameskermode/f90wrap/issues/30 4 | 5 | -------------------------------------------------------------------------------- /examples/type_bn/test.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | import type_bn 24 | 25 | a = type_bn.module_structure.type_face() 26 | a.type = 1 27 | assert(a.type == 1) 28 | -------------------------------------------------------------------------------- /examples/type_bn/type_bn.f90: -------------------------------------------------------------------------------- 1 | module module_structure 2 | 3 | type type_face 4 | integer :: type 5 | end type type_face 6 | 7 | end module module_structure -------------------------------------------------------------------------------- /examples/type_check/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # define the compiler names 3 | #======================================================================= 4 | 5 | CC = gcc 6 | F90 = gfortran 7 | PYTHON = python 8 | CFLAGS = -fPIC 9 | F90FLAGS = -fPIC 10 | PY_MOD = pywrapper 11 | F90_SRC = main.f90 12 | OBJ = $(F90_SRC:.f90=.o) 13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC}) 14 | WRAPFLAGS = -v --type-check --kind-map kind.map 15 | F2PYFLAGS = --build-dir build 16 | F90WRAP = f90wrap 17 | F2PY = f2py-f90wrap 18 | .PHONY: all clean 19 | 20 | all: test 21 | 22 | clean: 23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/ 24 | 25 | main.o: ${F90_SRC} 26 | ${F90} ${F90FLAGS} -c $< -o $@ 27 | 28 | %.o: %.f90 29 | ${F90} ${F90FLAGS} -c $< -o $@ 30 | 31 | ${F90WRAP_SRC}: ${OBJ} 32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC} 33 | 34 | f2py: ${F90WRAP_SRC} 35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o 36 | 37 | test: f2py 38 | ${PYTHON} type_check_test.py 39 | -------------------------------------------------------------------------------- /examples/type_check/Makefile.meson: -------------------------------------------------------------------------------- 1 | include ../make.meson.inc 2 | 3 | NAME := pywrapper 4 | WRAPFLAGS += --type-check --kind-map kind.map 5 | 6 | test: build 7 | $(PYTHON) type_check_test.py 8 | -------------------------------------------------------------------------------- /examples/type_check/kind.map: -------------------------------------------------------------------------------- 1 | {\ 2 | 'integer':{'1':'signed_char', '2':'short', '4':'int', '8':'long_long'},\ 3 | 'real':{'4':'float', '8':'double'},\ 4 | } 5 | -------------------------------------------------------------------------------- /f90wrap/__init__.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | 24 | # Originally based on: 25 | # f90doc - automatic documentation generator for Fortran 90 26 | # Copyright (C) 2004 Ian Rutt 27 | # 28 | # This program is free software; you can redistribute it and/or 29 | # modify it under the terms of the GNU General Public License as 30 | # published by the Free Software Foundation; either version 2 of 31 | # the License, or (at your option) any later version. 32 | # 33 | # This program is distributed in the hope that it will be useful, 34 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 35 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 36 | # GNU General Public License for more details. 37 | # 38 | # You should have received a copy of the GNU General Public 39 | # License along with this program; if not, write to the Free 40 | # Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 41 | # MA 02111-1307 USA 42 | 43 | """f90wrap package 44 | 45 | Add support for Fortran derived types and interfaces to f2py by 46 | wrapping Fortran code with a simple f90 interface layer. 47 | 48 | (c) James Kermode 2011-2024 """ 49 | 50 | __version__ = '0.2.16' 51 | -------------------------------------------------------------------------------- /f90wrap/__main__.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import sys 3 | from importlib import import_module 4 | 5 | commands = { 6 | '--f90wrap' : 'f90wrap.scripts.main', 7 | '--f2py' : 'f90wrap.scripts.f2py_f90wrap', 8 | '--f2py-f90wrap' : 'f90wrap.scripts.f2py_f90wrap', 9 | '--f90doc' : 'f90wrap.scripts.f90doc', 10 | } 11 | 12 | def main(): 13 | if len(sys.argv) == 1 or (len(sys.argv) == 2 and ('-h' in sys.argv or '--help' in sys.argv)): 14 | parser = argparse.ArgumentParser(description='f90wrap : F90 to Python interface generator with derived type support') 15 | parser.description = 'f90wrap tasks :\n' + '\n\t'.join(commands.keys()) 16 | parser.add_argument('--f90wrap', action='store_true', default=False, help='main function of f90wrap') 17 | parser.add_argument('--f2py', '--f2py-f90wrap', action='store_true', default=False, help='f90wrap patched version of f2py') 18 | parser.add_argument('--f90doc', action='store_true', default=False, help='documentation generator for Fortran 90') 19 | parser.parse_args() 20 | if len(sys.argv) == 1 : parser.print_help() 21 | else : 22 | for job in commands : 23 | if job in sys.argv : 24 | sys.argv.remove(job) 25 | return getattr(import_module(commands[job]), 'main')() 26 | else : 27 | job = '--f90wrap' 28 | return getattr(import_module(commands[job]), 'main')() 29 | 30 | 31 | if __name__ == "__main__": 32 | main() 33 | -------------------------------------------------------------------------------- /f90wrap/meson.build: -------------------------------------------------------------------------------- 1 | f2py = [py3, '-m', 'numpy.f2py', '@INPUT@', '--build-dir', '@OUTDIR@', '--lower'] 2 | 3 | sizeof_source = custom_target( 4 | input: 'sizeoffortran.f90', 5 | output: 'sizeof_fortran_tmodule.c', 6 | command: f2py + ['-m', 'sizeof_fortran_t'] 7 | ) 8 | 9 | py3.extension_module( 10 | 'sizeof_fortran_t', 11 | 'sizeoffortran.f90', sizeof_source, 12 | dependencies: fortranobject_dep, 13 | install: true, 14 | subdir: 'f90wrap', 15 | ) 16 | 17 | py3.extension_module( 18 | 'arraydata', 19 | 'arraydatamodule.c', 20 | dependencies: fortranobject_dep, 21 | install: true, 22 | subdir: 'f90wrap', 23 | ) 24 | 25 | py3.install_sources( 26 | 'codegen.py', 27 | 'f90wrapgen.py', 28 | 'fortran.py', 29 | 'fortrantype.py', 30 | '__init__.py', 31 | 'latex.py', 32 | '__main__.py', 33 | 'parser.py', 34 | 'pywrapgen.py', 35 | 'runtime.py', 36 | 'six.py', 37 | 'transform.py', 38 | 'scripts/f2py_f90wrap.py', 39 | 'scripts/f90doc.py', 40 | 'scripts/__init__.py', 41 | 'scripts/main.py', 42 | subdir: 'f90wrap', 43 | preserve_path: true, 44 | ) 45 | -------------------------------------------------------------------------------- /f90wrap/runtime.py: -------------------------------------------------------------------------------- 1 | # f90wrap: F90 to Python interface generator with derived type support 2 | # 3 | # Copyright James Kermode 2011-2018 4 | # 5 | # This file is part of f90wrap 6 | # For the latest version see github.com/jameskermode/f90wrap 7 | # 8 | # f90wrap is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU Lesser General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # f90wrap is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with f90wrap. If not, see . 20 | # 21 | # If you would like to license the source code under different terms, 22 | # please contact James Kermode, james.kermode@gmail.com 23 | 24 | """ 25 | f90wrap.runtime 26 | 27 | Contains everything needed by f90wrap generated Python modules at runtime 28 | """ 29 | 30 | from f90wrap.fortrantype import (FortranDerivedType, 31 | FortranDerivedTypeArray, 32 | FortranModule) 33 | from f90wrap.arraydata import get_array 34 | from f90wrap.sizeof_fortran_t import sizeof_fortran_t as _sizeof_fortran_t 35 | 36 | sizeof_fortran_t = _sizeof_fortran_t() 37 | empty_handle = [0]*sizeof_fortran_t 38 | empty_type = FortranDerivedType.from_handle(empty_handle) 39 | 40 | _f90wrap_classes = {} 41 | 42 | class register_class(object): 43 | def __init__(self, cls_name): 44 | self.cls_name = cls_name 45 | 46 | def __call__(self, cls): 47 | global _f90wrap_classes 48 | if self.cls_name in _f90wrap_classes: 49 | raise RuntimeError("Duplicate Fortran class name {0}".format(self.cls_name)) 50 | _f90wrap_classes[self.cls_name] = cls 51 | return cls 52 | 53 | def lookup_class(cls_name): 54 | global _f90wrap_classes 55 | return _f90wrap_classes[cls_name] 56 | -------------------------------------------------------------------------------- /f90wrap/scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/f90wrap/scripts/__init__.py -------------------------------------------------------------------------------- /f90wrap/sizeoffortran.f90: -------------------------------------------------------------------------------- 1 | subroutine sizeof_fortran_t(size_out) 2 | 3 | type ptr_type 4 | type(ptr_type), pointer :: p => NULL() 5 | end type ptr_type 6 | type(ptr_type) :: ptr_t 7 | integer, allocatable, dimension(:) :: ptr_int_t 8 | 9 | type ptr_class 10 | class(ptr_class), pointer :: p => NULL() 11 | end type ptr_class 12 | type(ptr_class) :: ptr_c 13 | integer, allocatable, dimension(:) :: ptr_int_c 14 | 15 | integer, intent(out) :: size_out 16 | 17 | ptr_t_size = size(transfer(ptr_t, ptr_int_t)) 18 | ptr_c_size = size(transfer(ptr_c, ptr_int_c)) 19 | size_out = max(ptr_t_size, ptr_c_size) 20 | 21 | end subroutine sizeof_fortran_t 22 | -------------------------------------------------------------------------------- /get_version.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | version = {} 4 | with open('f90wrap/__init__.py') as fp: 5 | exec(fp.read(), version) 6 | __version__ = version['__version__'] 7 | 8 | print(__version__) 9 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | # much of this file is derived from SciPy 2 | 3 | project('f90wrap', 4 | 'c', 5 | version: run_command('get_version.py', check: true).stdout().strip(), 6 | meson_version: '>= 0.64.0', 7 | ) 8 | 9 | # force rebuild to re-calculate the version if it changes 10 | import('fs').read('f90wrap/__init__.py') 11 | 12 | # Adding at project level causes many spurious -lgfortran flags. 13 | add_languages('fortran', native: false) 14 | 15 | py3 = import('python').find_installation(pure: false) 16 | py3_dep = py3.dependency() 17 | 18 | incdir_numpy = run_command( 19 | py3, '-c', 20 | 'import numpy; print(numpy.get_include())', 21 | check: true, 22 | ).stdout().strip() 23 | 24 | inc_np = include_directories(incdir_numpy) 25 | 26 | incdir_f2py = incdir_numpy / '..' / '..' / 'f2py' / 'src' 27 | inc_f2py = include_directories(incdir_f2py) 28 | fortranobject_c = incdir_f2py / 'fortranobject.c' 29 | 30 | # Share this object across multiple modules. 31 | fortranobject_lib = static_library('_fortranobject', 32 | fortranobject_c, 33 | dependencies: py3_dep, 34 | include_directories: [inc_np, inc_f2py], 35 | ) 36 | fortranobject_dep = declare_dependency( 37 | link_with: fortranobject_lib, 38 | include_directories: [inc_np, inc_f2py], 39 | ) 40 | 41 | subdir('f90wrap') 42 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | # Minimum requirements for the build system to execute. 3 | requires = [ 4 | "meson-python>=0.12.0", 5 | "numpy>=2.0.0", 6 | ] 7 | build-backend = 'mesonpy' 8 | 9 | [project] 10 | name = "f90wrap" 11 | description = "Fortran to Python interface generator with derived type support" 12 | authors = [{name = "James Kermode", email = "james.kermode@gmail.com"}] 13 | python-requires = ">=3.9" 14 | urls = {Homepage = "https://github.com/jameskermode/f90wrap"} 15 | dependencies = ["numpy>=1.13", "packaging"] 16 | dynamic = ["version"] 17 | 18 | [project.readme] 19 | file = "README.md" 20 | content-type = "text/markdown" 21 | 22 | [project.scripts] 23 | f90doc = "f90wrap.scripts.f90doc:main" 24 | f90wrap = "f90wrap.scripts.main:main" 25 | f2py-f90wrap = "f90wrap.scripts.f2py_f90wrap:main" 26 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | . 2 | 3 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | test.log 2 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from pathlib import Path 3 | 4 | test_dir = Path(__file__).parent.resolve() 5 | test_samples_dir = test_dir/'samples' 6 | 7 | log_file = test_dir/'test.log' 8 | if log_file.exists(): 9 | log_file.unlink() 10 | logging.basicConfig(filename=log_file,level=logging.DEBUG) 11 | -------------------------------------------------------------------------------- /test/samples/test_circle.f90: -------------------------------------------------------------------------------- 1 | program test_circle 2 | use ClassCircle 3 | block 4 | 5 | ! Use block so destructor fires 6 | type(Circle) :: c 7 | double precision :: x 8 | 9 | c = Circle(5.0) 10 | x = c%get_area() 11 | x = c%get_radius() 12 | call c%print() 13 | 14 | c = Circle('test', 3.0) 15 | x = c%get_area() 16 | x = c%get_radius() 17 | call c%print('tag') 18 | 19 | end block 20 | end program 21 | -------------------------------------------------------------------------------- /test/test_parser.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from f90wrap import parser 3 | from . import test_samples_dir 4 | 5 | 6 | class TestParser(unittest.TestCase): 7 | 8 | def test_parse_type_procedures(self): 9 | root = parser.read_files([str(test_samples_dir/'circle.f90')]) 10 | bindings = root.modules[0].types[0].bindings 11 | self.assertEqual(len(bindings), 7) 12 | self.assertEqual(bindings[0].type, 'procedure') 13 | self.assertEqual(bindings[0].name, 'get_area') 14 | self.assertEqual(bindings[2].attributes, ['private', 'non_overridable']) 15 | self.assertEqual(bindings[0].procedures[0].name, 'circle_get_area') 16 | self.assertEqual(bindings[4].type, 'generic') 17 | self.assertEqual(bindings[4].name, 'print') 18 | self.assertEqual(len(bindings[4].procedures), 2) 19 | self.assertEqual(bindings[5].type, 'final') 20 | 21 | def test_parse_dnad(self): 22 | root = parser.read_files([str(test_samples_dir/'DNAD.fpp')]) 23 | proc_names = [ p.name for p in root.modules[0].procedures ] 24 | self.assertIn('abs_d', proc_names) 25 | self.assertIn('add_di', proc_names) 26 | self.assertIn('assign_di', proc_names) 27 | -------------------------------------------------------------------------------- /tools/wheels/cibw_before_all_cp38_macosx_arm64.sh: -------------------------------------------------------------------------------- 1 | # https://cibuildwheel.readthedocs.io/en/stable/faq/#macos-building-cpython-38-wheels-on-arm64 2 | curl -o /tmp/Python38.pkg https://www.python.org/ftp/python/3.8.10/python-3.8.10-macos11.pkg 3 | sudo installer -pkg /tmp/Python38.pkg -target / 4 | sh "/Applications/Python 3.8/Install Certificates.command" 5 | -------------------------------------------------------------------------------- /tools/wheels/release-wheels.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ ! "$CIRRUS_TAG" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+ ]]; then 4 | echo "Not a release. No need to deploy!" 5 | exit 0 6 | fi 7 | 8 | if [[ "$GITHUB_TOKEN" == "" ]]; then 9 | echo "Please provide GitHub access token via GITHUB_TOKEN environment variable!" 10 | exit 1 11 | fi 12 | 13 | if [[ "$TWINE_PASSWORD" == "" ]]; then 14 | echo "Please provide PyPI access token via TWINE_PASSWORD environment variable!" 15 | exit 1 16 | fi 17 | 18 | echo "Uploading $CIRRUS_TAG to GitHub release" 19 | 20 | file_content_type="application/octet-stream" 21 | files_to_upload=wheelhouse/*.whl 22 | for fpath in $files_to_upload 23 | do 24 | echo "Uploading $fpath..." 25 | name=$(basename "$fpath") 26 | url_to_upload="https://uploads.github.com/repos/$CIRRUS_REPO_FULL_NAME/releases/$CIRRUS_RELEASE/assets?name=$name" 27 | curl -X POST \ 28 | --data-binary @$fpath \ 29 | --header "Authorization: token $GITHUB_TOKEN" \ 30 | --header "Content-Type: $file_content_type" \ 31 | $url_to_upload 32 | done 33 | 34 | echo "Uploading $CIRRUS_TAG to PyPI" 35 | pip install twine 36 | twine upload $files_to_upload 37 | --------------------------------------------------------------------------------