From ab5f848e7a6c77c51a20107aae9f9f63c3c46f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dieter=20Werthm=C3=BCller?= Date: Wed, 18 Dec 2024 21:31:04 +0100 Subject: [PATCH 1/6] Change prisae->emsig --- .github/workflows/pytest.yml | 2 +- CHANGELOG.rst | 9 +++++++++ README.rst | 10 +++++----- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index ed61bbc..d0d5b05 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -65,7 +65,7 @@ jobs: name: Deploy to PyPI runs-on: ubuntu-latest # Only from the origin repository, not forks; only master. - if: github.repository_owner == 'prisae' && github.ref == 'refs/heads/master' + if: github.repository_owner == 'emsig' && github.ref == 'refs/heads/main' steps: # Checks-out your repository under $GITHUB_WORKSPACE diff --git a/CHANGELOG.rst b/CHANGELOG.rst index da55d7f..91bd377 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,15 @@ Changelog ######### + +v0.2.2 : Update home and build backend +-------------------------------------- + +No code changes. What changed: +- Moved from github.com/prisae to github.com/emsig. +- Ported build from distutils to meson (thanks @jokva). + + v0.2.1 : Fix packaging ---------------------- diff --git a/README.rst b/README.rst index 7641c67..3a99e66 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -.. image:: https://github.com/prisae/fftlog/workflows/pytest/badge.svg?branch=master - :target: https://github.com/prisae/fftlog/actions +.. image:: https://github.com/emsig/fftlog/workflows/pytest/badge.svg?branch=master + :target: https://github.com/emsig/fftlog/actions :alt: GitHub Actions .. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.3830534.svg :target: https://doi.org/10.5281/zenodo.3830534 @@ -13,8 +13,8 @@ This is a simple `f2py`-wrapper for the logarithmic FFT code *FFTLog* as presented in Appendix B of [Hami00]_ and published at `casa.colorado.edu/~ajsh/FFTLog `_. -A pure python version (`pyfftlog`) can be found on `github.com/prisae/pyfftlog -`_. Tests have shown that `fftlog` is a bit +A pure python version (`pyfftlog`) can be found on `github.com/emsig/pyfftlog +`_. Tests have shown that `fftlog` is a bit faster than `pyfftlog`, but `pyfftlog` is easier to implement, as you only need `NumPy` and `SciPy`, without the need to compile anything. @@ -28,7 +28,7 @@ test from the original code, and my use case, which is `pyfftlog.fftl` with (forward). Please let me know if you encounter any issues. - **Documentation**: https://pyfftlog.readthedocs.io -- **Source Code**: https://github.com/prisae/fftlog +- **Source Code**: https://github.com/emsig/fftlog **Note** that the documentation is for the pure python version `pyfftlog`, but equally applies to `fftlog`. From b551fc61bc9183ca5dba373ac149ebbbf6a2bb86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dieter=20Werthm=C3=BCller?= Date: Wed, 18 Dec 2024 21:51:20 +0100 Subject: [PATCH 2/6] Update workflow --- .github/workflows/pytest.yml | 87 +++++++++++++----------------------- 1 file changed, 30 insertions(+), 57 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index d0d5b05..52b1b73 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -1,14 +1,21 @@ name: pytest -# Only build PRs, the master branch, and releases. +# Only build PRs, the main branch, and releases. on: pull_request: push: branches: - - master + - main release: types: - published + schedule: + - cron: "14 14 20 * *" + +# Cancel any previous run of the test job. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: test: @@ -19,19 +26,13 @@ jobs: fail-fast: false matrix: os: [ubuntu, ] # macos, windows] # Only Linux currently. - python-version: [3.6, 3.7, 3.8] + python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - # Cancel any previous run of the test job; [pin v0.6.0] - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@ce177499ccf9fd2aded3b0426c97e5434c2e8a73 - with: - access_token: ${{ github.token }} - # Checks-out your repository under $GITHUB_WORKSPACE - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: # Need to fetch more than the last commit so that setuptools_scm can # create the correct version string. If the number of commits since @@ -42,92 +43,64 @@ jobs: # to be able to push to GitHub. persist-credentials: false - # Need the tags so that setuptools_scm can form a valid version number - - name: Fetch git tags - run: git fetch origin 'refs/tags/*:refs/tags/*' - - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -r requirements-dev.txt - pip install -e . + python -m pip install .[all] + + - name: Flake8 + run: flake8 pyfftlog/ tests/ - name: Test with pytest - run: pytest --cov=fftlog --flake8 + run: pytest --cov=fftlog deploy: needs: test name: Deploy to PyPI runs-on: ubuntu-latest - # Only from the origin repository, not forks; only master. - if: github.repository_owner == 'emsig' && github.ref == 'refs/heads/main' + # Only from the origin repository, not forks; only main and tags. + if: github.repository_owner == 'emsig' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) steps: # Checks-out your repository under $GITHUB_WORKSPACE - name: Checkout - uses: actions/checkout@v2 - with: - # Need to fetch more than the last commit so that setuptools_scm can - # create the correct version string. If the number of commits since - # the last release is greater than this, the version will still be - # wrong. Increase if necessary. - fetch-depth: 100 - # The GitHub token is preserved by default but this job doesn't need - # to be able to push to GitHub. - persist-credentials: false - - # Need the tags so that setuptools_scm can form a valid version number - - name: Fetch git tags - run: git fetch origin 'refs/tags/*:refs/tags/*' + uses: actions/checkout@v4 - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.12" - name: Install dependencies run: | python -m pip install --upgrade pip - pip install wheel numpy - pip install -r requirements-dev.txt + python -m pip install build - name: Build source and wheel distributions + if: github.ref == 'refs/heads/main' run: | # Change setuptools-scm local_scheme to "no-local-version" so the # local part of the version isn't included, making the version string # compatible with Test PyPI. - sed --in-place "s/'root'/'local_scheme':'no-local-version','root'/g" setup.py + sed --in-place 's/version_file/local_scheme = "no-local-version"\nversion_file/g' pyproject.toml + + - name: Build source and wheel distributions + run: | # Build source and wheel packages - python setup.py sdist - # python setup.py bdist_wheel + python -m build echo "" echo "Generated files:" ls -lh dist/ - # # fftlog currently does not use setuptools_scm, hence the version - # # number has to be adjusted manually; too cumbersome. - # - name: Publish to Test PyPI - # if: success() - # # Hash corresponds to v1.4.1 - # uses: pypa/gh-action-pypi-publish@54b39fb9371c0b3a6f9f14bb8a67394defc7a806 - # with: - # user: __token__ - # password: ${{ secrets.TEST_PYPI_PASSWORD }} - # repository_url: https://test.pypi.org/legacy/ - # # Allow existing releases on test PyPI without errors. - # # NOT TO BE USED in PyPI! - # skip_existing: true - - name: Publish to PyPI # Only for releases if: success() && github.event_name == 'release' - # Hash corresponds to v1.4.1 - uses: pypa/gh-action-pypi-publish@54b39fb9371c0b3a6f9f14bb8a67394defc7a806 + uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PYPI_PASSWORD }} From fa3ce3c9985b67e183860eb55cb6a5fd2d8e12e7 Mon Sep 17 00:00:00 2001 From: Dieter Werthmuller Date: Mon, 30 Dec 2024 16:25:50 +0100 Subject: [PATCH 3/6] Add hide to intent --- fftlog/fftlog.pyf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fftlog/fftlog.pyf b/fftlog/fftlog.pyf index 77ae082..729cb2b 100644 --- a/fftlog/fftlog.pyf +++ b/fftlog/fftlog.pyf @@ -19,8 +19,8 @@ python module _fftlog ! in real*8 intent(in) :: dlnr real*8 optional, intent(in, out) :: kr=1 integer optional, intent(in) :: kropt=1 - real*8 dimension(2*n+3*(n/2)+19), intent(out) :: wsave - logical intent(out) :: ok + real*8 dimension(2*n+3*(n/2)+19), intent(hide, out) :: wsave + logical intent(hide, out) :: ok end subroutine fhti subroutine fftl(n,a,rk,dir,wsave) ! in :fftlog:src/fftlog.f integer, optional, intent(hide), depend(a) :: n=len(a) From bb159d9004a6fad117d4eb5b04476442411c4d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dieter=20Werthm=C3=BCller?= Date: Wed, 18 Dec 2024 22:00:08 +0100 Subject: [PATCH 4/6] s/pyfftlog/fftlog --- tests/{test_pyfftlog.py => test_fftlog.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{test_pyfftlog.py => test_fftlog.py} (100%) diff --git a/tests/test_pyfftlog.py b/tests/test_fftlog.py similarity index 100% rename from tests/test_pyfftlog.py rename to tests/test_fftlog.py From 224678f027f191c90231995537302095e92513f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Wed, 18 Dec 2024 21:36:45 +0100 Subject: [PATCH 5/6] Port build to meson+pyproject (#8) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To work with python >= 3.12, which will deprecated numpy.distutils, port the build to meson and pyproject. $ pip install build $ python -m build $ cd test && python -c "import fftlog; print(fftlog.__all__)" ['fhti', 'fftl', 'fht', 'fhtq'] The cd test is to avoid trying to import from $(pwd)/fftlog. This just changes the build, and does not hard constrain versions. Follow up work should be to figure out true minimum versions, maybe test with different compilers, and fix the type error in ifac and friends. The directory tree is flattened because fftlog/ doesn't form a cohesive module as-is. Due to the presence of the __init__.py the dir would be detected as a module and loaded by pytest and friends, shadowing the installed one and failing because it does not find the native extension. Finally, remove __init__.py from tests/ to not pretend it is a module anymore. --- .github/workflows/pytest.yml | 2 +- meson.build | 56 ++++++++++++++++++++++++++++++++ pyproject.toml | 43 +++++++++++++++++++++++++ requirements-dev.txt | 8 ----- requirements.txt | 1 - setup.py | 60 ----------------------------------- {fftlog => src}/__init__.py | 0 {fftlog/src => src}/cdgamma.f | 0 {fftlog/src => src}/drfftb.f | 0 {fftlog/src => src}/drfftf.f | 0 {fftlog/src => src}/drffti.f | 0 {fftlog/src => src}/fftlog.f | 0 {fftlog => src}/fftlog.pyf | 0 tests/__init__.py | 0 14 files changed, 100 insertions(+), 70 deletions(-) create mode 100644 meson.build create mode 100644 pyproject.toml delete mode 100644 requirements-dev.txt delete mode 100644 requirements.txt delete mode 100644 setup.py rename {fftlog => src}/__init__.py (100%) rename {fftlog/src => src}/cdgamma.f (100%) rename {fftlog/src => src}/drfftb.f (100%) rename {fftlog/src => src}/drfftf.f (100%) rename {fftlog/src => src}/drffti.f (100%) rename {fftlog/src => src}/fftlog.f (100%) rename {fftlog => src}/fftlog.pyf (100%) delete mode 100644 tests/__init__.py diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 52b1b73..5d68003 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -54,7 +54,7 @@ jobs: python -m pip install .[all] - name: Flake8 - run: flake8 pyfftlog/ tests/ + run: flake8 src/ tests/ - name: Test with pytest run: pytest --cov=fftlog diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..c8e6458 --- /dev/null +++ b/meson.build @@ -0,0 +1,56 @@ +project('fftlog', 'c') +# fortran_std=legacy? +add_languages('fortran') + +if meson.get_compiler('fortran').get_id() == 'gcc' + # Allow argument mismatch, otherwise (newer, probably >= 10) gfortran throws + # Error: Type mismatch in argument ‘ifac’ at (1); passed REAL(8) to INTEGER(4) + add_global_arguments('-fallow-argument-mismatch', + language: ['fortran']) +endif + +py = import('python') +py3 = py.find_installation() + +f2py_name = '_fftlog' +f2py_module_c = f'@f2py_name@module.c' +f2py_wrapper_f = f'@f2py_name@-f2pywrappers.f' +f2py_dep = custom_target( + 'f2py wrappers', + input: 'src/fftlog.pyf', + output: [f2py_module_c, f2py_wrapper_f], + command: [py3, '-m', 'numpy.f2py', '@INPUT@', + '--build-dir', '@OUTDIR@', ], +) + +incdir_numpy = run_command(py3, + ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'], + check : true +).stdout().strip() +incdir_f2py = run_command(py3, + ['-c', 'import os; os.chdir(".."); import numpy.f2py; print(numpy.f2py.get_include())'], + check : true +).stdout().strip() +inc_np = include_directories(incdir_numpy, incdir_f2py) + +py3.extension_module('_fftlog', + [f2py_dep, + incdir_f2py / 'fortranobject.c', + 'src/cdgamma.f', + 'src/drfftb.f', + 'src/drfftf.f', + 'src/drffti.f', + 'src/fftlog.f', + ], + link_language: 'fortran', + include_directories: inc_np, + install : true, + subdir: 'fftlog', +) + +py3.install_sources([ + 'src/__init__.py', + ], + pure: false, + subdir: 'fftlog', +) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..19b171b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,43 @@ +[build-system] +build-backend = "mesonpy" +requires = [ + "meson-python", + "numpy", + "wheel", + "charset_normalizer", +] + +[project] +name = "fftlog" +description = "A python wrapper for FFTLog" +readme = "README.rst" +version = "0.2.1" +authors = [ + {name = "The emsig community", email = "info@emsig.xyz"}, +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", +] +dependencies = [ + "numpy", + "scipy", +] + +[project.license] +file = "LICENSE" + +[project.optional-dependencies] +tests = [ + "flake8", + "pytest", + "coveralls", + "pytest_cov", + "flake8-pyproject", +] +all = [ + "fftlog[tests]", +] + +[project.urls] +Repository = "https://github.com/prisae/fftlog" diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index 02c654b..0000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,8 +0,0 @@ -# GLOBAL REQUIREMENTS --r requirements.txt - -# FOR TESTING -pytest -coveralls -pytest_cov -pytest_flake8 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 9c558e3..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -. diff --git a/setup.py b/setup.py deleted file mode 100644 index a1e3c2a..0000000 --- a/setup.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -import re -import sys - -# Get README and remove badges. -readme = open('README.rst').read() -readme = re.sub('.*`fftlog` - A', '`fftlog` - A', readme, flags=re.DOTALL) - -metadata = dict( - name='fftlog', - version='0.2.1', # Adjust in fftlog/__init__.py too! - description='Logarithmic Fast Fourier Transform', - long_description=readme, - author='Dieter Werthmüller', - author_email='dieter@werthmuller.org', - url='https://github.com/prisae/fftlog', - license='CC0-1.0', - packages=['fftlog', ], - include_package_data=True, - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication', - ], - install_requires=[ - 'scipy', - ], - # setup_requires=['numpy', ], -) - - -bdist = ('bdist_wheel', 'bdist_egg') -nonumpy = ('--help-commands', 'egg_info', '--version', 'clean') -argv2 = len(sys.argv) >= 2 -if argv2 and ('--help' in sys.argv[1:] or sys.argv[1] in nonumpy): - # For these actions, NumPy is not required. - # - # They are required to succeed without Numpy, for example when pip is - # used to install fftlog when Numpy is not yet present in the system. - from setuptools import setup -else: - if (argv2 >= 2 and sys.argv[1] in bdist) or ('develop' in sys.argv): - - # bdist_wheel/bdist_egg needs setuptools - import setuptools # noqa - - from numpy.distutils.core import setup, Extension - - metadata['ext_modules'] = [ - Extension( - name="fftlog._fftlog", - sources=['fftlog/fftlog.pyf', ] + - [ - 'fftlog/src/cdgamma.f', 'fftlog/src/drfftb.f', - 'fftlog/src/drfftf.f', 'fftlog/src/drffti.f', - 'fftlog/src/fftlog.f' - ], - ) - ] - -setup(**metadata) diff --git a/fftlog/__init__.py b/src/__init__.py similarity index 100% rename from fftlog/__init__.py rename to src/__init__.py diff --git a/fftlog/src/cdgamma.f b/src/cdgamma.f similarity index 100% rename from fftlog/src/cdgamma.f rename to src/cdgamma.f diff --git a/fftlog/src/drfftb.f b/src/drfftb.f similarity index 100% rename from fftlog/src/drfftb.f rename to src/drfftb.f diff --git a/fftlog/src/drfftf.f b/src/drfftf.f similarity index 100% rename from fftlog/src/drfftf.f rename to src/drfftf.f diff --git a/fftlog/src/drffti.f b/src/drffti.f similarity index 100% rename from fftlog/src/drffti.f rename to src/drffti.f diff --git a/fftlog/src/fftlog.f b/src/fftlog.f similarity index 100% rename from fftlog/src/fftlog.f rename to src/fftlog.f diff --git a/fftlog/fftlog.pyf b/src/fftlog.pyf similarity index 100% rename from fftlog/fftlog.pyf rename to src/fftlog.pyf diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29..0000000 From e6fac1feef43a3fc3415fea22b08cc41b35fdcd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dieter=20Werthm=C3=BCller?= Date: Wed, 18 Dec 2024 22:11:47 +0100 Subject: [PATCH 6/6] Give tmp version --- .github/workflows/pytest.yml | 2 +- pyproject.toml | 2 +- src/__init__.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 5d68003..05de20a 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -51,7 +51,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install .[all] + python -m pip install .[tests] - name: Flake8 run: flake8 src/ tests/ diff --git a/pyproject.toml b/pyproject.toml index 19b171b..1e3e991 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ requires = [ name = "fftlog" description = "A python wrapper for FFTLog" readme = "README.rst" -version = "0.2.1" +version = "0.2.2dev1" # also in __init__.py authors = [ {name = "The emsig community", email = "info@emsig.xyz"}, ] diff --git a/src/__init__.py b/src/__init__.py index 4ede578..ceca5c3 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -3,6 +3,6 @@ __all__ = ['fhti', 'fftl', 'fht', 'fhtq'] # Version -# Not using setuptools_scm, as in pyfftlog, because of numpy-setup. -# Has to be adjusted in setup.py too! -__version__ = '0.2.1' +# Not currently using setuptools_scm, as in pyfftlog, because of numpy-setup. +# Has to be adjusted in pyproject.toml too! +__version__ = '0.2.2dev1'