diff --git a/.cruft.json b/.cruft.json new file mode 100644 index 0000000000..b462f35c1a --- /dev/null +++ b/.cruft.json @@ -0,0 +1,44 @@ + +{ + "template": "https://github.com/scverse/cookiecutter-scverse", + "commit": "d383d94fadff9e4e6fdb59d77c68cb900d7cedec", + "checkout": "v0.6.0", + "context": { + "cookiecutter": { + "project_name": "scvi-tools", + "package_name": "scvi-tools", + "project_description": "Deep probabilistic analysis of single-cell omics data.", + "author_full_name": "Ori Kronfeld", + "author_email": "ori.kronfeld@weizmann.ac.il", + "github_user": "scverse", + "github_repo": "scvi-tools", + "license": "BSD 3-Clause License", + "ide_integration": true, + "_copy_without_render": [ + ".github/workflows/build.yaml", + ".github/workflows/test_linux.yaml", + "docs/_templates/autosummary/**.rst" + ], + "_exclude_on_template_update": [ + "CHANGELOG.md", + "LICENSE", + "README.md", + "docs/api.md", + "docs/index.md", + "docs/notebooks/example.ipynb", + "docs/references.bib", + "docs/references.md", + "src/**", + "tests/**" + ], + "_render_devdocs": false, + "_jinja2_env_vars": { + "lstrip_blocks": true, + "trim_blocks": true + }, + "_template": "https://github.com/scverse/cookiecutter-scverse", + "_commit": "d383d94fadff9e4e6fdb59d77c68cb900d7cedec" + } + }, + "directory": null +} diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 1a9d7af2c1..0000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: "" -labels: bug -assignees: "" ---- - - - -[TEXT HERE] - - - -```python -# Your code here -``` - - - -```pytb -[Paste the error output produced by the above code here] -``` - -#### Versions: - - - -> VERSION - - diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000..b226a16dc8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,71 @@ +name: Bug report +description: Report something that is broken or incorrect +#title: ... +type: Bug +labels: + - Triage 🩺 +#assignees: [] +body: + - type: checkboxes + id: terms + attributes: + label: Please make sure these conditions are met + # description: ... + options: + - label: I have checked that this issue has not already been reported. + required: true + - label: I have confirmed this bug exists on the latest version of scvi-tools. + required: true + - label: (optional) I have confirmed this bug exists on the main branch of scvi-tools. + required: false + - type: markdown + attributes: + value: | + **Note**: Please read [this guide][] detailing how to provide the necessary information for us to reproduce your bug. + + [this guide]: https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports + - type: textarea + id: Report + attributes: + label: Report + description: | + Describe the bug you encountered, and what you were trying to do. Please use [github markdown][] features for readability. + + [github markdown]: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax + value: | + Code: + + ```python + + ``` + + Traceback: + + ```pytb + + ``` + validations: + required: true + - type: textarea + id: versions + attributes: + label: Versions + description: | + Which version of scvi-tools and other related software you used. + + Please install `session-info2`, run the following command in a notebook, + click the “Copy as Markdown” button, + then paste the results into the text box below. + + ```python + In[1]: import scvi, session_info2; session_info2.session_info(dependencies=True) + ``` + + Alternatively, run this in a console: + + ```python + >>> import session_info2; print(session_info2.session_info(dependencies=True)._repr_mimebundle_()["text/markdown"]) + ``` + render: python + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index b7628704a7..5b62547f9a 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,5 @@ +blank_issues_enabled: false contact_links: - - name: Usage question - url: https://discourse.scvi-tools.org/ - about: Please ask and answer non-development questions at https://discourse.scvi-tools.org/. + - 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.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index fcd76a381a..0000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: "" -labels: enhancement -assignees: "" ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000000..3cde65b1ef --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,11 @@ +name: Feature request +description: Propose a new feature for scvi-tutorials and scvi-tools +type: 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 diff --git a/.gitignore b/.gitignore index 6fd834b0b3..73d793fc37 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,6 @@ __pycache__/ # IDEs /.idea/ -/.vscode/ # node /node_modules/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a13076ef43..8681798675 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,6 +6,16 @@ default_stages: - pre-push minimum_pre_commit_version: 2.16.0 repos: + - repo: https://github.com/biomejs/pre-commit + rev: v2.3.5 + hooks: + - id: biome-format + exclude: ^\.cruft\.json$ # inconsistent indentation with cruft - file never to be modified manually. + - repo: https://github.com/tox-dev/pyproject-fmt + rev: v2.11.1 + hooks: + - id: pyproject-fmt + - repo: https://github.com/asottile/blacken-docs rev: 1.20.0 hooks: @@ -57,6 +67,13 @@ repos: args: [--fix=lf] - id: trailing-whitespace - id: check-case-conflict + - id: check-added-large-files + - id: check-toml + - id: check-yaml + - id: check-merge-conflict + - id: detect-private-key + - id: no-commit-to-branch + args: ["--branch=main"] - repo: local hooks: diff --git a/.readthedocs.yaml b/.readthedocs.yaml index acedf0a788..be5e49ad73 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,8 +1,8 @@ version: 2 build: - os: ubuntu-20.04 + os: ubuntu-24.04 tools: - python: "3.11" + python: "3.13" sphinx: configuration: docs/conf.py python: diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000000..caaeb4f732 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,18 @@ +{ + "recommendations": [ + // GitHub integration + "github.vscode-github-actions", + "github.vscode-pull-request-github", + // Language support + "ms-python.python", + "ms-python.vscode-pylance", + "ms-toolsai.jupyter", + "tamasfe.even-better-toml", + // Dependency management + "ninoseki.vscode-mogami", + // Linting and formatting + "editorconfig.editorconfig", + "charliermarsh.ruff", + "biomejs.biome", + ], +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..5c5e982155 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Build Docs", + "type": "debugpy", + "request": "launch", + "module": "sphinx", + "args": ["-M", "html", ".", "_build"], + "cwd": "${workspaceFolder}/docs", + "console": "internalConsole", + "justMyCode": false, + }, + { + "name": "Python: Debug Test", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "purpose": ["debug-test"], + "console": "internalConsole", + "justMyCode": false, + "env": { "PYTEST_ADDOPTS": "--color=yes" }, + "presentation": { "hidden": true }, + }, + ], +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..7024abf5f2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,27 @@ +{ + "[python][toml][json][jsonc]": { + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit", + "source.fixAll": "explicit", + }, + }, + "[python]": { + "editor.defaultFormatter": "charliermarsh.ruff", + }, + "[toml]": { + "editor.defaultFormatter": "tamasfe.even-better-toml", + }, + "[json][jsonc]": { + "editor.defaultFormatter": "biomejs.biome", + }, + "python.analysis.typeCheckingMode": "basic", + "python.testing.pytestEnabled": true, + "python.testing.pytestArgs": [ + "--color=yes", + "-vv", + "--strict-warnings", + //"-nauto", + ], + "python.terminal.activateEnvironment": true, +} diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 0000000000..3c34a20713 --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,18 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.1.1/schema.json", + "formatter": { "useEditorconfig": true }, + "overrides": [ + { + "includes": ["./.vscode/*.json", "**/*.jsonc", "**/asv.conf.json"], + "json": { + "formatter": { + "trailingCommas": "all", + }, + "parser": { + "allowComments": true, + "allowTrailingCommas": true, + }, + }, + }, + ], +} diff --git a/docs/_static/css/override.css b/docs/_static/css/override.css index f31d6ec81a..4651d9d7fe 100644 --- a/docs/_static/css/override.css +++ b/docs/_static/css/override.css @@ -21,7 +21,9 @@ .filter-btn:hover { color: var(--pst-color-table-row-hover); border-color: var(--pst-color-table-row-hover); - background-color: var(--pst-color-hover-background); /* Add hover background */ + background-color: var( + --pst-color-hover-background + ); /* Add hover background */ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); /* Enhance shadow on hover */ } @@ -52,7 +54,7 @@ .card a { text-decoration: none; - } +} .card { border-radius: 1rem; /* Uniform border radius */ @@ -112,7 +114,9 @@ } .tab:hover { - background-color: var(--pst-color-hover-background); /* Add hover background */ + background-color: var( + --pst-color-hover-background + ); /* Add hover background */ color: var(--pst-color-table-row-hover); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); /* Enhance shadow on hover */ } diff --git a/docs/_static/js/custom.js b/docs/_static/js/custom.js index 7646bcb2b5..d6fa636043 100644 --- a/docs/_static/js/custom.js +++ b/docs/_static/js/custom.js @@ -2,12 +2,14 @@ function getUniqueTags() { let tagSet = new Set(); - $(".card-container").each(function() { - let tags = $(this).attr('data-tags').split(",") - .map(tag => tag.trim()) // Get rid of whitespace - .filter(tag => tag !== ""); // Make sure there are no empty tags + $(".card-container").each(function () { + let tags = $(this) + .attr("data-tags") + .split(",") + .map((tag) => tag.trim()) // Get rid of whitespace + .filter((tag) => tag !== ""); // Make sure there are no empty tags - tags.forEach(tag => tagSet.add(tag)); // Add tag to the set + tags.forEach((tag) => tagSet.add(tag)); // Add tag to the set }); let uniqueTags = Array.from(tagSet); @@ -19,14 +21,14 @@ function getUniqueTags() { function getUniqueGroups() { let groupSet = new Set(); - $(".card-container").each(function() { - let group = $(this).attr('data-group') + $(".card-container").each(function () { + let group = $(this).attr("data-group"); if (group && group.trim() !== "") { groupSet.add(group.trim()); } - groupSet.add(group) + groupSet.add(group); }); let uniqueGroups = Array.from(groupSet); @@ -37,10 +39,15 @@ function getUniqueGroups() { function createMenu() { let tags = getUniqueTags(); - tags.forEach(item => { + tags.forEach((item) => { let displayName = item.replace(/-/g, " "); // Replace underscores with spaces - $(".filter-menu") - .append("
" + displayName + "
") + $(".filter-menu").append( + "
" + + displayName + + "
", + ); }); } @@ -48,13 +55,14 @@ function createMenu() { function populateTabs() { let groups = getUniqueGroups(); - groups.forEach(item => { - $(".tab-menu") - .append("
" + item + "
") + groups.forEach((item) => { + $(".tab-menu").append( + "
" + item + "
", + ); }); } -$(document).ready(function() { +$(document).ready(function () { createMenu(); populateTabs(); }); @@ -96,11 +104,14 @@ $(document).on("click", ".filter-btn", function () { function filterCards() { $(".card-container").each(function () { let tagsData = $(this).attr("data-tags") || ""; - let cardTags = tagsData.split(",").map(tag => tag.trim()); + let cardTags = tagsData.split(",").map((tag) => tag.trim()); let groupName = $(this).attr("data-group"); - let matchesTags = selectedTagSet.size === 0 || [...selectedTagSet].every(tag => cardTags.includes(tag)); - let matchesGroup = selectedGroup === "all" || groupName === selectedGroup; + let matchesTags = + selectedTagSet.size === 0 || + [...selectedTagSet].every((tag) => cardTags.includes(tag)); + let matchesGroup = + selectedGroup === "all" || groupName === selectedGroup; $(this).toggleClass("hidden", !(matchesTags && matchesGroup)); @@ -115,7 +126,7 @@ function filterCards() { } // Add similar filtering functionality to the model group tabs (but only single select) -let selectedGroup = "all" +let selectedGroup = "all"; // Handle tab selection and filtering $(document).on("click", ".tab", function () { @@ -124,7 +135,7 @@ $(document).on("click", ".tab", function () { if (group !== selectedGroup) { $(".tab").removeClass("tab-selected"); // deselect current tab $(this).addClass("tab-selected"); - selectedGroup = group + selectedGroup = group; } filterCards(); // Trigger filtering immediately diff --git a/pyproject.toml b/pyproject.toml index 0115d61c3c..ce7c915453 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,241 +1,233 @@ [build-system] build-backend = "hatchling.build" -requires = ["hatchling"] +requires = [ "hatchling" ] [project] name = "scvi-tools" version = "1.4.1" description = "Deep probabilistic analysis of single-cell omics data." readme = "README.md" -requires-python = ">=3.11" -license = {file = "LICENSE"} -authors = [ - {name = "The scvi-tools development team"}, -] +license = { file = "LICENSE" } maintainers = [ - {name = "The scvi-tools development team", email = "ori.kronfeld@weizmann.ac.il"}, + { name = "The scvi-tools development team", email = "ori.kronfeld@weizmann.ac.il" }, ] -urls.Documentation = "https://scvi-tools.org" -urls.Source = "https://github.com/scverse/scvi-tools" -urls.Home-page = "https://scvi-tools.org" +authors = [ + { name = "The scvi-tools development team" }, +] +requires-python = ">=3.11" classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Science/Research", "Natural Language :: English", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Scientific/Engineering :: Bio-Informatics", ] dependencies = [ - "anndata>=0.11", - "docrep>=0.3.2", - "lightning>=2.0", - "ml-collections", - "mudata", - "numba>=0.60.0", - "numpy", - "pandas", - "pyro-ppl", - "rich", - "scanpy[skmisc]>=1.10", - "scikit-learn", - "scipy", - "sparse>=0.14.0", - "tensorboard", - "torch", - "torchmetrics", - "tqdm", - "xarray", + "anndata>=0.11", + "docrep>=0.3.2", + "lightning>=2", + "ml-collections", + "mudata", + "numba>=0.60", + "numpy", + "pandas", + "pyro-ppl", + "rich", + "scanpy[skmisc]>=1.10", + "scikit-learn", + "scipy", + "sparse>=0.14", + "tensorboard", + "torch", + "torchmetrics", + "tqdm", + "xarray", ] -[project.optional-dependencies] -tests = ["pytest", "pytest-pretty", "coverage", "scvi-tools[optional]"] -editing = ["jupyter", "pre-commit"] -dev = ["scvi-tools[editing,tests]"] -test = ["scvi-tools[tests]"] -cuda = ["torchvision", "torchaudio", "jax[cuda12]"] -metal = ["torchvision", "torchaudio", "jax-metal"] - -docs = [ - "docutils>=0.8,!=0.18.*,!=0.19.*", # see https://github.com/scverse/cookiecutter-scverse/pull/205 - "sphinx", - "ipython", - "sphinx-book-theme>=1.0.1", - "sphinx_copybutton", - "sphinx-design", - "sphinxext-opengraph", - "sphinx-hoverxref", - "sphinxcontrib-bibtex", - "myst-parser", - "myst-nb", - "sphinx-autodoc-typehints", -] -docsbuild = ["scvi-tools[docs,autotune,hub,jax]"] - +optional-dependencies.all = [ "scvi-tools[dev,docs,tutorials]" ] # scvi.autotune -autotune = ["hyperopt>=0.2", "ray[tune]", "scib-metrics", "muon"] -# scvi.hub dependencies -hub = ["huggingface_hub", "dvc[s3]", "boto3"] -# scvi.data.add_dna_sequence -regseq = ["biopython>=1.81", "genomepy"] +optional-dependencies.autotune = [ "hyperopt>=0.2", "muon", "ray[tune]", "scib-metrics" ] +optional-dependencies.cuda = [ "jax[cuda12]", "torchaudio", "torchvision" ] +# for custom dataloders +optional-dependencies.dataloaders = [ + "cellxgene-census", + "lamindb>=1.12.1", + "tiledbsoma", + "tiledbsoma-ml", + "torchdata", +] +optional-dependencies.dev = [ "scvi-tools[editing,tests]" ] +optional-dependencies.docs = [ + "docutils>=0.8,!=0.18.*,!=0.19.*", # see https://github.com/scverse/cookiecutter-scverse/pull/205 + "ipython", + "myst-nb", + "myst-parser", + "sphinx", + "sphinx-autodoc-typehints", + "sphinx-book-theme>=1.0.1", + "sphinx-copybutton", + "sphinx-design", + "sphinx-hoverxref", + "sphinxcontrib-bibtex", + "sphinxext-opengraph", +] +optional-dependencies.docsbuild = [ "scvi-tools[autotune,docs,hub,jax]" ] +optional-dependencies.editing = [ "jupyter", "pre-commit" ] # for files sharing or handling -file_sharing = ["pooch","gdown","readfcs","fcswrite"] -# for parallelization engine -parallel = ["dask[array]", "zarr"] +optional-dependencies.file_sharing = [ "fcswrite", "gdown", "pooch", "readfcs" ] +# scvi.hub dependencies +optional-dependencies.hub = [ "boto3", "dvc[s3]", "huggingface-hub" ] # for models interpretability -interpretability = ["captum", "shap", "decoupler"] +optional-dependencies.interpretability = [ "captum", "decoupler", "shap" ] # for jax support -jax = ["jax", "jaxlib", "optax", "numpyro", "flax"] -# for custom dataloders -dataloaders = ["lamindb>=1.12.1", "cellxgene-census", "tiledbsoma", "tiledbsoma_ml", "torchdata"] +optional-dependencies.jax = [ "flax", "jax", "jaxlib", "numpyro", "optax" ] +optional-dependencies.metal = [ "jax-metal", "torchaudio", "torchvision" ] # for mlflow -mlflow = ["mlflow","psutil","GPUtil"] - -optional = [ - "scvi-tools[autotune,mlflow,hub,jax,file_sharing,regseq,parallel,interpretability]", - "igraph","leidenalg","pynndescent", +optional-dependencies.mlflow = [ "gputil", "mlflow", "psutil" ] +optional-dependencies.optional = [ + "igraph", + "leidenalg", + "pynndescent", + "scvi-tools[autotune,file_sharing,hub,interpretability,jax,mlflow,parallel,regseq]", ] -tutorials = [ - "biomart", - "cell2location", - "dataloaders", - "jupyter", - "seaborn", - "matplotlib", - "plotnine", - "scrublet", - "scvi-tools[optional]", - "squidpy>=1.6.0", - "umap-learn>=0.5.0", +# for parallelization engine +optional-dependencies.parallel = [ "dask[array]", "zarr" ] +# scvi.data.add_dna_sequence +optional-dependencies.regseq = [ "biopython>=1.81", "genomepy" ] +optional-dependencies.test = [ "scvi-tools[tests]" ] +optional-dependencies.tests = [ "coverage", "pytest", "pytest-pretty", "scvi-tools[optional]" ] +optional-dependencies.tutorials = [ + "biomart", + "cell2location", + "dataloaders", + "jupyter", + "matplotlib", + "plotnine", + "scrublet", + "scvi-tools[optional]", + "seaborn", + "squidpy>=1.6", + "umap-learn>=0.5", ] - -all = ["scvi-tools[dev,docs,tutorials]"] +urls.Documentation = "https://scvi-tools.org" +urls.Home-page = "https://scvi-tools.org" +urls.Source = "https://github.com/scverse/scvi-tools" [tool.hatch.build.targets.wheel] -packages = ['src/scvi'] - -[tool.coverage.run] -source = ["scvi"] -omit = [ - "**/test_*.py", -] - -[tool.pytest.ini_options] -testpaths = ["tests"] -xfail_strict = true -markers = [ - "internet: mark tests that requires internet access", - "optional: mark optional tests, usually take more time", - "private: mark tests that uses private keys, like HF", - "multigpu: mark tests that are used to check multi GPU performance", - "autotune: mark tests that are used to check ray autotune capabilities", - "custom dataloaders: mark tests that are used to check different custom data loaders", -] +packages = [ 'src/scvi' ] [tool.ruff] -src = ["src"] -line-length = 99 -indent-width = 4 target-version = "py312" +line-length = 99 +indent-width = 4 +src = [ "src" ] # Exclude a variety of commonly ignored directories. exclude = [ - ".bzr", - ".direnv", - ".eggs", - ".git", - ".git-rewrite", - ".hg", - ".mypy_cache", - ".nox", - ".pants.d", - ".pytype", - ".ruff_cache", - ".svn", - ".tox", - ".venv", - "__pypackages__", - "_build", - "buck-out", - "build", - "dist", - "node_modules", - "venv", + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".mypy_cache", + ".nox", + ".pants.d", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "venv", ] -[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 - "PT", # pytest style - "NPY", # numpy formatting - "TCH", # flake8-type-checking - "FA", # flake8-future-annotations +# Like Black, indent with spaces, rather than tabs. +format.indent-style = "space" +# Like Black, use double quotes for strings. +format.quote-style = "double" +# Like Black, automatically detect the appropriate line ending. +format.line-ending = "auto" +# Like Black, respect magic trailing commas. +format.skip-magic-trailing-comma = false +format.docstring-code-format = true +lint.select = [ + "B", # flake8-bugbear + "BLE", # flake8-blind-except + "C4", # flake8-comprehensions + "D", # pydocstyle + "E", # Error detected by Pycodestyle + "F", # Errors detected by Pyflakes + "FA", # flake8-future-annotations + "I", # isort + "NPY", # numpy formatting + "PT", # pytest style + "RUF100", # Report unused noqa directives + "TCH", # flake8-type-checking + "TID", # flake8-tidy-imports + "UP", # pyupgrade + "W", # Warning detected by Pycodestyle ] -ignore = [ - # allow I, O, l as variable names -> I is the identity matrix - "E741", - # Missing docstring in the public package - "D104", - # Missing docstring in the public module - "D100", - # Missing docstring in __init__ - "D107", - # Errors from function calls in argument defaults. These are fine when the result is immutable. - "B008", - # the first line should end with a period [Bug: doesn't work with single-line docstrings] - "D400", - # The first line should be in an imperative mood; try rephrasing - "D401", - # We want docstrings to start immediately after the opening triple quote - "D213", - # Raising ValueError is enough in tests. - "PT011", - # We support np.random functions. - "NPY002" +lint.ignore = [ + # Errors from function calls in argument defaults. These are fine when the result is immutable. + "B008", + # Missing docstring in the public module + "D100", + # Missing docstring in the public package + "D104", + # Missing docstring in __init__ + "D107", + # We want docstrings to start immediately after the opening triple quote + "D213", + # the first line should end with a period [Bug: doesn't work with single-line docstrings] + "D400", + # The first line should be in an imperative mood; try rephrasing + "D401", + # allow I, O, l as variable names -> I is the identity matrix + "E741", + # We support np.random functions. + "NPY002", + # Raising ValueError is enough in tests. + "PT011", ] +lint.per-file-ignores."*/__init__.py" = [ "F401" ] +lint.per-file-ignores."docs/*" = [ "BLE001", "I" ] +lint.per-file-ignores."src/scvi/__init__.py" = [ "I" ] +lint.per-file-ignores."tests/*" = [ "D" ] +lint.flake8-type-checking.exempt-modules = [ ] +lint.flake8-type-checking.strict = true +lint.pydocstyle.convention = "numpy" -[tool.ruff.lint.pydocstyle] -convention = "numpy" - -[tool.ruff.lint.per-file-ignores] -"docs/*" = ["I", "BLE001"] -"tests/*" = ["D"] -"*/__init__.py" = ["F401"] -"src/scvi/__init__.py" = ["I"] - -[tool.ruff.format] -docstring-code-format = true -# Like Black, use double quotes for strings. -quote-style = "double" - -# Like Black, indent with spaces, rather than tabs. -indent-style = "space" - -# Like Black, respect magic trailing commas. -skip-magic-trailing-comma = false +[tool.pytest.ini_options] +testpaths = [ "tests" ] +xfail_strict = true +markers = [ + "internet: mark tests that requires internet access", + "optional: mark optional tests, usually take more time", + "private: mark tests that uses private keys, like HF", + "multigpu: mark tests that are used to check multi GPU performance", + "autotune: mark tests that are used to check ray autotune capabilities", + "custom dataloaders: mark tests that are used to check different custom data loaders", +] -# Like Black, automatically detect the appropriate line ending. -line-ending = "auto" +[tool.coverage.run] +source = [ "scvi" ] +omit = [ + "**/test_*.py", +] [tool.jupytext] formats = "ipynb,md" - -[tool.ruff.lint.flake8-type-checking] -exempt-modules = [] -strict = true