diff --git a/.cruft.json b/.cruft.json
old mode 100755
new mode 100644
index abbb619..343ece1
--- a/.cruft.json
+++ b/.cruft.json
@@ -13,6 +13,7 @@
"github_repo": "pycea",
"license": "BSD 3-Clause License",
"ide_integration": true,
+ "issue_categorization": "",
"_copy_without_render": [
".github/workflows/build.yaml",
".github/workflows/test.yaml",
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..914ad69
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,12 @@
+version: 2
+updates:
+ - package-ecosystem: github-actions
+ directory: /
+ schedule:
+ interval: weekly
+ cooldown:
+ default-days: 7
+ groups:
+ actions-deps:
+ patterns:
+ - "*"
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index c6ecc2f..876c355 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -18,6 +18,7 @@ jobs:
with:
filter: blob:none
fetch-depth: 0
+ persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Build package
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 9c79a02..de9101a 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -5,6 +5,8 @@ on:
types: [published]
# Use "trusted publishing", see https://docs.pypi.org/trusted-publishers/
+permissions: {}
+
jobs:
release:
name: Upload release to PyPI
@@ -13,15 +15,17 @@ jobs:
name: pypi
url: https://pypi.org/p/pycea-lineage
permissions:
+ contents: read
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
steps:
- uses: actions/checkout@v5
with:
filter: blob:none
fetch-depth: 0
+ persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Build package
run: uv build
- name: Publish package distributions to PyPI
- uses: pypa/gh-action-pypi-publish@release/v1
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 327964b..cc64891 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -19,7 +19,7 @@ jobs:
# Check [[tool.hatch.envs.hatch-test.matrix]] in pyproject.toml and https://hatch.pypa.io/latest/environment/ for
# more details.
get-environments:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-slim
outputs:
envs: ${{ steps.get-envs.outputs.envs }}
steps:
@@ -27,6 +27,7 @@ jobs:
with:
filter: blob:none
fetch-depth: 0
+ persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Get test environments
@@ -58,7 +59,7 @@ jobs:
name: ${{ matrix.env.label }}
runs-on: ${{ matrix.os }}
-
+
continue-on-error: ${{ matrix.env.allow_failure }}
steps:
@@ -66,12 +67,15 @@ jobs:
with:
filter: blob:none
fetch-depth: 0
+ persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.env.python }}
- name: create hatch environment
run: uvx hatch env create ${{ matrix.env.name }}
+ - name: list all all installed package versions
+ run: uvx hatch run ${{ matrix.env.name }}:uv pip list
- name: run tests using hatch
env:
MPLBACKEND: agg
@@ -80,7 +84,7 @@ jobs:
run: uvx hatch run ${{ matrix.env.name }}:run-cov -v --color=yes -n auto
- name: generate coverage report
run: |
- # See https://coverage.readthedocs.io/en/latest/config.html#run-patch
+ # See https://coverage.readthedocs.io/page/config.html#run-patch
test -f .coverage || uvx hatch run ${{ matrix.env.name }}:cov-combine
uvx hatch run ${{ matrix.env.name }}:cov-report # report visibly
uvx hatch run ${{ matrix.env.name }}:coverage xml # create report for upload
@@ -104,6 +108,6 @@ jobs:
- test
runs-on: ubuntu-latest
steps:
- - uses: re-actors/alls-green@release/v1
+ - uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
with:
jobs: ${{ toJSON(needs) }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 27d8a95..1344b43 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -36,3 +36,9 @@ repos:
# Check that there are no merge conflicts (could be generated by template sync)
- id: check-merge-conflict
args: [--assume-in-merge]
+
+ - repo: https://github.com/zizmorcore/zizmor-pre-commit
+ rev: v1.24.1
+ hooks:
+ - id: zizmor
+ args: [--no-progress, --fix]
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 6c28477..24bfa3c 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -1,4 +1,4 @@
-# https://docs.readthedocs.io/en/stable/config-file/v2.html
+# https://docs.readthedocs.io/page/config-file/v2.html
version: 2
build:
os: ubuntu-24.04
diff --git a/docs/_templates/autosummary/class.rst b/docs/_templates/autosummary/class.rst
deleted file mode 100644
index 7b4a0cf..0000000
--- a/docs/_templates/autosummary/class.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-{{ fullname | escape | underline}}
-
-.. currentmodule:: {{ module }}
-
-.. add toctree option to make autodoc generate the pages
-
-.. autoclass:: {{ objname }}
-
-{% block attributes %}
-{% if attributes %}
-Attributes table
-~~~~~~~~~~~~~~~~
-
-.. autosummary::
-{% for item in attributes %}
- ~{{ name }}.{{ item }}
-{%- endfor %}
-{% endif %}
-{% endblock %}
-
-{% block methods %}
-{% if methods %}
-Methods table
-~~~~~~~~~~~~~
-
-.. autosummary::
-{% for item in methods %}
- {%- if item != '__init__' %}
- ~{{ name }}.{{ item }}
- {%- endif -%}
-{%- endfor %}
-{% endif %}
-{% endblock %}
-
-{% block attributes_documentation %}
-{% if attributes %}
-Attributes
-~~~~~~~~~~
-
-{% for item in attributes %}
-
-.. autoattribute:: {{ [objname, item] | join(".") }}
-{%- endfor %}
-
-{% endif %}
-{% endblock %}
-
-{% block methods_documentation %}
-{% if methods %}
-Methods
-~~~~~~~
-
-{% for item in methods %}
-{%- if item != '__init__' %}
-
-.. automethod:: {{ [objname, item] | join(".") }}
-{%- endif -%}
-{%- endfor %}
-
-{% endif %}
-{% endblock %}
diff --git a/docs/conf.py b/docs/conf.py
index fd25dc5..b3f2f23 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -2,7 +2,7 @@
# This file only contains a selection of the most common options. For a full
# list see the documentation:
-# https://www.sphinx-doc.org/en/master/usage/configuration.html
+# https://www.sphinx-doc.org/page/usage/configuration.html
# -- Path setup --------------------------------------------------------------
import shutil
@@ -62,6 +62,7 @@
"sphinx_design",
"IPython.sphinxext.ipython_console_highlighting",
"sphinxext.opengraph",
+ "scverse_misc.sphinx_ext",
*[p.stem for p in (HERE / "extensions").glob("*.py")],
]
@@ -87,6 +88,9 @@
nb_execution_mode = "off"
nb_merge_streams = True
typehints_defaults = "braces"
+always_use_bars_union = (
+ True # use `|` instead of `Union` in types even when building with Python ≤3.14
+)
# Render @typing.overload'd functions as a single entry (the implementation).
# Otherwise sphinx-autodoc-typehints emits every overload signature, which both
# drops the short description from the API summary table and clutters each
@@ -100,8 +104,6 @@
}
intersphinx_mapping = {
- # TODO: replace `3.13` with `3` once ReadTheDocs supports building with Python 3.14
- "python": ("https://docs.python.org/3.13", None),
"anndata": ("https://anndata.readthedocs.io/en/stable/", None),
"cycler": ("https://matplotlib.org/cycler/", None),
"matplotlib": ("https://matplotlib.org/stable/", None),
@@ -109,7 +111,7 @@
"networkx": ("https://networkx.org/documentation/stable/", None),
"pandas": ("https://pandas.pydata.org/pandas-docs/stable/", None),
"python": ("https://docs.python.org/3", None),
- "scanpy": ("https://scanpy.readthedocs.io/en/stable/", None),
+ "scanpy": ("https://scanpy.scverse.org/en/stable/", None),
"scipy": ("https://docs.scipy.org/doc/scipy/reference/", None),
"squidpy": ("https://squidpy.readthedocs.io/en/stable/", None),
"treedata": ("https://treedata.readthedocs.io/en/stable/", None),
diff --git a/docs/contributing.md b/docs/contributing.md
index ab2538f..1699f06 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -9,7 +9,7 @@ the [scientific Python tutorials][], or the [scanpy developer guide][].
[pyopensci tutorials]: https://www.pyopensci.org/learn.html
[scientific Python tutorials]: https://learn.scientific-python.org/development/tutorials/
-[scanpy developer guide]: https://scanpy.readthedocs.io/en/latest/dev/index.html
+[scanpy developer guide]: https://scanpy.scverse.org/page/dev/
:::{tip} The *hatch* project manager
@@ -45,11 +45,21 @@ hatch test # defined in the table [tool.hatch.envs.hatch-test] in pyproject.tom
hatch run docs:build # defined in the table [tool.hatch.envs.docs]
```
-When using an IDE such as VS Code,
-you’ll have to point the editor at the paths to the virtual environments manually.
-The environment you typically want to use as your main development environment is the `hatch-test`
-environment with the latest Python version.
+### VS Code
+If you are using VS code, install the [hatch-code][] extension.
+Additionally, make sure that the `vscode-python-environments` extension is installed (should be by default)
+and `"python.useEnvironmentsExtension": true` is activated in your `settings.json`.
+
+Next, open the "Python Environment Managers" sidebar.
+You can do so by opening the command palette (Ctrl+Shift+P) and searching for `Python: Focus on Environment Managers View`.
+It will show a collapsible list where you can expand "Hatch"
+and activate an environment by clicking on the checkmark next to it.
+As the main development environment, we recommend to use `hatch-test` with the latest supported Python version.
+
+### Other IDEs
+
+For other IDEs, you’ll have to point the editor at the paths to the virtual environments manually.
To get a list of all environments for your projects, run
```bash
@@ -87,10 +97,8 @@ Then, obtain the path to the environment using
hatch env find hatch-test.py3.14-stable
```
-In case you are using VScode, now open the command palette (Ctrl+Shift+P) and search for `Python: Select Interpreter`.
-Choose `Enter Interpreter Path` and paste the path to the virtual environment from above.
+and manually point it to the python binary.
-In this future, this may become easier through a hatch vscode extension.
::::
@@ -103,7 +111,7 @@ This can have undesired side-effects,
such as requiring to install a lower version of a library your project depends on,
only because an outdated sphinx plugin pins an older version.
-To initalize a virtual environment in the `.venv` directory of your project, simply run
+To initialize a virtual environment in the `.venv` directory of your project, simply run
```bash
uv sync --all-extras
@@ -131,24 +139,26 @@ The `.venv` directory is typically automatically discovered by IDEs such as VS C
:::::
[hatch environments]: https://hatch.pypa.io/latest/tutorials/environment/basic-usage/
+[hatch-code]: https://marketplace.visualstudio.com/items?itemName=PyPA.hatch
[uv]: https://docs.astral.sh/uv/
## Code-style
-This package uses [pre-commit][] to enforce consistent code-styles.
-On every commit, pre-commit checks will either automatically fix issues with the code, or raise an error message.
+This package uses [pre-commit][]-style hooks to enforce consistent code-styles.
+We recommend running them with [prek][], a fast, drop-in replacement for `pre-commit` that reads the same `.pre-commit-config.yaml`.
+On every commit, the checks will either automatically fix issues with the code, or raise an error message.
-To enable pre-commit locally, simply run
+To enable the checks locally, install [prek][] (e.g. with `uv tool install prek`) and run
```bash
-pre-commit install
+prek install
```
in the root of the repository.
-Pre-commit will automatically download all dependencies when it is run for the first time.
+prek will automatically download all dependencies when it is run for the first time.
Alternatively, you can rely on the [pre-commit.ci][] service enabled on GitHub.
-If you didn’t run `pre-commit` before pushing changes to GitHub it will automatically commit fixes to your pull request, or show an error message.
+If you didn’t run the checks before pushing changes to GitHub it will automatically commit fixes to your pull request, or show an error message.
If pre-commit.ci added a commit on a branch you still have been working on locally, simply use
@@ -157,12 +167,13 @@ git pull --rebase
```
to integrate the changes into yours.
-While the [pre-commit.ci][] is useful, we strongly encourage installing and running pre-commit locally first to understand its usage.
+While the [pre-commit.ci][] is useful, we strongly encourage installing and running the checks locally first to understand their usage.
Finally, most editors have an _autoformat on save_ feature.
Consider enabling this option for [ruff][ruff-editors] and [biome][biome-editors].
[pre-commit]: https://pre-commit.com/
+[prek]: https://prek.j178.dev/
[pre-commit.ci]: https://pre-commit.ci/
[ruff-editors]: https://docs.astral.sh/ruff/integrations/
[biome-editors]: https://biomejs.dev/guides/integrate-in-editor/
@@ -175,12 +186,8 @@ This package uses [pytest][] for automated testing.
Please write {doc}`scanpy:dev/testing` for every function added to the package.
Most IDEs integrate with pytest and provide a GUI to run tests.
-Just point yours to one of the environments returned by
-
-```bash
-hatch env create hatch-test # create test environments for all supported versions
-hatch env find hatch-test # list all possible test environment paths
-```
+If you set up your virtual environments as described in [installing dev dependencies](#installing-dev-dependencies),
+test cases should be automatically discovered by your IDE.
Alternatively, you can run all tests from the command line by executing
@@ -268,11 +275,11 @@ This project uses [sphinx][] with the following features:
See scanpy’s {doc}`scanpy:dev/documentation` for more information on how to write your own.
-[sphinx]: https://www.sphinx-doc.org/en/master/
-[myst]: https://myst-parser.readthedocs.io/en/latest/intro.html
-[myst-nb]: https://myst-nb.readthedocs.io/en/latest/
-[numpydoc-napoleon]: https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html
-[numpydoc]: https://numpydoc.readthedocs.io/en/latest/format.html
+[sphinx]: https://www.sphinx-doc.org/
+[myst]: https://myst-parser.readthedocs.io/page/intro.html
+[myst-nb]: https://myst-nb.readthedocs.io/
+[numpydoc-napoleon]: https://www.sphinx-doc.org/page/usage/extensions/napoleon.html
+[numpydoc]: https://numpydoc.readthedocs.io/page/format.html
[sphinx-autodoc-typehints]: https://github.com/tox-dev/sphinx-autodoc-typehints
### Tutorials with myst-nb and jupyter notebooks
diff --git a/docs/extensions/typed_returns.py b/docs/extensions/typed_returns.py
deleted file mode 100644
index 0fbffef..0000000
--- a/docs/extensions/typed_returns.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# code from https://github.com/theislab/scanpy/blob/master/docs/extensions/typed_returns.py
-# with some minor adjustment
-from __future__ import annotations
-
-import re
-from collections.abc import Generator, Iterable
-
-from sphinx.application import Sphinx
-from sphinx.ext.napoleon import NumpyDocstring
-
-
-def _process_return(lines: Iterable[str]) -> Generator[str, None, None]:
- for line in lines:
- if m := re.fullmatch(r"(?P\w+)\s+:\s+(?P[\w.]+)", line):
- yield f"-{m['param']} (:class:`~{m['type']}`)"
- else:
- yield line
-
-
-def _parse_returns_section(self: NumpyDocstring, section: str) -> list[str]:
- lines_raw = self._dedent(self._consume_to_next_section())
- if lines_raw[0] == ":":
- del lines_raw[0]
- lines = self._format_block(":returns: ", list(_process_return(lines_raw)))
- if lines and lines[-1]:
- lines.append("")
- return lines
-
-
-def setup(app: Sphinx):
- """Set app."""
- NumpyDocstring._parse_returns_section = _parse_returns_section
diff --git a/pyproject.toml b/pyproject.toml
index 2aa26d7..f8ea107 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -40,8 +40,8 @@ dependencies = [
[project.urls]
Documentation = "https://pycea.readthedocs.io/"
-Homepage = "https://github.com/colganwi/pycea"
-Source = "https://github.com/colganwi/pycea"
+Homepage = "https://github.com/YosefLab/pycea"
+Source = "https://github.com/YosefLab/pycea"
[dependency-groups]
dev = [
@@ -58,6 +58,7 @@ doc = [
"ipython",
"myst-nb>=1.1",
"pandas",
+ "scverse-misc[sphinx]>=0.1.2", # provides scverse_misc.sphinx_ext (0.1.2+ needed for pydocstring-rs 0.4 API)
"sphinx>=8.1",
"sphinx-autodoc-typehints",
"sphinx-book-theme>=1",
@@ -95,9 +96,10 @@ dependency-groups = [ "dev", "test" ]
[tool.hatch.envs.hatch-test.overrides]
# If the matrix variable `deps` is set to "pre",
# set the environment variable `UV_PRERELEASE` to "allow".
-matrix.deps.env-vars = [
- { key = "UV_PRERELEASE", value = "allow", if = [ "pre" ] },
+envs.hatch-test.overrides.matrix.deps.env-vars = [
+ { value = "allow", key = "UV_PRERELEASE", if = [ "pre" ] },
]
+envs.hatch-test.dependency-groups = [ "dev", "test" ]
[tool.hatch.build.targets.wheel]
packages = [ "src/pycea" ]
@@ -107,9 +109,7 @@ exclude = [ "**/.DS_Store", "**/._*" ]
line-length = 120
src = [ "src" ]
extend-include = [ "*.ipynb" ]
-
format.docstring-code-format = true
-
lint.select = [
"B", # flake8-bugbear
"BLE", # flake8-blind-except
@@ -154,15 +154,16 @@ markers = [
"internet: tests which rely on internet resources (enable with `--internet-tests`)",
]
-[tool.coverage.run]
-source = [ "pycea" ]
-patch = [ "subprocess" ]
-omit = [
+[tool.coverage]
+run.omit = [
"**/test_*.py",
]
+run.patch = [ "subprocess" ]
+run.source = [ "pycea" ]
[tool.cruft]
skip = [
+ ".git",
"tests",
"src/**/__init__.py",
"src/**/basic.py",