From 9a2843d1bd358acb46937edf7ae52887a7c19794 Mon Sep 17 00:00:00 2001 From: Nabil Freij Date: Fri, 6 Sep 2024 15:40:39 -0400 Subject: [PATCH] [Fix] Package templating --- .github/workflows/testing.yml | 4 +- .pre-commit-config.yaml | 18 +- .readthedocs.yaml | 4 +- .ruff.toml | 76 +++++++ README.md | 6 +- docs/changelog/dev.rst | 8 - docs/changelog/index.rst | 1 - docs/conf.py | 2 - .../installation_for_development.rst | 32 +-- ...to_Data_Extraction_and_Visualization.ipynb | 8 +- noxfile.py | 34 ++- pyproject.toml | 215 +++--------------- pytest.ini | 24 ++ xrtpy/__init__.py | 6 +- xrtpy/image_correction/remove_lightleak.py | 10 +- .../tests/test_remove_lightleak.py | 7 +- xrtpy/response/effective_area.py | 5 +- .../response/temperature_from_filter_ratio.py | 19 +- xrtpy/response/tests/test_effective_area.py | 13 +- .../tests/test_temperature_response.py | 9 +- xrtpy/util/filename2repo_path.py | 2 +- 21 files changed, 208 insertions(+), 295 deletions(-) create mode 100644 .ruff.toml delete mode 100644 docs/changelog/dev.rst create mode 100644 pytest.ini diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 0186d4c2..6c7ac3a9 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -43,7 +43,7 @@ jobs: - name: Tests, Python 3.10, Linux os: ubuntu-latest - noxenv: tests-3.10 + noxenv: tests python: '3.10' - name: Import XRTpy, Python 3.10, Linux @@ -109,4 +109,4 @@ jobs: pandoc --version - name: Build documentation - run: nox -s docs -- -q + run: nox -s docs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 20e425ca..a0cf695d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,11 +47,6 @@ repos: args: [--autofix] - id: pretty-format-yaml args: [--autofix] - # For the labeler GitHub Action, labels with spaces in them must - # be put in quotes. However, the pretty-format-yaml hook will - # remove the quotes which will break that action (and certain other - # actions). - exclude: .github/labeler.yml|.pre-commit-search-and-replace.yaml - repo: https://github.com/MarcoGorelli/absolufy-imports rev: v0.3.1 @@ -62,8 +57,6 @@ repos: - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.10.0 hooks: - - id: python-check-blanket-noqa - name: noqa comments have an error code - id: rst-directive-colons - id: rst-inline-touching-normal - id: text-unicode-replacement-char @@ -79,10 +72,10 @@ repos: exclude: .*\.fits - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.3 + rev: v0.6.4 hooks: - id: ruff - name: ruff (see https://docs.astral.sh/ruff/rules) + name: ruff args: [--fix] - id: ruff-format name: autoformat source code with ruff formatter @@ -93,16 +86,13 @@ repos: - id: blacken-docs name: autoformat code blocks in docs additional_dependencies: - - black==24.1.1 + - black - repo: https://github.com/nbQA-dev/nbQA rev: 1.8.7 hooks: - id: nbqa-check-ast name: validate Python notebooks - - id: nbqa-ruff - name: ruff for notebooks (see https://docs.astral.sh/ruff/rules) - args: [--fix, '--select=A,ARG,B,BLE,C,C4,E,F,FLY,I,INT,ISC,PERF,PIE,PLC,PLE,PYI,Q003,RET,RSE,SIM,TID,TRY,UP,W', '--ignore=B018,E402,E501,PLC2401,TRY003'] - id: nbqa-black additional_dependencies: - - black==24.1.1 + - black diff --git a/.readthedocs.yaml b/.readthedocs.yaml index e9ce913a..c79487fa 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -7,9 +7,9 @@ formats: - htmlzip build: - os: ubuntu-22.04 + os: ubuntu-lts-latest tools: - python: '3.11' + python: latest apt_packages: - graphviz jobs: diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 00000000..7ae7e13a --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,76 @@ +target-version = "py310" +show-fixes = true +extend-exclude = [ + ".jupyter", + "__pycache__", + "_build", + "_dev", +] + +[lint] +# Find info about ruff rules at: https://docs.astral.sh/ruff/rules +extend-select = [ + "ARG", # flake8-unused-arguments + "B", # flake8-bugbear + "BLE", # flake8-blind-except + "C4", # flake8-comprehensions + "C90", # mccabe + "COM818", # trailing-comma-on-bare-tuple + "FBT003", # flake8-boolean-trap + "FLY", # flynt + "I", # isort + "ICN", # flake8-import-conventions + "INP", # flake8-no-pep420 + "INT", # flake8-gettext + "ISC", # flake8-implicit-str-concat + "N", # pep8-naming + "NPY", # numpy-deprecated-type-alias + "PD", # pandas-vet + "PERF", # perflint + "PGH", # pygrep-hooks + "PIE", # flake8-pie + "PLC", # pylint convention + "PLE", # pylint errors + "PLW", # pylint warnings + "PT", # flake8-pytest-style + "PTH", # flake8-use-pathlib + "PYI", # flake8-pyi + "RSE", # flake8-raise + "RUF005",# collection-literal-concatenation + "RUF006", # asyncio-dangling-task + "RUF007", # pairwise-over-zipped + "RUF008", # mutable-dataclass-default + "RUF009", # function-call-in-dataclass-default-argument + "RUF010", # explicit-f-string-type-conversion + "RUF013", # implicit-optional + "RUF015", # unnecessary-iterable-allocation-for-first-element + "RUF016", # invalid-index-type + "RUF100", # unused-noqa + "RUF200", # invalid-pyproject-toml + "S", # flake8-bandit + "SIM", # flake8-simplify + "TCH", # flake8-type-checking + "TID", # flake8-tidy-imports + "TRY", # tryceratops + "UP", # pyupgrade + "W", # pycodestyle warnings +] +ignore = [ + "C901", # is too complex + "E501", # line-too-long + "ISC001", # single-line-implicit-string-concatenation (formatter conflict) + "N802", # invalid-function-name + "N803", # invalid-argument-name + "N806", # non-lowercase-variable-in-function + "N816", # mixed-case-variable-in-global-scope + "PLC2401", # non-ascii-name + "S101", # asserts + "SIM108", # if-else-block-instead-of-if-exp + "TRY003", # raise-vanilla-args +] + +[lint.per-file-ignores] +"docs/conf.py" = [ + "E402", # Module imports not at top of file + "INP001", # Implicit-namespace-package. The examples are not a package. +] diff --git a/README.md b/README.md index 21d09875..22d002d7 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,8 @@ [![Read the Docs Status](https://readthedocs.org/projects/xrtpy/badge/?version=latest&logo=twitter)](http://xrtpy.readthedocs.io/en/latest/?badge=latest) [![astropy](http://img.shields.io/badge/powered%20by-AstroPy-orange.svg?style=flat&logo=astropy)](http://www.astropy.org/) -XRTpy is a Python package being developed for the analysis of observations -made by the X-Ray Telescope (XRT) on the *Hinode* spacecraft. +XRTpy is a Python package being developed for the analysis of observations made by the X-Ray Telescope (XRT) on the **Hinode** spacecraft. ## Acknowledgements -The development of XRTpy is supported by NASA contract NNM07AB07C to the -Smithsonian Astrophysical Observatory. +The development of XRTpy is supported by NASA contract **NNM07AB07C** to the Smithsonian Astrophysical Observatory. diff --git a/docs/changelog/dev.rst b/docs/changelog/dev.rst deleted file mode 100644 index a7648c71..00000000 --- a/docs/changelog/dev.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -================== -Unreleased changes -================== - -.. changelog:: - :towncrier: ../../ diff --git a/docs/changelog/index.rst b/docs/changelog/index.rst index 2b1bf0e2..1ef992fd 100644 --- a/docs/changelog/index.rst +++ b/docs/changelog/index.rst @@ -11,7 +11,6 @@ including bug fixes and changes to the application programming interface .. toctree:: :maxdepth: 1 - dev 0.4.0 0.3.0 0.2.0 diff --git a/docs/conf.py b/docs/conf.py index a436e659..9d6f76aa 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -35,11 +35,9 @@ "sphinx.ext.napoleon", "sphinx.ext.todo", "nbsphinx", - "sphinx_changelog", "sphinx_copybutton", "sphinx_gallery.load_style", "IPython.sphinxext.ipython_console_highlighting", - "sphinx_changelog", "sphinx_issues", "sphinxcontrib.bibtex", "hoverxref.extension", diff --git a/docs/contributing/installation_for_development.rst b/docs/contributing/installation_for_development.rst index 7d9765bc..869a3199 100644 --- a/docs/contributing/installation_for_development.rst +++ b/docs/contributing/installation_for_development.rst @@ -5,17 +5,17 @@ Installation for Development **************************** Development Environment -======================= +======================== To set up your development environment: 1. Clone the repository:: - .. code-block:: shell - git clone https://github.com/HinodeXRT/xrtpy.git + + git clone https://github.com/HinodeXRT/xrtpy.git` cd xrtpy -2. Install the package and required dependencies:: - .. code-block:: shell - pip install -e .[dev,docs,tests] +2. Install the package in editable mode:: + + pip install -e . Coding Standards ================ @@ -26,26 +26,14 @@ Coding Standards Testing ======= -We use `pytest` for testing, with Nox_ as the test runner. To run the -tests locally, use the following command in the top-level directory: - -.. code-block:: shell - nox +We use `pytest` for testing. To run the tests, use the following command:: -Ensure that all tests pass before merging your PR. - -Documentation -============= -We use Sphinx_ to build documentation via a Nox_ session. To build -documentation locally, run + pytest -.. code-block:: shell - nox -s docs +Ensure that all tests pass before submitting your PR. Communication ============= For any questions or discussions, you can email us at `xrtpy@cfa.harvard.edu`. -.. _PEP-8: https://peps.python.org/pep-0008 -.. _Nox: https://nox.thea.codes -.. _Sphinx: https://www.sphinx-doc.org +.. _PEP-8: https://peps.python.org/pep-0008/ diff --git a/docs/notebooks/getting_started/A_Practical_Guide_to_Data_Extraction_and_Visualization.ipynb b/docs/notebooks/getting_started/A_Practical_Guide_to_Data_Extraction_and_Visualization.ipynb index 1d41d727..9d8d32bc 100644 --- a/docs/notebooks/getting_started/A_Practical_Guide_to_Data_Extraction_and_Visualization.ipynb +++ b/docs/notebooks/getting_started/A_Practical_Guide_to_Data_Extraction_and_Visualization.ipynb @@ -79,8 +79,8 @@ "outputs": [], "source": [ "# Standard library imports for file and temporary directory management\n", - "import os\n", "import tempfile\n", + "from pathlib import Path\n", "\n", "# Counting occurrences of unique elements\n", "# creating and managing images and videos\n", @@ -1066,7 +1066,7 @@ " plt.tight_layout()\n", "\n", " # Saving the frame\n", - " frame_path = os.path.join(frames_dir, f\"frame_{i:04d}.png\")\n", + " frame_path = Path(frames_dir) / f\"frame_{i:04d}.png\"\n", " plt.savefig(frame_path)\n", " plt.close(fig)\n", " frames.append(frame_path)\n", @@ -1084,8 +1084,8 @@ "\n", " # Cleanup: Remove temporary frames and directory\n", " for frame_path in frames:\n", - " os.remove(frame_path)\n", - " os.rmdir(frames_dir)\n", + " Path(frame_path).unlink()\n", + " Path(frames_dir).rmdir()\n", "\n", " if processing:\n", " print(\n", diff --git a/noxfile.py b/noxfile.py index 54757f7f..3a01c783 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,43 +1,42 @@ import nox nox.options.sessions = ["tests"] - python_versions = ("3.10", "3.11", "3.12") @nox.session def tests(session): - """Run tests with pytest.""" - - pytest_options = [ - "--ignore", - "xrtpy/response/effective_area.py", - "--ignore", - "xrtpy/response/temperature_response.py", - ] - - session.install(".[dev,tests]") + """ + Run tests with pytest. + """ + pytest_options = {} + session.install(".[tests]") session.run("pytest", *pytest_options) @nox.session def linters(session): - """Run all pre-commit hooks on all files.""" + """ + Run all pre-commit hooks on all files. + """ session.install("pre-commit") session.run("pre-commit", "run", "--all-files", *session.posargs) @nox.session def import_package(session): - """Import xrtpy.""" + """ + Import xrtpy. + """ session.install(".") - session.run("python", "-c", 'import xrtpy') # fmt: skip + session.run("python", "-c", "import xrtpy") @nox.session def docs(session): - """Build documentation with Sphinx.""" - + """ + Build documentation with Sphinx. + """ sphinx_paths = ["docs", "docs/_build/html"] sphinx_fail_on_warnings = ["-W", "--keep-going"] sphinx_builder = ["-b", "html"] @@ -45,8 +44,7 @@ def docs(session): sphinx_opts = ( sphinx_paths + sphinx_fail_on_warnings + sphinx_builder + sphinx_nitpicky ) - - session.install(".[dev,docs]") + session.install(".[docs]") session.run( "sphinx-build", *sphinx_opts, diff --git a/pyproject.toml b/pyproject.toml index f2c2631b..0449731d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,15 +1,15 @@ [build-system] build-backend = "setuptools.build_meta" requires = [ - "setuptools>=50", - "setuptools_scm>=6", + "setuptools>=62.1,!=71.0.1", + "setuptools_scm[toml]>=6.2", "wheel>=0.34", ] [project] name = "xrtpy" readme = "README.md" -keywords = ["solar physics"] +keywords = ["Solar Physics", "x-ray", "Hinode", "XRT"] description = "For analyzing data from the X-Ray Telescope (XRT) on the Hinode spacecraft." license = {file = "LICENSE"} classifiers = [ @@ -21,7 +21,6 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: Implementation :: CPython", "Topic :: Scientific/Engineering :: Astronomy", "Topic :: Scientific/Engineering :: Physics", ] @@ -34,56 +33,47 @@ authors = [ {name = "Jonathan Slavin", email = "jslavin@cfa.harvard.edu"}, {name = "Nick Murpy", email="namurphy@cfa.harvard.edu"}, {name = "Will Barnes"}, + {name = "Nabil Freij"}, {name = "Stuart Mumford"}, ] dependencies = [ - "astropy >= 5.1", - "cached-property >= 1.5.2", + "astropy >= 5.3.0", "matplotlib >= 3.5.0", - "numpy >= 1.24.0", - "requests >= 2.28.0", + "numpy>=1.23.5", "scikit-image >= 0.19.0", - "scipy >= 1.8.0", - # install setuptools to get pkg_resources - "setuptools; python_version >= '3.12'", - "sunpy[map] >= 4.0.0", + # !=1.10.0 due to https://github.com/scipy/scipy/issues/17718 + "scipy>=1.9.0,!=1.10.0", + "sunpy[map] >= 5.0.0", ] [project.optional-dependencies] dev = [ + "xrtpy[tests,docs]", "nox >= 2022.8.7", - "pre-commit >= 3.6.0", ] tests = [ "pytest >= 8.0.0", - "pytest-allclose >= 1.0.0", - "pytest-xdist >= 3.6.1", + "pytest-astropy", ] docs = [ - "docutils >= 0.19", "imageio >= 2.20.0", - "ipykernel >= 6.20.0", "ipython >= 8.4.0", "ipywidgets >= 8.1.0", - "jinja2 != 3.1, >= 3.0.0", "nbconvert >= 7.7.0, < 7.14", "nbsphinx >= 0.9", - "numpydoc >= 1.5.0", - "pillow >= 9.1.0", - "pygments >= 2.12.0", "sphinx >= 7.3.0", - "sphinx-changelog >= 1.5.0", + "sphinx_automodapi >= 0.17.0", + "sphinx-rtd-theme", "sphinx-codeautolink >= 0.15.2", "sphinx-copybutton >= 0.5.2", - "sphinx-gallery >= 0.16.0", + "sphinx-gallery", "sphinx-hoverxref >= 1.4.0", "sphinx-issues >= 4.1.0", - "sphinx_automodapi >= 0.17.0", - "sphinx_rtd_theme >= 2.0.0", + # Need pkg_resources for sphinxcontrib-bibtex + # and this comes from setuptools + "setuptools", "sphinxcontrib-bibtex >= 2.6.2", - "sunpy[net] >= 4.0.0", - "towncrier >= 23.11.0", ] [project.urls] @@ -92,96 +82,22 @@ Repository = "https://github.com/HinodeXRT/xrtpy" Issues = "https://github.com/HinodeXRT/xrtpy/issues" Changelog = "https://xrtpy.readthedocs.io/en/stable/changelog/index.html" -[tool.ruff] -target-version = "py310" -show-fixes = true -extend-exclude = [ - ".jupyter", - "__pycache__", - "_build", - "_dev", -] -namespace-packages = [".github/workflows", "docs"] - -[tool.ruff.lint] -# Find info about ruff rules at: https://docs.astral.sh/ruff/rules -extend-select = [ - "ARG", # flake8-unused-arguments - "B", # flake8-bugbear - "BLE", # flake8-blind-except - "C4", # flake8-comprehensions - "C90", # mccabe - "COM818", # trailing-comma-on-bare-tuple - "FBT003", # flake8-boolean-trap - "FLY", # flynt - "I", # isort - "ICN", # flake8-import-conventions - "INP", # flake8-no-pep420 - "INT", # flake8-gettext - "ISC", # flake8-implicit-str-concat - "N", # pep8-naming - "NPY", # numpy-deprecated-type-alias - "PD", # pandas-vet - "PERF", # perflint - "PGH", # pygrep-hooks - "PIE", # flake8-pie - "PLC", # pylint convention - "PLE", # pylint errors - "PLW", # pylint warnings - "PT", # flake8-pytest-style - "PTH", # flake8-use-pathlib - "PYI", # flake8-pyi - "RSE", # flake8-raise - "RUF005",# collection-literal-concatenation - "RUF006", # asyncio-dangling-task - "RUF007", # pairwise-over-zipped - "RUF008", # mutable-dataclass-default - "RUF009", # function-call-in-dataclass-default-argument - "RUF010", # explicit-f-string-type-conversion - "RUF013", # implicit-optional - "RUF015", # unnecessary-iterable-allocation-for-first-element - "RUF016", # invalid-index-type - "RUF100", # unused-noqa - "RUF200", # invalid-pyproject-toml - "S", # flake8-bandit - "SIM", # flake8-simplify - "TCH", # flake8-type-checking - "TID", # flake8-tidy-imports - "TRY", # tryceratops - "UP", # pyupgrade - "W", # pycodestyle warnings -] -ignore = [ - "E501", # line-too-long - "ISC001", # single-line-implicit-string-concatenation (formatter conflict) - "N802", # invalid-function-name - "N803", # invalid-argument-name - "N806", # non-lowercase-variable-in-function - "N816", # mixed-case-variable-in-global-scope - "PLC2401", # non-ascii-name - "S101", # asserts - "SIM108", # if-else-block-instead-of-if-exp - "TRY003", # raise-vanilla-args -] - -[tool.ruff.lint.per-file-ignores] -"__init__.py" = ["E402", "F401", "F402", "F403"] # ignore import errors -"docs/notebooks/computing_functions/temperature_response.ipynb" = ["A001"] # filter variable shadows Python builtin -"docs/notebooks/getting_started/A_Practical_Guide_to_Data_Extraction_and_Visualization.ipynb" = ["PTH106", "PTH107", "PTH118"] # should switch to using pathlib here later +[tool.setuptools] +packages = ["xrtpy"] -[tool.ruff.lint.flake8-import-conventions.aliases] -"astropy.units" = "u" -"matplotlib.pyplot" = "plt" -numpy = "np" -pandas = "pd" +[tool.setuptools.package-data] +"xrtpy" = ["data/*"] +"xrtpy.response" = ["data/*.txt", "data/*.geny"] +"xrtpy.response.tests" = ["data/*/*/*.txt"] -[tool.ruff.lint.mccabe] -max-complexity = 12 +[tool.setuptools_scm] +write_to = "xrtpy/version.py" [tool.codespell] skip = "*.genx,*.geny,*.png,*egg*,.git,.hypothesis,.nox,.tox,.idea,__pycache__,_build" ignore-words-list = """ 4rd, +aas, bu, circularly, egde, @@ -189,83 +105,8 @@ fo, nd, ons, sav, +sav, te, tne, -ue, -aas +ue """ - -[tool.pytest.ini_options] -testpaths = ['xrtpy', 'docs'] -xfail_strict = true -doctest_optionflags = """ -NORMALIZE_WHITESPACE -ELLIPSIS -NUMBER -IGNORE_EXCEPTION_DETAIL""" -norecursedirs = [ - 'build', - 'docs/_build', - 'examples', - 'auto_examples', -] -addopts = [ - '--doctest-modules', - '--doctest-continue-on-failure', - '--ignore=docs/conf.py', -] - -[tool.setuptools] -packages = ["xrtpy"] - -[tool.setuptools.package-data] -"xrtpy" = ["data/*"] -"xrtpy.response" = ["data/*.txt", "data/*.geny"] -"xrtpy.response.tests" = ["data/*/*/*.txt"] - -[tool.setuptools_scm] -write_to = "xrtpy/version.py" - -[tool.towncrier] -package = "xrtpy" -name = "XRTpy" -filename = "CHANGELOG.rst" -directory = "changelog/" -title_format = "{name} v{version} ({project_date})" -issue_format = ":pr:`{issue}`" # Despite the name mismatch, we use this for linking to PRs -wrap = true - -[[tool.towncrier.type]] -directory = "breaking" -name = "Backwards Incompatible Changes" -showcontent = true - -[[tool.towncrier.type]] -directory = "removal" -name = "Deprecations and Removals" -showcontent = true - -[[tool.towncrier.type]] -directory = "feature" -name = "Features" -showcontent = true - -[[tool.towncrier.type]] -directory = "bugfix" -name = "Bug Fixes" -showcontent = true - -[[tool.towncrier.type]] -directory = "doc" -name = "Improved Documentation" -showcontent = true - -[[tool.towncrier.type]] -directory = "trivial" -name = "Trivial/Internal Changes" -showcontent = true - -[tool.gilesbot] - -[tool.gilesbot.pull_requests] -enabled = true diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 00000000..984a006c --- /dev/null +++ b/pytest.ini @@ -0,0 +1,24 @@ +[pytest] +minversion = 8.0 +testpaths = + xrtpy + docs +xfail_strict = true +norecursedirs = + build + docs/_build + examples + auto_examples +doctest_plus = enabled +doctest_optionflags = + NORMALIZE_WHITESPACE + FLOAT_CMP + ELLIPSIS + IGNORE_EXCEPTION_DETAIL +addopts = + --doctest-rst + -p no:unraisableexception + -p no:theadexception + --arraydiff + --doctest-ignore-import-errors + --doctest-continue-on-failure diff --git a/xrtpy/__init__.py b/xrtpy/__init__.py index 6ffc3a2f..ba3646be 100644 --- a/xrtpy/__init__.py +++ b/xrtpy/__init__.py @@ -10,8 +10,8 @@ try: from xrtpy.version import __version__ except ImportError: - warnings.warn("version not found.") # noqa: B028 - + warnings.warn("version not found.", stacklevel=3) + __version__ = "0.0.0" # Then you can be explicit to control what ends up in the namespace, -__all__ = ["response"] +__all__ = ["response", "__version__"] diff --git a/xrtpy/image_correction/remove_lightleak.py b/xrtpy/image_correction/remove_lightleak.py index eeb13a5f..5b0981ea 100644 --- a/xrtpy/image_correction/remove_lightleak.py +++ b/xrtpy/image_correction/remove_lightleak.py @@ -86,9 +86,10 @@ def _get_stray_light_phase(date_obs): phase = 0 if phase == 6: - warnings.warn( # noqa: B028 + warnings.warn( "light leak images for this period are not yet" - " available. Defaulting to previous phase." + " available. Defaulting to previous phase.", + stacklevel=3, ) phase = 5 @@ -203,7 +204,10 @@ def remove_lightleak(in_map, scale=1.0, leak_map=None): images at the phase 1 (as of Feb-2022). """ if "Light leak subtraction: DONE" in in_map.meta["HISTORY"]: - warnings.warn("HISTORY indicates light leak subtraction already done on image.") # noqa: B028 + warnings.warn( + "HISTORY indicates light leak subtraction already done on image.", + stacklevel=3, + ) if leak_map is None: fw1 = in_map.meta["EC_FW1_"] diff --git a/xrtpy/image_correction/tests/test_remove_lightleak.py b/xrtpy/image_correction/tests/test_remove_lightleak.py index d0185513..77cae726 100644 --- a/xrtpy/image_correction/tests/test_remove_lightleak.py +++ b/xrtpy/image_correction/tests/test_remove_lightleak.py @@ -1,5 +1,6 @@ from pathlib import Path +import numpy as np import pytest from sunpy.map import Map @@ -46,7 +47,7 @@ def get_composite_data_files(): @pytest.mark.parametrize(("idlfile", "compfile"), data_files) -def test_lightleak(idlfile, compfile, allclose): +def test_lightleak(idlfile, compfile): IDL_map = Map(idlfile) input_map = Map(compfile) @@ -56,6 +57,6 @@ def test_lightleak(idlfile, compfile, allclose): # Because of rebinning for full resolution images, the match is worse # between IDL created images and XRTpy ones. IDL's method of rebinning # is different from that used by sunpy. - assert allclose(ll_removed_map_xrtpy.data, IDL_map.data, atol=0.75) + np.testing.assert_allclose(ll_removed_map_xrtpy.data, IDL_map.data, atol=0.75) else: - assert allclose(ll_removed_map_xrtpy.data, IDL_map.data, atol=1e-5) + np.testing.assert_allclose(ll_removed_map_xrtpy.data, IDL_map.data, atol=1e-5) diff --git a/xrtpy/response/effective_area.py b/xrtpy/response/effective_area.py index 4796fa8a..24d8dc07 100644 --- a/xrtpy/response/effective_area.py +++ b/xrtpy/response/effective_area.py @@ -5,7 +5,6 @@ import datetime import math -import os from functools import cached_property from pathlib import Path @@ -115,7 +114,7 @@ def observation_date(self, date): f"Date must be after {epoch}." ) - modified_time_path = os.path.getmtime(_ccd_contam_filename) # noqa: PTH204 + modified_time_path = Path(_ccd_contam_filename).stat().st_mtime modified_time = astropy.time.Time(modified_time_path, format="unix") latest_available_ccd_data = _ccd_contamination_file_time[-1].datetime.strftime( "%Y/%m/%d" @@ -344,7 +343,7 @@ def n_DEHP_attributes(self): "data/n_DEHP.txt", package="xrtpy.response" ) - with open(_n_DEHP_filename) as n_DEHP: # noqa: PTH123 + with Path(_n_DEHP_filename).open() as n_DEHP: list_of_DEHP_attributes = [] for line in n_DEHP: stripped_line = line.strip() diff --git a/xrtpy/response/temperature_from_filter_ratio.py b/xrtpy/response/temperature_from_filter_ratio.py index a9664966..3e86fc06 100644 --- a/xrtpy/response/temperature_from_filter_ratio.py +++ b/xrtpy/response/temperature_from_filter_ratio.py @@ -6,8 +6,8 @@ __all__ = ["temperature_from_filter_ratio"] import logging -from collections import namedtuple from datetime import datetime +from typing import Any, NamedTuple import numpy as np from astropy import units as u @@ -18,10 +18,15 @@ from xrtpy.response.temperature_response import TemperatureResponseFundamental -TempEMdata = namedtuple("TempEMdata", "Tmap, EMmap, Terrmap, EMerrmap") # noqa: PYI024 +class TempEMdata(NamedTuple): + Tmap: Any + EMmap: Any + Terrmap: Any + EMerrmap: Any -def temperature_from_filter_ratio( # noqa: C901 + +def temperature_from_filter_ratio( map1, map2, abundance_model="coronal", @@ -287,7 +292,7 @@ def temperature_from_filter_ratio( # noqa: C901 logging.info(f"Examined T_e range: {Tmodel.min():.3E} - {Tmodel.max():.3E} K") logging.info("No thresholds applied") Tmap, EMmap, Terrmap, EMerrmap = make_results_maps( - hdr1, hdr2, T_e, EM, T_error, EMerror, mask + hdr1, hdr2, T_e, EM, T_error, EMerror ) return TempEMdata(Tmap, EMmap, Terrmap, EMerrmap) @@ -605,7 +610,7 @@ def calculate_TE_errors(map1, map2, T_e, EM, model_ratio, tresp1, tresp2, Trange return T_error, EMerror, K1, K2 -def make_results_maps(hdr1, hdr2, T_e, EM, T_error, EMerror, mask): # noqa: ARG001 +def make_results_maps(hdr1, hdr2, T_e, EM, T_error, EMerror): """ Create SunPy Map objects from the image metadata and temperature, volume emission measure, temperature uncertainty and emission measure uncertainty @@ -632,10 +637,6 @@ def make_results_maps(hdr1, hdr2, T_e, EM, T_error, EMerror, mask): # noqa: ARG EMerror : 2D float array image containing the uncertainties in EM derived for the images - mask : 2D boolean array - image containing the mask for T_e and EM, either provided or derived - from the data - Returns: -------- Tmap : ~sunpy.map.sources.hinode.XRTMap diff --git a/xrtpy/response/tests/test_effective_area.py b/xrtpy/response/tests/test_effective_area.py index 750eeed9..d1e65ab3 100644 --- a/xrtpy/response/tests/test_effective_area.py +++ b/xrtpy/response/tests/test_effective_area.py @@ -1,6 +1,7 @@ from datetime import datetime from pathlib import Path +import numpy as np import pytest from astropy import units as u @@ -92,7 +93,7 @@ def test_EffectiveArea_contamination_on_filter(name, date): @pytest.mark.parametrize("date", invalid_dates) @pytest.mark.parametrize("name", channel_names) def test_EffectiveArea_exception_is_raised(name, date): - with pytest.raises(ValueError): # noqa: PT011 + with pytest.raises(ValueError, match="Invalid date"): EffectiveAreaFundamental(name, date) @@ -110,7 +111,7 @@ def get_IDL_data_files(): def _IDL_raw_data_list(filename): - with open(filename) as filter_file: # noqa: PTH123 + with Path(filename).open() as filter_file: list_of_IDL_effective_area_data = [] for line in filter_file: stripped_line = line.strip() @@ -143,7 +144,7 @@ def IDL_test_date(list_of_lists): def _IDL_effective_area_raw_data(filename): - with open(filename) as filter_file: # noqa: PTH123 + with Path(filename).open() as filter_file: list_of_lists = [] for line in filter_file: stripped_line = line.strip() @@ -157,7 +158,7 @@ def _IDL_effective_area_raw_data(filename): @pytest.mark.parametrize("filename", filenames) -def test_EffectiveAreaPreparatory_effective_area(filename, allclose): +def test_EffectiveAreaPreparatory_effective_area(filename): data_list = _IDL_raw_data_list(filename) filter_name = IDL_test_filter_name(data_list) @@ -169,4 +170,6 @@ def test_EffectiveAreaPreparatory_effective_area(filename, allclose): actual_effective_area = instance.effective_area() assert actual_effective_area.unit == IDL_effective_area.unit - assert allclose(actual_effective_area.value, IDL_effective_area.value, atol=1e-2) + np.testing.assert_allclose( + actual_effective_area.value, IDL_effective_area.value, atol=1e-2 + ) diff --git a/xrtpy/response/tests/test_temperature_response.py b/xrtpy/response/tests/test_temperature_response.py index c9fedfae..93f27a8d 100644 --- a/xrtpy/response/tests/test_temperature_response.py +++ b/xrtpy/response/tests/test_temperature_response.py @@ -1,6 +1,7 @@ from datetime import datetime from pathlib import Path +import numpy as np import pytest from xrtpy.response.temperature_response import TemperatureResponseFundamental @@ -18,7 +19,7 @@ def get_IDL_data_files(model): def _IDL_raw_data_list(filename): - with open(filename) as filter_file: # noqa: PTH123 + with Path(filename).open() as filter_file: IDL_data_list = [] for line in filter_file: stripped_line = line.strip() @@ -51,7 +52,7 @@ def IDL_test_date(IDL_data_list): def _IDL_temperature_response_raw_data(filename): - with open(filename) as filter_file: # noqa: PTH123 + with Path(filename).open() as filter_file: IDL_data_list = [] for line in filter_file: stripped_line = line.strip() @@ -63,7 +64,7 @@ def _IDL_temperature_response_raw_data(filename): @pytest.mark.parametrize("abundance_model", ["coronal", "hybrid", "photospheric"]) -def test_temperature_response(abundance_model, allclose): +def test_temperature_response(abundance_model): filenames = get_IDL_data_files(abundance_model) for filename in filenames: IDL_data = _IDL_raw_data_list(filename) @@ -78,7 +79,7 @@ def test_temperature_response(abundance_model, allclose): actual_temperature_response = instance.temperature_response() atol = actual_temperature_response.value.max() * 0.013 - assert allclose( + np.testing.assert_allclose( actual_temperature_response.value, IDL_temperature_response, rtol=0.028, diff --git a/xrtpy/util/filename2repo_path.py b/xrtpy/util/filename2repo_path.py index 5cf513b3..94bb8859 100644 --- a/xrtpy/util/filename2repo_path.py +++ b/xrtpy/util/filename2repo_path.py @@ -2,7 +2,7 @@ from pathlib import Path -def filename2repo_path( # noqa: C901 +def filename2repo_path( filename, urlroot="https://xrt.cfa.harvard.edu/", join=False, verbose=False ): """