diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f384b14..f9cea62 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,29 +30,36 @@ jobs: slepc: 'slepc' steps: - - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - name: Set up Conda + uses: conda-incubator/setup-miniconda@v3.1.0 with: python-version: ${{ matrix.python }} + auto-update-conda: true + channels: conda-forge,defaults - name: Install pip dependencies + shell: bash -el {0} run: | python -m pip install --upgrade pip - pip install tox codecov + pip install '.[test]' + + - name: Install conda dependencies + if: ${{ matrix.slepc == 'slepc' }} + shell: bash -el {0} + run: | + conda install petsc slepc petsc4py slepc4py mpi4py - name: Test + shell: bash -el {0} run: | - tox -e py${{ matrix.python }}-${{ matrix.slepc }} -vv - env: - PLATFORM: ${{ matrix.os }} + python -m pytest --cov --cov-config=tox.ini --no-cov-on-fail --cov-report=xml --cov-report=term-missing:skip-covered -vv - name: Upload coverage - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: + fail_ci_if_error: false files: ./coverage.xml - flags: unittests name: ${{ matrix.os }}-${{ matrix.python }}-${{ matrix.slepc }} - env_vars: OS,PYTHON - fail_ci_if_error: false + token: ${{ secrets.CODECOV_TOKEN }} verbose: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7cad946..52a52a1 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -16,14 +16,14 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python 3.10 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.10' - name: Cache pre-commit - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cache/pre-commit key: pre-commit-${{ env.pythonLocation }}-${{ hashFiles('**/.pre-commit-config.yaml') }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3ead81d..47cfccc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,9 +8,9 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.10' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dbe616f..0e43eea 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,42 +4,41 @@ default_language_version: default_stages: - commit - push -minimum_pre_commit_version: 2.9.0 +minimum_pre_commit_version: 3.0.0 repos: - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.3.0 + rev: v1.13.0 hooks: - id: mypy additional_dependencies: [numpy>=1.20.0, scipy>=1.6.0] - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 24.10.0 hooks: - id: black additional_dependencies: [toml] - repo: https://github.com/timothycrosley/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort additional_dependencies: [toml] args: [--order-by-type] - repo: https://github.com/asottile/yesqa - rev: v1.4.0 + rev: v1.5.0 hooks: - id: yesqa additional_dependencies: [flake8-tidy-imports, flake8-docstrings, flake8-rst-docstrings, flake8-comprehensions, flake8-bugbear, flake8-logging-format, flake8-blind-except, flake8-builtins, flake8-pytest-style, flake8-string-format] - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks - rev: v2.9.0 + rev: v2.14.0 hooks: - id: pretty-format-yaml args: [--autofix, --indent, '4', --preserve-quotes] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v5.0.0 hooks: - id: detect-private-key - id: check-merge-conflict - id: check-ast - id: check-symlinks - - id: check-added-large-files - id: check-executables-have-shebangs - id: fix-encoding-pragma args: [--remove] @@ -56,12 +55,12 @@ repos: - id: check-toml - id: requirements-txt-fixer - repo: https://github.com/pycqa/flake8 - rev: 6.0.0 + rev: 7.1.1 hooks: - id: flake8 additional_dependencies: [flake8-tidy-imports, flake8-docstrings, flake8-rst-docstrings, flake8-comprehensions, flake8-bugbear, flake8-logging-format, flake8-blind-except, flake8-builtins, flake8-pytest-style, flake8-string-format] - repo: https://github.com/myint/autoflake - rev: v2.1.1 + rev: v2.3.1 hooks: - id: autoflake args: [--in-place, --remove-all-unused-imports, --remove-unused-variable, --ignore-init-module-imports] @@ -72,12 +71,12 @@ repos: name: Check executable files use .sh extension types: [shell, executable] - repo: https://github.com/asottile/blacken-docs - rev: 1.13.0 + rev: 1.19.1 hooks: - id: blacken-docs additional_dependencies: [black==23.1.0] - repo: https://github.com/asottile/pyupgrade - rev: v3.4.0 + rev: v3.19.0 hooks: - id: pyupgrade args: [--py3-plus, --py37-plus] @@ -91,6 +90,6 @@ repos: - id: rst-directive-colons - id: rst-inline-touching-normal - repo: https://github.com/PyCQA/doc8 - rev: v1.1.1 + rev: v1.1.2 hooks: - id: doc8 diff --git a/docs/requirements.txt b/docs/requirements.txt index 66c7686..82c147f 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,9 +1,7 @@ -r ../requirements.txt -nbsphinx>=0.8 -sphinx>=5 -sphinx-autodoc-annotation -sphinx-autodoc-typehints>=1.10.3 +myst-nb +sphinx>=8 sphinx-copybutton -sphinx_last_updated_by_git +sphinx_autodoc_typehints sphinx_rtd_theme sphinxcontrib-spelling diff --git a/docs/source/_templates/autosummary/class.rst b/docs/source/_templates/autosummary/class.rst index 81e6503..57e2365 100644 --- a/docs/source/_templates/autosummary/class.rst +++ b/docs/source/_templates/autosummary/class.rst @@ -1,33 +1,31 @@ :github_url: {{ fullname }} -{{ fullname | escape | underline}} +{{ fullname | escape | underline }} .. currentmodule:: {{ module }} .. autoclass:: {{ objname }} + {% block methods %} + {%- if methods %} + .. rubric:: {{ _('Methods') }} - {% block methods %} - {% if methods %} - .. rubric:: Methods + .. autosummary:: + :toctree: . + {% for item in methods %} + {%- if item not in ['__init__', 'tree_flatten', 'tree_unflatten', 'bind', 'tabulate', 'module_paths'] %} + ~{{ name }}.{{ item }} + {%- endif %} + {%- endfor %} + {%- endif %} + {%- endblock %} + {% block attributes %} + {%- if attributes %} + .. rubric:: {{ _('Attributes') }} - .. autosummary:: - :toctree: . - {% for item in methods %} - {%- if item != '__init__' %} - ~{{ fullname }}.{{ item }} - {%- endif -%} - {%- endfor %} - {% endif %} - {% endblock %} - - {% block attributes %} - {% if attributes %} - .. rubric:: Attributes - - .. autosummary:: - :toctree: . - {% for item in attributes %} - ~{{ fullname }}.{{ item }} - {%- endfor %} - {% endif %} - {% endblock %} + .. autosummary:: + :toctree: . + {% for item in attributes %} + ~{{ name }}.{{ item }} + {%- endfor %} + {%- endif %} + {% endblock %} diff --git a/docs/source/conf.py b/docs/source/conf.py index d70915d..eb0eb06 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -47,7 +47,7 @@ "sphinx_autodoc_typehints", "sphinx_copybutton", "typed_returns", - "nbsphinx", + "myst_nb", ] intersphinx_mapping = { "python": ("https://docs.python.org/3", None), @@ -63,7 +63,7 @@ # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["build", "**.ipynb_checkpoints"] -source_suffix = ".rst" +source_suffix = {".rst": "restructuredtext", ".ipynb": "myst-nb"} add_function_parentheses = True # -- Options for HTML output ------------------------------------------------- @@ -86,29 +86,21 @@ napoleon_use_admonition_for_references = False todo_include_todos = False -# binder -nbsphinx_highlight_language = "python3" -nbsphinx_execute_arguments = [ - "--InlineBackend.figure_formats={'png', 'pdf'}", # correct figure resize - "--InlineBackend.rc={'figure.dpi': 96}", +# myst-nb +myst_heading_anchors = 2 +nb_execution_mode = "off" +nb_mime_priority_overrides = [("spelling", "text/plain", 0)] +myst_enable_extensions = [ + "colon_fence", + "amsmath", + "dollarmath", ] -nbsphinx_prolog = r""" -{% set docname = 'docs/source/' + env.doc2path(env.docname, base=None) %} -.. raw:: html - -
- Interactive version - Binder badge - -
-""" # noqa: E501 # spelling spelling_lang = "en_US" spelling_warning = True spelling_word_list_filename = "spelling_wordlist.txt" spelling_add_pypi_package_names = True -spelling_show_suggestions = True # see: https://pyenchant.github.io/pyenchant/api/enchant.tokenize.html spelling_filters = ["enchant.tokenize.URLFilter", "enchant.tokenize.EmailFilter"] @@ -119,6 +111,7 @@ "https://pubs.acs.org/doi/abs/10.1021/acs.jctc.8b00079", "https://doi.org/10.1063/1.5064530", ] +linkcheck_report_timeouts_as_broken = False # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/environment.yml b/environment.yml deleted file mode 100644 index fdd371c..0000000 --- a/environment.yml +++ /dev/null @@ -1,6 +0,0 @@ -name: pygpcca - -dependencies: -- matplotlib -- pip: - - git+https://github.com/msmdev/pygpcca diff --git a/pyproject.toml b/pyproject.toml index 822d122..8347ede 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,8 @@ [build-system] -requires = ['setuptools', 'setuptools_scm', 'wheel'] -build-backend = 'setuptools.build_meta' +requires = ["setuptools>=61", "setuptools-scm[toml]>=6.2"] +build-backend = "setuptools.build_meta" + +[tool.setuptools_scm] [tool.black] line-length = 120 diff --git a/setup.py b/setup.py index c00ad45..d3791c8 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ "slepc4py>=3.18.0", ], dev=["pre-commit>=2.9.0", "bump2version"], - test=["tox>=3.20.1"], + test=["pytest", "pytest-cov", "pytest-mock", "codecov"], docs=[ line.strip() for line in (Path("docs") / "requirements.txt").read_text("utf-8").splitlines() diff --git a/tests/conftest.py b/tests/conftest.py index ccbf687..45f8464 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -70,7 +70,7 @@ def bdc(q: np.ndarray, p: np.ndarray, sparse: bool = True) -> Tuple[np.ndarray, mu[0] = 1.0 mu[1:] = np.cumprod(p[:-1] / q[1:]) - return (P if sparse else P.A), mu / np.sum(mu) + return (P if sparse else P.toarray()), mu / np.sum(mu) def mu(mu: int): @@ -98,7 +98,6 @@ def _session_setup(): def _skip_if_no_petsc_slepc() -> bool: try: - import mpi4py # noqa: F401 import petsc4py # noqa: F401 import slepc4py # noqa: F401 diff --git a/tests/test_gpcca.py b/tests/test_gpcca.py index 99d8ace..20dc80b 100644 --- a/tests/test_gpcca.py +++ b/tests/test_gpcca.py @@ -31,7 +31,7 @@ import pytest -from scipy.linalg import lu, pinv, eigvals, hilbert, subspace_angles +from scipy.linalg import lu, pinv, hilbert, subspace_angles from scipy.sparse import issparse, csr_matrix import numpy as np @@ -543,8 +543,8 @@ def sort_evals(e: np.ndarray, take: int = 4) -> np.ndarray: ) assert_allclose(EA, 1.0, atol=5) - l1 = sort_evals(eigvals(R_i)) - l2 = sort_evals(eigvals(RR)) + l1 = sort_evals(np.linalg.eigvals(R_i)) + l2 = sort_evals(np.linalg.eigvals(RR)) EL = np.true_divide(np.abs(l1 - l2), eps * np.abs(l1)) assert_allclose(EL, 1.0, atol=5) @@ -792,7 +792,6 @@ class TestCustom: @pytest.mark.parametrize("method", ["krylov", "brandts"]) def test_P_i(self, P_i: np.ndarray, method: str): if method == "krylov": - pytest.importorskip("mpi4py") pytest.importorskip("petsc4py") pytest.importorskip("slepc4py") @@ -827,7 +826,6 @@ def test_P_2_LM( method: str, ): if method == "krylov": - pytest.importorskip("mpi4py") pytest.importorskip("petsc4py") pytest.importorskip("slepc4py") @@ -912,7 +910,6 @@ def test_P_2_LR( method: str, ): if method == "krylov": - pytest.importorskip("mpi4py") pytest.importorskip("petsc4py") pytest.importorskip("slepc4py") diff --git a/tox.ini b/tox.ini index 0168a8d..4fe467b 100644 --- a/tox.ini +++ b/tox.ini @@ -74,7 +74,6 @@ skip_empty = True sort = Miss [tox] -requires = tox-conda isolated_build = True envlist = covclean @@ -91,14 +90,7 @@ deps = pytest pytest-cov pytest-mock -conda_deps = - slepc: mpi4py - slepc: petsc4py - slepc: slepc4py -conda_channels= - conda-forge passenv = TOXENV,CI,CODECOV_*,GITHUB_ACTIONS -usedevelop = true commands = python -m pytest --cov --cov-append --cov-report=term-missing --cov-config={toxinidir}/tox.ini --ignore docs/ {posargs:-vv} [testenv:covclean] @@ -122,7 +114,7 @@ commands = [testenv:lint] description = Perform linting. -deps = pre-commit>=2.7.1 +deps = pre-commit>=3.0.0 skip_install = true commands = pre-commit run --all-files --show-diff-on-failure {posargs:}