diff --git a/.cruft.json b/.cruft.json index 8a9f41e9..97aa2c04 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,7 +1,7 @@ { "template": "https://github.com/scverse/cookiecutter-scverse", - "commit": "8e96abb5c3e2d5078c44713958da672711cf2a48", - "checkout": "v0.3.0", + "commit": "586b1652162ff7994b0070a034023d64289ae416", + "checkout": "v0.3.1", "context": { "cookiecutter": { "project_name": "spatialdata-plot", @@ -13,7 +13,8 @@ "project_repo": "https://github.com/scverse/spatialdata-plot", "license": "BSD 3-Clause License", "_copy_without_render": [ - ".github/workflows/**.yaml", + ".github/workflows/build.yaml", + ".github/workflows/test.yaml", "docs/_templates/autosummary/**.rst" ], "_render_devdocs": false, diff --git a/.flake8 b/.flake8 deleted file mode 100644 index a30ef821..00000000 --- a/.flake8 +++ /dev/null @@ -1,60 +0,0 @@ -# Can't yet be moved to the pyproject.toml due to https://github.com/PyCQA/flake8/issues/234 -[flake8] -max-line-length = 120 -ignore = - # line break before a binary operator -> black does not adhere to PEP8 - W503 - # line break occured after a binary operator -> black does not adhere to PEP8 - W504 - # line too long -> we accept long comment lines; black gets rid of long code lines - E501 - # whitespace before : -> black does not adhere to PEP8 - E203 - # line break before binary operator -> black does not adhere to PEP8 - W503 - # missing whitespace after ,', ';', or ':' -> black does not adhere to PEP8 - E231 - # continuation line over-indented for hanging indent -> black does not adhere to PEP8 - E126 - # too many leading '#' for block comment -> this is fine for indicating sections - E262 - # Do not assign a lambda expression, use a def -> lambda expression assignments are convenient - E731 - # allow I, O, l as variable names -> I is the identity matrix - E741 - # Missing docstring in public package - D104 - # Missing docstring in public module - D100 - # Missing docstring in __init__ - D107 - # Errors from function calls in argument defaults. These are fine when the result is immutable. - B008 - # Missing docstring in magic method - D105 - # format string does contain unindexed parameters - P101 - # first line should end with a period [Bug: doesn't work with single-line docstrings] - D400 - # First line should be in imperative mood; try rephrasing - D401 -exclude = .git,__pycache__,build,docs/_build,dist -per-file-ignores = - tests/*: D - */__init__.py: F401 - src/spatialdata_io/_constants/_enum.py: RST, D -rst-roles = - class, - func, - ref, - attr, - cite:p, - cite:t, -rst-directives = - envvar, - exception, - seealso, -rst-substitutions = - version, -extend-ignore = - RST307, diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a76ae081..5522b54f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -4,28 +4,26 @@ on: release: types: [published] +# Use "trusted publishing", see https://docs.pypi.org/trusted-publishers/ jobs: release: - # requires that you have put your twine API key in your - # github secrets (see readme for details) + name: Upload release to PyPI runs-on: ubuntu-latest - if: contains(github.ref, 'tags') + environment: + name: pypi + url: https://pypi.org/p/spatialdata_plot + permissions: + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python 3.10 - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 with: - python-version: "3.10" - - - name: Install hatch - run: pip install hatch - - - name: Build project for distribution - run: hatch build - - - name: Publish a Python distribution to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 + filter: blob:none + fetch-depth: 0 + - uses: actions/setup-python@v4 with: - password: ${{ secrets.PYPI_API_TOKEN }} + python-version: "3.x" + cache: "pip" + - run: pip install build + - run: python -m build + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.mypy.ini b/.mypy.ini index 2cd7b3d6..a47d0f87 100644 --- a/.mypy.ini +++ b/.mypy.ini @@ -25,4 +25,4 @@ no_warn_no_return = True show_error_codes = True show_column_numbers = True -error_summary = True \ No newline at end of file +error_summary = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 787a10b2..1db2a790 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,21 +5,11 @@ default_stages: - commit - push minimum_pre_commit_version: 2.16.0 -ci: - skip: [] repos: - - repo: https://github.com/psf/black - rev: 24.3.0 - hooks: - - id: black - repo: https://github.com/pre-commit/mirrors-prettier rev: v4.0.0-alpha.8 hooks: - id: prettier - - repo: https://github.com/asottile/blacken-docs - rev: 1.16.0 - hooks: - - id: blacken-docs - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.9.0 hooks: @@ -30,4 +20,29 @@ repos: rev: v0.3.4 hooks: - id: ruff + types_or: [python, pyi, jupyter] args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format + types_or: [python, pyi, jupyter] + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: detect-private-key + - id: check-ast + - id: end-of-file-fixer + - id: mixed-line-ending + args: [--fix=lf] + - id: trailing-whitespace + - id: check-case-conflict + # Check that there are no merge conflicts (could be generated by template sync) + - id: check-merge-conflict + args: [--assume-in-merge] + - repo: local + hooks: + - id: forbid-to-commit + name: Don't commit rej files + entry: | + Cannot commit .rej files. These indicate merge conflicts that arise during automated template updates. + Fix the merge conflicts manually and remove the .rej files. + language: fail + files: '.*\.rej$' diff --git a/docs/conf.py b/docs/conf.py index 0535c2e6..09944bc6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -59,6 +59,7 @@ "sphinx.ext.mathjax", "IPython.sphinxext.ipython_console_highlighting", "sphinx_design", + "sphinxext.opengraph", *[p.stem for p in (HERE / "extensions").glob("*.py")], ] @@ -130,6 +131,7 @@ html_theme = "sphinx_book_theme" # html_theme = "sphinx_rtd_theme" html_static_path = ["_static"] +html_css_files = ["css/custom.css"] html_title = project_name html_logo = "_static/img/spatialdata_horizontal.png" @@ -145,19 +147,3 @@ # you can add an exception to this list. ("py:class", "igraph.Graph"), ] - - -def setup(app): - """App setup hook.""" - app.add_config_value( - "recommonmark_config", - { - "auto_toc_tree_section": "Contents", - "enable_auto_toc_tree": True, - "enable_math": True, - "enable_inline_math": False, - "enable_eval_rst": True, - }, - True, - ) - app.add_css_file("css/custom.css") diff --git a/docs/conf.py.rej b/docs/conf.py.rej deleted file mode 100644 index 97caeb8a..00000000 --- a/docs/conf.py.rej +++ /dev/null @@ -1,44 +0,0 @@ -diff a/docs/conf.py b/docs/conf.py (rejected hunks) -@@ -57,6 +57,7 @@ extensions = [ - "sphinx_autodoc_typehints", - "sphinx.ext.mathjax", - "IPython.sphinxext.ipython_console_highlighting", -+ "sphinxext.opengraph", - *[p.stem for p in (HERE / "extensions").glob("*.py")], - ] - -@@ -108,12 +109,15 @@ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "**.ipynb_checkpoints"] - # - html_theme = "sphinx_book_theme" - html_static_path = ["_static"] -+html_css_files = ["css/custom.css"] -+ - html_title = project_name - - html_theme_options = { - "repository_url": repository_url, - "use_repository_button": True, - "path_to_docs": "docs/", -+ "navigation_with_keys": False, - } - - pygments_style = "default" -@@ -123,18 +127,3 @@ nitpick_ignore = [ - # you can add an exception to this list. - # ("py:class", "igraph.Graph"), - ] -- -- --def setup(app): -- """App setup hook.""" -- app.add_config_value( -- "recommonmark_config", -- { -- "auto_toc_tree_section": "Contents", -- "enable_auto_toc_tree": True, -- "enable_math": True, -- "enable_inline_math": False, -- "enable_eval_rst": True, -- }, -- True, -- ) diff --git a/docs/contributing.md b/docs/contributing.md index e4e3eebe..6a0cfac3 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -93,7 +93,7 @@ Before making a release, you need to update the version number in the `pyproject > Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. Once you are done, commit and push your changes and navigate to the "Releases" page of this project on GitHub. -Specify `vX.X.X` as a tag name and create a release. For more information, see [managing Github releases][]. This will automatically create a git tag and trigger a Github workflow that creates a release on PyPI. +Specify `vX.X.X` as a tag name and create a release. For more information, see [managing GitHub releases][]. This will automatically create a git tag and trigger a Github workflow that creates a release on PyPI. ## Writing documentation @@ -157,3 +157,4 @@ open _build/html/index.html [numpydoc]: https://numpydoc.readthedocs.io/en/latest/format.html [sphinx autodoc typehints]: https://github.com/tox-dev/sphinx-autodoc-typehints [pypi]: https://pypi.org/ +[managing GitHub releases]: https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository diff --git a/docs/index.md b/docs/index.md index 46aa14d4..53ff8f2a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,7 +8,6 @@ api.md changelog.md -template_usage.md contributing.md references.md ``` diff --git a/docs/index.md.rej b/docs/index.md.rej deleted file mode 100644 index 14a8d31f..00000000 --- a/docs/index.md.rej +++ /dev/null @@ -1,9 +0,0 @@ -diff a/docs/index.md b/docs/index.md (rejected hunks) -@@ -8,7 +8,6 @@ - - api.md - changelog.md --template_usage.md - contributing.md - references.md - diff --git a/docs/notebooks/preprocessing.ipynb b/docs/notebooks/preprocessing.ipynb index 56baf5fa..a72b4720 100644 --- a/docs/notebooks/preprocessing.ipynb +++ b/docs/notebooks/preprocessing.ipynb @@ -131,9 +131,7 @@ "tags": [] }, "outputs": [], - "source": [ - "import spatialdata_plot" - ] + "source": [] }, { "cell_type": "markdown", diff --git a/pyproject.toml b/pyproject.toml index c04ea8d6..84b85668 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ [project.optional-dependencies] dev = [ - "bump2version", + "pre-commit", ] docs = [ "sphinx>=4.5", @@ -39,6 +39,7 @@ docs = [ "myst-nb", "sphinxcontrib-bibtex>=1.0.0", "sphinx-autodoc-typehints", + "sphinxext-opengraph", "sphinx-design", # For notebooks "ipython>=8.6.0", @@ -72,30 +73,6 @@ filterwarnings = [ # "ignore:.*U.*mode is deprecated:DeprecationWarning", ] -[tool.black] -line-length = 120 -target-version = ['py39'] -include = '\.pyi?$' -exclude = ''' -( - /( - \.eggs - | \.git - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | _build - | buck-out - | build - | dist - )/ -) -''' - -[tool.jupytext] -formats = "ipynb,md" - [tool.hatch.build.targets.wheel] packages = ['src/spatialdata_plot'] @@ -109,35 +86,15 @@ version-file = "_version.py" allow-direct-references = true [tool.ruff] -exclude = [ - ".git", - ".tox", - "__pycache__", - "build", - "docs/_build", - "dist", - "setup.py", -] -lint.ignore = [ - # Do not assign a lambda expression, use a def -> lambda expression assignments are convenient - "E731", - # allow I, O, l as variable names -> I is the identity matrix, i, j, k, l is reasonable indexing notation - "E741", - # Missing docstring in public package - "D104", - # Missing docstring in public module - "D100", - # Missing docstring in __init__ - "D107", - # Missing docstring in magic method - "D105", - # Do not perform function calls in argument defaults. - "B008", - # Missing docstring in magic method - "D105", -] line-length = 120 -lint.select = [ +src = ["src"] +extend-include = ["*.ipynb"] + +[tool.ruff.format] +docstring-code-format = true + +[tool.ruff.lint] +select = [ "D", # flake8-docstrings "I", # isort "E", # pycodestyle @@ -156,8 +113,26 @@ lint.select = [ "RET", # flake8-raise "PGH", # pygrep-hooks ] -lint.unfixable = ["B", "UP", "C4", "BLE", "T20", "RET"] -target-version = "py39" +ignore = [ + # Do not assign a lambda expression, use a def -> lambda expression assignments are convenient + "E731", + # allow I, O, l as variable names -> I is the identity matrix, i, j, k, l is reasonable indexing notation + "E741", + # Missing docstring in public package + "D104", + # Missing docstring in public module + "D100", + # Missing docstring in __init__ + "D107", + # Missing docstring in magic method + "D105", + # Do not perform function calls in argument defaults. + "B008", + # Missing docstring in magic method + "D105", +] +unfixable = ["B", "UP", "C4", "BLE", "T20", "RET"] + [tool.ruff.lint.per-file-ignores] "tests/*" = ["D", "PT", "B024"] "*/__init__.py" = ["F401", "D104", "D107", "E402"] @@ -165,27 +140,18 @@ target-version = "py39" # "src/spatialdata/transformations/transformations.py" = ["D101","D102", "D106", "B024", "T201", "RET504"] "tests/conftest.py"= ["E402", "RET504"] "src/spatialdata_plot/pl/utils.py"= ["PGH003"] + [tool.ruff.lint.pydocstyle] convention = "numpy" -[tool.bumpver] -current_version = "0.0.2" -version_pattern = "MAJOR.MINOR.PATCH" -commit_message = "bump version {old_version} -> {new_version}" -tag_message = "{new_version}" -tag_scope = "default" -pre_commit_hook = "" -post_commit_hook = "" -commit = true -tag = true -push = false - -[tool.bumpver.file_patterns] -"pyproject.toml" = [ - 'current_version = "{version}"', +[tool.cruft] +skip = [ + "tests", + "src/**/__init__.py", + "src/**/basic.py", + "docs/api.md", + "docs/changelog.md", + "docs/references.bib", + "docs/references.md", + "docs/notebooks/example.ipynb", ] -"README.md" = [ - "{version}", - "{pep440_version}", -] - diff --git a/pyproject.toml.rej b/pyproject.toml.rej deleted file mode 100644 index f78ba8ad..00000000 --- a/pyproject.toml.rej +++ /dev/null @@ -1,63 +0,0 @@ -diff a/pyproject.toml b/pyproject.toml (rejected hunks) -@@ -7,7 +7,7 @@ name = "spatialdata-plot" - version = "0.0.1" - description = "A very interesting piece of code" - readme = "README.md" --requires-python = ">=3.8" -+requires-python = ">=3.9" - license = {file = "LICENSE"} - authors = [ - {name = "scverse"}, -@@ -26,25 +26,26 @@ dependencies = [ - - [project.optional-dependencies] - dev = [ -- # CLI for bumping the version number -- "bump2version", - "pre-commit", - "twine>=4.0.2" - ] - doc = [ -+ "docutils>=0.8,!=0.18.*,!=0.19.*", - "sphinx>=4", - "sphinx-book-theme>=1.0.0", - "myst-nb", - "sphinxcontrib-bibtex>=1.0.0", - "sphinx-autodoc-typehints", -+ "sphinxext-opengraph", - # For notebooks - "ipykernel", - "ipython", - "sphinx-copybutton", -+ "pandas", - ] - test = [ - "pytest", -- "pytest-cov", -+ "coverage", - ] - - [tool.coverage.run] -@@ -62,12 +63,10 @@ addopts = [ - - [tool.black] - line-length = 120 --target-version = ["py38"] - - [tool.ruff] - src = ["src"] - line-length = 120 --target-version = "py38" - select = [ - "F", # Errors detected by Pyflakes - "E", # Error detected by Pycodestyle -@@ -117,9 +116,6 @@ convention = "numpy" - "tests/*" = ["D"] - "*/__init__.py" = ["F401"] - --[tool.jupytext] --formats = "ipynb,md" -- - [tool.cruft] - skip = [ - "tests", diff --git a/tests/conftest.py b/tests/conftest.py index ce1fb93e..c0c02761 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,7 +9,6 @@ import pyarrow as pa import pytest import spatialdata as sd -import spatialdata_plot # noqa: F401 from anndata import AnnData from geopandas import GeoDataFrame from matplotlib.testing.compare import compare_images @@ -30,6 +29,8 @@ ) from xarray import DataArray +import spatialdata_plot # noqa: F401 + HERE: Path = Path(__file__).parent EXPECTED = HERE / "_images" @@ -193,8 +194,7 @@ def empty_table() -> SpatialData: @pytest.fixture( # params=["labels"] - params=["full", "empty"] - + ["images", "labels", "points", "table_single_annotation", "table_multiple_annotations"] + params=["full", "empty"] + ["images", "labels", "points", "table_single_annotation", "table_multiple_annotations"] # + ["empty_" + x for x in ["table"]] # TODO: empty table not supported yet ) def sdata(request) -> SpatialData: diff --git a/tests/pl/test_get_extent.py b/tests/pl/test_get_extent.py index b3d75fc7..7984508f 100644 --- a/tests/pl/test_get_extent.py +++ b/tests/pl/test_get_extent.py @@ -4,13 +4,13 @@ import matplotlib.pyplot as plt import numpy as np import scanpy as sc -import spatialdata_plot # noqa: F401 from geopandas import GeoDataFrame from shapely.geometry import MultiPolygon, Point, Polygon from spatialdata import SpatialData from spatialdata.models import PointsModel, ShapesModel from spatialdata.transformations import Affine, set_transformation +import spatialdata_plot # noqa: F401 from tests.conftest import PlotTester, PlotTesterMeta sc.pl.set_rcParams_defaults() diff --git a/tests/pl/test_render_images.py b/tests/pl/test_render_images.py index 24c63317..6ce89428 100644 --- a/tests/pl/test_render_images.py +++ b/tests/pl/test_render_images.py @@ -1,10 +1,10 @@ import dask.array as da import matplotlib import scanpy as sc -import spatialdata_plot # noqa: F401 from spatial_image import to_spatial_image from spatialdata import SpatialData +import spatialdata_plot # noqa: F401 from tests.conftest import PlotTester, PlotTesterMeta sc.pl.set_rcParams_defaults() diff --git a/tests/pl/test_render_labels.py b/tests/pl/test_render_labels.py index 0f432c69..19ecde4f 100644 --- a/tests/pl/test_render_labels.py +++ b/tests/pl/test_render_labels.py @@ -3,13 +3,13 @@ import numpy as np import pandas as pd import scanpy as sc -import spatialdata_plot # noqa: F401 from anndata import AnnData from spatial_image import to_spatial_image from spatialdata import SpatialData from spatialdata._core.query.relational_query import _get_unique_label_values_as_index from spatialdata.models import TableModel +import spatialdata_plot # noqa: F401 from tests.conftest import PlotTester, PlotTesterMeta sc.pl.set_rcParams_defaults() diff --git a/tests/pl/test_render_points.py b/tests/pl/test_render_points.py index 18f385d6..934ebbf2 100644 --- a/tests/pl/test_render_points.py +++ b/tests/pl/test_render_points.py @@ -2,11 +2,11 @@ import numpy as np import pandas as pd import scanpy as sc -import spatialdata_plot # noqa: F401 from anndata import AnnData from spatialdata import SpatialData from spatialdata.models import TableModel +import spatialdata_plot # noqa: F401 from tests.conftest import PlotTester, PlotTesterMeta RNG = np.random.default_rng(seed=42) diff --git a/tests/pl/test_render_shapes.py b/tests/pl/test_render_shapes.py index 82d04bfe..09927fbe 100644 --- a/tests/pl/test_render_shapes.py +++ b/tests/pl/test_render_shapes.py @@ -4,12 +4,12 @@ import numpy as np import pandas as pd import scanpy as sc -import spatialdata_plot # noqa: F401 from anndata import AnnData from shapely.geometry import MultiPolygon, Point, Polygon from spatialdata import SpatialData from spatialdata.models import ShapesModel, TableModel +import spatialdata_plot # noqa: F401 from tests.conftest import PlotTester, PlotTesterMeta sc.pl.set_rcParams_defaults() diff --git a/tests/pl/test_show.py b/tests/pl/test_show.py index be162a98..cf78ecb4 100644 --- a/tests/pl/test_show.py +++ b/tests/pl/test_show.py @@ -1,8 +1,8 @@ import matplotlib import scanpy as sc -import spatialdata_plot # noqa: F401 from spatialdata import SpatialData +import spatialdata_plot # noqa: F401 from tests.conftest import PlotTester, PlotTesterMeta sc.pl.set_rcParams_defaults() diff --git a/tests/pl/test_upstream_plots.py b/tests/pl/test_upstream_plots.py index f10c7bf1..218ce203 100644 --- a/tests/pl/test_upstream_plots.py +++ b/tests/pl/test_upstream_plots.py @@ -3,7 +3,6 @@ import matplotlib import matplotlib.pyplot as plt import scanpy as sc -import spatialdata_plot # noqa: F401 from spatialdata import SpatialData from spatialdata.transformations import ( Affine, @@ -14,6 +13,7 @@ set_transformation, ) +import spatialdata_plot # noqa: F401 from tests.conftest import PlotTester, PlotTesterMeta sc.pl.set_rcParams_defaults()