diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml index b7f35ff5a..a187295bd 100644 --- a/.github/workflows/emscripten.yml +++ b/.github/workflows/emscripten.yml @@ -37,7 +37,7 @@ jobs: uses: actions/checkout@v4 - name: Build and test PyWavelets - uses: pypa/cibuildwheel@faf86a6ed7efa889faf6996aa23820831055001a # v2.23.3 + uses: pypa/cibuildwheel@9e4e50bd76b3190f55304387e333f6234823ea9b # v3.1.2 env: CIBW_PLATFORM: pyodide CIBW_TEST_REQUIRES: pytest matplotlib diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d7825607d..32e8a4926 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -51,7 +51,7 @@ jobs: - runs-on: ubuntu-latest python-version: "3.11" - runs-on: ubuntu-latest - python-version: "3.11" + python-version: "3.14-dev" USE_SDIST: 1 OPTIONS_NAME: "install-from-sdist" - runs-on: ubuntu-latest @@ -62,11 +62,8 @@ jobs: python-version: "3.13" OPTIONS_NAME: "editable-install" steps: - - name: Checkout PyWavelets - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 with: python-version: ${{ matrix.python-version}} allow-prereleases: true @@ -140,35 +137,25 @@ jobs: popd test_pywavelets_linux_free_threaded: - name: linux-cp313t-default + name: linux-cp${{ matrix.python-version }}-default runs-on: ubuntu-latest strategy: - # Ensure that a wheel builder finishes even if another fails fail-fast: false - + matrix: + python-version: ["3.13t", "3.14t-dev"] steps: - - name: Checkout PyWavelets - uses: actions/checkout@v4 - - # TODO: replace with setup-python when there is support - - uses: deadsnakes/action@e640ac8743173a67cca4d7d77cd837e514bf98e8 # v3.2.0 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 with: - python-version: "3.13-dev" - nogil: true + python-version: ${{ matrix.python-version}} - name: Build package run: | - which python - python --version pip install --upgrade pip build - # We need nightly wheels for free-threaded support and latest fixes - pip install --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython numpy - pip install pytest meson-python ninja + pip install cython numpy meson-python ninja pytest pip install . -v --no-build-isolation - name: Run tests - env: - PYTHON_GIL: 0 run: | # Move out of source directory to avoid finding local pywt cd demo @@ -196,11 +183,8 @@ jobs: OPTIONS_NAME: "pre-releases" steps: - - name: Checkout PyWavelets - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 with: python-version: ${{ matrix.python-version}} allow-prereleases: true @@ -253,8 +237,8 @@ jobs: python ../pywt/tests/test_doc.py elif [ "${REFGUIDE_CHECK}" == "1" ]; then # doctests docstrings - pytest --doctest-modules --pyargs pywt -v --doctest-collect=api - pytest --doctest-modules --pyargs pywt.data -v + pytest --doctest-modules --doctest-only-doctests=true --pyargs pywt -v --doctest-collect=api + pytest --doctest-modules --doctest-only-doctests=true --pyargs pywt.data -v else pytest --pyargs pywt fi diff --git a/.github/workflows/wheel_tests_and_release.yml b/.github/workflows/wheel_tests_and_release.yml index 3c190aec2..792552f96 100644 --- a/.github/workflows/wheel_tests_and_release.yml +++ b/.github/workflows/wheel_tests_and_release.yml @@ -34,38 +34,25 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - cibw_python: ["cp311", "cp312", "cp313", "cp313t"] + cibw_python: ["cp311", "cp312", "cp313", "cp313t", "cp314", "cp314t"] cibw_arch: ["x86_64"] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 name: Install Python with: python-version: "3.12" - - name: Install build deps; set CIBW environment variables - if: ${{ matrix.cibw_python }} == "cp313t" - run: | - PYPI_URL="https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" - CIBW_DEPS="pip install --pre -i $PYPI_URL cython &&\ - pip install numpy pytest meson-python ninja" - NO_BUILD_ISOLATION="pip; args: --no-build-isolation" - echo "CIBW_BEFORE_BUILD=$CIBW_DEPS" >> "$GITHUB_ENV" - echo "CIBW_BEFORE_TEST=$CIBW_DEPS" >> "$GITHUB_ENV" - echo "CIBW_BUILD_FRONTEND=$NO_BUILD_ISOLATION" >> "$GITHUB_ENV" - - name: Build the wheel - uses: pypa/cibuildwheel@faf86a6ed7efa889faf6996aa23820831055001a # v2.23.3 + uses: pypa/cibuildwheel@9e4e50bd76b3190f55304387e333f6234823ea9b # v3.1.2 with: output-dir: dist env: CIBW_BUILD: ${{ matrix.cibw_python }}-* CIBW_ARCHS_LINUX: ${{ matrix.cibw_arch }} - CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014 - CIBW_MUSLLINUX_X86_64_IMAGE: musllinux_1_2 - CIBW_FREE_THREADED_SUPPORT: True + CIBW_ENABLE: cpython-freethreading - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: wheels_linux_${{ matrix.cibw_arch }}_${{ matrix.cibw_python }} @@ -79,26 +66,25 @@ jobs: fail-fast: false matrix: os: [ubuntu-22.04-arm] - cibw_python: ["cp311", "cp312", "cp313"] + cibw_python: ["cp311", "cp312", "cp313", "cp313t", "cp314", "cp314t"] cibw_arch: ["aarch64"] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 name: Install Python with: python-version: "3.12" - name: Build the wheel - uses: pypa/cibuildwheel@faf86a6ed7efa889faf6996aa23820831055001a # v2.23.3 + uses: pypa/cibuildwheel@9e4e50bd76b3190f55304387e333f6234823ea9b # v3.1.2 with: output-dir: dist env: CIBW_BUILD: ${{ matrix.cibw_python }}-* CIBW_ARCHS_LINUX: ${{ matrix.cibw_arch }} - CIBW_MANYLINUX_AARCH64_IMAGE: manylinux2014 - CIBW_MUSLLINUX_AARCH64_IMAGE: musllinux_1_2 + CIBW_ENABLE: cpython-freethreading - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: wheels_linux_${{ matrix.cibw_arch }}_${{ matrix.cibw_python }} @@ -112,55 +98,42 @@ jobs: matrix: # macos-13 is the last runner that supports Intel (x86_64) architecture os: [macos-13, macos-14] - cibw_python: ["cp311", "cp312", "cp313", "cp313t"] + cibw_python: ["cp311", "cp312", "cp313", "cp313t", "cp314", "cp314t"] cibw_arch: ["x86_64", "arm64"] exclude: - os: macos-14 cibw_arch: "x86_64" - os: macos-13 cibw_arch: "arm64" - - os: macos-13 - cibw_arch: "x86_64" - cibw_python: "cp313t" steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 name: Install Python with: python-version: "3.12" - - name: Install build deps; set CIBW environment variables - if: ${{ matrix.cibw_python }} == "cp313t" - run: | - PYPI_URL="https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" - CIBW_DEPS="pip install --pre -i $PYPI_URL cython &&\ - pip install numpy pytest meson-python ninja" - NO_BUILD_ISOLATION="pip; args: --no-build-isolation" - echo "CIBW_BEFORE_BUILD=$CIBW_DEPS" >> "$GITHUB_ENV" - echo "CIBW_BEFORE_TEST=$CIBW_DEPS" >> "$GITHUB_ENV" - echo "CIBW_BUILD_FRONTEND=$NO_BUILD_ISOLATION" >> "$GITHUB_ENV" - - name: Build wheels for CPython (macOS) (x86_64) if: matrix.cibw_arch == 'x86_64' - uses: pypa/cibuildwheel@faf86a6ed7efa889faf6996aa23820831055001a # v2.23.3 + uses: pypa/cibuildwheel@9e4e50bd76b3190f55304387e333f6234823ea9b # v3.1.2 with: output-dir: dist env: CIBW_BUILD: ${{ matrix.cibw_python }}-* CIBW_ARCHS_MACOS: ${{ matrix.cibw_arch }} + CIBW_ENABLE: cpython-freethreading - name: Build wheels for CPython (macOS) (arm64) if: matrix.cibw_arch == 'arm64' - uses: pypa/cibuildwheel@faf86a6ed7efa889faf6996aa23820831055001a # v2.23.3 + uses: pypa/cibuildwheel@9e4e50bd76b3190f55304387e333f6234823ea9b # v3.1.2 with: output-dir: dist env: CIBW_BUILD: ${{ matrix.cibw_python }}-* CIBW_ARCHS_MACOS: ${{ matrix.cibw_arch }} - CIBW_FREE_THREADED_SUPPORT: True + CIBW_ENABLE: cpython-freethreading - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: @@ -176,13 +149,13 @@ jobs: matrix: os: [windows-latest] cibw_arch: ["AMD64", "x86"] - cibw_python: ["cp311", "cp312", "cp313", "cp313t"] + cibw_python: ["cp311", "cp312", "cp313", "cp313t", "cp314", "cp314t"] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 name: Install Python with: python-version: "3.12" @@ -199,26 +172,14 @@ jobs: with: architecture: x64 - - name: Install build deps; set CIBW environment variables - if: ${{ matrix.cibw_python }} == "cp313t" - shell: bash -el {0} - run: | - PYPI_URL="https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" - CIBW_DEPS="pip install --pre -i $PYPI_URL cython numpy &&\ - pip install pytest meson-python ninja" - NO_BUILD_ISOLATION="pip; args: --no-build-isolation" - echo "CIBW_BEFORE_BUILD=$CIBW_DEPS" >> "$GITHUB_ENV" - echo "CIBW_BEFORE_TEST=$CIBW_DEPS" >> "$GITHUB_ENV" - echo "CIBW_BUILD_FRONTEND=$NO_BUILD_ISOLATION" >> "$GITHUB_ENV" - - name: Build Windows wheels for CPython - uses: pypa/cibuildwheel@faf86a6ed7efa889faf6996aa23820831055001a # v2.23.3 + uses: pypa/cibuildwheel@9e4e50bd76b3190f55304387e333f6234823ea9b # v3.1.2 with: output-dir: dist env: CIBW_BUILD: ${{ matrix.cibw_python }}-* CIBW_ARCHS_WINDOWS: ${{ matrix.cibw_arch }} - CIBW_FREE_THREADED_SUPPORT: True + CIBW_ENABLE: cpython-freethreading - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: @@ -243,7 +204,7 @@ jobs: with: fetch-depth: 0 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 name: Install Python with: python-version: "3.12" @@ -275,7 +236,7 @@ jobs: TWINE_PASSWORD: ${{ secrets.TWINE_TOKEN }} - name: Github release - uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2 + uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 # v2.3.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_REPOSITORY: ${{ github.repository }} diff --git a/LICENSE b/LICENSE index 0f67833e6..d61b491ba 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ Copyright (c) 2006-2012 Filip Wasilewski -Copyright (c) 2012-2020 The PyWavelets Developers +Copyright (c) 2012- The PyWavelets Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/LICENSES_bundled.txt b/LICENSES_bundled.txt deleted file mode 100644 index c016032a9..000000000 --- a/LICENSES_bundled.txt +++ /dev/null @@ -1,10 +0,0 @@ -The PyWavelets repository and source distributions bundle some code that is -adapted from compatibly licensed projects. We list these here. - -Name: NumPy -Files: pywt/_pytesttester.py -License: 3-clause BSD - -Name: SciPy -Files: meson.build, util/* -License: 3-clause BSD diff --git a/doc/source/ref/cwt.rst b/doc/source/ref/cwt.rst index 292c3c543..88985a94c 100644 --- a/doc/source/ref/cwt.rst +++ b/doc/source/ref/cwt.rst @@ -167,7 +167,7 @@ where :math:`B` is the bandwidth and :math:`C` is the center frequency. Frequency B-Spline Wavelets ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The frequency B-spline wavelets (``"fpspM-B-C"`` with integer M and floating +The frequency B-spline wavelets (``"fbspM-B-C"`` with integer M and floating point B, C) correspond to the following wavelets: .. math:: diff --git a/licenses_bundled/LICENSE_numpy.txt b/licenses_bundled/LICENSE_numpy.txt new file mode 100644 index 000000000..6ccec6824 --- /dev/null +++ b/licenses_bundled/LICENSE_numpy.txt @@ -0,0 +1,30 @@ +Copyright (c) 2005-2024, NumPy Developers. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the NumPy Developers nor the names of any + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/licenses_bundled/LICENSE_scipy.txt b/licenses_bundled/LICENSE_scipy.txt new file mode 100644 index 000000000..117117616 --- /dev/null +++ b/licenses_bundled/LICENSE_scipy.txt @@ -0,0 +1,30 @@ +Copyright (c) 2001-2002 Enthought, Inc. 2003-2024, SciPy Developers. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/licenses_bundled/README.txt b/licenses_bundled/README.txt new file mode 100644 index 000000000..ce889ac72 --- /dev/null +++ b/licenses_bundled/README.txt @@ -0,0 +1,12 @@ +The PyWavelets repository and source distributions bundle some code that is +adapted from compatibly licensed projects. We list these here, together with +the path to the files (relative to the root of the repository or sdist) +identifying the vendored code that required including a license file. + +Name: NumPy +Files: pywt/_pytesttester.py +License: BSD-3-Clause + +Name: SciPy +Files: meson.build, util/* +License: BSD-3-Clause diff --git a/pyproject.toml b/pyproject.toml index 1de84bfbc..3b81d6edb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ [build-system] build-backend = "mesonpy" requires = [ - "meson-python>=0.16.0", + "meson-python>=0.18.0", "Cython>=3.0.4", # numpy requirement for wheel builds for distribution on PyPI - building @@ -18,14 +18,17 @@ requires = [ # disabling build isolation. "numpy>=2.0.0; python_version<'3.13'", "numpy>=2.1.0; python_version>='3.13'", + "numpy>=2.3.2; python_version>='3.14'", ] [project] name = "PyWavelets" version = "1.9.0.dev0" -# TODO: add `license-files` once PEP 639 is accepted (see meson-python#88) -# at that point, no longer include them in `py3.install_sources()` -license = {file = "LICENSE"} +license = "MIT and BSD-3-Clause" +license-files = [ + "LICENSE", + "licenses_bundled/LICENSE_*", +] maintainers = [ {name = "The PyWavelets Developers", email = "pywavelets@googlegroups.com"} ] @@ -38,7 +41,6 @@ classifiers = [ "Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Science/Research", - "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: C", "Programming Language :: Python", @@ -46,6 +48,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Software Development :: Libraries :: Python Modules" ] diff --git a/pywt/__init__.py b/pywt/__init__.py index 2916bb0d1..669b06b62 100644 --- a/pywt/__init__.py +++ b/pywt/__init__.py @@ -1,7 +1,7 @@ # flake8: noqa # Copyright (c) 2006-2012 Filip Wasilewski -# Copyright (c) 2012-2020 The PyWavelets Developers +# Copyright (c) 2012- The PyWavelets Developers # # See LICENSE for more details. diff --git a/pywt/_cwt.py b/pywt/_cwt.py index d867e03b5..7facec1f3 100644 --- a/pywt/_cwt.py +++ b/pywt/_cwt.py @@ -24,7 +24,8 @@ def next_fast_len(n): return 2**ceil(np.log2(n)) -def cwt(data, scales, wavelet, sampling_period=1., method='conv', axis=-1, precision=12, *, hop_size=1): +def cwt(data, scales, wavelet, sampling_period=1., method='conv', axis=-1, precision=12, + *, hop_size=1): """ One dimensional Continuous Wavelet Transform. diff --git a/pywt/tests/test_matlab_compatibility_cwt.py b/pywt/tests/test_matlab_compatibility_cwt.py index 21d37c0a7..7819c50fb 100644 --- a/pywt/tests/test_matlab_compatibility_cwt.py +++ b/pywt/tests/test_matlab_compatibility_cwt.py @@ -149,7 +149,7 @@ def _load_matlab_result_psi(wavelet): def _check_accuracy(data, w, scales, coefs, wavelet, epsilon): # PyWavelets result - coefs_pywt, freq = pywt.cwt(data, scales, w) + coefs_pywt, freq = pywt.cwt(data, scales, w, precision=10) # coefs from Matlab are from R2012a which is missing the complex conjugate # as shown in Eq. 2 of Torrence and Compo. We take the complex conjugate of