From d8c980538798c567eb27ab9e5c446f56cced3b47 Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Thu, 15 Feb 2024 12:27:27 +0000 Subject: [PATCH 01/27] Adds SunPy packaging template --- .cruft.json | 31 +++++++++ .flake8 | 27 ++++++++ .github/workflows/ci.yml | 62 ++++++++++++----- .github/workflows/sub_package_update.yml | 79 +++++++++++++++++++++ .gitignore | 81 +++++++++++++++------- .pre-commit-config.yml | 22 ++++++ .readthedocs.yaml | 29 ++++++++ .rtd-environment.yml | 2 +- .ruff.toml | 39 +++++++++++ MANIFEST.in | 10 +-- docs/conf.py | 2 + docs/make.bat | 70 +++++++++---------- licenses/LICENSE.rst | 22 ++++++ licenses/TEMPLATE_LICENSE.rst | 6 +- ndcube/_dev/scm_version.py | 4 +- ndcube/data/README.rst | 6 ++ ndcube/tests/__init__.py | 3 +- ndcube/version.py | 8 +-- pyproject.toml | 87 ++++++++++++++++++++++-- 19 files changed, 491 insertions(+), 99 deletions(-) create mode 100644 .cruft.json create mode 100644 .flake8 create mode 100644 .github/workflows/sub_package_update.yml create mode 100644 .pre-commit-config.yml create mode 100644 .readthedocs.yaml create mode 100644 .ruff.toml create mode 100644 licenses/LICENSE.rst create mode 100644 ndcube/data/README.rst diff --git a/.cruft.json b/.cruft.json new file mode 100644 index 000000000..7299f184b --- /dev/null +++ b/.cruft.json @@ -0,0 +1,31 @@ +{ + "template": "/home/sam/Code/OpenAstronomy/../OpenAstronomy/packaging-guide", + "commit": "79c7c63fa9f20c7873063e08516778e99dd39318", + "checkout": null, + "context": { + "cookiecutter": { + "package_name": "ndcube", + "module_name": "ndcube", + "short_description": "A package for multi-dimensional contiguous and non-contiguous coordinate aware arrays.", + "author_name": "The SunPy Community", + "author_email": "sunpy@googlegroups.com", + "project_url": "https://docs.sunpy.org/projects/ndcube/", + "license": "BSD 2-Clause", + "minimum_python_version": "3.9", + "use_compiled_extensions": "n", + "enable_dynamic_dev_versions": "y", + "include_example_code": "n", + "include_cruft_update_github_workflow": "y", + "_sphinx_theme": "alabaster", + "_parent_project": "", + "_install_requires": "", + "_copy_without_render": [ + "docs/_templates", + "docs/_static", + ".github/workflows/sub_package_update.yml" + ], + "_template": "/home/sam/Code/OpenAstronomy/../OpenAstronomy/packaging-guide" + } + }, + "directory": null +} diff --git a/.flake8 b/.flake8 new file mode 100644 index 000000000..fcccaa10e --- /dev/null +++ b/.flake8 @@ -0,0 +1,27 @@ +[flake8] +ignore = + # missing-whitespace-around-operator + E225 + # missing-whitespace-around-arithmetic-operator + E226 + # line-too-long + E501 + # unused-import + F401 + # undefined-local-with-import-star + F403 + # redefined-while-unused + F811 + # Line break occurred before a binary operator + W503, + # Line break occurred after a binary operator + W504 +max-line-length = 110 +exclude = + .git + __pycache__ + docs/conf.py + build + ndcube/__init__.py, +rst-directives = + plot diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 993b439ce..e9fe37d50 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,3 +1,4 @@ +{% set default_python = '3.10' %} name: CI on: @@ -15,33 +16,58 @@ on: # Allow manual runs through the web UI workflow_dispatch: -# Automatically cancel old builds concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: core: - uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@v1 + uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@main with: submodules: false coverage: codecov toxdeps: tox-pypi-filter envs: | - - linux: py311 + - linux: py312 + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + sdist_verify: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.10' + - run: python -m pip install -U --user build + - run: python -m build . --sdist + - run: python -m pip install -U --user twine + - run: python -m twine check dist/* test: - needs: [core] - uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@v1 + needs: [core, sdist_verify] + uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@main with: - default_python: '3.9' submodules: false coverage: codecov toxdeps: tox-pypi-filter + posargs: -n auto envs: | + - windows: py311 - macos: py310 - - windows: py39 - - linux: py39-oldestdeps + - linux: py310-oldestdeps + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + docs: + needs: [core] + uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@main + with: + default_python: '3.10' + submodules: false + pytest: false + toxdeps: tox-pypi-filter + envs: | - linux: build_docs posargs: '' pytest: false @@ -56,20 +82,20 @@ jobs: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'Run cron CI') ) - uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@v1 + uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@main with: - default_python: '3.9' + default_python: '3.10' submodules: false coverage: codecov toxdeps: tox-pypi-filter envs: | - linux: py311-devdeps - - linux: py39-conda - libraries: '' + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - publish: - # Build wheels when pushing to any branch except main - # publish.yml will only publish if tagged ^v.* +publish_pure: + needs: [test, docs] + uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish_pure_python.yml@main if: | github.event_name != 'pull_request' && ( github.ref_name != 'main' || @@ -77,9 +103,9 @@ jobs: needs: [test] uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish_pure_python.yml@v1 with: - python-version: '3.9' - test_extras: 'dev' - test_command: 'pytest -p no:warnings --doctest-rst -m "not mpl_image_compare" --pyargs ndcube' + python-version: '3.10' + test_extras: 'tests' + test_command: 'pytest -p no:warnings --doctest-rst --pyargs ndcube' submodules: false secrets: pypi_token: ${{ secrets.pypi_token }} diff --git a/.github/workflows/sub_package_update.yml b/.github/workflows/sub_package_update.yml new file mode 100644 index 000000000..7f10d1bda --- /dev/null +++ b/.github/workflows/sub_package_update.yml @@ -0,0 +1,79 @@ +""" +This template is taken from the cruft example code, for further information please see: +https://cruft.github.io/cruft/#automating-updates-with-github-actions +""" +name: Automatic Update from package template +permissions: + contents: write + pull-requests: write + +on: + pull_request: + branches: + main +jobs: + update: + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + include: + - add-paths: . + body: Use this to merge the changes to the repo + branch: cruft/update + commit-message: "Automate package template update" + title: Incoming updates from package template + - add-paths: .cruft.json + body: Use this to reject changes in the repo + branch: cruft/reject + commit-message: "Chore: reject this cruft update" + title: Reject new updates from package template + + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Install Cruft + run: pip3 install cruft + + - name: Check if update is available + continue-on-error: false + id: check + run: | + CHANGES=0 + if [ -f .cruft.json ]; then + if ! cruft check; then + CHANGES=1 + fi + else + echo "No .cruft.json file" + fi + + echo "has_changes=$CHANGES" >> "$GITHUB_OUTPUT" + + - name: Run update if available + if: steps.check.outputs.has_changes == '1' + run: | + git config --global user.email "gromit@cruft.com" + git config --global user.name "Gromit" + + cruft update --skip-apply-ask --refresh-private-variables + git restore --staged + + - name: Create pull request + if: steps.check.output.has_changes == '1' + uses: peter-evans/create-pull-request@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + add-paths: ${{ matrix.add-paths }} + commit-message: ${{ matrix.commit-message }} + branch: ${{ matrix.branch }} + delete-branch: true + branch-suffix: timestamp + title: ${{ matrix.title }} + body: | + This is an autogenerated PR. ${{ matrix.body }} + [Cruft](https://cruft.github.io/cruft/) has detected updates from the Package Template diff --git a/.gitignore b/.gitignore index 65e62a5e9..4b2b58f09 100644 --- a/.gitignore +++ b/.gitignore @@ -24,11 +24,12 @@ parts/ sdist/ var/ wheels/ +share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST - +ndcube/_version.py # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. @@ -42,14 +43,17 @@ pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ +.nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover +*.py,cover .hypothesis/ .pytest_cache/ +cover/ junit/ # Translations @@ -60,6 +64,7 @@ junit/ *.log local_settings.py db.sqlite3 +db.sqlite3-journal # Flask stuff: instance/ @@ -72,16 +77,42 @@ instance/ docs/_build/ # PyBuilder +.pybuilder/ target/ # Jupyter Notebook .ipynb_checkpoints -# pyenv -.python-version +# IPython +profile_default/ +ipython_config.py -# celery beat schedule file +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff celerybeat-schedule +celerybeat.pid # SageMath parsed files *.sage.py @@ -95,10 +126,6 @@ ENV/ env.bak/ venv.bak/ -# Spyder project settings -.spyderproject -.spyproject - # Rope project settings .ropeproject @@ -108,8 +135,22 @@ venv.bak/ # mypy .mypy_cache/ -### https://raw.github.com/github/gitignore/master/Global/OSX.gitignore +# Pyre type checker +.pyre/ + +# IDE +# PyCharm +.idea + +# Spyder project settings +.spyderproject +.spyproject +### VScode: https://raw.githubusercontent.com/github/gitignore/master/Global/VisualStudioCode.gitignore +.vscode/* +.vs/* + +### https://raw.github.com/github/gitignore/master/Global/OSX.gitignore .DS_Store .AppleDouble .LSOverride @@ -117,7 +158,6 @@ venv.bak/ # Icon must ends with two \r. Icon - # Thumbnails ._* @@ -126,7 +166,6 @@ Icon .Trashes ### Linux: https://raw.githubusercontent.com/github/gitignore/master/Global/Linux.gitignore - *~ # temporary files which can be created if a process still has a handle open of a deleted file @@ -142,6 +181,7 @@ Icon .nfs* ### MacOS: https://raw.githubusercontent.com/github/gitignore/master/Global/macOS.gitignore +.pytype/ # General .DS_Store @@ -197,9 +237,7 @@ $RECYCLE.BIN/ # Windows shortcuts *.lnk -### VScode: https://raw.githubusercontent.com/github/gitignore/master/Global/VisualStudioCode.gitignore -.vscode/* -.vs/* +### Extra Python Items and SunPy Specific ### Extra Python Items and ndcube Specific .hypothesis @@ -209,15 +247,13 @@ ndcube/_version.py docs/_build docs/generated docs/api +docs/whatsnew/latest_changelog.txt examples/**/*.asdf examples/**/*.csv figure_test_images* tags baseline -### Pycharm(?) -.idea - # Release script .github_cache @@ -225,13 +261,10 @@ baseline .history *.orig .tmp - -### Vagrant: https://www.toptal.com/developers/gitignore/api/vagrant -# General -.vagrant/ +node_modules/ +package-lock.json +package.json +.prettierrc # Log files generated by 'vagrant up' *.log - -### Vagrant Patch ### -*.box diff --git a/.pre-commit-config.yml b/.pre-commit-config.yml new file mode 100644 index 000000000..59d754139 --- /dev/null +++ b/.pre-commit-config.yml @@ -0,0 +1,22 @@ +repos: + # This should be before any formatting hooks like isort + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.2.1" + hooks: + - id: ruff + args: ["--fix"] + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-ast + - id: check-case-conflict + - id: trailing-whitespace + exclude: ".*(.fits|.fts|.fit|.header|.txt)$" + - id: check-yaml + - id: debug-statements + - id: check-added-large-files + args: ["--enforce-all", "--maxkb=1054"] + - id: end-of-file-fixer + exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|.json)$|^CITATION.rst$" + - id: mixed-line-ending + exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*)$" diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..790abab48 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,29 @@ +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "mambaforge-4.10" + jobs: + post_checkout: + - git fetch --unshallow || true + pre_install: + - git update-index --assume-unchanged .rtd-environment.yml docs/conf.py + +conda: + environment: .rtd-environment.yml + +sphinx: + builder: html + configuration: docs/conf.py + fail_on_warning: false + +formats: + - htmlzip + +python: + install: + - method: pip + extra_requirements: + - docs + path: . diff --git a/.rtd-environment.yml b/.rtd-environment.yml index 774611683..757d9a44f 100644 --- a/.rtd-environment.yml +++ b/.rtd-environment.yml @@ -1,4 +1,4 @@ -name: rtd_ndcube +name: ndcube channels: - conda-forge dependencies: diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 000000000..f9be9de96 --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,39 @@ +target-version = "py310" +line-length = 110 +exclude = [ + ".git,", + "__pycache__", + "build", + "ndcube/version.py", +] + +[lint] +select = ["E", "F", "W", "UP", "PT"] +extend-ignore = [ + # pycodestyle (E, W) + "E501", # LineTooLong # TODO! fix + # pytest (PT) + "PT001", # Always use pytest.fixture() + "PT004", # Fixtures which don't return anything should have leading _ + "PT007", # Parametrize should be lists of tuples # TODO! fix + "PT011", # Too broad exception assert # TODO! fix + "PT023", # Always use () on pytest decorators +] + +[flake8-tidy-imports] +[flake8-tidy-imports.banned-api] +"warnings.warn".msg = "Use sunpy specific warning helpers warn_* from sunpy.utils.exceptions" + +[per-file-ignores] +# Part of configuration, not a package. +"setup.py" = ["INP001"] +"conftest.py" = ["INP001"] +# Implicit-namespace-package. The examples are not a package. +"docs/*.py" = ["INP001"] +"__init__.py" = ["E402", "F401", "F403"] +"test_*.py" = ["B011", "D", "E402", "PGH001", "S101"] +# Need to import clients to register them, but don't use them in file +"ndcube/net/__init__.py" = ["F811"] + +[pydocstyle] +convention = "numpy" diff --git a/MANIFEST.in b/MANIFEST.in index dcdec96e6..140bead61 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,9 +7,11 @@ exclude .pre-commit-config.yaml exclude .readthedocs.yml # Prune folders -prune .circleci -prune .github -prune changelog +prune build +prune docs/_build +prune docs/api +global-exclude *.pyc *.o -# This subpackage is only used in development checkouts and should not be included in built tarballs +# This subpackage is only used in development checkouts +# and should not be included in built tarballs prune ndcube/_dev diff --git a/docs/conf.py b/docs/conf.py index 03c2af632..ce9324879 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- +# # Configuration file for the Sphinx documentation builder. import os import warnings diff --git a/docs/make.bat b/docs/make.bat index 922152e96..2119f5109 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -1,35 +1,35 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/licenses/LICENSE.rst b/licenses/LICENSE.rst new file mode 100644 index 000000000..8fcd3990b --- /dev/null +++ b/licenses/LICENSE.rst @@ -0,0 +1,22 @@ +Copyright (c) 2024, The SunPy Community + +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. + +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 HOLDER 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/TEMPLATE_LICENSE.rst b/licenses/TEMPLATE_LICENSE.rst index f29177b0b..9ac870dc3 100644 --- a/licenses/TEMPLATE_LICENSE.rst +++ b/licenses/TEMPLATE_LICENSE.rst @@ -1,10 +1,10 @@ -This project is based upon the Astropy package template -(https://github.com/astropy/package-template/) which is licenced under the terms +This project is based upon the OpenAstronomy package template +(https://github.com/open-astronomy/package-template/) which is licenced under the terms of the following licence. --- -Copyright (c) 2018, Astropy Developers +Copyright (c) 2018, OpenAstronomy Developers All rights reserved. Redistribution and use in source and binary forms, with or without modification, diff --git a/ndcube/_dev/scm_version.py b/ndcube/_dev/scm_version.py index b33a5bac6..6c6da82c0 100644 --- a/ndcube/_dev/scm_version.py +++ b/ndcube/_dev/scm_version.py @@ -7,6 +7,6 @@ version = get_version(root=os.path.join('..', '..'), relative_to=__file__) except ImportError: - raise ImportError('setuptools_scm not installed') + raise except Exception as e: - raise ValueError(f'setuptools_scm broken with {e}') + raise ValueError(f'setuptools_scm can not determine version.') from e diff --git a/ndcube/data/README.rst b/ndcube/data/README.rst new file mode 100644 index 000000000..382f6e769 --- /dev/null +++ b/ndcube/data/README.rst @@ -0,0 +1,6 @@ +Data directory +============== + +This directory contains data files included with the package source +code distribution. Note that this is intended only for relatively small files +- large files should be externally hosted and downloaded as needed. diff --git a/ndcube/tests/__init__.py b/ndcube/tests/__init__.py index 09615fb57..838b45731 100644 --- a/ndcube/tests/__init__.py +++ b/ndcube/tests/__init__.py @@ -1,3 +1,4 @@ +# Licensed under a 3-clause BSD style license - see LICENSE.rst """ -This module contains package tests and helpers. +This module contains package tests. """ diff --git a/ndcube/version.py b/ndcube/version.py index 0e64e7e49..515c2f0af 100644 --- a/ndcube/version.py +++ b/ndcube/version.py @@ -1,5 +1,5 @@ # NOTE: First try _dev.scm_version if it exists and setuptools_scm is installed -# This file is not included in sunpy wheels/tarballs, so otherwise it will +# This file is not included in wheels/tarballs, so otherwise it will # fall back on the generated _version module. try: try: @@ -15,9 +15,3 @@ del warnings version = '0.0.0' - -from packaging.version import parse as _parse - -_version = _parse(version) -major, minor, bugfix = [*_version.release, 0][:3] -release = not _version.is_devrelease diff --git a/pyproject.toml b/pyproject.toml index 200751905..e285f213b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,89 @@ [build-system] requires = [ - "setuptools", - "setuptools_scm", - "wheel", + "setuptools>=62.1", + "setuptools_scm[toml]>=6.2", + "wheel",] +build-backend = "setuptools.build_meta" + +[project] +name = "ndcube" +description = "A package for multi-dimensional contiguous and non-contiguous coordinate aware arrays." +readme = "README.rst" +requires-python = ">=3.9" +license = { file = "licenses/LICENSE.rst", content-type = "text/plain" } +authors = [ + { name = "The SunPy Community", email = "sunpy@googlegroups.com" }, +] +dependencies = [] +dynamic = ["version"] + +[project.optional-dependencies] +tests = [ + "pytest", + "pytest-doctestplus", + "pytest-cov", +] +docs = [ + "sphinx", + "sphinx-automodapi", + "tomli; python_version <\"3.11\"", +] + +[project.urls] +repository = "https://docs.sunpy.org/projects/ndcube/" + +[tool.setuptools] +zip-safe = false +include-package-data = true + +[tool.setuptools.packages.find] + +[tool.setuptools_scm] +write_to = "ndcube/_version.py" + +[tool.pytest.ini_options] +testpaths = [ + "ndcube", + "docs", +] +doctest_plus = "enabled" +text_file_format = "rst" +addopts = "--doctest-rst" + +[tool.coverage.run] +omit = [ + "ndcube/__init*", + "ndcube/conftest.py", + "ndcube/*setup_package*", + "ndcube/tests/*", + "ndcube/*/tests/*", + "ndcube/extern/*", + "ndcube/version*", + "*/ndcube/__init*", + "*/ndcube/conftest.py", + "*/ndcube/*setup_package*", + "*/ndcube/tests/*", + "*/ndcube/*/tests/*", + "*/ndcube/extern/*", + "*/ndcube/version*", +] + +[tool.coverage.report] +exclude_lines = [ + # Have to re-enable the standard pragma + "pragma: no cover", + # Don't complain about packages we have installed + "except ImportError", + # Don't complain if tests don't hit assertions + "raise AssertionError", + "raise NotImplementedError", + # Don't complain about script hooks + "def main(.*):", + # Ignore branches that don't pertain to this version of Python + "pragma: py{ignore_python_version}", + # Don't complain about IPython completion helper + "def _ipython_key_completions_", ] -build-backend = 'setuptools.build_meta' [tool.towncrier] package = "ndcube" From b23d2b85aabbef2119042144deb2e6397ce8603c Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Thu, 15 Feb 2024 12:32:57 +0000 Subject: [PATCH 02/27] Clean out duplicated files --- .pre-commit-config.yaml | 55 ++++++----------------------------------- .pre-commit-config.yml | 22 ----------------- .readthedocs.yml | 25 ------------------- setup.py | 30 ---------------------- 4 files changed, 7 insertions(+), 125 deletions(-) delete mode 100644 .pre-commit-config.yml delete mode 100644 .readthedocs.yml delete mode 100755 setup.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 28544131a..59d754139 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,44 +1,10 @@ repos: -# The warnings/errors we check for here are: - # E901 - SyntaxError or IndentationError - # E902 - IOError - # F822 - undefined name in __all__ - # F823 - local variable name referenced before assignment - # Others are taken care of by autopep8 - - repo: https://github.com/PyCQA/flake8 - rev: 7.0.0 + # This should be before any formatting hooks like isort + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.2.1" hooks: - - id: flake8 - args: - [ - "--count", - "--select", - "E901,E902,F822,F823", - ] - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*|.rst|.md)$" - - repo: https://github.com/PyCQA/autoflake - rev: v2.2.1 - hooks: - - id: autoflake - args: - [ - "--in-place", - "--remove-all-unused-imports", - "--remove-unused-variable", - ] - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*|.rst|.md|__init__.py)$" - - repo: https://github.com/PyCQA/isort - rev: 5.13.2 - hooks: - - id: isort - args: ["--sp", "setup.cfg"] - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*|.rst|.md)$" - - repo: https://github.com/hhatto/autopep8 - rev: v2.0.4 - hooks: - - id: autopep8 - args: ["--in-place","--max-line-length", "200"] - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*|.rst|.md)$" + - id: ruff + args: ["--fix"] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: @@ -49,15 +15,8 @@ repos: - id: check-yaml - id: debug-statements - id: check-added-large-files - args: ['--enforce-all','--maxkb=1054'] + args: ["--enforce-all", "--maxkb=1054"] - id: end-of-file-fixer - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*)$" + exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|.json)$|^CITATION.rst$" - id: mixed-line-ending exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*)$" - - repo: https://github.com/codespell-project/codespell - rev: v2.2.6 - hooks: - - id: codespell - args: ['--config setup.cfg'] -ci: - autofix_prs: false diff --git a/.pre-commit-config.yml b/.pre-commit-config.yml deleted file mode 100644 index 59d754139..000000000 --- a/.pre-commit-config.yml +++ /dev/null @@ -1,22 +0,0 @@ -repos: - # This should be before any formatting hooks like isort - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.2.1" - hooks: - - id: ruff - args: ["--fix"] - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 - hooks: - - id: check-ast - - id: check-case-conflict - - id: trailing-whitespace - exclude: ".*(.fits|.fts|.fit|.header|.txt)$" - - id: check-yaml - - id: debug-statements - - id: check-added-large-files - args: ["--enforce-all", "--maxkb=1054"] - - id: end-of-file-fixer - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|.json)$|^CITATION.rst$" - - id: mixed-line-ending - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*)$" diff --git a/.readthedocs.yml b/.readthedocs.yml deleted file mode 100644 index b0c5ef79c..000000000 --- a/.readthedocs.yml +++ /dev/null @@ -1,25 +0,0 @@ -version: 2 - -build: - os: ubuntu-22.04 - tools: - python: "mambaforge-4.10" - jobs: - pre_install: - - git update-index --assume-unchanged .rtd-environment.yml docs/conf.py - -conda: - environment: .rtd-environment.yml - -sphinx: - builder: html - configuration: docs/conf.py - fail_on_warning: false - -python: - install: - - method: pip - extra_requirements: - - all - - docs - path: . diff --git a/setup.py b/setup.py deleted file mode 100755 index 3a360e0cf..000000000 --- a/setup.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -from setuptools import setup # isort:skip -import os -from itertools import chain - -try: - # Recommended for setuptools 61.0.0+ - # (though may disappear in the future) - from setuptools.config.setupcfg import read_configuration -except ImportError: - from setuptools.config import read_configuration - -################################################################################ -# Programmatically generate some extras combos. -################################################################################ -extras = read_configuration("setup.cfg")['options']['extras_require'] - - -# All is everything but tests and docs -exclude_keys = ("tests", "docs") -ex_extras = dict(filter(lambda i: i[0] not in exclude_keys, extras.items())) -# Concatenate all the values together for 'all' -extras['all'] = list(chain.from_iterable(ex_extras.values())) -# Dev is everything -extras['dev'] = list(chain(*extras.values())) - -setup( - extras_require=extras, - use_scm_version={'write_to': os.path.join('ndcube', '_version.py')}, -) From 337946408f905619147ac786e7dec56e1bf16833 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 12:42:44 +0000 Subject: [PATCH 03/27] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- docs/conf.py | 3 +-- ndcube/_dev/scm_version.py | 2 +- ndcube/extra_coords/extra_coords.py | 13 +++++++------ ndcube/ndcube.py | 21 +++++++++++---------- ndcube/tests/helpers.py | 2 +- ndcube/utils/tests/test_utils_wcs.py | 2 +- ndcube/utils/wcs_high_level_conversion.py | 4 ++-- 7 files changed, 24 insertions(+), 23 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index ce9324879..31c610258 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. import os @@ -18,7 +17,7 @@ # -- Project information project = 'ndcube' author = 'The SunPy Community' -copyright = '{}, {}'.format(datetime.now().year, author) +copyright = f'{datetime.now().year}, {author}' # The full version, including alpha/beta/rc tags from ndcube import __version__ # NOQA diff --git a/ndcube/_dev/scm_version.py b/ndcube/_dev/scm_version.py index 6c6da82c0..1bcf0dd99 100644 --- a/ndcube/_dev/scm_version.py +++ b/ndcube/_dev/scm_version.py @@ -9,4 +9,4 @@ except ImportError: raise except Exception as e: - raise ValueError(f'setuptools_scm can not determine version.') from e + raise ValueError('setuptools_scm can not determine version.') from e diff --git a/ndcube/extra_coords/extra_coords.py b/ndcube/extra_coords/extra_coords.py index 05b75f34c..3ca351884 100644 --- a/ndcube/extra_coords/extra_coords.py +++ b/ndcube/extra_coords/extra_coords.py @@ -1,5 +1,6 @@ import abc -from typing import Any, Tuple, Union, Iterable +from typing import Any +from collections.abc import Iterable from numbers import Integral from functools import reduce, partial @@ -41,10 +42,10 @@ class ExtraCoordsABC(abc.ABC): """ @abc.abstractmethod def add(self, - name: Union[str, Iterable[str]], - array_dimension: Union[int, Iterable[int]], + name: str | Iterable[str], + array_dimension: int | Iterable[int], lookup_table: Any, - physical_types: Union[str, Iterable[str]] = None, + physical_types: str | Iterable[str] = None, **kwargs): """ Add a coordinate to this `~ndcube.ExtraCoords` based on a lookup table. @@ -73,7 +74,7 @@ def keys(self) -> Iterable[str]: @property @abc.abstractmethod - def mapping(self) -> Iterable[Tuple[int, int]]: + def mapping(self) -> Iterable[tuple[int, int]]: """ The mapping between the array dimensions and pixel dimensions. @@ -103,7 +104,7 @@ def is_empty(self): """Return True if no extra coords present, else return False.""" @abc.abstractmethod - def __getitem__(self, item: Union[str, int, slice, Iterable[Union[str, int, slice]]]) -> "ExtraCoordsABC": + def __getitem__(self, item: str | int | slice | Iterable[str | int | slice]) -> "ExtraCoordsABC": """ ExtraCoords can be sliced with either a string, or a numpy like slice. diff --git a/ndcube/ndcube.py b/ndcube/ndcube.py index ae7da59e1..15a75f1f5 100644 --- a/ndcube/ndcube.py +++ b/ndcube/ndcube.py @@ -2,7 +2,8 @@ import textwrap import warnings from copy import deepcopy -from typing import Any, Tuple, Union, Iterable, Optional +from typing import Any +from collections.abc import Iterable from collections import namedtuple from collections.abc import Mapping @@ -72,7 +73,7 @@ def combined_wcs(self) -> BaseHighLevelWCS: @property @abc.abstractmethod - def array_axis_physical_types(self) -> Iterable[Tuple[str, ...]]: + def array_axis_physical_types(self) -> Iterable[tuple[str, ...]]: """ Returns the WCS physical types that vary along each array axis. @@ -89,9 +90,9 @@ def array_axis_physical_types(self) -> Iterable[Tuple[str, ...]]: @abc.abstractmethod def axis_world_coords(self, - *axes: Union[int, str], + *axes: int | str, pixel_corners: bool = False, - wcs: Optional[Union[BaseHighLevelWCS, ExtraCoordsABC]] = None + wcs: BaseHighLevelWCS | ExtraCoordsABC | None = None ) -> Iterable[Any]: """ Returns objects representing the world coordinates of pixel centers for a desired axes. @@ -133,9 +134,9 @@ def axis_world_coords(self, @abc.abstractmethod def axis_world_coords_values(self, - *axes: Union[int, str], + *axes: int | str, pixel_corners: bool = False, - wcs: Optional[Union[BaseHighLevelWCS, ExtraCoordsABC]] = None + wcs: BaseHighLevelWCS | ExtraCoordsABC | None = None ) -> Iterable[u.Quantity]: """ Returns the world coordinate values of all pixels for desired axes. @@ -182,7 +183,7 @@ def axis_world_coords_values(self, @abc.abstractmethod def crop(self, *points: Iterable[Any], - wcs: Optional[Union[BaseHighLevelWCS, ExtraCoordsABC]] = None + wcs: BaseHighLevelWCS | ExtraCoordsABC | None = None ) -> "NDCubeABC": """ Crop using real world coordinates. @@ -226,9 +227,9 @@ def crop(self, @abc.abstractmethod def crop_by_values(self, - *points: Iterable[Union[u.Quantity, float]], - units: Optional[Iterable[Union[str, u.Unit]]] = None, - wcs: Optional[Union[BaseHighLevelWCS, ExtraCoordsABC]] = None + *points: Iterable[u.Quantity | float], + units: Iterable[str | u.Unit] | None = None, + wcs: BaseHighLevelWCS | ExtraCoordsABC | None = None ) -> "NDCubeABC": """ Crop using real world coordinates. diff --git a/ndcube/tests/helpers.py b/ndcube/tests/helpers.py index eda18e4b0..adddb3d3a 100644 --- a/ndcube/tests/helpers.py +++ b/ndcube/tests/helpers.py @@ -164,4 +164,4 @@ def assert_collections_equal(collection1, collection2): elif isinstance(cube1, NDCubeSequence): assert_cubesequences_equal(cube1, cube2) else: - raise TypeError("Unsupported Type in NDCollection: {0}".format(type(cube1))) + raise TypeError(f"Unsupported Type in NDCollection: {type(cube1)}") diff --git a/ndcube/utils/tests/test_utils_wcs.py b/ndcube/utils/tests/test_utils_wcs.py index 084615bbd..d6fe96912 100644 --- a/ndcube/utils/tests/test_utils_wcs.py +++ b/ndcube/utils/tests/test_utils_wcs.py @@ -45,7 +45,7 @@ def test_wcs(): return WCSTest() -class WCSTest(): +class WCSTest: def __init__(self): self.world_axis_physical_types = [ 'custom:pos.helioprojective.lon', 'custom:pos.helioprojective.lat', 'em.wl', 'time'] diff --git a/ndcube/utils/wcs_high_level_conversion.py b/ndcube/utils/wcs_high_level_conversion.py index b21a1adc9..2f3c026be 100644 --- a/ndcube/utils/wcs_high_level_conversion.py +++ b/ndcube/utils/wcs_high_level_conversion.py @@ -46,8 +46,8 @@ def high_level_objects_to_values(*world_objects, low_level_wcs): # Check that the number of classes matches the number of inputs if len(world_objects) != len(classes): - raise ValueError("Number of world inputs ({}) does not match " - "expected ({})".format(len(world_objects), len(classes))) + raise ValueError(f"Number of world inputs ({len(world_objects)}) does not match " + f"expected ({len(classes)})") # Determine whether the classes are uniquely matched, that is we check # whether there is only one of each class. From 6ee0b2d43cd237a4bc5a24201e10bc807e787f4f Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Mon, 15 Apr 2024 18:32:14 +0100 Subject: [PATCH 04/27] Registers NdCube with the SunPy template --- .codecov.yaml | 5 +++ .codespellrc | 13 ++++++ .coveragerc | 30 ++++++++++++++ .cruft.json | 8 ++-- .flake8 | 2 +- .github/workflows/ci.yml | 3 ++ .github/workflows/sub_package_update.yml | 51 +++++++++++++----------- .gitignore | 6 +-- .isort.cfg | 16 ++++++++ .ruff.toml | 10 +++-- licenses/TEMPLATE_LICENSE.rst | 2 +- pyproject.toml | 14 +++---- pytest.ini | 27 +++++++++++++ setup.py | 4 ++ tox.ini | 22 ++++++++-- 15 files changed, 168 insertions(+), 45 deletions(-) create mode 100644 .codespellrc create mode 100644 .coveragerc create mode 100644 .isort.cfg create mode 100644 pytest.ini create mode 100755 setup.py diff --git a/.codecov.yaml b/.codecov.yaml index bd2cef304..8fe09b731 100644 --- a/.codecov.yaml +++ b/.codecov.yaml @@ -4,3 +4,8 @@ coverage: project: default: threshold: 0.2% + +codecov: + require_ci_to_pass: false + notify: + wait_for_ci: true diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 000000000..042a14edc --- /dev/null +++ b/.codespellrc @@ -0,0 +1,13 @@ +[codespell] +skip = *.asdf,*.fits,*.fts,*.header,*.json,*.xsh,*cache*,*egg*,*extern*,.git,.idea,.tox,_build,*truncated,*.svg,.asv_env,.history +ignore-words-list = + alog, + nd, + nin, + observ, + ot, + te, + upto, + afile, + precessed, + precess diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 000000000..a5de52d67 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,30 @@ +[run] +omit = + ndcube/conftest.py + ndcube/*setup_package* + ndcube/extern/* + ndcube/version* + */ndcube/conftest.py + */ndcube/*setup_package* + */ndcube/extern/* + */ndcube/version* + +[report] +exclude_lines = + # Have to re-enable the standard pragma + pragma: no cover + # Don't complain about packages we have installed + except ImportError + # Don't complain if tests don't hit assertions + raise AssertionError + raise NotImplementedError + # Don't complain about script hooks + def main(.*): + # Ignore branches that don't pertain to this version of Python + pragma: py{ignore_python_version} + # Don't complain about IPython completion helper + def _ipython_key_completions_ + # typing.TYPE_CHECKING is False at runtime + if TYPE_CHECKING: + # Ignore typing overloads + @overload diff --git a/.cruft.json b/.cruft.json index 7299f184b..64ef33449 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { - "template": "/home/sam/Code/OpenAstronomy/../OpenAstronomy/packaging-guide", - "commit": "79c7c63fa9f20c7873063e08516778e99dd39318", + "template": "https://github.com/sunpy/package-template", + "commit": "6d6729b22066ef890e70c37438da70cac33e03b4", "checkout": null, "context": { "cookiecutter": { @@ -9,7 +9,7 @@ "short_description": "A package for multi-dimensional contiguous and non-contiguous coordinate aware arrays.", "author_name": "The SunPy Community", "author_email": "sunpy@googlegroups.com", - "project_url": "https://docs.sunpy.org/projects/ndcube/", + "project_url": "https://docs.sunpy.org/projects/ndcube", "license": "BSD 2-Clause", "minimum_python_version": "3.9", "use_compiled_extensions": "n", @@ -24,7 +24,7 @@ "docs/_static", ".github/workflows/sub_package_update.yml" ], - "_template": "/home/sam/Code/OpenAstronomy/../OpenAstronomy/packaging-guide" + "_template": "https://github.com/sunpy/package-template" } }, "directory": null diff --git a/.flake8 b/.flake8 index fcccaa10e..667c71300 100644 --- a/.flake8 +++ b/.flake8 @@ -22,6 +22,6 @@ exclude = __pycache__ docs/conf.py build - ndcube/__init__.py, + ndcube/__init__.py rst-directives = plot diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9fe37d50..5f6a6bf21 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,6 +67,9 @@ jobs: submodules: false pytest: false toxdeps: tox-pypi-filter + libraries: | + apt: + - graphviz envs: | - linux: build_docs posargs: '' diff --git a/.github/workflows/sub_package_update.yml b/.github/workflows/sub_package_update.yml index 7f10d1bda..94a9e7e1a 100644 --- a/.github/workflows/sub_package_update.yml +++ b/.github/workflows/sub_package_update.yml @@ -1,16 +1,21 @@ -""" -This template is taken from the cruft example code, for further information please see: -https://cruft.github.io/cruft/#automating-updates-with-github-actions -""" +# This template is taken from the cruft example code, for further information please see: +# https://cruft.github.io/cruft/#automating-updates-with-github-actions name: Automatic Update from package template permissions: contents: write pull-requests: write on: - pull_request: - branches: - main + # Allow manual runs through the web UI + workflow_dispatch: + schedule: + # ┌───────── minute (0 - 59) + # │ ┌───────── hour (0 - 23) + # │ │ ┌───────── day of the month (1 - 31) + # │ │ │ ┌───────── month (1 - 12 or JAN-DEC) + # │ │ │ │ ┌───────── day of the week (0 - 6 or SUN-SAT) + - cron: '0 7 * * 1' # Every Monday at 7am UTC + jobs: update: runs-on: ubuntu-latest @@ -19,25 +24,25 @@ jobs: matrix: include: - add-paths: . - body: Use this to merge the changes to the repo + body: apply the changes to this repo. branch: cruft/update - commit-message: "Automate package template update" - title: Incoming updates from package template + commit-message: "Automatic package template update" + title: Updates from the package template - add-paths: .cruft.json - body: Use this to reject changes in the repo + body: reject these changes for this repo. branch: cruft/reject - commit-message: "Chore: reject this cruft update" + commit-message: "Reject this package template update" title: Reject new updates from package template steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install Cruft - run: pip3 install cruft + run: python -m pip install cruft - name: Check if update is available continue-on-error: false @@ -57,15 +62,15 @@ jobs: - name: Run update if available if: steps.check.outputs.has_changes == '1' run: | - git config --global user.email "gromit@cruft.com" - git config --global user.name "Gromit" + git config --global user.email "${{ github.actor }}@users.noreply.github.com" + git config --global user.name "${{ github.actor }}" cruft update --skip-apply-ask --refresh-private-variables - git restore --staged + git restore --staged . - name: Create pull request - if: steps.check.output.has_changes == '1' - uses: peter-evans/create-pull-request@v4 + if: steps.check.outputs.has_changes == '1' + uses: peter-evans/create-pull-request@v6 with: token: ${{ secrets.GITHUB_TOKEN }} add-paths: ${{ matrix.add-paths }} @@ -75,5 +80,5 @@ jobs: branch-suffix: timestamp title: ${{ matrix.title }} body: | - This is an autogenerated PR. ${{ matrix.body }} - [Cruft](https://cruft.github.io/cruft/) has detected updates from the Package Template + This is an autogenerated PR, which will ${{ matrix.body }}. + [Cruft](https://cruft.github.io/cruft/) has detected updates from the Package Template diff --git a/.gitignore b/.gitignore index 4b2b58f09..5f2c3f600 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,8 @@ instance/ # Sphinx documentation docs/_build/ +# automodapi +docs/api # PyBuilder .pybuilder/ @@ -180,7 +182,7 @@ Icon # .nfs files are created when an open file is removed but is still being accessed .nfs* -### MacOS: https://raw.githubusercontent.com/github/gitignore/master/Global/macOS.gitignore +# pytype static type analyzer .pytype/ # General @@ -237,8 +239,6 @@ $RECYCLE.BIN/ # Windows shortcuts *.lnk -### Extra Python Items and SunPy Specific - ### Extra Python Items and ndcube Specific .hypothesis .pytest_cache diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 000000000..507c4e705 --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,16 @@ +[settings] +balanced_wrapping = true +skip = + docs/conf.py + ndcube/__init__.py +default_section = THIRDPARTY +include_trailing_comma = true +known_astropy = astropy, asdf +known_sunpy = sunpy +known_first_party = ndcube +length_sort = false +length_sort_sections = stdlib +line_length = 110 +multi_line_output = 3 +no_lines_before = LOCALFOLDER +sections = STDLIB, THIRDPARTY, ASTROPY, SUNPY, FIRSTPARTY, LOCALFOLDER diff --git a/.ruff.toml b/.ruff.toml index f9be9de96..cf615fba9 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -28,12 +28,16 @@ extend-ignore = [ # Part of configuration, not a package. "setup.py" = ["INP001"] "conftest.py" = ["INP001"] -# Implicit-namespace-package. The examples are not a package. -"docs/*.py" = ["INP001"] +"docs/conf.py" = [ + "E402" # Module imports not at top of file +] +"docs/*.py" = [ + "INP001", # Implicit-namespace-package. The examples are not a package. +] "__init__.py" = ["E402", "F401", "F403"] "test_*.py" = ["B011", "D", "E402", "PGH001", "S101"] # Need to import clients to register them, but don't use them in file "ndcube/net/__init__.py" = ["F811"] -[pydocstyle] +[lint.pydocstyle] convention = "numpy" diff --git a/licenses/TEMPLATE_LICENSE.rst b/licenses/TEMPLATE_LICENSE.rst index 9ac870dc3..544a2dba7 100644 --- a/licenses/TEMPLATE_LICENSE.rst +++ b/licenses/TEMPLATE_LICENSE.rst @@ -1,5 +1,5 @@ This project is based upon the OpenAstronomy package template -(https://github.com/open-astronomy/package-template/) which is licenced under the terms +(https://github.com/OpenAstronomy/package-template/) which is licensed under the terms of the following licence. --- diff --git a/pyproject.toml b/pyproject.toml index e285f213b..9d7f1759a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,8 +8,8 @@ build-backend = "setuptools.build_meta" [project] name = "ndcube" description = "A package for multi-dimensional contiguous and non-contiguous coordinate aware arrays." -readme = "README.rst" requires-python = ">=3.9" +readme = { file = "README.rst", content-type = "text/x-rst" } license = { file = "licenses/LICENSE.rst", content-type = "text/plain" } authors = [ { name = "The SunPy Community", email = "sunpy@googlegroups.com" }, @@ -19,18 +19,18 @@ dynamic = ["version"] [project.optional-dependencies] tests = [ - "pytest", - "pytest-doctestplus", - "pytest-cov", + "pytest", + "pytest-doctestplus", + "pytest-cov" ] docs = [ - "sphinx", - "sphinx-automodapi", + "sphinx", + "sphinx-automodapi", "tomli; python_version <\"3.11\"", ] [project.urls] -repository = "https://docs.sunpy.org/projects/ndcube/" +repository = "https://docs.sunpy.org/projects/ndcube" [tool.setuptools] zip-safe = false diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 000000000..a5e467af2 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,27 @@ +[pytest] +minversion = 7.0 +testpaths = + ndcube + docs +norecursedirs = + .tox + build + docs/_build + docs/generated + *.egg-info + examples + ndcube/_dev + .history + ndcube/extern +doctest_plus = enabled +doctest_optionflags = NORMALIZE_WHITESPACE FLOAT_CMP ELLIPSIS +text_file_format = rst +addopts = --doctest-rst -p no:unraisableexception -p no:threadexception +filterwarnings = + # Turn all warnings into errors so they do not pass silently. + error + # Do not fail on pytest config issues (i.e. missing plugins) but do show them + always::pytest.PytestConfigWarning + # A list of warnings to ignore follows. If you add to this list, you MUST + # add a comment or ideally a link to an issue that explains why the warning + # is being ignored diff --git a/setup.py b/setup.py new file mode 100755 index 000000000..c82334553 --- /dev/null +++ b/setup.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +from setuptools import setup + +setup() diff --git a/tox.ini b/tox.ini index 38d509080..2d32bc006 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,13 @@ [tox] min_version = 4.0 +requires = + tox-pypi-filter>=0.14 envlist = - py{39,310,311}{,-devdeps,-online,-figure,-conda,-oldestdeps} - build_docs + py{310,311,312} + py312-devdeps + py310-oldestdeps codestyle + build_docs [testenv] pypi_filter = https://raw.githubusercontent.com/sunpy/sunpy/main/.test_package_pins.txt @@ -15,10 +19,22 @@ allowlist_externals= changedir = .tmp/{envname} description = run tests + oldestdeps: with the oldest supported version of key dependencies devdeps: with the latest developer version of key dependencies online: that require remote data (as well as the offline ones) figure: runs the figure test suite. -setenv = + +pass_env = + # A variable to tell tests we are on a CI system + CI + # Custom compiler locations (such as ccache) + CC + # Location of locales (needed by sphinx on some systems) + LOCALE_ARCHIVE + # If the user has set a LC override we should follow it + LC_ALL + +set_env = MPLBACKEND = agg COLUMNS = 180 PYTEST_COMMAND = pytest -vvv -s -raR --pyargs ndcube --cov-report=xml --cov=ndcube --cov-config={toxinidir}/setup.cfg {toxinidir}/docs From 89df6f83f0e49752ae29f9581e5d8233ea4153d0 Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Mon, 15 Apr 2024 20:42:15 +0100 Subject: [PATCH 05/27] Upgrades minium dep version of numpy --- .github/workflows/ci.yml | 1 - tox.ini | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f6a6bf21..c09952094 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,3 @@ -{% set default_python = '3.10' %} name: CI on: diff --git a/tox.ini b/tox.ini index 2d32bc006..cc1ebde46 100644 --- a/tox.ini +++ b/tox.ini @@ -61,7 +61,7 @@ deps = oldestdeps: sunpy<4.0 oldestdeps: astropy<4.3 oldestdeps: gwcs<0.16 - oldestdeps: numpy<1.18 + oldestdeps: numpy<1.23 oldestdeps: matplotlib<3.3 oldestdeps: mpl_animators<1.1 oldestdeps: reproject==0.7.1 From 74054059925d46a499478c4403ef8f3db11e9bb1 Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Tue, 16 Apr 2024 10:19:24 +0100 Subject: [PATCH 06/27] Remove sunpy-core specific ruff config --- .ruff.toml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.ruff.toml b/.ruff.toml index cf615fba9..0b94cd4fa 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -20,10 +20,6 @@ extend-ignore = [ "PT023", # Always use () on pytest decorators ] -[flake8-tidy-imports] -[flake8-tidy-imports.banned-api] -"warnings.warn".msg = "Use sunpy specific warning helpers warn_* from sunpy.utils.exceptions" - [per-file-ignores] # Part of configuration, not a package. "setup.py" = ["INP001"] @@ -36,8 +32,6 @@ extend-ignore = [ ] "__init__.py" = ["E402", "F401", "F403"] "test_*.py" = ["B011", "D", "E402", "PGH001", "S101"] -# Need to import clients to register them, but don't use them in file -"ndcube/net/__init__.py" = ["F811"] [lint.pydocstyle] convention = "numpy" From a94d77a708a5c81b12b8ebf1eb8784e799c88178 Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Tue, 16 Apr 2024 10:23:10 +0100 Subject: [PATCH 07/27] Corrects ci indentation error --- .github/workflows/ci.yml | 33 ++++++++++++++++----------------- pyproject.toml | 3 ++- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c09952094..837b17220 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -95,23 +95,22 @@ jobs: secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} -publish_pure: - needs: [test, docs] - uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish_pure_python.yml@main - if: | - github.event_name != 'pull_request' && ( - github.ref_name != 'main' || - github.event_name == 'workflow_dispatch' ) - needs: [test] - uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish_pure_python.yml@v1 - with: - python-version: '3.10' - test_extras: 'tests' - test_command: 'pytest -p no:warnings --doctest-rst --pyargs ndcube' - submodules: false - secrets: - pypi_token: ${{ secrets.pypi_token }} - + publish_pure: + needs: [test, docs] + uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish_pure_python.yml@main + if: | + github.event_name != 'pull_request' && ( + github.ref_name != 'main' || + github.event_name == 'workflow_dispatch' ) + needs: [test] + uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish_pure_python.yml@v1 + with: + python-version: '3.10' + test_extras: 'tests' + test_command: 'pytest -p no:warnings --doctest-rst --pyargs ndcube' + submodules: false + secrets: + pypi_token: ${{ secrets.pypi_token }} notify: if: always() && github.event_name == 'workflow_dispatch' needs: [publish, cron] diff --git a/pyproject.toml b/pyproject.toml index 9d7f1759a..7be5f9a24 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,8 @@ requires = [ "setuptools>=62.1", "setuptools_scm[toml]>=6.2", - "wheel",] + "wheel" +] build-backend = "setuptools.build_meta" [project] From 2d08fefe049ca46f5cb8e5a075139003bb3ff4b6 Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Tue, 16 Apr 2024 14:37:18 +0100 Subject: [PATCH 08/27] Removes duplications in pyproject.toml --- pyproject.toml | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7be5f9a24..bee6b07d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,50 +42,6 @@ include-package-data = true [tool.setuptools_scm] write_to = "ndcube/_version.py" -[tool.pytest.ini_options] -testpaths = [ - "ndcube", - "docs", -] -doctest_plus = "enabled" -text_file_format = "rst" -addopts = "--doctest-rst" - -[tool.coverage.run] -omit = [ - "ndcube/__init*", - "ndcube/conftest.py", - "ndcube/*setup_package*", - "ndcube/tests/*", - "ndcube/*/tests/*", - "ndcube/extern/*", - "ndcube/version*", - "*/ndcube/__init*", - "*/ndcube/conftest.py", - "*/ndcube/*setup_package*", - "*/ndcube/tests/*", - "*/ndcube/*/tests/*", - "*/ndcube/extern/*", - "*/ndcube/version*", -] - -[tool.coverage.report] -exclude_lines = [ - # Have to re-enable the standard pragma - "pragma: no cover", - # Don't complain about packages we have installed - "except ImportError", - # Don't complain if tests don't hit assertions - "raise AssertionError", - "raise NotImplementedError", - # Don't complain about script hooks - "def main(.*):", - # Ignore branches that don't pertain to this version of Python - "pragma: py{ignore_python_version}", - # Don't complain about IPython completion helper - "def _ipython_key_completions_", -] - [tool.towncrier] package = "ndcube" filename = "CHANGELOG.rst" From 2a73c4f8655cb17fcfb0c4bfbb207d56d9f3c5a8 Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Wed, 17 Apr 2024 10:56:22 +0100 Subject: [PATCH 09/27] Adds dependancies and correct ci --- .github/workflows/ci.yml | 6 ++---- pyproject.toml | 22 +++++++++++++++++++--- tox.ini | 12 +++--------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 837b17220..c8cb06f27 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,13 +96,11 @@ jobs: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} publish_pure: - needs: [test, docs] - uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish_pure_python.yml@main if: | github.event_name != 'pull_request' && ( github.ref_name != 'main' || github.event_name == 'workflow_dispatch' ) - needs: [test] + needs: [test, docs] uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish_pure_python.yml@v1 with: python-version: '3.10' @@ -113,7 +111,7 @@ jobs: pypi_token: ${{ secrets.pypi_token }} notify: if: always() && github.event_name == 'workflow_dispatch' - needs: [publish, cron] + needs: [publish_pure, cron] runs-on: ubuntu-latest steps: - uses: Cadair/matrix-notify-action@main diff --git a/pyproject.toml b/pyproject.toml index bee6b07d8..d5de0e476 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,19 +15,35 @@ license = { file = "licenses/LICENSE.rst", content-type = "text/plain" } authors = [ { name = "The SunPy Community", email = "sunpy@googlegroups.com" }, ] -dependencies = [] +dependencies = [ + "astropy>=5.0.6,!=5.1.0", + "gwcs>=0.18", + "numpy>=1.23.0", + "dask" +] dynamic = ["version"] [project.optional-dependencies] tests = [ + "dask", "pytest", + "pytest-astropy", "pytest-doctestplus", - "pytest-cov" + "pytest-mpl>=0.12", + "scipy", + "sunpy>=5.0.0" ] docs = [ + "matplotlib", + "mpl-animators>=1.0", + "pytest-docstestplus>=0.9.0", "sphinx", "sphinx-automodapi", - "tomli; python_version <\"3.11\"", + "sphinx-changelog>=1.1.0", + "sphinx-gallery", + "sphinxext-opengraph", + "sunpy-sphinx-theme", + "sunpy>=5.0.0" ] [project.urls] diff --git a/tox.ini b/tox.ini index cc1ebde46..334a9c43e 100644 --- a/tox.ini +++ b/tox.ini @@ -58,15 +58,7 @@ deps = online: pytest-rerunfailures online: pytest-timeout # Oldest Dependencies - oldestdeps: sunpy<4.0 - oldestdeps: astropy<4.3 - oldestdeps: gwcs<0.16 - oldestdeps: numpy<1.23 - oldestdeps: matplotlib<3.3 - oldestdeps: mpl_animators<1.1 - oldestdeps: reproject==0.7.1 - oldestdeps: scipy<1.8.0 - oldestdeps: dask<2021.5.0 + oldestdeps: minimum_dependencies # Figure tests need a tightly controlled environment figure-!devdeps: matplotlib==3.7.2 figure-!devdeps: astropy==5.3.3 @@ -79,6 +71,8 @@ extras = commands = !oldestdeps-!online-!hypothesis-!figure: {env:PYTEST_COMMAND} {posargs} online: {env:PYTEST_COMMAND} --reruns 2 --reruns-delay 15 --timeout=180 --remote-data=any {posargs} + oldestdeps: minimum_dependencies {{ cookiecutter.module_name }} --filename requirements-min.txt + oldestdeps: pip install -r requirements-min.txt figure: /bin/bash -c "mkdir -p ./figure_test_images; python -c 'import matplotlib as mpl; print(mpl.ft2font.__file__, mpl.ft2font.__freetype_version__, mpl.ft2font.__freetype_build_type__)' > ./figure_test_images/figure_version_info.txt" figure: /bin/bash -c "pip freeze >> ./figure_test_images/figure_version_info.txt" figure: /bin/bash -c "cat ./figure_test_images/figure_version_info.txt" From 1a8cf8a9076f9dddf75534b5055434d2d13e9c27 Mon Sep 17 00:00:00 2001 From: Samuel Bennett Date: Wed, 17 Apr 2024 14:58:08 +0100 Subject: [PATCH 10/27] Update pyproject.toml Co-authored-by: Stuart Mumford --- pyproject.toml | 11 ++++++++++- tox.ini | 6 ++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d5de0e476..a6e8faeb5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,16 @@ docs = [ "sunpy-sphinx-theme", "sunpy>=5.0.0" ] - +plotting = [ + "matplotlib>=3.5.0", + "mpl_animators>=1.0", +] +reproject = [ + "reproject>=0.7.1", +] +all = [ + "ndcube[plotting, reproject]", +] [project.urls] repository = "https://docs.sunpy.org/projects/ndcube" diff --git a/tox.ini b/tox.ini index 334a9c43e..18379735b 100644 --- a/tox.ini +++ b/tox.ini @@ -66,7 +66,8 @@ deps = figure-!devdeps: scipy figure-!devdeps: dask extras = - all + plotting + reproject tests commands = !oldestdeps-!online-!hypothesis-!figure: {env:PYTEST_COMMAND} {posargs} @@ -83,7 +84,8 @@ commands = changedir = docs description = Invoke sphinx-build to build the HTML docs extras = - all + plotting + reproject docs commands = pip freeze --all --no-input From bb5139a4b4db1fb77210756696bf80f9f868ff0d Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Thu, 18 Apr 2024 15:12:03 +0100 Subject: [PATCH 11/27] Recitfy pytest.ini --- pytest.ini | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index a5e467af2..bf54de278 100644 --- a/pytest.ini +++ b/pytest.ini @@ -16,7 +16,8 @@ norecursedirs = doctest_plus = enabled doctest_optionflags = NORMALIZE_WHITESPACE FLOAT_CMP ELLIPSIS text_file_format = rst -addopts = --doctest-rst -p no:unraisableexception -p no:threadexception +addopts = --doctest-rst -p no:unraisableexception -p no:threadexception -m "not mpl_image_compare" --doctest-rst --doctest-ignore-import-errors -p no:unraisableexception -p no:threadexception +remote_data_strict = True filterwarnings = # Turn all warnings into errors so they do not pass silently. error @@ -25,3 +26,24 @@ filterwarnings = # A list of warnings to ignore follows. If you add to this list, you MUST # add a comment or ideally a link to an issue that explains why the warning # is being ignored + # This is hit on oldestdeps + ignore:.*distutils Version classes are deprecated.* + # This is due to dependencies building with a numpy version different from + # the local installed numpy version, but should be fine + # See https://github.com/numpy/numpy/issues/15748#issuecomment-598584838 + ignore:numpy.ufunc size changed:RuntimeWarning + ignore:numpy.ndarray size changed:RuntimeWarning + # Figure tests use agg backend so show doesn't work but we use it in peek + # Recent change to astropy has made our tests emit this warning. + ignore:'datfix' made the change:astropy.wcs.wcs.FITSFixedWarning + ignore:'unitfix' made the change:astropy.wcs.wcs.FITSFixedWarning + # TODO: This ones NEED to be fixed in future + # Ignore this, oh we emit so many + ignore::UserWarning + # WCSAxes is raising this + ignore:FLIP_TOP_BOTTOM is deprecated + # This is hit on oldestdeps + ignore:distutils Version classes are deprecated + ignore:The default kernel will change from 'Hann' to 'Gaussian' in a future release. To suppress this warning, explicitly select a kernel with the 'kernel' argument.:FutureWarning + ignore:The default boundary mode will change from 'ignore' to 'strict' in a future release. To suppress this warning, explicitly select a mode with the 'boundary_mode' argument.:FutureWarning + From c53e27e79e974b926c195746400ec43913c9a339 Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Thu, 18 Apr 2024 15:12:03 +0100 Subject: [PATCH 12/27] Recitfy pytest.ini --- pytest.ini | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index a5e467af2..804f84f9b 100644 --- a/pytest.ini +++ b/pytest.ini @@ -16,7 +16,8 @@ norecursedirs = doctest_plus = enabled doctest_optionflags = NORMALIZE_WHITESPACE FLOAT_CMP ELLIPSIS text_file_format = rst -addopts = --doctest-rst -p no:unraisableexception -p no:threadexception +addopts = --doctest-rst -p no:unraisableexception -p no:threadexception -m "not mpl_image_compare" --doctest-ignore-import-errors +remote_data_strict = True filterwarnings = # Turn all warnings into errors so they do not pass silently. error @@ -25,3 +26,24 @@ filterwarnings = # A list of warnings to ignore follows. If you add to this list, you MUST # add a comment or ideally a link to an issue that explains why the warning # is being ignored + # This is hit on oldestdeps + ignore:.*distutils Version classes are deprecated.* + # This is due to dependencies building with a numpy version different from + # the local installed numpy version, but should be fine + # See https://github.com/numpy/numpy/issues/15748#issuecomment-598584838 + ignore:numpy.ufunc size changed:RuntimeWarning + ignore:numpy.ndarray size changed:RuntimeWarning + # Figure tests use agg backend so show doesn't work but we use it in peek + # Recent change to astropy has made our tests emit this warning. + ignore:'datfix' made the change:astropy.wcs.wcs.FITSFixedWarning + ignore:'unitfix' made the change:astropy.wcs.wcs.FITSFixedWarning + # TODO: This ones NEED to be fixed in future + # Ignore this, oh we emit so many + ignore::UserWarning + # WCSAxes is raising this + ignore:FLIP_TOP_BOTTOM is deprecated + # This is hit on oldestdeps + ignore:distutils Version classes are deprecated + ignore:The default kernel will change from 'Hann' to 'Gaussian' in a future release. To suppress this warning, explicitly select a kernel with the 'kernel' argument.:FutureWarning + ignore:The default boundary mode will change from 'ignore' to 'strict' in a future release. To suppress this warning, explicitly select a mode with the 'boundary_mode' argument.:FutureWarning + From d5d79c9ff3aca1a3148a664bbeacce1b9a59bfcd Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Thu, 18 Apr 2024 15:24:48 +0100 Subject: [PATCH 13/27] Deps additions --- pyproject.toml | 2 +- tox.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a6e8faeb5..b0ac7dec5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,13 +30,13 @@ tests = [ "pytest-astropy", "pytest-doctestplus", "pytest-mpl>=0.12", + "pytest-xdist", "scipy", "sunpy>=5.0.0" ] docs = [ "matplotlib", "mpl-animators>=1.0", - "pytest-docstestplus>=0.9.0", "sphinx", "sphinx-automodapi", "sphinx-changelog>=1.1.0", diff --git a/tox.ini b/tox.ini index 18379735b..eafb04ebd 100644 --- a/tox.ini +++ b/tox.ini @@ -72,7 +72,7 @@ extras = commands = !oldestdeps-!online-!hypothesis-!figure: {env:PYTEST_COMMAND} {posargs} online: {env:PYTEST_COMMAND} --reruns 2 --reruns-delay 15 --timeout=180 --remote-data=any {posargs} - oldestdeps: minimum_dependencies {{ cookiecutter.module_name }} --filename requirements-min.txt + oldestdeps: minimum_dependencies ndcube --filename requirements-min.txt oldestdeps: pip install -r requirements-min.txt figure: /bin/bash -c "mkdir -p ./figure_test_images; python -c 'import matplotlib as mpl; print(mpl.ft2font.__file__, mpl.ft2font.__freetype_version__, mpl.ft2font.__freetype_build_type__)' > ./figure_test_images/figure_version_info.txt" figure: /bin/bash -c "pip freeze >> ./figure_test_images/figure_version_info.txt" From 7e4d5a6a1d0f5c02ddfb9da54d38172733bf3f4b Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Thu, 18 Apr 2024 15:34:54 +0100 Subject: [PATCH 14/27] Removing unneeded module --- docs/conf.py | 1 - pytest.ini | 1 - 2 files changed, 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 31c610258..6c0cbdc3a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -48,7 +48,6 @@ 'sphinx_automodapi.smart_resolver', 'ndcube.utils.sphinx.code_context', 'sphinx_changelog', - 'pytest_doctestplus.sphinx.doctestplus', 'sphinx_gallery.gen_gallery', "sphinxext.opengraph", ] diff --git a/pytest.ini b/pytest.ini index bf54de278..89090dc3c 100644 --- a/pytest.ini +++ b/pytest.ini @@ -46,4 +46,3 @@ filterwarnings = ignore:distutils Version classes are deprecated ignore:The default kernel will change from 'Hann' to 'Gaussian' in a future release. To suppress this warning, explicitly select a kernel with the 'kernel' argument.:FutureWarning ignore:The default boundary mode will change from 'ignore' to 'strict' in a future release. To suppress this warning, explicitly select a mode with the 'boundary_mode' argument.:FutureWarning - From bb7200cd5938ed68e374c519a1384dc1b1b78a62 Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Thu, 18 Apr 2024 15:41:42 +0100 Subject: [PATCH 15/27] Rectifies docs/tests issues: --- docs/reference/index.rst | 1 - docs/reference/tests.rst | 8 -------- 2 files changed, 9 deletions(-) delete mode 100644 docs/reference/tests.rst diff --git a/docs/reference/index.rst b/docs/reference/index.rst index 2e819a208..f62cafb30 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -12,5 +12,4 @@ API Reference mixins visualization utils - tests wcs diff --git a/docs/reference/tests.rst b/docs/reference/tests.rst deleted file mode 100644 index 135f2fef4..000000000 --- a/docs/reference/tests.rst +++ /dev/null @@ -1,8 +0,0 @@ -********************** -tests (`ndcube.tests`) -********************** - -.. automodapi:: ndcube.tests - :no-heading: - -.. automodapi:: ndcube.tests.helpers From e2361744380c219549c91ec433c9fcf7d089201b Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Thu, 18 Apr 2024 15:45:37 +0100 Subject: [PATCH 16/27] Standardises pre-commit-config --- .pre-commit-config.yaml | 50 +++-------- .ruff.toml | 2 +- pyproject.toml | 2 +- setup.cfg | 178 ---------------------------------------- tox.ini | 2 +- 5 files changed, 14 insertions(+), 220 deletions(-) delete mode 100644 setup.cfg diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4f4b8559..c92e29b09 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,46 +1,17 @@ repos: -# The warnings/errors we check for here are: - # E901 - SyntaxError or IndentationError - # E902 - IOError - # F822 - undefined name in __all__ - # F823 - local variable name referenced before assignment - # Others are taken care of by autopep8 - - repo: https://github.com/PyCQA/flake8 - rev: 7.0.0 + # This should be before any formatting hooks like isort + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.2.2" hooks: - - id: flake8 - args: - [ - "--count", - "--select", - "E901,E902,F822,F823", - ] - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*|.rst|.md)$" - - repo: https://github.com/PyCQA/autoflake - rev: v2.3.1 - hooks: - - id: autoflake - args: - [ - "--in-place", - "--remove-all-unused-imports", - "--remove-unused-variable", - ] - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*|.rst|.md|__init__.py)$" + - id: ruff + args: ["--fix"] - repo: https://github.com/PyCQA/isort rev: 5.13.2 hooks: - id: isort - args: ["--sp", "setup.cfg"] - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*|.rst|.md)$" - - repo: https://github.com/hhatto/autopep8 - rev: v2.1.0 - hooks: - - id: autopep8 - args: ["--in-place","--max-line-length", "200"] - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*|.rst|.md)$" + exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*|ndcube/extern)$" - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v4.5.0 hooks: - id: check-ast - id: check-case-conflict @@ -49,15 +20,16 @@ repos: - id: check-yaml - id: debug-statements - id: check-added-large-files - args: ['--enforce-all','--maxkb=1054'] + args: ["--enforce-all", "--maxkb=1054"] - id: end-of-file-fixer - exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*)$" + exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|.json)$|^CITATION.rst$" - id: mixed-line-ending exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*)$" - repo: https://github.com/codespell-project/codespell rev: v2.2.6 hooks: - id: codespell - args: ['--config setup.cfg'] + args: [ "--write-changes" ] ci: autofix_prs: false + autoupdate_schedule: "quarterly" diff --git a/.ruff.toml b/.ruff.toml index 0b94cd4fa..c79b7a57c 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -20,7 +20,7 @@ extend-ignore = [ "PT023", # Always use () on pytest decorators ] -[per-file-ignores] +[lint.per-file-ignores] # Part of configuration, not a package. "setup.py" = ["INP001"] "conftest.py" = ["INP001"] diff --git a/pyproject.toml b/pyproject.toml index b0ac7dec5..aa380cfd9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ tests = [ docs = [ "matplotlib", "mpl-animators>=1.0", - "sphinx", + "sphinx<7.3.0", "sphinx-automodapi", "sphinx-changelog>=1.1.0", "sphinx-gallery", diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index e1865cce4..000000000 --- a/setup.cfg +++ /dev/null @@ -1,178 +0,0 @@ -[metadata] -name = ndcube -provides = ndcube -author = The SunPy Community -author_email = sunpy@googlegroups.com -license = BSD 2-Clause -license_files = LICENSE.rst -url = https://docs.sunpy.org/projects/ndcube/ -download_url = https://pypi.org/project/ndcube/ -project_urls= - Source Code = https://github.com/sunpy/ndcube/ - Documentation = https://docs.sunpy.org/projects/ndcube/ - Changelog = https://docs.sunpy.org/projects/ndcube/en/stable/whatsnew/changelog.html - Issue Tracker = https://github.com/sunpy/ndcube/issues -description = A package for multi-dimensional contiguous and non-contiguous coordinate aware arrays. -long_description = file: README.rst -long_description_content_type = text/x-rst -edit_on_github = True -github_project = sunpy/ndcube -platform = any -keywords = nddata, science, sun, wcs, gwcs, coordinates, sunpy, astropy, solar, spectroscopy -classifiers = - Development Status :: 5 - Production/Stable - Intended Audience :: Science/Research - License :: OSI Approved :: BSD License - Natural Language :: English - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Topic :: Scientific/Engineering :: Physics - -[options] -zip_safe = False -packages = find: -include_package_data = True -python_requires = >=3.9 -install_requires = - astropy>=5.0.6,!=5.1.0 - gwcs>=0.18 - numpy>=1.21.0 - -[options.extras_require] -tests = - dask - pytest - pytest-astropy - pytest-mpl>=0.12 - scipy - sunpy>=5.0.0 -docs = - matplotlib - pytest-doctestplus>=0.9.0 - sphinx - sphinx-automodapi - # Remove next line when fixed in towncrier; see https://github.com/twisted/towncrier/issues/528 - importlib-resources<6 - sphinx-changelog>=1.1.0 - sphinx-gallery - sphinxext-opengraph - sunpy-sphinx-theme - sunpy>=5.0.0 -plotting = - matplotlib>=3.5.0 - mpl_animators>=1.0 -reproject = - reproject>=0.7.1 - -[options.packages.find] -exclude = ndcube._dev - -[tool:pytest] -testpaths = "ndcube" "docs" -norecursedirs = ".tox" "build" "docs[\/]_build" "docs[\/]generated" "*.egg-info" "examples" ".history" -doctest_plus = enabled -doctest_optionflags = NORMALIZE_WHITESPACE FLOAT_CMP ELLIPSIS -text_file_format = rst -mpl-results-path = figure_test_images -mpl-use-full-test-name = True -addopts = -m "not mpl_image_compare" --doctest-rst --doctest-ignore-import-errors -p no:unraisableexception -p no:threadexception -markers = - remote_data: marks this test function as needing remote data. - online: marks this test function as needing online connectivity. -remote_data_strict = True -filterwarnings = - error - # Do not fail on pytest config issues (i.e. missing plugins) but do show them - always::pytest.PytestConfigWarning - # - # A list of warnings to ignore follows. If you add to this list, you MUST - # add a comment or ideally a link to an issue that explains why the warning - # is being ignored - # - # - # This is hit on oldestdeps - ignore:.*distutils Version classes are deprecated.* - # This is due to dependencies building with a numpy version different from - # the local installed numpy version, but should be fine - # See https://github.com/numpy/numpy/issues/15748#issuecomment-598584838 - ignore:numpy.ufunc size changed:RuntimeWarning - ignore:numpy.ndarray size changed:RuntimeWarning - # Figure tests use agg backend so show doesn't work but we use it in peek - # Recent change to astropy has made our tests emit this warning. - ignore:'datfix' made the change:astropy.wcs.wcs.FITSFixedWarning - ignore:'unitfix' made the change:astropy.wcs.wcs.FITSFixedWarning - # TODO: This ones NEED to be fixed in future - # Ignore this, oh we emit so many - ignore::UserWarning - # WCSAxes is raising this - ignore:FLIP_TOP_BOTTOM is deprecated - # This is hit on oldestdeps - ignore:distutils Version classes are deprecated - ignore:The default kernel will change from 'Hann' to 'Gaussian' in a future release. To suppress this warning, explicitly select a kernel with the 'kernel' argument.:FutureWarning - ignore:The default boundary mode will change from 'ignore' to 'strict' in a future release. To suppress this warning, explicitly select a mode with the 'boundary_mode' argument.:FutureWarning - -[flake8] -exclude = extern,sphinx,*parsetab.py,conftest.py,docs/conf.py,setup.py -max-line-length = 110 - -[pycodestyle] -exclude = extern,sphinx,*parsetab.py,conftest.py,docs/conf.py,setup.py -max_line_length = 110 - -[isort] -line_length = 110 -sections = FUTURE, STDLIB, THIRDPARTY, FIRSTPARTY, LOCALFOLDER -default_section = THIRDPARTY -known_first_party = ndcube -known_third_party = astropy,matplotlib,numpy,pytest,setuptools -multi_line_output = 0 -balanced_wrapping = True -include_trailing_comma = False -length_sort = False -length_sort_sections = stdlib -skip_glob = *.rst --filter-files - -[coverage:run] -omit = - ndcube/conftest.py - ndcube/*setup* - ndcube/*/tests/* - ndcube/version* - ndcube/__init__* - ndcube/tests/* - */ndcube/conftest.py - */ndcube/*setup* - */ndcube/*/tests/* - */ndcube/tests/* - */ndcube/version* - */ndcube/__init__* - -[coverage:report] -exclude_lines = - # Have to re-enable the standard pragma - pragma: no cover - # Don't complain about packages we have installed - except ImportError - # Don't complain if tests don't hit assertions - raise AssertionError - raise NotImplementedError - # Don't complain about script hooks - def main\(.*\): - # Ignore branches that don't pertain to this version of Python - pragma: py{ignore_python_version} - -[codespell] -skip = *.asdf,*.fits,*.fts,*.header,*.json,*.xsh,*cache*,*egg*,*extern*,.git,.idea,.tox,_build,*truncated,*.,*svg,*.bib -ignore-words-list = - alog, - nd, - nin, - observ, - ot, - te, - upto, - aas diff --git a/tox.ini b/tox.ini index eafb04ebd..eff7864c5 100644 --- a/tox.ini +++ b/tox.ini @@ -37,7 +37,7 @@ pass_env = set_env = MPLBACKEND = agg COLUMNS = 180 - PYTEST_COMMAND = pytest -vvv -s -raR --pyargs ndcube --cov-report=xml --cov=ndcube --cov-config={toxinidir}/setup.cfg {toxinidir}/docs + PYTEST_COMMAND = pytest -vvv -r fEs --pyargs ndcube --cov-report=xml --cov=ndcube --cov-config={toxinidir}/.coveragerc {toxinidir}/docs PARFIVE_HIDE_PROGESS = True devdeps: PIP_EXTRA_INDEX_URL = https://pypi.anaconda.org/astropy/simple https://pypi.anaconda.org/scientific-python-nightly-wheels/simple passenv = From 4eb67817fa057db6cf163e64736fe9a896e7413f Mon Sep 17 00:00:00 2001 From: Samuel Bennett Date: Thu, 18 Apr 2024 16:06:13 +0100 Subject: [PATCH 17/27] Update pyproject.toml Co-authored-by: Stuart Mumford --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index aa380cfd9..3ec46fd40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,6 +63,7 @@ zip-safe = false include-package-data = true [tool.setuptools.packages.find] +exclude = ["ndcube._dev*"] [tool.setuptools_scm] write_to = "ndcube/_version.py" From 116ff300d1d869723b92bfe11ee2a4018875902d Mon Sep 17 00:00:00 2001 From: Samuel Bennett Date: Thu, 18 Apr 2024 16:06:48 +0100 Subject: [PATCH 18/27] Update .ruff.toml Co-authored-by: Stuart Mumford --- .ruff.toml | 9 ++++++++- pytest.ini | 2 +- tox.ini | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.ruff.toml b/.ruff.toml index c79b7a57c..000e09088 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -8,8 +8,15 @@ exclude = [ ] [lint] -select = ["E", "F", "W", "UP", "PT"] +select = [ + "E", + #"F", + "W", + #"UP", + #"PT" +] extend-ignore = [ + "E712", # pycodestyle (E, W) "E501", # LineTooLong # TODO! fix # pytest (PT) diff --git a/pytest.ini b/pytest.ini index 89090dc3c..197029712 100644 --- a/pytest.ini +++ b/pytest.ini @@ -16,7 +16,7 @@ norecursedirs = doctest_plus = enabled doctest_optionflags = NORMALIZE_WHITESPACE FLOAT_CMP ELLIPSIS text_file_format = rst -addopts = --doctest-rst -p no:unraisableexception -p no:threadexception -m "not mpl_image_compare" --doctest-rst --doctest-ignore-import-errors -p no:unraisableexception -p no:threadexception +addopts = --doctest-rst -p no:unraisableexception -p no:threadexception -m "not mpl_image_compare" --doctest-ignore-import-errors remote_data_strict = True filterwarnings = # Turn all warnings into errors so they do not pass silently. diff --git a/tox.ini b/tox.ini index eff7864c5..c7aa5c3c9 100644 --- a/tox.ini +++ b/tox.ini @@ -89,7 +89,7 @@ extras = docs commands = pip freeze --all --no-input - sphinx-build -j auto --color -W --keep-going -b html -d _build/.doctrees . _build/html {posargs} + sphinx-build --color -W --keep-going -b html -d _build/.doctrees . _build/html {posargs} python -c 'import pathlib; print("Documentation available under file://\{0\}".format(pathlib.Path(r"{toxinidir}") / "docs" / "_build" / "index.html"))' [testenv:codestyle] From bb105573638b3606a01043ab26abe0978acde7c1 Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Thu, 18 Apr 2024 16:21:17 +0100 Subject: [PATCH 19/27] reverse sphinx pin --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3ec46fd40..784ef067c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ tests = [ docs = [ "matplotlib", "mpl-animators>=1.0", - "sphinx<7.3.0", + "sphinx", "sphinx-automodapi", "sphinx-changelog>=1.1.0", "sphinx-gallery", From 83b9d13557a7bd3d45cd40efff1b48bcfbaa006a Mon Sep 17 00:00:00 2001 From: Samuel Bennett Date: Thu, 18 Apr 2024 16:21:39 +0100 Subject: [PATCH 20/27] Update .codespellrc Co-authored-by: Stuart Mumford --- .codespellrc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.codespellrc b/.codespellrc index 042a14edc..c02e1676b 100644 --- a/.codespellrc +++ b/.codespellrc @@ -2,6 +2,8 @@ skip = *.asdf,*.fits,*.fts,*.header,*.json,*.xsh,*cache*,*egg*,*extern*,.git,.idea,.tox,_build,*truncated,*.svg,.asv_env,.history ignore-words-list = alog, + aas, + Hart, nd, nin, observ, From 509dca54b9aede9e128fd10d5f0b24d964c0f750 Mon Sep 17 00:00:00 2001 From: Samuel Bennett Date: Thu, 18 Apr 2024 16:21:48 +0100 Subject: [PATCH 21/27] Update .ruff.toml Co-authored-by: Stuart Mumford --- .ruff.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ruff.toml b/.ruff.toml index 000e09088..5709980c4 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -17,6 +17,7 @@ select = [ ] extend-ignore = [ "E712", + "E721", # pycodestyle (E, W) "E501", # LineTooLong # TODO! fix # pytest (PT) From 5a76e5ece8b9fbec9dc4026340d7ff4842a8a5e8 Mon Sep 17 00:00:00 2001 From: Samuel Bennett Date: Thu, 18 Apr 2024 16:21:58 +0100 Subject: [PATCH 22/27] Update pyproject.toml Co-authored-by: Stuart Mumford --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3ec46fd40..784ef067c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ tests = [ docs = [ "matplotlib", "mpl-animators>=1.0", - "sphinx<7.3.0", + "sphinx", "sphinx-automodapi", "sphinx-changelog>=1.1.0", "sphinx-gallery", From b726cdae908d1b1278e854bde63cbec86b56a9e6 Mon Sep 17 00:00:00 2001 From: Samuel Bennett Date: Thu, 18 Apr 2024 16:27:39 +0100 Subject: [PATCH 23/27] Update tox.ini Co-authored-by: Stuart Mumford --- tox.ini | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index c7aa5c3c9..59a4a89cb 100644 --- a/tox.ini +++ b/tox.ini @@ -69,11 +69,13 @@ extras = plotting reproject tests -commands = - !oldestdeps-!online-!hypothesis-!figure: {env:PYTEST_COMMAND} {posargs} - online: {env:PYTEST_COMMAND} --reruns 2 --reruns-delay 15 --timeout=180 --remote-data=any {posargs} +commands_pre = oldestdeps: minimum_dependencies ndcube --filename requirements-min.txt oldestdeps: pip install -r requirements-min.txt + pip freeze --all --no-input +commands = + !online-!hypothesis-!figure: {env:PYTEST_COMMAND} {posargs} + online: {env:PYTEST_COMMAND} --reruns 2 --reruns-delay 15 --timeout=180 --remote-data=any {posargs} figure: /bin/bash -c "mkdir -p ./figure_test_images; python -c 'import matplotlib as mpl; print(mpl.ft2font.__file__, mpl.ft2font.__freetype_version__, mpl.ft2font.__freetype_build_type__)' > ./figure_test_images/figure_version_info.txt" figure: /bin/bash -c "pip freeze >> ./figure_test_images/figure_version_info.txt" figure: /bin/bash -c "cat ./figure_test_images/figure_version_info.txt" From 98526e5d0b7832d036e49293142fb4f4707b6090 Mon Sep 17 00:00:00 2001 From: Samuel Bennett Date: Thu, 18 Apr 2024 16:34:26 +0100 Subject: [PATCH 24/27] Update tox.ini Co-authored-by: Stuart Mumford --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index 59a4a89cb..3d1879701 100644 --- a/tox.ini +++ b/tox.ini @@ -72,6 +72,7 @@ extras = commands_pre = oldestdeps: minimum_dependencies ndcube --filename requirements-min.txt oldestdeps: pip install -r requirements-min.txt + oldestdeps: python -c "import astropy.time; astropy.time.update_leap_seconds()" pip freeze --all --no-input commands = !online-!hypothesis-!figure: {env:PYTEST_COMMAND} {posargs} From 0bf3a865da5ae0662156df8a9a503d7b4b589cbf Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Fri, 19 Apr 2024 11:12:14 +0100 Subject: [PATCH 25/27] Ignore .bib in codespell rc --- .codespellrc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.codespellrc b/.codespellrc index c02e1676b..0ea6290ae 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,9 +1,8 @@ [codespell] -skip = *.asdf,*.fits,*.fts,*.header,*.json,*.xsh,*cache*,*egg*,*extern*,.git,.idea,.tox,_build,*truncated,*.svg,.asv_env,.history +skip = *.asdf,*.fits,*.fts,*.header,*.json,*.xsh,*cache*,*egg*,*extern*,.git,.idea,.tox,_build,*truncated,*.svg,.asv_env,.history,.bib ignore-words-list = alog, aas, - Hart, nd, nin, observ, From 2ed8b115b015f25c98d8cef6d45a9fca8b63dc72 Mon Sep 17 00:00:00 2001 From: CyclingNinja Date: Fri, 19 Apr 2024 11:43:56 +0100 Subject: [PATCH 26/27] Apply isort to imports --- examples/creating_ndcube_from_fitsfile.py | 1 + examples/slicing_ndcube.py | 4 +++- ndcube/conftest.py | 5 +++-- ndcube/extra_coords/__init__.py | 9 +++++++-- ndcube/extra_coords/extra_coords.py | 15 ++++++++++----- ndcube/extra_coords/table_coord.py | 3 ++- ndcube/extra_coords/tests/test_extra_coords.py | 3 ++- .../extra_coords/tests/test_lookup_table_coord.py | 11 ++++++++--- ndcube/global_coords.py | 1 + ndcube/ndcube.py | 6 +++--- ndcube/ndcube_sequence.py | 3 ++- ndcube/tests/helpers.py | 5 +++-- ndcube/tests/test_global_coords.py | 3 ++- ndcube/tests/test_ndcollection.py | 5 +++-- ndcube/tests/test_ndcube.py | 5 +++-- ndcube/tests/test_ndcubesequence.py | 3 ++- ndcube/utils/cube.py | 3 ++- ndcube/utils/tests/test_utils_collection.py | 3 ++- ndcube/utils/tests/test_utils_cube.py | 1 + ndcube/utils/tests/test_utils_wcs.py | 1 + ndcube/utils/wcs.py | 1 + ndcube/visualization/mpl_plotter.py | 3 ++- ndcube/visualization/mpl_sequence_plotter.py | 3 ++- ndcube/visualization/tests/test_plotting.py | 3 ++- ndcube/visualization/tests/test_plotting_utils.py | 3 ++- ndcube/wcs/tests/test_tools.py | 3 ++- ndcube/wcs/tools.py | 1 + ndcube/wcs/wrappers/compound_wcs.py | 1 + ndcube/wcs/wrappers/reordered_wcs.py | 1 + ndcube/wcs/wrappers/resampled_wcs.py | 1 + ndcube/wcs/wrappers/tests/test_compound_wcs.py | 3 ++- ndcube/wcs/wrappers/tests/test_reordered_wcs.py | 3 ++- ndcube/wcs/wrappers/tests/test_resampled_wcs.py | 3 ++- 33 files changed, 82 insertions(+), 37 deletions(-) diff --git a/examples/creating_ndcube_from_fitsfile.py b/examples/creating_ndcube_from_fitsfile.py index 780116c52..b3a06435f 100644 --- a/examples/creating_ndcube_from_fitsfile.py +++ b/examples/creating_ndcube_from_fitsfile.py @@ -8,6 +8,7 @@ """ import matplotlib.pyplot as plt + from astropy.io import fits from astropy.utils.data import get_pkg_data_filename from astropy.wcs import WCS diff --git a/examples/slicing_ndcube.py b/examples/slicing_ndcube.py index 203d57d55..904559678 100644 --- a/examples/slicing_ndcube.py +++ b/examples/slicing_ndcube.py @@ -10,10 +10,12 @@ For example, there may be a region of interest you would like to crop out along a certain dimension of your cube. In this example, this method to slice an `~ndcube.NDCube` are illustrated. """ -import astropy.wcs import numpy as np + +import astropy.wcs from astropy import units as u from astropy.coordinates import SkyCoord, SpectralCoord + from sunpy.coordinates import frames from ndcube import NDCube diff --git a/ndcube/conftest.py b/ndcube/conftest.py index 76f33a1b4..8e5dcc692 100644 --- a/ndcube/conftest.py +++ b/ndcube/conftest.py @@ -4,11 +4,12 @@ """ import logging -import astropy.nddata -import astropy.units as u import dask.array import numpy as np import pytest + +import astropy.nddata +import astropy.units as u from astropy.coordinates import SkyCoord from astropy.nddata import StdDevUncertainty from astropy.time import Time, TimeDelta diff --git a/ndcube/extra_coords/__init__.py b/ndcube/extra_coords/__init__.py index 2d41f91b0..315b95209 100644 --- a/ndcube/extra_coords/__init__.py +++ b/ndcube/extra_coords/__init__.py @@ -1,5 +1,10 @@ -from .table_coord import (BaseTableCoordinate, MultipleTableCoordinate, QuantityTableCoordinate, - SkyCoordTableCoordinate, TimeTableCoordinate) +from .table_coord import ( + BaseTableCoordinate, + MultipleTableCoordinate, + QuantityTableCoordinate, + SkyCoordTableCoordinate, + TimeTableCoordinate, +) __all__ = ['TimeTableCoordinate', "MultipleTableCoordinate", 'SkyCoordTableCoordinate', 'QuantityTableCoordinate', "BaseTableCoordinate"] diff --git a/ndcube/extra_coords/extra_coords.py b/ndcube/extra_coords/extra_coords.py index 3ca351884..7c88af705 100644 --- a/ndcube/extra_coords/extra_coords.py +++ b/ndcube/extra_coords/extra_coords.py @@ -1,11 +1,12 @@ import abc from typing import Any -from collections.abc import Iterable from numbers import Integral from functools import reduce, partial +from collections.abc import Iterable -import astropy.units as u import numpy as np + +import astropy.units as u from astropy.coordinates import SkyCoord from astropy.time import Time from astropy.wcs import WCS @@ -15,9 +16,13 @@ from ndcube.utils.wcs import convert_between_array_and_pixel_axes from ndcube.wcs.wrappers import CompoundLowLevelWCS, ResampledLowLevelWCS - -from .table_coord import (BaseTableCoordinate, MultipleTableCoordinate, QuantityTableCoordinate, - SkyCoordTableCoordinate, TimeTableCoordinate) +from .table_coord import ( + BaseTableCoordinate, + MultipleTableCoordinate, + QuantityTableCoordinate, + SkyCoordTableCoordinate, + TimeTableCoordinate, +) __all__ = ['ExtraCoordsABC', 'ExtraCoords'] diff --git a/ndcube/extra_coords/table_coord.py b/ndcube/extra_coords/table_coord.py index bdba908b4..503d6f1c7 100644 --- a/ndcube/extra_coords/table_coord.py +++ b/ndcube/extra_coords/table_coord.py @@ -3,10 +3,11 @@ from numbers import Integral from collections import defaultdict -import astropy.units as u import gwcs import gwcs.coordinate_frames as cf import numpy as np + +import astropy.units as u from astropy.coordinates import SkyCoord from astropy.modeling import models from astropy.modeling.models import tabular_model diff --git a/ndcube/extra_coords/tests/test_extra_coords.py b/ndcube/extra_coords/tests/test_extra_coords.py index ea410fac0..c8b9bd706 100644 --- a/ndcube/extra_coords/tests/test_extra_coords.py +++ b/ndcube/extra_coords/tests/test_extra_coords.py @@ -1,9 +1,10 @@ from unittest.mock import MagicMock -import astropy.units as u import gwcs import numpy as np import pytest + +import astropy.units as u from astropy.coordinates import SkyCoord from astropy.time import Time, TimeDelta from astropy.wcs import WCS diff --git a/ndcube/extra_coords/tests/test_lookup_table_coord.py b/ndcube/extra_coords/tests/test_lookup_table_coord.py index c20fb6f80..7443691b0 100644 --- a/ndcube/extra_coords/tests/test_lookup_table_coord.py +++ b/ndcube/extra_coords/tests/test_lookup_table_coord.py @@ -1,12 +1,17 @@ -import astropy.units as u import gwcs.coordinate_frames as cf import numpy as np import pytest + +import astropy.units as u from astropy.coordinates import SkyCoord from astropy.time import Time -from ndcube.extra_coords.table_coord import (MultipleTableCoordinate, QuantityTableCoordinate, - SkyCoordTableCoordinate, TimeTableCoordinate) +from ndcube.extra_coords.table_coord import ( + MultipleTableCoordinate, + QuantityTableCoordinate, + SkyCoordTableCoordinate, + TimeTableCoordinate, +) @pytest.fixture diff --git a/ndcube/global_coords.py b/ndcube/global_coords.py index f7ccc41e8..a15c1facf 100644 --- a/ndcube/global_coords.py +++ b/ndcube/global_coords.py @@ -5,6 +5,7 @@ from collections.abc import Mapping import numpy as np + from astropy.coordinates.sky_coordinate import SkyCoord from astropy.wcs.wcsapi.high_level_api import default_order from astropy.wcs.wcsapi.utils import deserialize_class diff --git a/ndcube/ndcube.py b/ndcube/ndcube.py index 15a75f1f5..1ce16333a 100644 --- a/ndcube/ndcube.py +++ b/ndcube/ndcube.py @@ -3,13 +3,13 @@ import warnings from copy import deepcopy from typing import Any -from collections.abc import Iterable from collections import namedtuple -from collections.abc import Mapping +from collections.abc import Mapping, Iterable + +import numpy as np import astropy.nddata import astropy.units as u -import numpy as np from astropy.units import UnitsError try: diff --git a/ndcube/ndcube_sequence.py b/ndcube/ndcube_sequence.py index ce2c471b9..1ede34e79 100644 --- a/ndcube/ndcube_sequence.py +++ b/ndcube/ndcube_sequence.py @@ -2,9 +2,10 @@ import numbers import textwrap -import astropy.units as u import numpy as np +import astropy.units as u + from ndcube import utils from ndcube.visualization.descriptor import PlotterDescriptor diff --git a/ndcube/tests/helpers.py b/ndcube/tests/helpers.py index adddb3d3a..e0cd7ec21 100644 --- a/ndcube/tests/helpers.py +++ b/ndcube/tests/helpers.py @@ -6,16 +6,17 @@ from pathlib import Path from functools import wraps -import astropy import matplotlib as mpl import matplotlib.pyplot as plt import mpl_animators import numpy as np import pytest +from numpy.testing import assert_equal + +import astropy from astropy.wcs.wcsapi.fitswcs import SlicedFITSWCS from astropy.wcs.wcsapi.low_level_api import BaseLowLevelWCS from astropy.wcs.wcsapi.wrappers.sliced_wcs import sanitize_slices -from numpy.testing import assert_equal from ndcube import NDCube, NDCubeSequence diff --git a/ndcube/tests/test_global_coords.py b/ndcube/tests/test_global_coords.py index e97f53007..38453ba47 100644 --- a/ndcube/tests/test_global_coords.py +++ b/ndcube/tests/test_global_coords.py @@ -1,6 +1,7 @@ -import astropy.units as u import numpy as np import pytest + +import astropy.units as u from astropy.coordinates import SkyCoord from astropy.coordinates.spectral_coordinate import SpectralCoord from astropy.wcs.wcsapi.high_level_api import HighLevelWCSMixin diff --git a/ndcube/tests/test_ndcollection.py b/ndcube/tests/test_ndcollection.py index da2d1bd7b..86424f29a 100644 --- a/ndcube/tests/test_ndcollection.py +++ b/ndcube/tests/test_ndcollection.py @@ -1,9 +1,10 @@ -import astropy.units as u -import astropy.wcs import numpy as np import pytest +import astropy.units as u +import astropy.wcs + from ndcube import NDCollection, NDCube, NDCubeSequence from ndcube.tests import helpers diff --git a/ndcube/tests/test_ndcube.py b/ndcube/tests/test_ndcube.py index b8f1e1ada..94447472a 100644 --- a/ndcube/tests/test_ndcube.py +++ b/ndcube/tests/test_ndcube.py @@ -1,11 +1,12 @@ from inspect import signature from textwrap import dedent -import astropy.units as u -import astropy.wcs import dask.array import numpy as np import pytest + +import astropy.units as u +import astropy.wcs from astropy.coordinates import SkyCoord, SpectralCoord from astropy.io import fits from astropy.nddata import UnknownUncertainty diff --git a/ndcube/tests/test_ndcubesequence.py b/ndcube/tests/test_ndcubesequence.py index 65bf803a5..b952646cd 100644 --- a/ndcube/tests/test_ndcubesequence.py +++ b/ndcube/tests/test_ndcubesequence.py @@ -1,8 +1,9 @@ import unittest -import astropy.units as u import numpy as np import pytest + +import astropy.units as u from astropy.time import Time, TimeDelta from ndcube import NDCube, NDCubeSequence diff --git a/ndcube/utils/cube.py b/ndcube/utils/cube.py index b4964597a..cdaee114b 100644 --- a/ndcube/utils/cube.py +++ b/ndcube/utils/cube.py @@ -2,8 +2,9 @@ from functools import wraps from itertools import chain -import astropy.nddata import numpy as np + +import astropy.nddata from astropy.wcs.wcsapi import BaseHighLevelWCS, HighLevelWCSWrapper, SlicedLowLevelWCS from ndcube.utils import wcs as wcs_utils diff --git a/ndcube/utils/tests/test_utils_collection.py b/ndcube/utils/tests/test_utils_collection.py index 0f43a2ee3..cf4d3ebb5 100644 --- a/ndcube/utils/tests/test_utils_collection.py +++ b/ndcube/utils/tests/test_utils_collection.py @@ -1,7 +1,8 @@ -import astropy.units as u import pytest +import astropy.units as u + from ndcube.utils import collection as collection_utils diff --git a/ndcube/utils/tests/test_utils_cube.py b/ndcube/utils/tests/test_utils_cube.py index db839e794..394c8c49f 100644 --- a/ndcube/utils/tests/test_utils_cube.py +++ b/ndcube/utils/tests/test_utils_cube.py @@ -1,6 +1,7 @@ import numpy as np import pytest + from astropy.nddata import StdDevUncertainty from ndcube.utils.cube import propagate_rebin_uncertainties diff --git a/ndcube/utils/tests/test_utils_wcs.py b/ndcube/utils/tests/test_utils_wcs.py index d6fe96912..f21244ca4 100644 --- a/ndcube/utils/tests/test_utils_wcs.py +++ b/ndcube/utils/tests/test_utils_wcs.py @@ -1,6 +1,7 @@ import numpy as np import pytest + from astropy.wcs import WCS from ndcube import utils diff --git a/ndcube/utils/wcs.py b/ndcube/utils/wcs.py index 7eb842b44..9268676e2 100644 --- a/ndcube/utils/wcs.py +++ b/ndcube/utils/wcs.py @@ -6,6 +6,7 @@ from collections import UserDict import numpy as np + from astropy.wcs.utils import pixel_to_pixel from astropy.wcs.wcsapi import BaseHighLevelWCS, BaseLowLevelWCS, low_level_api diff --git a/ndcube/visualization/mpl_plotter.py b/ndcube/visualization/mpl_plotter.py index d95d27564..c44847781 100644 --- a/ndcube/visualization/mpl_plotter.py +++ b/ndcube/visualization/mpl_plotter.py @@ -1,8 +1,9 @@ import warnings -import astropy.units as u import matplotlib.pyplot as plt import numpy as np + +import astropy.units as u from astropy.utils.exceptions import AstropyUserWarning from astropy.visualization.wcsaxes import WCSAxes diff --git a/ndcube/visualization/mpl_sequence_plotter.py b/ndcube/visualization/mpl_sequence_plotter.py index a77a82e41..ef907b1d2 100644 --- a/ndcube/visualization/mpl_sequence_plotter.py +++ b/ndcube/visualization/mpl_sequence_plotter.py @@ -1,6 +1,7 @@ -from astropy.wcs.wcsapi import BaseLowLevelWCS from mpl_animators import ArrayAnimatorWCS +from astropy.wcs.wcsapi import BaseLowLevelWCS + from .base import BasePlotter from .plotting_utils import prep_plot_kwargs diff --git a/ndcube/visualization/tests/test_plotting.py b/ndcube/visualization/tests/test_plotting.py index 3c635b476..39672331f 100644 --- a/ndcube/visualization/tests/test_plotting.py +++ b/ndcube/visualization/tests/test_plotting.py @@ -1,8 +1,9 @@ -import astropy.units as u import matplotlib.pyplot as plt import mpl_animators import numpy as np import pytest + +import astropy.units as u from astropy.visualization.wcsaxes import WCSAxes from astropy.wcs import WCS diff --git a/ndcube/visualization/tests/test_plotting_utils.py b/ndcube/visualization/tests/test_plotting_utils.py index 36bee7212..e82c9a3d2 100644 --- a/ndcube/visualization/tests/test_plotting_utils.py +++ b/ndcube/visualization/tests/test_plotting_utils.py @@ -1,6 +1,7 @@ -import astropy.units as u import pytest +import astropy.units as u + import ndcube.visualization.plotting_utils as utils diff --git a/ndcube/wcs/tests/test_tools.py b/ndcube/wcs/tests/test_tools.py index ed9c99661..1aed41c23 100644 --- a/ndcube/wcs/tests/test_tools.py +++ b/ndcube/wcs/tests/test_tools.py @@ -1,8 +1,9 @@ import numpy as np +from numpy.testing import assert_array_almost_equal, assert_array_equal + from astropy.time import Time from astropy.wcs import WCS from astropy.wcs.wcsapi import SlicedLowLevelWCS -from numpy.testing import assert_array_almost_equal, assert_array_equal from ndcube.wcs.tools import unwrap_wcs_to_fitswcs from ndcube.wcs.wrappers import ResampledLowLevelWCS diff --git a/ndcube/wcs/tools.py b/ndcube/wcs/tools.py index 78793cebf..a74579a55 100644 --- a/ndcube/wcs/tools.py +++ b/ndcube/wcs/tools.py @@ -1,6 +1,7 @@ from numbers import Integral import numpy as np + from astropy.wcs import WCS from astropy.wcs.wcsapi import SlicedLowLevelWCS from astropy.wcs.wcsapi.wrappers.base import BaseWCSWrapper diff --git a/ndcube/wcs/wrappers/compound_wcs.py b/ndcube/wcs/wrappers/compound_wcs.py index d149af1bc..4fb26d5a0 100644 --- a/ndcube/wcs/wrappers/compound_wcs.py +++ b/ndcube/wcs/wrappers/compound_wcs.py @@ -1,6 +1,7 @@ from functools import reduce import numpy as np + from astropy.wcs.wcsapi.wrappers.base import BaseWCSWrapper __all__ = ['CompoundLowLevelWCS'] diff --git a/ndcube/wcs/wrappers/reordered_wcs.py b/ndcube/wcs/wrappers/reordered_wcs.py index 36c920d61..11639e01b 100644 --- a/ndcube/wcs/wrappers/reordered_wcs.py +++ b/ndcube/wcs/wrappers/reordered_wcs.py @@ -1,6 +1,7 @@ import numpy as np + from astropy.wcs.wcsapi.wrappers.base import BaseWCSWrapper __all__ = ['ReorderedLowLevelWCS'] diff --git a/ndcube/wcs/wrappers/resampled_wcs.py b/ndcube/wcs/wrappers/resampled_wcs.py index a84086eaa..3f3c2836a 100644 --- a/ndcube/wcs/wrappers/resampled_wcs.py +++ b/ndcube/wcs/wrappers/resampled_wcs.py @@ -1,4 +1,5 @@ import numpy as np + from astropy.wcs.wcsapi.wrappers.base import BaseWCSWrapper __all__ = ['ResampledLowLevelWCS'] diff --git a/ndcube/wcs/wrappers/tests/test_compound_wcs.py b/ndcube/wcs/wrappers/tests/test_compound_wcs.py index 355bcfe4d..5d38554d9 100644 --- a/ndcube/wcs/wrappers/tests/test_compound_wcs.py +++ b/ndcube/wcs/wrappers/tests/test_compound_wcs.py @@ -2,12 +2,13 @@ import numpy as np import pytest +from numpy.testing import assert_allclose, assert_equal + from astropy import units as u from astropy.coordinates import SkyCoord from astropy.tests.helper import assert_quantity_allclose from astropy.units import Quantity from astropy.wcs.wcsapi import HighLevelWCSWrapper -from numpy.testing import assert_allclose, assert_equal from ndcube.wcs.wrappers import CompoundLowLevelWCS diff --git a/ndcube/wcs/wrappers/tests/test_reordered_wcs.py b/ndcube/wcs/wrappers/tests/test_reordered_wcs.py index 379cb74e4..596333e36 100644 --- a/ndcube/wcs/wrappers/tests/test_reordered_wcs.py +++ b/ndcube/wcs/wrappers/tests/test_reordered_wcs.py @@ -2,12 +2,13 @@ import numpy as np import pytest +from numpy.testing import assert_allclose, assert_equal + from astropy import units as u from astropy.coordinates import SkyCoord from astropy.tests.helper import assert_quantity_allclose from astropy.units import Quantity from astropy.wcs.wcsapi import HighLevelWCSWrapper -from numpy.testing import assert_allclose, assert_equal from ndcube.wcs.wrappers import ReorderedLowLevelWCS diff --git a/ndcube/wcs/wrappers/tests/test_resampled_wcs.py b/ndcube/wcs/wrappers/tests/test_resampled_wcs.py index 90149a5a3..933c6bc44 100644 --- a/ndcube/wcs/wrappers/tests/test_resampled_wcs.py +++ b/ndcube/wcs/wrappers/tests/test_resampled_wcs.py @@ -2,11 +2,12 @@ import numpy as np import pytest +from numpy.testing import assert_allclose, assert_equal + from astropy import units as u from astropy.coordinates import SkyCoord from astropy.tests.helper import assert_quantity_allclose from astropy.wcs.wcsapi import HighLevelWCSWrapper -from numpy.testing import assert_allclose, assert_equal from ndcube.wcs.wrappers import ResampledLowLevelWCS From d1d02e7b81c917a0fcad3f63d7a7affbe0b3126f Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Mon, 22 Apr 2024 14:26:52 +0100 Subject: [PATCH 27/27] update template --- .cruft.json | 4 ++-- .pre-commit-config.yaml | 4 ++-- pyproject.toml | 13 +++++++------ pytest.ini | 12 ++++++++++-- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/.cruft.json b/.cruft.json index 64ef33449..0d054712a 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/sunpy/package-template", - "commit": "6d6729b22066ef890e70c37438da70cac33e03b4", + "commit": "1eff2ed0ff32c123e64b5faacf7c505362cfbb92", "checkout": null, "context": { "cookiecutter": { @@ -11,7 +11,7 @@ "author_email": "sunpy@googlegroups.com", "project_url": "https://docs.sunpy.org/projects/ndcube", "license": "BSD 2-Clause", - "minimum_python_version": "3.9", + "minimum_python_version": "3.10", "use_compiled_extensions": "n", "enable_dynamic_dev_versions": "y", "include_example_code": "n", diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c92e29b09..c2a2a5247 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: # This should be before any formatting hooks like isort - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.2.2" + rev: "v0.3.7" hooks: - id: ruff args: ["--fix"] @@ -11,7 +11,7 @@ repos: - id: isort exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*|ndcube/extern)$" - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-ast - id: check-case-conflict diff --git a/pyproject.toml b/pyproject.toml index 27d8a3656..2775a06e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta" [project] name = "ndcube" description = "A package for multi-dimensional contiguous and non-contiguous coordinate aware arrays." -requires-python = ">=3.9" +requires-python = ">=3.10" readme = { file = "README.rst", content-type = "text/x-rst" } license = { file = "licenses/LICENSE.rst", content-type = "text/plain" } authors = [ @@ -24,20 +24,21 @@ dynamic = ["version"] [project.optional-dependencies] tests = [ - "dask", "pytest", - "pytest-astropy", "pytest-doctestplus", - "pytest-mpl>=0.12", + "pytest-cov", "pytest-xdist", + "pytest-astropy", + "pytest-mpl>=0.12", + "dask", "scipy", "sunpy>=5.0.0" ] docs = [ - "matplotlib", - "mpl-animators>=1.0", "sphinx", "sphinx-automodapi", + "matplotlib", + "mpl-animators>=1.0", "sphinx-changelog>=1.1.0", "sphinx-gallery", "sphinxext-opengraph", diff --git a/pytest.ini b/pytest.ini index 197029712..08dd95160 100644 --- a/pytest.ini +++ b/pytest.ini @@ -14,9 +14,17 @@ norecursedirs = .history ndcube/extern doctest_plus = enabled -doctest_optionflags = NORMALIZE_WHITESPACE FLOAT_CMP ELLIPSIS +doctest_optionflags = + NORMALIZE_WHITESPACE + FLOAT_CMP + ELLIPSIS text_file_format = rst -addopts = --doctest-rst -p no:unraisableexception -p no:threadexception -m "not mpl_image_compare" --doctest-ignore-import-errors +addopts = + --doctest-rst + -p no:unraisableexception + -p no:threadexception + -m "not mpl_image_compare" + --doctest-ignore-import-errors remote_data_strict = True filterwarnings = # Turn all warnings into errors so they do not pass silently.