{"id":43997435,"url":"https://github.com/rjfarmer/gfort2py","last_synced_at":"2026-02-07T12:02:45.977Z","repository":{"id":57434141,"uuid":"72889348","full_name":"rjfarmer/gfort2py","owner":"rjfarmer","description":"Library to allow calling fortran code from python","archived":false,"fork":false,"pushed_at":"2026-01-19T20:11:24.000Z","size":1011,"stargazers_count":121,"open_issues_count":6,"forks_count":22,"subscribers_count":9,"default_branch":"main","last_synced_at":"2026-01-27T05:59:36.245Z","etag":null,"topics":["bindings","ctypes","fortran","gfortran","python"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rjfarmer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"docs/support.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":".zenodo.json","notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-11-04T22:16:42.000Z","updated_at":"2026-01-12T18:52:23.000Z","dependencies_parsed_at":"2023-12-01T18:41:12.174Z","dependency_job_id":"922ffe86-f29d-4776-8f18-d79d4bb77e43","html_url":"https://github.com/rjfarmer/gfort2py","commit_stats":{"total_commits":322,"total_committers":5,"mean_commits":64.4,"dds":"0.33229813664596275","last_synced_commit":"c8b897cd073eb55760f727f77c7196318a532ff2"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/rjfarmer/gfort2py","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rjfarmer%2Fgfort2py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rjfarmer%2Fgfort2py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rjfarmer%2Fgfort2py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rjfarmer%2Fgfort2py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rjfarmer","download_url":"https://codeload.github.com/rjfarmer/gfort2py/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rjfarmer%2Fgfort2py/sbom","scorecard":{"id":777897,"data":{"date":"2025-08-11","repo":{"name":"github.com/rjfarmer/gfort2py","commit":"2e23461bb02d977fd53a7788ede9652b2c635322"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5.7,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/24 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":3,"reason":"4 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":9,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/zizmor.yml:16","Info: jobLevel 'actions' permission set to 'read': .github/workflows/zizmor.yml:17","Info: found token with 'none' permissions: .github/workflows/black.yml:1","Info: found token with 'none' permissions: .github/workflows/coveralls.yml:1","Info: found token with 'none' permissions: .github/workflows/cygwin.yml:1","Info: found token with 'none' permissions: .github/workflows/linux.yml:1","Info: found token with 'none' permissions: .github/workflows/macos.yml:1","Info: found token with 'none' permissions: .github/workflows/pypi.yml:1","Info: found token with 'none' permissions: .github/workflows/pypy.yml:1","Info: found token with 'none' permissions: .github/workflows/qemu.yml:1","Info: found token with 'none' permissions: .github/workflows/windows.yml:1","Info: found token with 'none' permissions: .github/workflows/zenodo.yml:1","Warn: no topLevel permission defined: .github/workflows/zizmor.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/black.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/black.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/black.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/black.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/coveralls.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/coveralls.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/coveralls.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/coveralls.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/cygwin.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/cygwin.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/cygwin.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/cygwin.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/cygwin.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/cygwin.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/cygwin.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/cygwin.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/linux.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/linux.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/linux.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/linux.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/linux.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/linux.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/macos.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/macos.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/macos.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/macos.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/macos.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/macos.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/pypi.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/pypi.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pypi.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/pypi.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypy.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/pypy.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypy.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/pypy.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pypy.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/pypy.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/qemu.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/qemu.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/qemu.yml:63: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/qemu.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/windows.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/windows.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/windows.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/windows.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/windows.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/windows.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/zenodo.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/zenodo.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/zenodo.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/zenodo.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/zizmor.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/zizmor.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/zizmor.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/zizmor.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/zizmor.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/rjfarmer/gfort2py/zizmor.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/scripts/run_arm.sh:18","Warn: pipCommand not pinned by hash: .github/workflows/scripts/run_ppc64.sh:19","Warn: pipCommand not pinned by hash: .github/workflows/scripts/run_s390x.sh:18","Warn: pipCommand not pinned by hash: .github/workflows/coveralls.yml:33","Warn: pipCommand not pinned by hash: .github/workflows/coveralls.yml:34","Warn: pipCommand not pinned by hash: .github/workflows/coveralls.yml:40","Warn: pipCommand not pinned by hash: .github/workflows/linux.yml:32","Warn: pipCommand not pinned by hash: .github/workflows/linux.yml:33","Warn: pipCommand not pinned by hash: .github/workflows/linux.yml:43","Warn: pipCommand not pinned by hash: .github/workflows/macos.yml:31","Warn: pipCommand not pinned by hash: .github/workflows/macos.yml:32","Warn: pipCommand not pinned by hash: .github/workflows/macos.yml:42","Warn: pipCommand not pinned by hash: .github/workflows/pypi.yml:26","Warn: pipCommand not pinned by hash: .github/workflows/pypi.yml:27","Warn: pipCommand not pinned by hash: .github/workflows/pypi.yml:38","Warn: pipCommand not pinned by hash: .github/workflows/qemu.yml:77","Warn: pipCommand not pinned by hash: .github/workflows/qemu.yml:78","Warn: pipCommand not pinned by hash: .github/workflows/zenodo.yml:21","Info:   0 out of  21 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   9 third-party GitHubAction dependencies pinned","Info:   1 out of  19 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: COPYING.txt:0","Info: FSF or OSI recognized license: GNU General Public License v2.0: COPYING.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/pypi.yml:6"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":3,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Warn: branch 'main' does not require approvers","Warn: codeowners review is not required on branch 'main'","Warn: no status checks found to merge onto branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":10,"reason":"SAST tool is run on all commits","details":["Info: all commits (6) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-23T04:06:21.054Z","repository_id":57434141,"created_at":"2025-08-23T04:06:21.054Z","updated_at":"2025-08-23T04:06:21.054Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29194007,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T07:37:03.739Z","status":"ssl_error","status_checked_at":"2026-02-07T07:37:03.029Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bindings","ctypes","fortran","gfortran","python"],"created_at":"2026-02-07T12:02:31.010Z","updated_at":"2026-02-07T12:02:45.960Z","avatar_url":"https://github.com/rjfarmer.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Continuous Integration](https://github.com/rjfarmer/gfort2py/actions/workflows/linux.yml/badge.svg)](https://github.com/rjfarmer/gfort2py/actions/workflows/linux.yml)\n[![Coverage Status](https://coveralls.io/repos/github/rjfarmer/gfort2py/badge.svg?branch=main)](https://coveralls.io/github/rjfarmer/gfort2py?branch=main)\n[![PyPI version](https://badge.fury.io/py/gfort2py.svg)](https://badge.fury.io/py/gfort2py)\n[![DOI](https://zenodo.org/badge/72889348.svg)](https://zenodo.org/badge/latestdoi/72889348)\n[![Python versions](https://img.shields.io/pypi/pyversions/gfort2py.svg)](https://img.shields.io/pypi/pyversions/gfort2py.svg)\n[![gfortran versions](https://img.shields.io/badge/gfortran-8%7C9%7C10%7C11%7C12%7C13-blue)](https://img.shields.io/badge/gfortran-8%7C9%7C10%7C11%7C12%7C13-blue)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/gfort2py)\n\n\n# gfort2py\nLibrary to allow calling Fortran code from Python. Requires gfortran\u003e=8.0, Works with python \u003e= 3.8\n\n## Build\nInstalling locally:\n````bash\npython -m pip install .\n````\n\nor install via pypi\n````bash\npython -m pip install --upgrade --user gfort2py\n````\n\nFor a full list of supportetd platforms [see the support documentation](docs/support.md).\n\n## Why use this over other Fortran to Python translators?\n\ngfort2py has three main aims:\n\n1. Make it trivially easy to call Fortran code from Python\n2. Minimise the number of changes needed in the Fortran code to make this work.\n3. Support as many Fortran features as possible.\n\nWe achieve this by tightly coupling the code to the gfortran compiler, by doing so we can easily embed assumptions about how advanced Fortran features work which makes development easier and minimises the number of changes needed on the Fortran side. \n\ngfort2py use the gfortran ``mod`` files to translate your Fortran code's ABI to Python-compatible types using Python's ctype library.\nBy using the ``mod`` file we can determine the call signature of all procedures, components of derived types, and the size and shapes of all module-level variables. As long as your code is inside a Fortran module, no other changes are needed to your Fortran code.\n\nThe downside to this approach is that we are tightly tied to gfortran's ABI, which means we can not support other non-gfortran compilers and we do not support all versions of gfortran. When gfortran next breaks its ABI (which happens rarely, the last break was gfortran 8) we will re-evaluate our supported gfortran versions.\n\n## Using\n\nThere are two ways to load Fortran code into Python.\nEither ``fFort`` or ``compile``. The recommended way\nis via ``fFort`` for interfacing with existing code,\nwhile ``compile`` is more suitable for wrapping short snippets of Fortran code\n\n### fFort\n\nYour Fortran code must be inside a module and then compiled as a shared library.\n\nOn linux: \n````bash\ngfortran -fPIC -shared -c file.f90\ngfortran -fPIC -shared -o libfile.so file.f90\n````\n\nOn MacOS: \n````bash\ngfortran -dynamiclib -c file.f90\ngfortran -dynamiclib -o libfile.dylib file.f90\n````\n\nOn Windows:\n````bash\ngfortran -shared -c file.f90\ngfortran -shared -o libfile.dll file.f90\n````\n\nIf the shared library needs other\nshared libraries you may need to set the ``LD_LIBRARY_PATH`` environment variable, and it is also recommended to run chrpath on the shared \nlibraries so you can access them from anywhere.\n\n#### Python side\n````python\n\nimport gfort2py as gf\n\nSHARED_LIB_NAME=f'./test_mod.{gf.lib_ext()}' # Handle whether on Linux, Mac, or Windows\nMOD_FILE_NAME='tester.mod'\n\nx=gf.fFort(SHARED_LIB_NAME,MOD_FILE_NAME) \n\n````\n\n\u003e **_NOTE:_** The mod data is cached to speed up re-reading the data. To control this pass cache_folder to ``fFort``.\nA value of False disables caching, a string sets the folder location, while leaving the argument as None defaults to platformdirs ``user_cache_dir``\n\n\n\n### compile\n\n````python\n\nimport gfort2py as gf\n\n\nfstr = \"\"\"\n            integer function myfunc(x,y)\n                integer :: x,y\n                myfunc = x+y\n            end function myfunc\n\"\"\"\n\nx  = gf.compile(string=fstr)\n\n````\n\nThe Fortran code can also be in a file in which case:\n\n\n````python\n\nimport gfort2py as gf\n\nx  = gf.compile(file='my_fortran_file.f90')\n\n````\n\nIn either casee the code will be compilied into a\nFortran module and then into a shared library. Any Fortran code is valid as long as it can be inserted into a Fortran Module (Its optional whether you need to wrap things in ``module``/``end module``, if you do not then that is done automatically for you).\n\nAdditional options available for ``compile``:\n\n- FC: str Path to gfortran compilier\n- FFLAGS: str Additional Fortran compile options. This defaults to -O2.\n- LDLIBS: str Any additional libraries needed to be linked in (-l)\n- LDFLAGS: str Locations of addtional libraries (-L)\n- ouput: str Location to save intermediate files to. Defaults to ``None`` which saves files in a temporary location. Otherwise save to the location specified.\n\n\u003e **_NOTE:_** The interface to compile is currently considered unstable and may change.\n\n### Interface\n\n\n``x`` now contains all variables, parameters and procedures from the module (tab completable), and is independant on how the Fortran code was loaded.\n\n\n### Functions\n````python\ny = x.func_name(a,b,c)\n````\n\nWill call the Fortran function with variables ``a,b,c`` and returns the result in ``y``.\n\n``y`` will be  named tuple which contains (result, args). Where ``result`` is a python object for the return value (0 if a subroutine) and where args is a dict containing all arguments passed to the procedure (both those with intent (in) which will be unchanged and intent(inout/out) which may have changed).\n\n\n### Variables\n\n````python\nx.some_var = 1\n````\n\nSets a module variable to 1, will attempt to coerce it to the Fortran type\n\n````python\nx.some_var\n````\n\nWill return a Python object \n\n\nOptional arguments that are not present should be passed as a Python ``None``.\n\n\n### Arrays\n\nArrays should be passed as a NumPy array of the correct size and shape.\n\n\nRemember that Fortran by default has 1-based array numbering while Numpy\nis 0-based.\n\n\nIf a procedure expects an unallocated array, then pass None as the argument, otherwise pass an array of the correct shape.\n\n### Derived types\n\nDerived types can be set with a dict \n````python\nx.my_dt={'x':1,'y':'abc'}\n````\n\n````python\ny=x.my_dt\ny['x']\ny['y']\n````\nIf the derived type contains another derived type then you can set a dict in a dict\n\n````python\nx.my_dt={'x':1,'y':{'a':1}}\n````\n\nWhen setting the components of a derived type you do not need to specify\nall of them at the same time.\n\n\nIf you have an array of derived types\n\n````fortran\ntype(my_type), dimension(5) :: my_dt\ntype(my_type), dimension(5,5) :: my_dt2\n````\n\nElements can be accessed via an index:\n\n````python\nx.my_dt[0]['x']\nx.my_dt2[0,0]['x']\n````\n\nYou can only access one component at a time (i.e no striding [:]). Allocatable derived types are not yet supported.\n\nDerived types that are dummy arguments to a procedure are returned as a ``fDT`` type. This is a dict-like object where the components\ncan only be accessed via the item interface ``['x']`` and not as attributes ``.x``.  This was done so that we do not have a name collision\nbetween Python functions (``keys``, ``items`` etc) and any Fortran-derived type components.\n\nYou can pass a ``fDT`` as an argument to a procedure.\n\n\n### Quad precision variables\n\nQuad precision (REAL128) variables are not natively supported by Python thus we need a different way to handle them. For now that is the [pyQuadp library](https://github.com/rjfarmer/pyQuadp) which can be installed from PyPi with:\n\n````bash\npython -m pip install pyquadp\n````\n\nor from a git checkout:\n\n````bash\npython -m pip install .[qaud]\n````\n\nFor more details see pyQuadp's documentation, but briefly you can create a \nquad precision variable from an ``int``, ``float``, or ``string``. On return you will receive a ``qfloat`` type. This ``qfloat`` type acts like a Python Number, so you can do things like add, multiply, subtract etc this Number with other Numbers (including non-``qfloat`` types).\n\nWe currently only support scalar Quad's and scalar complex Quad's. Arrays of\nquad precision values is planned but not yet supported. Quad values can also not be returned as a function result (this is a limitation in ``ctypes`` which we have no control over). Thus a quad precision value can only occur in:\n\n- Module variables\n- Parameters\n- Procedure arguments\n\n``pyQuadp`` is currently an optional requirement, you must manually install it, it does not get auto-installed when ``gfort2py`` is installed. If you try to access a quad precision variable without ``pyQuadp`` you should get a ``TypeError``.\n\n\n### Callback arguments\n\nTo pass a Fortran function as a callback argument to another function then pass the function directly:\n\n````python\n\ny = x.callback_function(1)\n\ny = x.another_function(x.callback_function)\n\n````\n\nCurrently only Fortran functions can be passed. No checking is done to ensure that the callback function has the \ncorrect signature to be a callback to the second function.\n\nThe callback and also be created in Python at runtime (but must be valid Fortran):\n\n````python\n\nfstr = \"\"\"\n        integer function callback(x)\n            integer :: x\n            write(*,*) x\n            callback = 3*x\n        end function callback\n\n        \"\"\"\n\nf = gf.compile(fstr)\n\n\ny = x.another_function(f.callback)\n\n````\n\n\n\n## Testing\n\n````bash\npython -m pip install .[test]\npytest -v\n````\n\nTo run unit tests\n\n## Things that work\n\n### Module variables\n\n- [x] Scalars\n- [x] Parameters\n- [x] Characters\n- [x] Explicit size arrays\n- [X] Complex numbers (Scalar and parameters)\n- [x] Getting a pointer\n- [x] Getting the value of a pointer\n- [x] Allocatable arrays\n- [x] Derived types\n- [x] Nested derived types\n- [X] Explicit Arrays of derived types\n- [ ] Allocatable Arrays of derived types\n- [ ] Procedure pointers inside derived types\n- [x] Derived types with dimension(:) array components (pointer, allocatable, target)\n- [x] Allocatable strings (partial)\n- [x] Explicit Arrays of strings\n- [x] Allocatable arrays of strings\n- [ ] Classes\n- [ ] Abstract interfaces\n- [ ] Common blocks\n- [ ] Equivalences \n- [ ] Namelists\n- [ ] Quad precision variables\n- [ ] function overloading \n\n### Procedures\n\n- [X] Basic calling (no arguments)\n- [x] Argument passing (scalars)\n- [x] Argument passing (strings)\n- [X] Argument passing (explicit arrays)\n- [x] Argument passing (assumed size arrays)\n- [x] Argument passing (assumed shape arrays)\n- [x] Argument passing (allocatable arrays)\n- [x] Argument passing (derived types)\n- [x] Argument intents (in, out, inout and none)\n- [x] Passing characters of fixed size (len=10 or len=* etc)\n- [x] Functions that return a character as their result\n- [x] Allocatable strings (Only for things that do not get altered inside the procedure)\n- [x] Explicit arrays of strings\n- [x] Allocatable arrays of strings\n- [x] Pointer arguments \n- [x] Optional arguments\n- [x] Value arguments\n- [x] Keyword arguments\n- [ ] Generic/Elemental functions\n- [ ] Functions as an argument\n- [x] Unary operations (arguments that involve an expression to evaluate like dimension(n+1) or dimension((2*n)+1))\n- [x] Functions returning an explicit array as their result \n\n### Common block elements\n\nThere is no way currently to access components of a common block.\n\n\n## Accessing module file data\n\nFor those wanting to explore the module file format, there is a routine ``mod_info`` available from the top-level ``gfort2py`` module:\n\n````python\nmodule = gf.mod_info('file.mod')\n````\n\nThat will parse the mod file and convert it into an intermediate format inside ``module``.\n\nVariables or procedures can be looked up via the item interface (I also recommend using pprint for easier viewing):\n\n````\nfrom pprint import pprint\n\npprint(module['a_variable'])\n````\n\nAccessing the list of all available components can be had via ``module.keys()``.\n\nYou can also do:\n````python\nmodule = gf.mod_info('file.mod',json=True)\nmodule['a_variable']\n````\n\nThen when you access each component the return value will be JSON-formatted. Note you can currently only access each component as JSON not the whole module file as JSON at the moment.\n\n\n## Contributing\n\nBug reports are of course welcome and PR's should target the main branch.\n\nFor those wanting to get more involved, adding Fortran examples to the test suite of currently untested or unsupported features would be helpful. Bonus points if you also provide a Python test case (that can be marked ``@pytest.mark.skip`` if it does not work) that demonstrates the proposed interface to the new Fortran feature. Features with test cases will move higher in the order of things I add to the code.\n\nSee [how to write a test case](docs/test_suite.md) for details on how to write test cases.\n\nFor those wanting to go further and add the new feature themselves open a bug report and we can chat about what needs doing.\n\n## Debugging\n\n[Debugging instructions are here](docs/debugging.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frjfarmer%2Fgfort2py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frjfarmer%2Fgfort2py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frjfarmer%2Fgfort2py/lists"}