diff --git a/.codecov.yaml b/.codecov.yaml index 829e56c..d0c0e29 100644 --- a/.codecov.yaml +++ b/.codecov.yaml @@ -1,17 +1,17 @@ # Based on pydata/xarray codecov: - require_ci_to_pass: no + require_ci_to_pass: no coverage: - status: - project: - default: - # Require 1% coverage, i.e., always succeed - target: 1 - patch: false - changes: false + status: + project: + default: + # Require 1% coverage, i.e., always succeed + target: 1 + patch: false + changes: false comment: - layout: diff, flags, files - behavior: once - require_base: no + layout: diff, flags, files + behavior: once + require_base: no diff --git a/.cruft.json b/.cruft.json index 65f08fc..7101f08 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,23 +1,29 @@ { - "template": "https://github.com/scverse/cookiecutter-scverse", - "commit": "c96cadaa981a71113cc97ada8e5085188ed22ed7", - "checkout": "v0.1.1", - "context": { - "cookiecutter": { - "project_name": "monkeybread", - "package_name": "monkeybread", - "project_description": "Tool for analyzing cell closeness in spatial transcriptomic data", - "author_full_name": "Immunitas Therapeutics", - "author_email": "mbernstein@immunitastx.com", - "github_user": "immunitastx", - "project_repo": "https://github.com/immunitastx/monkeybread", - "license": "MIT License", - "_copy_without_render": [ - ".github/workflows/**.yaml", - "docs/_templates/autosummary/**.rst" - ], - "_template": "https://github.com/scverse/cookiecutter-scverse" - } - }, - "directory": null + "template": "https://github.com/scverse/cookiecutter-scverse", + "commit": "87a407a65408d75a949c0b54b19fd287475a56f8", + "checkout": "v0.4.0", + "context": { + "cookiecutter": { + "project_name": "monkeybread", + "package_name": "monkeybread", + "project_description": "Tool for analyzing cell closeness in spatial transcriptomic data", + "author_full_name": "Immunitas Therapeutics", + "author_email": "mbernstein@immunitastx.com", + "github_user": "immunitastx", + "project_repo": "https://github.com/immunitastx/monkeybread", + "license": "MIT License", + "_copy_without_render": [ + ".github/workflows/build.yaml", + ".github/workflows/test.yaml", + "docs/_templates/autosummary/**.rst" + ], + "_render_devdocs": false, + "_jinja2_env_vars": { + "lstrip_blocks": true, + "trim_blocks": true + }, + "_template": "https://github.com/scverse/cookiecutter-scverse" + } + }, + "directory": null } diff --git a/.editorconfig b/.editorconfig index 2fe0ce0..050f911 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,5 +8,11 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true +[*.{yml,yaml}] +indent_size = 2 + +[.cruft.json] +indent_size = 2 + [Makefile] indent_style = tab diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 10cfc5a..0000000 --- a/.flake8 +++ /dev/null @@ -1,57 +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 -rst-roles = - class, - func, - ref, - cite:p, - cite:t, -rst-directives = - envvar, - exception, -rst-substitutions = - version, -extend-ignore = - RST307, diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 9dfd4ac..a5a20e6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -2,88 +2,88 @@ name: Bug report description: Report something that is broken or incorrect labels: bug body: - - type: markdown - attributes: - value: | - **Note**: Please read [this guide](https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports) - detailing how to provide the necessary information for us to reproduce your bug. In brief: - * Please provide exact steps how to reproduce the bug in a clean Python environment. - * In case it's not clear what's causing this bug, please provide the data or the data generation procecure. - * Sometimes it is not possible to share the data but usually it is possible to replicate problems on publicly - available datasets or to share a subset of your data. + - type: markdown + attributes: + value: | + **Note**: Please read [this guide](https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports) + detailing how to provide the necessary information for us to reproduce your bug. In brief: + * Please provide exact steps how to reproduce the bug in a clean Python environment. + * In case it's not clear what's causing this bug, please provide the data or the data generation procedure. + * Sometimes it is not possible to share the data, but usually it is possible to replicate problems on publicly + available datasets or to share a subset of your data. - - type: textarea - id: report - attributes: - label: Report - description: A clear and concise description of what the bug is. - validations: - required: true + - type: textarea + id: report + attributes: + label: Report + description: A clear and concise description of what the bug is. + validations: + required: true - - type: textarea - id: versions - attributes: - label: Version information - description: | - Please paste below the output of + - type: textarea + id: versions + attributes: + label: Version information + description: | + Please paste below the output of - ```python - import session_info - session_info.show(html=False, dependencies=True) - ``` - placeholder: | - ----- - anndata 0.8.0rc2.dev27+ge524389 - session_info 1.0.0 - ----- - asttokens NA - awkward 1.8.0 - backcall 0.2.0 - cython_runtime NA - dateutil 2.8.2 - debugpy 1.6.0 - decorator 5.1.1 - entrypoints 0.4 - executing 0.8.3 - h5py 3.7.0 - ipykernel 6.15.0 - jedi 0.18.1 - mpl_toolkits NA - natsort 8.1.0 - numpy 1.22.4 - packaging 21.3 - pandas 1.4.2 - parso 0.8.3 - pexpect 4.8.0 - pickleshare 0.7.5 - pkg_resources NA - prompt_toolkit 3.0.29 - psutil 5.9.1 - ptyprocess 0.7.0 - pure_eval 0.2.2 - pydev_ipython NA - pydevconsole NA - pydevd 2.8.0 - pydevd_file_utils NA - pydevd_plugins NA - pydevd_tracing NA - pygments 2.12.0 - pytz 2022.1 - scipy 1.8.1 - setuptools 62.5.0 - setuptools_scm NA - six 1.16.0 - stack_data 0.3.0 - tornado 6.1 - traitlets 5.3.0 - wcwidth 0.2.5 - zmq 23.1.0 - ----- - IPython 8.4.0 - jupyter_client 7.3.4 - jupyter_core 4.10.0 - ----- - Python 3.9.13 | packaged by conda-forge | (main, May 27 2022, 16:58:50) [GCC 10.3.0] - Linux-5.18.6-arch1-1-x86_64-with-glibc2.35 - ----- - Session information updated at 2022-07-07 17:55 + ```python + import session_info + session_info.show(html=False, dependencies=True) + ``` + placeholder: | + ----- + anndata 0.8.0rc2.dev27+ge524389 + session_info 1.0.0 + ----- + asttokens NA + awkward 1.8.0 + backcall 0.2.0 + cython_runtime NA + dateutil 2.8.2 + debugpy 1.6.0 + decorator 5.1.1 + entrypoints 0.4 + executing 0.8.3 + h5py 3.7.0 + ipykernel 6.15.0 + jedi 0.18.1 + mpl_toolkits NA + natsort 8.1.0 + numpy 1.22.4 + packaging 21.3 + pandas 1.4.2 + parso 0.8.3 + pexpect 4.8.0 + pickleshare 0.7.5 + pkg_resources NA + prompt_toolkit 3.0.29 + psutil 5.9.1 + ptyprocess 0.7.0 + pure_eval 0.2.2 + pydev_ipython NA + pydevconsole NA + pydevd 2.8.0 + pydevd_file_utils NA + pydevd_plugins NA + pydevd_tracing NA + pygments 2.12.0 + pytz 2022.1 + scipy 1.8.1 + setuptools 62.5.0 + setuptools_scm NA + six 1.16.0 + stack_data 0.3.0 + tornado 6.1 + traitlets 5.3.0 + wcwidth 0.2.5 + zmq 23.1.0 + ----- + IPython 8.4.0 + jupyter_client 7.3.4 + jupyter_core 4.10.0 + ----- + Python 3.9.13 | packaged by conda-forge | (main, May 27 2022, 16:58:50) [GCC 10.3.0] + Linux-5.18.6-arch1-1-x86_64-with-glibc2.35 + ----- + Session information updated at 2022-07-07 17:55 diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 5cad625..5b62547 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,5 @@ blank_issues_enabled: false contact_links: - - name: Scverse Community Forum - url: https://discourse.scverse.org/ - about: If you have questions about “How to do X”, please ask them here. + - name: Scverse Community Forum + url: https://discourse.scverse.org/ + about: If you have questions about “How to do X”, please ask them here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 98993c2..6a25b15 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -2,10 +2,10 @@ name: Feature request description: Propose a new feature for monkeybread labels: enhancement body: - - type: textarea - id: description - attributes: - label: Description of feature - description: Please describe your suggestion for a new feature. It might help to describe a problem or use case, plus any alternatives that you have considered. - validations: - required: true + - type: textarea + id: description + attributes: + label: Description of feature + description: Please describe your suggestion for a new feature. It might help to describe a problem or use case, plus any alternatives that you have considered. + validations: + required: true diff --git a/.github/workflows/build.yaml.rej b/.github/workflows/build.yaml.rej new file mode 100644 index 0000000..ccae0a2 --- /dev/null +++ b/.github/workflows/build.yaml.rej @@ -0,0 +1,49 @@ +diff a/.github/workflows/build.yaml b/.github/workflows/build.yaml (rejected hunks) +@@ -1,23 +1,29 @@ + name: Check Build + + on: +- push: +- branches: [main] +- pull_request: +- branches: [main] ++ push: ++ branches: [main] ++ pull_request: ++ branches: [main] ++ ++concurrency: ++ group: ${{ github.workflow }}-${{ github.ref }} ++ cancel-in-progress: true + + jobs: +- package: +- runs-on: ubuntu-latest +- steps: +- - uses: actions/checkout@v2 +- - name: Set up Python 3.10 +- uses: actions/setup-python@v2 +- with: +- python-version: "3.10" +- - name: Install build dependencies +- run: python -m pip install --upgrade pip wheel twine build +- - name: Build package +- run: python -m build +- - name: Check package +- run: twine check --strict dist/*.whl ++ package: ++ runs-on: ubuntu-latest ++ steps: ++ - uses: actions/checkout@v3 ++ - name: Set up Python 3.10 ++ uses: actions/setup-python@v4 ++ with: ++ python-version: "3.10" ++ cache: "pip" ++ cache-dependency-path: "**/pyproject.toml" ++ - name: Install build dependencies ++ run: python -m pip install --upgrade pip wheel twine build ++ - name: Build package ++ run: python -m build ++ - name: Check package ++ run: twine check --strict dist/*.whl diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..f604a20 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,29 @@ +name: Release + +on: + release: + types: [published] + +# Use "trusted publishing", see https://docs.pypi.org/trusted-publishers/ +jobs: + release: + name: Upload release to PyPI + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/monkeybread + permissions: + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing + steps: + - uses: actions/checkout@v4 + with: + filter: blob:none + fetch-depth: 0 + - uses: actions/setup-python@v4 + with: + 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/.github/workflows/sync.yaml b/.github/workflows/sync.yaml deleted file mode 100644 index 5219499..0000000 --- a/.github/workflows/sync.yaml +++ /dev/null @@ -1,46 +0,0 @@ -name: Sync Template - -on: - workflow_dispatch: - schedule: - - cron: "0 2 * * *" # every night at 2:00 UTC - -jobs: - sync: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Python 3.10 - uses: actions/setup-python@v4 - with: - python-version: "3.10" - - name: Install dependencies - # for now, pin cookiecutter version, due to https://github.com/cruft/cruft/issues/166 - run: python -m pip install --upgrade cruft "cookiecutter<2" pre-commit toml - - name: Find Latest Tag - uses: oprypin/find-latest-tag@v1.1.0 - id: get-latest-tag - with: - repository: scverse/cookiecutter-scverse - releases-only: false - sort-tags: true - regex: '^v\d+\.\d+\.\d+$' # vX.X.X - - name: Sync - run: | - cruft update --checkout ${{ steps.get-latest-tag.outputs.tag }} --skip-apply-ask --project-dir . - - name: Create Pull Request - uses: peter-evans/create-pull-request@v4 - with: - commit-message: Automated template update from cookiecutter-scverse - branch: template-update - title: Automated template update from cookiecutter-scverse - body: | - A new version of the [scverse cookiecutter template](https://github.com/scverse/cookiecutter-scverse/releases) - got released. This PR adds all new changes to your repository and helps to to stay in sync with - the latest best-practice template maintained by the scverse team. - - **If a merge conflict arised, a `.rej` file with the rejected patch is generated. You'll need to - manually merge these changes.** - - For more information about the template sync, please refer to the - [template documentation](https://cookiecutter-scverse-instance.readthedocs.io/en/latest/developer_docs.html#automated-template-sync). diff --git a/.github/workflows/test.yaml.rej b/.github/workflows/test.yaml.rej new file mode 100644 index 0000000..f125858 --- /dev/null +++ b/.github/workflows/test.yaml.rej @@ -0,0 +1,124 @@ +diff a/.github/workflows/test.yaml b/.github/workflows/test.yaml (rejected hunks) +@@ -1,62 +1,67 @@ + name: Test + + on: +- push: +- branches: [main] +- pull_request: +- branches: [main] ++ push: ++ branches: [main] ++ pull_request: ++ branches: [main] ++ schedule: ++ - cron: "0 5 1,15 * *" ++ ++concurrency: ++ group: ${{ github.workflow }}-${{ github.ref }} ++ cancel-in-progress: true + + jobs: +- test: +- runs-on: ${{ matrix.os }} +- defaults: +- run: +- shell: bash -e {0} # -e to fail on error +- +- strategy: +- fail-fast: false +- matrix: +- python: ["3.8", "3.10"] +- os: [ubuntu-latest] ++ test: ++ runs-on: ${{ matrix.os }} ++ defaults: ++ run: ++ shell: bash -e {0} # -e to fail on error ++ ++ strategy: ++ fail-fast: false ++ matrix: ++ include: ++ - os: ubuntu-latest ++ python: "3.10" ++ - os: ubuntu-latest ++ python: "3.12" ++ - os: ubuntu-latest ++ python: "3.12" ++ pip-flags: "--pre" ++ name: PRE-RELEASE DEPENDENCIES ++ ++ name: ${{ matrix.name }} Python ${{ matrix.python }} ++ ++ env: ++ OS: ${{ matrix.os }} ++ PYTHON: ${{ matrix.python }} ++ ++ steps: ++ - uses: actions/checkout@v3 ++ - name: Set up Python ${{ matrix.python }} ++ uses: actions/setup-python@v4 ++ with: ++ python-version: ${{ matrix.python }} ++ cache: "pip" ++ cache-dependency-path: "**/pyproject.toml" + ++ - name: Install test dependencies ++ run: | ++ python -m pip install --upgrade pip wheel ++ - name: Install dependencies ++ run: | ++ pip install ${{ matrix.pip-flags }} ".[dev,test]" ++ - name: Test + env: +- OS: ${{ matrix.os }} +- PYTHON: ${{ matrix.python }} +- +- steps: +- - uses: actions/checkout@v2 +- - name: Set up Python ${{ matrix.python }} +- uses: actions/setup-python@v2 +- with: +- python-version: ${{ matrix.python }} +- +- - name: Get pip cache dir +- id: pip-cache-dir +- run: | +- echo "::set-output name=dir::$(pip cache dir)" +- - name: Restore pip cache +- uses: actions/cache@v2 +- with: +- path: ${{ steps.pip-cache-dir.outputs.dir }} +- key: pip-${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('**/pyproject.toml') }} +- restore-keys: | +- pip-${{ runner.os }}-${{ env.pythonLocation }}- +- - name: Install test dependencies +- run: | +- python -m pip install --upgrade pip wheel +- pip install codecov +- - name: Install dependencies +- run: | +- pip install ".[dev,test]" +- - name: Test +- env: +- MPLBACKEND: agg +- PLATFORM: ${{ matrix.os }} +- DISPLAY: :42 +- run: | +- pytest -v --cov --color=yes +- - name: Upload coverage +- env: +- CODECOV_NAME: ${{ matrix.python }}-${{ matrix.os }} +- run: | +- codecov --required --flags=unittests ++ MPLBACKEND: agg ++ PLATFORM: ${{ matrix.os }} ++ DISPLAY: :42 ++ run: | ++ coverage run -m pytest -v --color=yes ++ - name: Report coverage ++ run: | ++ coverage report ++ - name: Upload coverage ++ uses: codecov/codecov-action@v3 diff --git a/.gitignore b/.gitignore index 19d03fa..b64febf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,13 @@ # Temp files .DS_Store *~ +buck-out/ # Compiled files +.venv/ __pycache__/ +.mypy_cache/ +.ruff_cache/ # Distribution / packaging /build/ diff --git a/.gitignore.rej b/.gitignore.rej new file mode 100644 index 0000000..429bfdc --- /dev/null +++ b/.gitignore.rej @@ -0,0 +1,9 @@ +diff a/.gitignore b/.gitignore (rejected hunks) +@@ -14,6 +18,7 @@ __pycache__/ + /.pytest_cache/ + /.cache/ + /data/ ++/node_modules/ + + # docs + /docs/generated/ diff --git a/.pre-commit-config.yaml.rej b/.pre-commit-config.yaml.rej new file mode 100644 index 0000000..7c76634 --- /dev/null +++ b/.pre-commit-config.yaml.rej @@ -0,0 +1,118 @@ +diff a/.pre-commit-config.yaml b/.pre-commit-config.yaml (rejected hunks) +@@ -1,79 +1,42 @@ + fail_fast: false + default_language_version: +- python: python3 ++ python: python3 + default_stages: +- - commit +- - push ++ - commit ++ - push + minimum_pre_commit_version: 2.16.0 + repos: +- - repo: https://github.com/psf/black +- rev: 24.4.2 +- 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/PyCQA/isort +- rev: 5.13.2 +- hooks: +- - id: isort +- - repo: https://github.com/asottile/yesqa +- rev: v1.5.0 +- hooks: +- - id: yesqa +- additional_dependencies: +- - flake8-tidy-imports +- - flake8-docstrings +- - flake8-rst-docstrings +- - flake8-comprehensions +- - flake8-bugbear +- - flake8-blind-except +- - 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 +- - repo: https://github.com/myint/autoflake +- rev: v2.3.1 +- hooks: +- - id: autoflake +- args: +- - --in-place +- - --remove-all-unused-imports +- - --remove-unused-variable +- - --ignore-init-module-imports +- - repo: https://github.com/PyCQA/flake8 +- rev: 7.0.0 +- hooks: +- - id: flake8 +- additional_dependencies: +- - flake8-tidy-imports +- - flake8-docstrings +- - flake8-rst-docstrings +- - flake8-comprehensions +- - flake8-bugbear +- - flake8-blind-except +- - repo: https://github.com/asottile/pyupgrade +- rev: v3.15.2 +- hooks: +- - id: pyupgrade +- args: [--py3-plus, --py38-plus, --keep-runtime-typing] +- - 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$' ++ - repo: https://github.com/pre-commit/mirrors-prettier ++ rev: v4.0.0-alpha.8 ++ hooks: ++ - id: prettier ++ - repo: https://github.com/astral-sh/ruff-pre-commit ++ rev: v0.4.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/.readthedocs.yaml b/.readthedocs.yaml index 9e5d5fa..69897c3 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,16 +1,16 @@ # https://docs.readthedocs.io/en/stable/config-file/v2.html version: 2 build: - os: ubuntu-20.04 - tools: - python: "3.10" + os: ubuntu-20.04 + tools: + python: "3.10" sphinx: - configuration: docs/conf.py - # disable this for more lenient docs builds - fail_on_warning: true + configuration: docs/conf.py + # disable this for more lenient docs builds + fail_on_warning: true python: - install: - - method: pip - path: . - extra_requirements: - - doc + install: + - method: pip + path: . + extra_requirements: + - doc diff --git a/README.md.rej b/README.md.rej new file mode 100644 index 0000000..bb234bb --- /dev/null +++ b/README.md.rej @@ -0,0 +1,19 @@ +diff a/README.md b/README.md (rejected hunks) +@@ -3,7 +3,7 @@ + [![Tests][badge-tests]][link-tests] + [![Documentation][badge-docs]][link-docs] + +-[badge-tests]: https://img.shields.io/github/workflow/status/immunitastx/monkeybread/Test/main ++[badge-tests]: https://img.shields.io/github/actions/workflow/status/immunitastx/monkeybread/test.yaml?branch=main + [link-tests]: https://github.com/immunitastx/monkeybread/actions/workflows/test.yml + [badge-docs]: https://img.shields.io/readthedocs/monkeybread + +@@ -17,7 +17,7 @@ Please refer to the [documentation][link-docs]. In particular, the + + ## Installation + +-You need to have Python 3.8 or newer installed on your system. If you don't have ++You need to have Python 3.10 or newer installed on your system. If you don't have + Python installed, we recommend installing [Mambaforge](https://github.com/conda-forge/miniforge#mambaforge). + + There are several alternative options to install monkeybread: diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css new file mode 100644 index 0000000..b8c8d47 --- /dev/null +++ b/docs/_static/css/custom.css @@ -0,0 +1,4 @@ +/* Reduce the font size in data frames - See https://github.com/scverse/cookiecutter-scverse/issues/193 */ +div.cell_output table.dataframe { + font-size: 0.8em; +} diff --git a/docs/_templates/autosummary/class.rst b/docs/_templates/autosummary/class.rst index 17dc123..e4665df 100644 --- a/docs/_templates/autosummary/class.rst +++ b/docs/_templates/autosummary/class.rst @@ -39,9 +39,6 @@ Attributes {% for item in attributes %} -{{ item }} -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - .. autoattribute:: {{ [objname, item] | join(".") }} {%- endfor %} @@ -56,9 +53,6 @@ Methods {% for item in methods %} {%- if item != '__init__' %} -{{ item }} -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - .. automethod:: {{ [objname, item] | join(".") }} {%- endif -%} {%- endfor %} diff --git a/docs/conf.py b/docs/conf.py index b5996b9..7f72cad 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,5 @@ # Configuration file for the Sphinx documentation builder. -# + # 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 @@ -38,10 +38,10 @@ html_context = { "display_github": True, # Integrate GitHub - "github_user": "immunitastx", # Username - "github_repo": project_name, # Repo name - "github_version": "main", # Version - "conf_py_path": "/docs/", # Path in the checkout to the docs root + "github_user": "immunitastx", + "github_repo": "https://github.com/immunitastx/monkeybread", + "github_version": "main", + "conf_py_path": "/docs/", } # -- General configuration --------------------------------------------------- @@ -71,7 +71,7 @@ napoleon_include_init_with_doc = False napoleon_use_rtype = True # having a separate entry generally helps readability napoleon_use_param = True -myst_heading_anchors = 3 # create anchors for h1-h3 +myst_heading_anchors = 6 # create anchors for h1-h6 myst_enable_extensions = [ "amsmath", "colon_fence", diff --git a/docs/conf.py.rej b/docs/conf.py.rej new file mode 100644 index 0000000..f69acc4 --- /dev/null +++ b/docs/conf.py.rej @@ -0,0 +1,74 @@ +diff a/docs/conf.py b/docs/conf.py (rejected hunks) +@@ -16,12 +16,15 @@ sys.path.insert(0, str(HERE / "extensions")) + + # -- Project information ----------------------------------------------------- + ++# NOTE: If you installed your project in editable mode, this might be stale. ++# If this is the case, reinstall it to refresh the metadata + info = metadata("monkeybread") + project_name = info["Name"] + author = info["Author"] + copyright = f"{datetime.now():%Y}, {author}." + version = info["Version"] +-repository_url = f"https://github.com/immunitastx/{project_name}" ++urls = dict(pu.split(", ") for pu in info.get_all("Project-URL")) ++repository_url = urls["Source"] + + # The full version, including alpha/beta/rc tags + release = info["Version"] +@@ -54,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")], + ] + +@@ -87,11 +91,11 @@ source_suffix = { + } + + intersphinx_mapping = { ++ "python": ("https://docs.python.org/3", None), + "anndata": ("https://anndata.readthedocs.io/en/stable/", None), + "numpy": ("https://numpy.org/doc/stable/", None), + } + +- + # List of patterns, relative to source directory, that match files and + # directories to ignore when looking for source files. + # This pattern also affects html_static_path and html_extra_path. +@@ -105,11 +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" +@@ -119,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 new file mode 100644 index 0000000..2afbd98 --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,160 @@ +# Contributing guide + +Scanpy provides extensive [developer documentation][scanpy developer guide], most of which applies to this project, too. +This document will not reproduce the entire content from there. Instead, it aims at summarizing the most important +information to get you started on contributing. + +We assume that you are already familiar with git and with making pull requests on GitHub. If not, please refer +to the [scanpy developer guide][]. + +## Installing dev dependencies + +In addition to the packages needed to _use_ this package, you need additional python packages to _run tests_ and _build +the documentation_. It's easy to install them using `pip`: + +```bash +cd monkeybread +pip install -e ".[dev,test,doc]" +``` + +## 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. + +To enable pre-commit locally, simply run + +```bash +pre-commit install +``` + +in the root of the repository. Pre-commit 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 pre-commit.ci added a commit on a branch you still have been working on locally, simply use + +```bash +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. + +Finally, most editors have an _autoformat on save_ feature. Consider enabling this option for [ruff][ruff-editors] +and [prettier][prettier-editors]. + +[ruff-editors]: https://docs.astral.sh/ruff/integrations/ +[prettier-editors]: https://prettier.io/docs/en/editors.html + +## Writing tests + +```{note} +Remember to first install the package with `pip install -e '.[dev,test]'` +``` + +This package uses the [pytest][] for automated testing. Please [write tests][scanpy-test-docs] for every function added +to the package. + +Most IDEs integrate with pytest and provide a GUI to run tests. Alternatively, you can run all tests from the +command line by executing + +```bash +pytest +``` + +in the root of the repository. + +### Continuous integration + +Continuous integration will automatically run the tests on all pull requests and test +against the minimum and maximum supported Python version. + +Additionally, there's a CI job that tests against pre-releases of all dependencies +(if there are any). The purpose of this check is to detect incompatibilities +of new package versions early on and gives you time to fix the issue or reach +out to the developers of the dependency before the package is released to a wider audience. + +[scanpy-test-docs]: https://scanpy.readthedocs.io/en/latest/dev/testing.html#writing-tests + +## Publishing a release + +### Updating the version number + +Before making a release, you need to update the version number in the `pyproject.toml` file. Please adhere to [Semantic Versioning][semver], in brief + +> Given a version number MAJOR.MINOR.PATCH, increment the: +> +> 1. MAJOR version when you make incompatible API changes, +> 2. MINOR version when you add functionality in a backwards compatible manner, and +> 3. PATCH version when you make backwards compatible bug fixes. +> +> 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. + +## Writing documentation + +Please write documentation for new or changed features and use-cases. This project uses [sphinx][] with the following features: + +- the [myst][] extension allows to write documentation in markdown/Markedly Structured Text +- [Numpy-style docstrings][numpydoc] (through the [napoloen][numpydoc-napoleon] extension). +- Jupyter notebooks as tutorials through [myst-nb][] (See [Tutorials with myst-nb](#tutorials-with-myst-nb-and-jupyter-notebooks)) +- [Sphinx autodoc typehints][], to automatically reference annotated input and output types +- Citations (like {cite:p}`Virshup_2023`) can be included with [sphinxcontrib-bibtex](https://sphinxcontrib-bibtex.readthedocs.io/) + +See the [scanpy developer docs](https://scanpy.readthedocs.io/en/latest/dev/documentation.html) for more information +on how to write documentation. + +### Tutorials with myst-nb and jupyter notebooks + +The documentation is set-up to render jupyter notebooks stored in the `docs/notebooks` directory using [myst-nb][]. +Currently, only notebooks in `.ipynb` format are supported that will be included with both their input and output cells. +It is your responsibility to update and re-run the notebook whenever necessary. + +If you are interested in automatically running notebooks as part of the continuous integration, please check +out [this feature request](https://github.com/scverse/cookiecutter-scverse/issues/40) in the `cookiecutter-scverse` +repository. + +#### Hints + +- If you refer to objects from other packages, please add an entry to `intersphinx_mapping` in `docs/conf.py`. Only + if you do so can sphinx automatically create a link to the external documentation. +- If building the documentation fails because of a missing link that is outside your control, you can add an entry to + the `nitpick_ignore` list in `docs/conf.py` + +#### Building the docs locally + +```bash +cd docs +make html +open _build/html/index.html +``` + + + +[scanpy developer guide]: https://scanpy.readthedocs.io/en/latest/dev/index.html +[cookiecutter-scverse-instance]: https://cookiecutter-scverse-instance.readthedocs.io/en/latest/template_usage.html +[github quickstart guide]: https://docs.github.com/en/get-started/quickstart/create-a-repo?tool=webui +[codecov]: https://about.codecov.io/sign-up/ +[codecov docs]: https://docs.codecov.com/docs +[codecov bot]: https://docs.codecov.com/docs/team-bot +[codecov app]: https://github.com/apps/codecov +[pre-commit.ci]: https://pre-commit.ci/ +[readthedocs.org]: https://readthedocs.org/ +[myst-nb]: https://myst-nb.readthedocs.io/en/latest/ +[jupytext]: https://jupytext.readthedocs.io/en/latest/ +[pre-commit]: https://pre-commit.com/ +[anndata]: https://github.com/scverse/anndata +[mudata]: https://github.com/scverse/mudata +[pytest]: https://docs.pytest.org/ +[semver]: https://semver.org/ +[sphinx]: https://www.sphinx-doc.org/en/master/ +[myst]: https://myst-parser.readthedocs.io/en/latest/intro.html +[numpydoc-napoleon]: https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.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/extensions/typed_returns.py b/docs/extensions/typed_returns.py index 9447813..1135204 100644 --- a/docs/extensions/typed_returns.py +++ b/docs/extensions/typed_returns.py @@ -1,24 +1,27 @@ # 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): +def _process_return(lines: Iterable[str]) -> Generator[str, None, None]: for line in lines: - m = re.fullmatch(r"(?P\w+)\s+:\s+(?P[\w.]+)", line) - if m: - # Once this is in scanpydoc, we can use the fancy hover stuff + 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, section): - lines_raw = list(_process_return(self._dedent(self._consume_to_next_section()))) - lines = self._format_block(":returns: ", lines_raw) +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 diff --git a/docs/index.md.rej b/docs/index.md.rej new file mode 100644 index 0000000..7b31e8b --- /dev/null +++ b/docs/index.md.rej @@ -0,0 +1,10 @@ +diff a/docs/index.md b/docs/index.md (rejected hunks) +@@ -8,7 +8,7 @@ + + api.md + changelog.md +-developer_docs.md ++contributing.md + references.md + + notebooks/example diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 954237b..0000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -%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.https://www.sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "" goto help - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/pyproject.toml b/pyproject.toml index c060dc4..95f1a90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,35 +71,63 @@ addopts = [ "--import-mode=importlib", # allow using test files with same name ] -[tool.isort] -include_trailing_comma = true -multi_line_output = 3 -profile = "black" -skip_glob = ["docs/*"] - -[tool.black] +[tool.ruff] line-length = 120 -target-version = ['py38'] -include = '\.pyi?$' -exclude = ''' -( - /( - \.eggs - | \.git - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | _build - | buck-out - | build - | dist - )/ -) -''' +src = ["src"] +extend-include = ["*.ipynb"] + +[tool.ruff.format] +docstring-code-format = true + +[tool.ruff.lint] +select = [ + "F", # Errors detected by Pyflakes + "E", # Error detected by Pycodestyle + "W", # Warning detected by Pycodestyle + "I", # isort + "D", # pydocstyle + "B", # flake8-bugbear + "TID", # flake8-tidy-imports + "C4", # flake8-comprehensions + "BLE", # flake8-blind-except + "UP", # pyupgrade + "RUF100", # Report unused noqa directives +] +ignore = [ + # line too long -> we accept long comment lines; formatter gets rid of long code lines + "E501", + # 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", + # __magic__ methods are often self-explanatory, allow missing docstrings + "D105", + # 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", + ## Disable one in each pair of mutually incompatible rules + # We don’t want a blank line before a class docstring + "D203", + # We want docstrings to start immediately after the opening triple quote + "D213", +] + +[tool.ruff.lint.pydocstyle] +convention = "numpy" -[tool.jupytext] -formats = "ipynb,md" +[tool.ruff.lint.per-file-ignores] +"docs/*" = ["I"] +"tests/*" = ["D"] +"*/__init__.py" = ["F401"] [tool.cruft] skip = [ @@ -110,5 +138,5 @@ skip = [ "docs/changelog.md", "docs/references.bib", "docs/references.md", - "docs/notebooks/example.ipynb" + "docs/notebooks/example.ipynb", ] diff --git a/pyproject.toml.rej b/pyproject.toml.rej new file mode 100644 index 0000000..fa504ca --- /dev/null +++ b/pyproject.toml.rej @@ -0,0 +1,55 @@ +diff a/pyproject.toml b/pyproject.toml (rejected hunks) +@@ -2,13 +2,12 @@ + build-backend = "hatchling.build" + requires = ["hatchling"] + +- + [project] + name = "monkeybread" + version = "0.0.1" + description = "Tool for analyzing cell closeness in spatial transcriptomic data" + readme = "README.md" +-requires-python = ">=3.8" ++requires-python = ">=3.10" + license = {file = "LICENSE"} + authors = [ + {name = "Immunitas Therapeutics"}, +@@ -22,29 +21,31 @@ urls.Home-page = "https://github.com/immunitastx/monkeybread" + dependencies = [ + "anndata", + # for debug logging (referenced from the issue template) +- "session-info" ++ "session-info", + ] + + [project.optional-dependencies] + dev = [ +- # CLI for bumping the version number +- "bump2version", +- "pre-commit" ++ "pre-commit", ++ "twine>=4.0.2", + ] + doc = [ ++ "docutils>=0.8,!=0.18.*,!=0.19.*", + "sphinx>=4", +- "sphinx-book-theme>=0.3.3", +- "myst-nb", ++ "sphinx-book-theme>=1.0.0", ++ "myst-nb>=1.1.0", + "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]