From f529cab06608303a03f2f5c1a186f7a849edb113 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 21:35:20 +0000 Subject: [PATCH 01/18] Bump actions/setup-python from 4 to 5 (#46) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/coveralls.yml | 2 +- .github/workflows/pypi.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fb2fa9c..a3d26e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: 'pip' diff --git a/.github/workflows/coveralls.yml b/.github/workflows/coveralls.yml index ec9b305..123a941 100644 --- a/.github/workflows/coveralls.yml +++ b/.github/workflows/coveralls.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: 'pip' diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index fa08eb9..30bdf05 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: cache: 'pip' From e307d5816d2116c6aa24121b71080fe913a5be1a Mon Sep 17 00:00:00 2001 From: Robert Farmer Date: Thu, 18 Jan 2024 22:21:22 +0000 Subject: [PATCH 02/18] Add test for exp (**) in arg list --- tests/explicit_arrays.f90 | 10 ++++++++++ tests/explicit_arrays_test.py | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/tests/explicit_arrays.f90 b/tests/explicit_arrays.f90 index 24f0ec8..d7053b0 100644 --- a/tests/explicit_arrays.f90 +++ b/tests/explicit_arrays.f90 @@ -242,4 +242,14 @@ function func_return_2d_int_arr() result(x) end function func_return_2d_int_arr + + subroutine func_exp_array_in(n,x) + integer, intent(in) :: n + integer, dimension(2*n,2**n) :: x + + x = 5 + + end subroutine func_exp_array_in + + end module explicit_arrays diff --git a/tests/explicit_arrays_test.py b/tests/explicit_arrays_test.py index b8b7325..f22ab33 100644 --- a/tests/explicit_arrays_test.py +++ b/tests/explicit_arrays_test.py @@ -315,3 +315,13 @@ def test_func_return_2d_int_arr(self): assert np.array_equal( res.result, np.array([1, 2, 3, 4, 5, 6]).reshape(3, 2, order="F") ) + + def test_func_exp_array_in(self): + n = 3 + y = np.zeros((2 * n, 2**n), dtype=int) + + res = x.func_exp_array_in(n, y) + + result = np.zeros(np.shape(y), dtype=int) + result[:, :] = 5 + assert np.array_equal(res.args["x"], result) From 51dd200c2ecb1191bcd43c03893a0062ea508203 Mon Sep 17 00:00:00 2001 From: Rob farmer Date: Sun, 21 Jan 2024 19:38:50 +0000 Subject: [PATCH 03/18] Get cygwin working --- .github/workflows/cygwin.yml | 6 ++++++ gfort2py/utils.py | 2 +- tests/compile_test.py | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml index 2863874..7d17fb7 100644 --- a/.github/workflows/cygwin.yml +++ b/.github/workflows/cygwin.yml @@ -19,6 +19,12 @@ jobs: python39-devel python39-pip python-pip-wheel python-setuptools-wheel liblapack-devel liblapack0 gcc-fortran git dash python39-numpy automake + - name: pip cache + uses: actions/cache@v4 + with: + path: 'C:\cygwin\home\runneradmin\.cache\pip' + key: ${{ runner.os }}-${{ hashFiles('pyproject.toml') }} + - name: Set Windows PATH uses: egor-tensin/cleanup-path@v3 with: diff --git a/gfort2py/utils.py b/gfort2py/utils.py index 83e0dfe..d381531 100644 --- a/gfort2py/utils.py +++ b/gfort2py/utils.py @@ -92,7 +92,7 @@ def library_ext(): os_platform = platform.system() if os_platform == "Darwin": return "dylib" - elif os_platform == "Windows": + elif os_platform == "Windows" or 'CYGWIN' in os_platform: return "dll" else: return "so" diff --git a/tests/compile_test.py b/tests/compile_test.py index 01709a9..2fc88cb 100644 --- a/tests/compile_test.py +++ b/tests/compile_test.py @@ -28,13 +28,13 @@ def test_compile_nomod_str(self): def test_compile_mod_str(self): fstr = """ - module a + module abc contains integer function myfunc(x,y) integer :: x,y myfunc = x+y end function myfunc - end module + end module abc """ x = gf.compile(string=fstr) From cd6bb8262a5730bd900abda3fc610ddd8c1aaa18 Mon Sep 17 00:00:00 2001 From: Rob farmer Date: Sun, 21 Jan 2024 19:56:53 +0000 Subject: [PATCH 04/18] Add missing make to cygwin --- .github/workflows/cygwin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml index 7d17fb7..6739d52 100644 --- a/.github/workflows/cygwin.yml +++ b/.github/workflows/cygwin.yml @@ -17,7 +17,7 @@ jobs: install-dir: 'C:\tools\cygwin' packages: >- python39-devel python39-pip python-pip-wheel python-setuptools-wheel - liblapack-devel liblapack0 gcc-fortran git dash python39-numpy automake + liblapack-devel liblapack0 gcc-fortran git dash python39-numpy automake make - name: pip cache uses: actions/cache@v4 From 8683ce70eb4a720c5f748b122829efe104305588 Mon Sep 17 00:00:00 2001 From: Rob Farmer Date: Sun, 21 Jan 2024 20:19:25 +0000 Subject: [PATCH 05/18] Fix linting --- gfort2py/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfort2py/utils.py b/gfort2py/utils.py index d381531..92b547c 100644 --- a/gfort2py/utils.py +++ b/gfort2py/utils.py @@ -92,7 +92,7 @@ def library_ext(): os_platform = platform.system() if os_platform == "Darwin": return "dylib" - elif os_platform == "Windows" or 'CYGWIN' in os_platform: + elif os_platform == "Windows" or "CYGWIN" in os_platform: return "dll" else: return "so" From 6ae070407b85f9bddf672d2c3e10d7447996556c Mon Sep 17 00:00:00 2001 From: Rob Farmer Date: Sun, 21 Jan 2024 20:39:44 +0000 Subject: [PATCH 06/18] Add pypy test --- .github/workflows/pypy.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/pypy.yml diff --git a/.github/workflows/pypy.yml b/.github/workflows/pypy.yml new file mode 100644 index 0000000..ed9770f --- /dev/null +++ b/.github/workflows/pypy.yml @@ -0,0 +1,35 @@ +name: PyPy +on: [push, pull_request] + +jobs: + pypy: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + toolchain: + - {compiler: gcc, version: 12} + + steps: + - uses: actions/checkout@v4 + - name: Set up PyPy + uses: actions/setup-python@v5 + with: + python-version: 'pypy3.9' + cache: 'pip' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install build wheel pytest + + - uses: fortran-lang/setup-fortran@v1 + id: setup-fortran + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + + - name: Build and test + run: + pypy3 -m build . + pypy3 -m pytest -v From f20069bf34227fbec19f61497be4523725abc446 Mon Sep 17 00:00:00 2001 From: Rob Farmer Date: Sun, 21 Jan 2024 20:50:48 +0000 Subject: [PATCH 07/18] Fix pypy workflow --- .github/workflows/pypy.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pypy.yml b/.github/workflows/pypy.yml index ed9770f..4996799 100644 --- a/.github/workflows/pypy.yml +++ b/.github/workflows/pypy.yml @@ -21,7 +21,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install build wheel pytest + python -m pip install build wheel pytest numpy platformdirs cpyparsing - uses: fortran-lang/setup-fortran@v1 id: setup-fortran @@ -29,7 +29,8 @@ jobs: compiler: ${{ matrix.toolchain.compiler }} version: ${{ matrix.toolchain.version }} - - name: Build and test - run: - pypy3 -m build . - pypy3 -m pytest -v + - name: Build + run: pypy3 -m build . + + - name: Test + run: pypy3 -m pytest -v From 378f7d35cc2388b4ac126113fc35e1a8b41f4521 Mon Sep 17 00:00:00 2001 From: Rob Farmer Date: Sun, 21 Jan 2024 20:55:49 +0000 Subject: [PATCH 08/18] Switch to pytest over tox --- .github/workflows/ci.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3d26e7..b32a210 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install tox tox-gh-actions build wheel pytest + python -m pip install build wheel pytest - uses: fortran-lang/setup-fortran@v1 id: setup-fortran @@ -50,9 +50,10 @@ jobs: compiler: ${{ matrix.toolchain.compiler }} version: ${{ matrix.toolchain.version }} - - name: Run tox - run: tox -e py - env: - FC: ${{ env.FC }} - _GFORT2PY_TEST_FLAG: 1 + - name: Build + run: python -m pip install . + + + - name: Test + run: python -m pytest -v From 039a84b528cecce0f85c31c1243ee5fd820b4bbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jan 2024 19:15:13 +0000 Subject: [PATCH 09/18] Bump actions/cache from 3 to 4 (#49) Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/qemu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/qemu.yml b/.github/workflows/qemu.yml index 564cc9d..b9a4c50 100644 --- a/.github/workflows/qemu.yml +++ b/.github/workflows/qemu.yml @@ -68,7 +68,7 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - name: Cache docker container - uses: actions/cache@v3 + uses: actions/cache@v4 id: container-cache with: path: ~/docker_${{ matrix.BUILD_PROP[1] }} From ee85f821ff7a67497696c44fe04d73a1bd43a681 Mon Sep 17 00:00:00 2001 From: Rob Farmer Date: Wed, 24 Jan 2024 19:38:34 +0000 Subject: [PATCH 10/18] Re-organise ci tests --- .github/workflows/{ci.yml => linux.yml} | 6 +-- .github/workflows/macos.yml | 46 +++++++++++++++++ .github/workflows/windows.yml | 45 +++++++++++++++++ README.md | 66 +------------------------ 4 files changed, 96 insertions(+), 67 deletions(-) rename .github/workflows/{ci.yml => linux.yml} (94%) create mode 100644 .github/workflows/macos.yml create mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/linux.yml similarity index 94% rename from .github/workflows/ci.yml rename to .github/workflows/linux.yml index b32a210..05257bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/linux.yml @@ -1,13 +1,13 @@ -name: CI +name: Linux CI on: [push, pull_request] jobs: - CI: + linux_ci: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: [ubuntu-20.04, ubuntu-22.04, macos-latest, windows-latest] + os: [ubuntu-20.04, ubuntu-22.04] python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] toolchain: - {compiler: gcc, version: 8} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml new file mode 100644 index 0000000..dd4de4a --- /dev/null +++ b/.github/workflows/macos.yml @@ -0,0 +1,46 @@ +name: macOS CI +on: [push, pull_request] + +jobs: + macos_ci: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [macos-latest] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] + toolchain: + - {compiler: gcc, version: 8} + - {compiler: gcc, version: 9} + - {compiler: gcc, version: 10} + - {compiler: gcc, version: 11} + - {compiler: gcc, version: 12} + - {compiler: gcc, version: 13} + + + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install build wheel pytest + + - uses: fortran-lang/setup-fortran@v1 + id: setup-fortran + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + + - name: Build + run: python -m pip install . + + + - name: Test + run: python -m pytest -v + diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 0000000..8c8c161 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,45 @@ +name: windows CI +on: [push, pull_request] + +jobs: + windows_ci: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [windows-latest] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] + toolchain: + - {compiler: gcc, version: 8} + - {compiler: gcc, version: 9} + - {compiler: gcc, version: 10} + - {compiler: gcc, version: 11} + - {compiler: gcc, version: 12} + - {compiler: gcc, version: 13} + + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install build wheel pytest + + - uses: fortran-lang/setup-fortran@v1 + id: setup-fortran + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + + - name: Build + run: python -m pip install . + + + - name: Test + run: python -m pytest -v + diff --git a/README.md b/README.md index eb560ac..f9f2b8f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Continuous Integration](https://github.com/rjfarmer/gfort2py/actions/workflows/ci.yml/badge.svg)](https://github.com/rjfarmer/gfort2py/actions/workflows/ci.yml) +[![Continuous Integration](https://github.com/rjfarmer/gfort2py/actions/workflows/linux.yml/badge.svg)](https://github.com/rjfarmer/gfort2py/actions/workflows/linux.yml) [![Coverage Status](https://coveralls.io/repos/github/rjfarmer/gfort2py/badge.svg?branch=main)](https://coveralls.io/github/rjfarmer/gfort2py?branch=main) [![PyPI version](https://badge.fury.io/py/gfort2py.svg)](https://badge.fury.io/py/gfort2py) [![DOI](https://zenodo.org/badge/72889348.svg)](https://zenodo.org/badge/latestdoi/72889348) @@ -278,13 +278,7 @@ y = x.another_function(f.callback) ## Testing ````bash -pytest -```` - -or - -````bash -tox +pytest -v ```` To run unit tests @@ -365,62 +359,6 @@ x.b x.c ```` - - - - - ## Accessing module file data For those wanting to explore the module file format, there is a routine ``mod_info`` available from the top-level ``gfort2py`` module: From 0e8f86a164680d2c340dfc53324749ebbd6647d3 Mon Sep 17 00:00:00 2001 From: Rob Farmer Date: Wed, 24 Jan 2024 19:46:35 +0000 Subject: [PATCH 11/18] Add optional dependencies Closes #48 --- README.md | 7 +++++++ pyproject.toml | 3 +++ 2 files changed, 10 insertions(+) diff --git a/README.md b/README.md index f9f2b8f..4f7f675 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,12 @@ Quad precision (REAL128) variables are not natively supported by Python thus we python -m pip install pyquadp ```` +or from a git checkout: + +````bash +python -m pip install .[qaud] +```` + For more details see pyQuadp's documentation, but briefly you can create a quad 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). @@ -278,6 +284,7 @@ y = x.another_function(f.callback) ## Testing ````bash +python -m pip install .[test] pytest -v ```` diff --git a/pyproject.toml b/pyproject.toml index 0854b6b..2dcb004 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,3 +44,6 @@ dependencies = [ dynamic = ["version"] +[project.optional-dependencies] +test = ['pytest'] +quad = ['pyquadp'] \ No newline at end of file From 044be19543c927b14760d60890d6089548365eb1 Mon Sep 17 00:00:00 2001 From: Rob Farmer Date: Wed, 24 Jan 2024 20:06:31 +0000 Subject: [PATCH 12/18] Add ability to output JSON formatted info for components closes #47 --- README.md | 9 +++++++ gfort2py/gfort2py.py | 5 ++-- gfort2py/module_parse.py | 53 +++++++++++++++++++++++----------------- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 4f7f675..4fdb3b1 100644 --- a/README.md +++ b/README.md @@ -386,6 +386,15 @@ pprint(module['a_variable']) Accessing the list of all available components can be had via ``module.keys()``. +You can also do: +````python +module = gf.mod_info('file.mod',json=True) +module['a_variable'] +```` + +Then 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. + + ## Contributing Bug reports are of course welcome and PR's should target the main branch. diff --git a/gfort2py/gfort2py.py b/gfort2py/gfort2py.py index de0f4bc..0fd679c 100644 --- a/gfort2py/gfort2py.py +++ b/gfort2py/gfort2py.py @@ -132,13 +132,14 @@ def __str__(self): return f"{self._module.filename}" -def mod_info(mod_file, load_only=False): +def mod_info(mod_file, *,load_only=False, json=False): """ Returns a parsed data structure that describes the module pprint is recommened to help understand the nested structure. """ - return module(mod_file, load_only=load_only) + return module(mod_file, load_only=load_only, json=json) + def lib_ext(): diff --git a/gfort2py/module_parse.py b/gfort2py/module_parse.py index f6a3862..76ca8e9 100644 --- a/gfort2py/module_parse.py +++ b/gfort2py/module_parse.py @@ -3,6 +3,7 @@ # https://github.com/gcc-mirror/gcc/blob/master/gcc/fortran/module.cc from cPyparsing import OneOrMore, nestedExpr from dataclasses import dataclass +from dataclasses_json import dataclass_json import numpy as np import gzip import sys @@ -45,7 +46,7 @@ class NotAnArrayError(Exception): ################################# - +@dataclass_json @dataclass class s_item: name: str @@ -93,7 +94,7 @@ def names(self): ################################# - +@dataclass_json @dataclass class symbol_ref: ref: int = -1 @@ -104,7 +105,7 @@ def __post_init__(self): ################################# - +@dataclass_json @dataclass(init=False) class c_item: name: str = "" @@ -129,7 +130,7 @@ def __init__(self, *args): ################################# - +@dataclass_json @dataclass(init=False) class generics: name: str = "" @@ -381,7 +382,7 @@ def dt_type(self): def dt_components(self): return self.sym.comp - +@dataclass_json @dataclass(init=False) class attribute: flavor: str = "" @@ -404,7 +405,7 @@ def __init__(self, *args): self.attributes = set([string_clean(i) for i in args[7:]]) self.raw = args - +@dataclass_json @dataclass class namespace: ref: int = -1 @@ -412,7 +413,7 @@ class namespace: def __post_init__(self): self.ref = symbol_ref(self.ref) - +@dataclass_json @dataclass class header: id: int @@ -435,7 +436,7 @@ def mn_name(self): return f"__{self.module}_MOD_{self.name}" - +@dataclass_json @dataclass(init=False) class formal_arglist: symbol: t.List[symbol_ref] = None @@ -453,7 +454,7 @@ def __len__(self): def __iter__(self): return iter(self.symbol) - +@dataclass_json @dataclass(init=False) class typebound_proc: name: str = "" @@ -482,7 +483,7 @@ def __init__(self, *args, **kwargs): self.raw = args self.kwargs = kwargs - +@dataclass_json @dataclass(init=False) class derived_ns: unknown1: str = None @@ -499,14 +500,14 @@ def __init__(self, *args, **kwargs): for i in args[1]: self.proc.append(typebound_proc(i)) - +@dataclass_json @dataclass(init=False) class actual_arglist: def __init__(self, *args, **kwargs): self.raw = args self.kwargs = kwargs - +@dataclass_json @dataclass(init=False) class typespec: type: str = "" @@ -548,7 +549,7 @@ def __init__(self, *args): except (TypeError, IndexError): self.deferred_cl = False - +@dataclass_json @dataclass(init=False) class expression: exp_type: str = "" @@ -635,7 +636,7 @@ def value(self): def value(self, value): self._resolved_value = value - +@dataclass_json @dataclass(init=False) class arrayspec: rank: int = -1 @@ -683,7 +684,7 @@ def pyshape(self): def size(self): return np.prod(self.pyshape) - +@dataclass_json @dataclass(init=False) class component(utils): id: int = -1 @@ -723,7 +724,7 @@ def __init__(self, *args): # inside the parent utils class self.sym = self - +@dataclass_json @dataclass(init=False) class components: comp: t.List[component] = None @@ -741,7 +742,7 @@ def __len__(self): def __iter__(self): return iter(self.comp) - +@dataclass_json @dataclass(init=False) class namelist: sym_ref: t.List[symbol_ref] = None @@ -753,7 +754,7 @@ def __init__(self, *args): for i in args: self.sym_ref.append(symbol_ref(i)) - +@dataclass_json @dataclass(init=False) class simd_dec: args: None @@ -763,7 +764,7 @@ def __init__(self, *args, **kwargs): self.raw = args self.kwargs = kwargs - +@dataclass_json @dataclass(init=False) class data: attr: attribute @@ -821,7 +822,7 @@ def __init__(self, *args): if args[15] is not None: self.simd = simd_dec(*args[14]) - +@dataclass_json @dataclass(init=False) class symbol(utils): head: header = None @@ -845,8 +846,10 @@ def mangled_name(self): class module(object): version = 15 - def __init__(self, filename, load_only=False, cache_folder=None): + def __init__(self, filename, load_only=False, + cache_folder=None, json=False): self.filename = filename + self._json=json with gzip.open(self.filename) as f: x = f.read().decode() @@ -927,11 +930,15 @@ def __contains__(self, key): def __getitem__(self, key): try: - return self.symbols[self.summary[key].id] + x = self.symbols[self.summary[key].id] except KeyError: # Not a global variable maybe a function argument? - return self.symbols[key] + x = self.symbols[key] + if self._json: + return x.to_json() + else: + return x if __name__ == "__main__": m = module(filename=sys.argv[1]) From 2ebfd48801e5574aa056577be2e28a58204e5827 Mon Sep 17 00:00:00 2001 From: Rob Farmer Date: Wed, 24 Jan 2024 20:16:20 +0000 Subject: [PATCH 13/18] Add missing dependency --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 2dcb004..1a501d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,7 @@ dependencies = [ "numpy", "cpyparsing", "platformdirs", + "dataclasses_json", ] dynamic = ["version"] From 2fe490cc02e6195d8539529ca19ecaf57240e8ef Mon Sep 17 00:00:00 2001 From: Rob Farmer Date: Wed, 24 Jan 2024 20:24:03 +0000 Subject: [PATCH 14/18] Setup formatting --- gfort2py/gfort2py.py | 3 +-- gfort2py/module_parse.py | 26 +++++++++++++++++++++++--- pyproject.toml | 3 ++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/gfort2py/gfort2py.py b/gfort2py/gfort2py.py index 0fd679c..d8392e4 100644 --- a/gfort2py/gfort2py.py +++ b/gfort2py/gfort2py.py @@ -132,14 +132,13 @@ def __str__(self): return f"{self._module.filename}" -def mod_info(mod_file, *,load_only=False, json=False): +def mod_info(mod_file, *, load_only=False, json=False): """ Returns a parsed data structure that describes the module pprint is recommened to help understand the nested structure. """ return module(mod_file, load_only=load_only, json=json) - def lib_ext(): diff --git a/gfort2py/module_parse.py b/gfort2py/module_parse.py index 76ca8e9..2ff5bd0 100644 --- a/gfort2py/module_parse.py +++ b/gfort2py/module_parse.py @@ -46,6 +46,7 @@ class NotAnArrayError(Exception): ################################# + @dataclass_json @dataclass class s_item: @@ -94,6 +95,7 @@ def names(self): ################################# + @dataclass_json @dataclass class symbol_ref: @@ -105,6 +107,7 @@ def __post_init__(self): ################################# + @dataclass_json @dataclass(init=False) class c_item: @@ -130,6 +133,7 @@ def __init__(self, *args): ################################# + @dataclass_json @dataclass(init=False) class generics: @@ -382,6 +386,7 @@ def dt_type(self): def dt_components(self): return self.sym.comp + @dataclass_json @dataclass(init=False) class attribute: @@ -405,6 +410,7 @@ def __init__(self, *args): self.attributes = set([string_clean(i) for i in args[7:]]) self.raw = args + @dataclass_json @dataclass class namespace: @@ -413,6 +419,7 @@ class namespace: def __post_init__(self): self.ref = symbol_ref(self.ref) + @dataclass_json @dataclass class header: @@ -436,6 +443,7 @@ def mn_name(self): return f"__{self.module}_MOD_{self.name}" + @dataclass_json @dataclass(init=False) class formal_arglist: @@ -454,6 +462,7 @@ def __len__(self): def __iter__(self): return iter(self.symbol) + @dataclass_json @dataclass(init=False) class typebound_proc: @@ -483,6 +492,7 @@ def __init__(self, *args, **kwargs): self.raw = args self.kwargs = kwargs + @dataclass_json @dataclass(init=False) class derived_ns: @@ -500,6 +510,7 @@ def __init__(self, *args, **kwargs): for i in args[1]: self.proc.append(typebound_proc(i)) + @dataclass_json @dataclass(init=False) class actual_arglist: @@ -507,6 +518,7 @@ def __init__(self, *args, **kwargs): self.raw = args self.kwargs = kwargs + @dataclass_json @dataclass(init=False) class typespec: @@ -549,6 +561,7 @@ def __init__(self, *args): except (TypeError, IndexError): self.deferred_cl = False + @dataclass_json @dataclass(init=False) class expression: @@ -636,6 +649,7 @@ def value(self): def value(self, value): self._resolved_value = value + @dataclass_json @dataclass(init=False) class arrayspec: @@ -684,6 +698,7 @@ def pyshape(self): def size(self): return np.prod(self.pyshape) + @dataclass_json @dataclass(init=False) class component(utils): @@ -724,6 +739,7 @@ def __init__(self, *args): # inside the parent utils class self.sym = self + @dataclass_json @dataclass(init=False) class components: @@ -742,6 +758,7 @@ def __len__(self): def __iter__(self): return iter(self.comp) + @dataclass_json @dataclass(init=False) class namelist: @@ -754,6 +771,7 @@ def __init__(self, *args): for i in args: self.sym_ref.append(symbol_ref(i)) + @dataclass_json @dataclass(init=False) class simd_dec: @@ -764,6 +782,7 @@ def __init__(self, *args, **kwargs): self.raw = args self.kwargs = kwargs + @dataclass_json @dataclass(init=False) class data: @@ -822,6 +841,7 @@ def __init__(self, *args): if args[15] is not None: self.simd = simd_dec(*args[14]) + @dataclass_json @dataclass(init=False) class symbol(utils): @@ -846,10 +866,9 @@ def mangled_name(self): class module(object): version = 15 - def __init__(self, filename, load_only=False, - cache_folder=None, json=False): + def __init__(self, filename, load_only=False, cache_folder=None, json=False): self.filename = filename - self._json=json + self._json = json with gzip.open(self.filename) as f: x = f.read().decode() @@ -940,6 +959,7 @@ def __getitem__(self, key): else: return x + if __name__ == "__main__": m = module(filename=sys.argv[1]) for i in m.keys(): diff --git a/pyproject.toml b/pyproject.toml index 1a501d5..5f2bd38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,4 +47,5 @@ dynamic = ["version"] [project.optional-dependencies] test = ['pytest'] -quad = ['pyquadp'] \ No newline at end of file +quad = ['pyquadp'] +dev = ['pre-commit','black'] \ No newline at end of file From c4d2b98d42f3964f7341fd9aad65bc8546a01ffd Mon Sep 17 00:00:00 2001 From: Rob Farmer Date: Wed, 24 Jan 2024 20:28:37 +0000 Subject: [PATCH 15/18] Fix pypy install --- .github/workflows/pypy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pypy.yml b/.github/workflows/pypy.yml index 4996799..1d85ad0 100644 --- a/.github/workflows/pypy.yml +++ b/.github/workflows/pypy.yml @@ -30,7 +30,7 @@ jobs: version: ${{ matrix.toolchain.version }} - name: Build - run: pypy3 -m build . + run: pypy3 -m pip install . - name: Test run: pypy3 -m pytest -v From abf7aca62e4c88e0cb642f13d3db4503a08e7724 Mon Sep 17 00:00:00 2001 From: Robert Farmer Date: Wed, 24 Jan 2024 20:51:25 +0000 Subject: [PATCH 16/18] Delete .readthedocs.yml --- .readthedocs.yml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 .readthedocs.yml diff --git a/.readthedocs.yml b/.readthedocs.yml deleted file mode 100644 index 8c3cd7b..0000000 --- a/.readthedocs.yml +++ /dev/null @@ -1,18 +0,0 @@ -# .readthedocs.yml -# Read the Docs configuration file -# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details - -# Required -version: 2 - -# Build documentation in the docs/ directory with Sphinx -sphinx: - configuration: docs/source/conf.py - -# Build documentation with MkDocs -#mkdocs: -# configuration: mkdocs.yml - -# Optionally build your docs in additional formats such as PDF and ePub -formats: all - From 1d36e9387e52ba9ea081ab394c5fd35c041c6804 Mon Sep 17 00:00:00 2001 From: Robert Farmer Date: Fri, 26 Jan 2024 19:37:50 +0000 Subject: [PATCH 17/18] Set some package version limits --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5f2bd38..1fe6b1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,10 +36,10 @@ classifiers = [ ] dependencies = [ - "numpy", - "cpyparsing", - "platformdirs", - "dataclasses_json", + "numpy >=1.13.0, <2", + "cpyparsing >=2.4.7, <=2.5", + "platformdirs >=3, <=5", + "dataclasses_json >=0.6, <=1.0", ] dynamic = ["version"] From 7f3de2acd664065d6369f437fb69532bd721ef4d Mon Sep 17 00:00:00 2001 From: Robert Farmer Date: Fri, 26 Jan 2024 19:45:08 +0000 Subject: [PATCH 18/18] Fix linter --- .pre-commit-config.yaml | 2 +- gfort2py/module_parse.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 82e8966..29355f3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ fail_fast: true repos: - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 24.1.0 hooks: - id: black language_version: python3 # Should be a command that runs python3.6+ diff --git a/gfort2py/module_parse.py b/gfort2py/module_parse.py index 2ff5bd0..e14bf71 100644 --- a/gfort2py/module_parse.py +++ b/gfort2py/module_parse.py @@ -570,7 +570,9 @@ class expression: rank: int = -1 _saved_value: t.Any = None _value: t.Any = None - _resolved_value: t.Any = None # value may by a symbol_ref, so this is the value after resolving the reference + _resolved_value: t.Any = ( + None # value may by a symbol_ref, so this is the value after resolving the reference + ) arglist: actual_arglist = None # PDT's? charlen: int = -1 unary_op: str = ""