diff --git a/.coveragerc-core b/.coveragerc-core index 00f5e75..b36c0af 100644 --- a/.coveragerc-core +++ b/.coveragerc-core @@ -3,9 +3,7 @@ branch = True source = biofilter omit = */tests/* - */biofilter/alembic/* */biofilter/modules/etl/dtps/* - */biofilter/modules/report/reports_bkp/* [report] show_missing = True diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 57d2455..440983c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,13 +9,20 @@ jobs: test: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.10", "3.11", "3.12", "3.13"] + + name: test (py${{ matrix.python-version }}) + steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: ${{ matrix.python-version }} - name: Install Poetry run: | diff --git a/README.md b/README.md index 580d723..a42ebcc 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ A **bundle**: a dated directory of Parquet files with a `manifest.json` describing them. ``` -20260914/ +bundle/ ├── manifest.json the catalogue: every file, its rows, its size ├── bundle_plan.json which sources went in, at which versions ├── build_record.json what each build run did, in order @@ -87,13 +87,13 @@ for the disk, time and memory it takes. Biofilter has two halves, separated by the bundle rather than by an API. -| | Builds a bundle | Reads a bundle | -|---|---|---| -| Who | whoever maintains the data | everyone else | -| How often | a few times a year | constantly | -| Engine | SQLAlchemy models, staging SQLite | DuckDB, in process | -| Can write | yes — it is the only code that can | no, structurally | -| Commands | `bundle`, `etl`, `db` | `report` | +| | Builds a bundle | Reads a bundle | +| --------- | ---------------------------------- | ------------------ | +| Who | whoever maintains the data | everyone else | +| How often | a few times a year | constantly | +| Engine | SQLAlchemy models, staging SQLite | DuckDB, in process | +| Can write | yes — it is the only code that can | no, structurally | +| Commands | `bundle`, `etl`, `db` | `report` | The build runs in **two branches**. The core — genes, proteins, pathways, diseases, GO, chemicals and their relationships — is about 7 million rows and @@ -103,7 +103,7 @@ no foreign keys, so there is nothing to resolve and nothing to stage: it writes its final Parquet directly. 📖 [System Overview](https://biofilter.readthedocs.io/en/latest/technical/system_overview.html) - · [The Read Path](https://biofilter.readthedocs.io/en/latest/technical/read_path.html) +· [The Read Path](https://biofilter.readthedocs.io/en/latest/technical/read_path.html) --- @@ -112,14 +112,14 @@ its final Parquet directly. A report takes a list of things you have and returns a table. Seventeen of them, in six families: -| Family | What they answer | -|---|---| -| `resolve_*` | Which of my names does Biofilter recognise? | -| `annotate_*` | What is known about these genes, variants, proteins, pathways, diseases, GO terms? | -| `expand_*` | What is connected to them — neighbours, relationships, variants in a gene, regulatory evidence? | -| `pair_*` | Which of these genes or variants share biology, and on what support? | -| `aggregate_*` | Roll a cohort's variants up to a summary. | -| `platform_*` | What does this bundle contain, and how was it built? | +| Family | What they answer | +| ------------- | ----------------------------------------------------------------------------------------------- | +| `resolve_*` | Which of my names does Biofilter recognise? | +| `annotate_*` | What is known about these genes, variants, proteins, pathways, diseases, GO terms? | +| `expand_*` | What is connected to them — neighbours, relationships, variants in a gene, regulatory evidence? | +| `pair_*` | Which of these genes or variants share biology, and on what support? | +| `aggregate_*` | Roll a cohort's variants up to a summary. | +| `platform_*` | What does this bundle contain, and how was it built? | ```bash biofilter report list --verbose @@ -133,14 +133,14 @@ biofilter report explain --report-name expand_gene_to_variant One per report, runnable against a bundle: -| | | -|---|---| -| [`reports__101`](notebooks/templates/reports__101.ipynb) | **start here** — how reports work | -| [`reports__resolve_entity`](notebooks/templates/reports__resolve_entity.ipynb) | start here for a new input list | -| [`reports__annotate_gene`](notebooks/templates/reports__annotate_gene.ipynb) | annotating a gene list | -| [`reports__expand_gene_to_variant`](notebooks/templates/reports__expand_gene_to_variant.ipynb) | variants in a gene, filtered by predicted damage | -| [`reports__aggregate_cohort_variants`](notebooks/templates/reports__aggregate_cohort_variants.ipynb) | a cohort, matched and binned | -| [`reports__TEMPLATE`](notebooks/templates/reports__TEMPLATE.ipynb) | copy this to write a new report | +| | | +| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------ | +| [`reports__101`](notebooks/templates/reports__101.ipynb) | **start here** — how reports work | +| [`reports__resolve_entity`](notebooks/templates/reports__resolve_entity.ipynb) | start here for a new input list | +| [`reports__annotate_gene`](notebooks/templates/reports__annotate_gene.ipynb) | annotating a gene list | +| [`reports__expand_gene_to_variant`](notebooks/templates/reports__expand_gene_to_variant.ipynb) | variants in a gene, filtered by predicted damage | +| [`reports__aggregate_cohort_variants`](notebooks/templates/reports__aggregate_cohort_variants.ipynb) | a cohort, matched and binned | +| [`reports__TEMPLATE`](notebooks/templates/reports__TEMPLATE.ipynb) | copy this to write a new report | All of them: [`notebooks/templates/`](notebooks/templates/) @@ -203,7 +203,7 @@ apptainer run \ `--output` writes inside the container, so it has to point at `/workspace`. 📖 [docker/README.md](docker/README.md) · Penn LPC users: -[lpc__quickstart.md](notebooks/lpc__quickstart.md) +[lpc\_\_quickstart.md](notebooks/lpc__quickstart.md) --- diff --git a/assistent/gpt_builder/consolidated/bf4_agents.md b/assistent/gpt_builder/consolidated/bf4_agents.md index ce5c5f5..b16f05e 100644 --- a/assistent/gpt_builder/consolidated/bf4_agents.md +++ b/assistent/gpt_builder/consolidated/bf4_agents.md @@ -170,7 +170,7 @@ one; the wrapper is what carries `.provenance`, `.num_rows` and `.columns`. ## 8) The reports -Sixteen, in six families. `biofilter report list --verbose` is always the +Seventeen, in six families. `biofilter report list --verbose` is always the authority for what your install has. | Family | Reports | @@ -178,7 +178,7 @@ authority for what your install has. | `annotate_*` | `annotate_gene`, `annotate_variant`, `annotate_protein`, `annotate_disease`, `annotate_pathway`, `annotate_go` | | `expand_*` | `expand_gene_to_variant`, `expand_variant_regulatory`, `expand_entity_neighborhood`, `expand_entity_relationship` | | `resolve_*` | `resolve_entity` | -| `pair_*` | `pair_variants` | +| `pair_*` | `pair_genes`, `pair_variants` | | `aggregate_*` | `aggregate_cohort_variants` | | `platform_*` | `platform_data_statistics`, `platform_etl_status`, `platform_etl_packages` | @@ -191,6 +191,7 @@ By the question instead: | rsIDs or positions | `annotate_variant` | | genes, want the variants in them | `expand_gene_to_variant` | | variants, want what they regulate | `expand_variant_regulatory` | +| genes, want pairs that share biology | `pair_genes` | | variants, want candidate pairs | `pair_variants` | | a cohort | `aggregate_cohort_variants` | | a bundle you do not know | `platform_data_statistics` | @@ -353,7 +354,7 @@ docker run --rm \ -v /path/to/bundles/20260914:/bundle:ro \ -v "$PWD/out:/workspace" \ --user "$(id -u):$(id -g)" \ - ricoandre/biofilter:latest \ + ghcr.io/ritchielab/biofilter:latest \ report run --report-name annotate_gene --input TP53 --output /workspace/genes.csv ``` @@ -361,7 +362,7 @@ Under Apptainer, `--bind` replaces `-v` and output ownership takes care of itself: ```bash -apptainer pull bf4.sif docker://ghcr.io/ritchielab/biofilter-hpc:latest +apptainer pull bf4.sif docker://ghcr.io/ritchielab/biofilter:latest ``` ### 3.3 Option C - Source diff --git a/assistent/gpt_builder/consolidated/bf4_docs.md b/assistent/gpt_builder/consolidated/bf4_docs.md index ac9b680..facd99f 100644 --- a/assistent/gpt_builder/consolidated/bf4_docs.md +++ b/assistent/gpt_builder/consolidated/bf4_docs.md @@ -475,10 +475,10 @@ python -c "from biofilter import Biofilter; print('OK')" ## Docker -One image, published to two registries. Pull it rather than building: +One image, for Docker and Apptainer alike. Pull it rather than building: ```bash -docker pull ricoandre/biofilter:latest +docker pull ghcr.io/ritchielab/biofilter:latest ``` The image carries no data. It expects two mounts: @@ -496,7 +496,7 @@ docker run --rm \ -v /shared/bundles/20260914:/bundle:ro \ -v "$(pwd)/out:/workspace" \ --user "$(id -u):$(id -g)" \ - ricoandre/biofilter:latest \ + ghcr.io/ritchielab/biofilter:latest \ report run --report-name annotate_gene --input TP53 --output /workspace/genes.csv ``` @@ -515,7 +515,7 @@ docker run --rm -it \ -v /shared/bundles/20260914:/bundle:ro \ -v "$(pwd):/workspace" \ --entrypoint /bin/bash \ - ricoandre/biofilter:latest + ghcr.io/ritchielab/biofilter:latest ``` To build it yourself from a checkout: @@ -530,7 +530,7 @@ The same image. `--bind` replaces `-v`, and output ownership takes care of itself because the container runs as you: ```bash -apptainer pull bf4.sif docker://ghcr.io/ritchielab/biofilter-hpc:latest +apptainer pull bf4.sif docker://ghcr.io/ritchielab/biofilter:latest apptainer run \ --bind /shared/bundles/20260914:/bundle:ro \ @@ -539,8 +539,8 @@ apptainer run \ report run --report-name annotate_gene --input APOE --output /workspace/apoe.csv ``` -The GHCR name `biofilter-hpc` predates the merge of what used to be two -images; it is the same image as Docker Hub's. +It is the same image either way — what changes is `--bind` in place of +`-v`, and that Apptainer runs the container as you. ## From source @@ -2323,7 +2323,7 @@ to that path, or the file leaves with the container: docker run --rm \ -v /shared/bundles/20260914:/bundle:ro \ -v "$(pwd)/out:/workspace" \ - ricoandre/biofilter:latest \ + ghcr.io/ritchielab/biofilter:latest \ report run --report-name platform_etl_status --output /workspace/etl_status.csv ``` diff --git a/assistent/gpt_builder/consolidated/bf4_faq.md b/assistent/gpt_builder/consolidated/bf4_faq.md index a203d56..26381a0 100644 --- a/assistent/gpt_builder/consolidated/bf4_faq.md +++ b/assistent/gpt_builder/consolidated/bf4_faq.md @@ -36,7 +36,7 @@ provenance inside the file. biofilter report list --verbose ``` -Sixteen, in six families. By the shape of the question: +Seventeen, in six families. By the shape of the question: | You have | Report | |---|---| @@ -53,6 +53,7 @@ Sixteen, in six families. By the shape of the question: | a gene-to-anything list of your own, want the pairs it implies | `pair_genes` | | a cohort | `aggregate_cohort_variants` | | a bundle you do not know | `platform_data_statistics` | +| to know what ran to build it | `platform_etl_status`, and `platform_etl_packages` for the raw record | ### A2b) `pair_variants` or `pair_genes`? @@ -399,7 +400,7 @@ docker run --rm \ -v /path/to/bundles/20260914:/bundle:ro \ -v "$PWD/out:/workspace" \ --user "$(id -u):$(id -g)" \ - ricoandre/biofilter:latest \ + ghcr.io/ritchielab/biofilter:latest \ report run --report-name annotate_gene --input TP53 --output /workspace/genes.csv ``` @@ -419,7 +420,7 @@ container runs as you. ### D4) Apptainer / Singularity ```bash -apptainer pull bf4.sif docker://ghcr.io/ritchielab/biofilter-hpc:latest +apptainer pull bf4.sif docker://ghcr.io/ritchielab/biofilter:latest apptainer run \ --bind /path/to/bundles/20260914:/bundle:ro \ @@ -428,7 +429,7 @@ apptainer run \ report run --report-name annotate_gene --input APOE --output /workspace/apoe.csv ``` -Same image as Docker Hub; the `-hpc` name is historical. +The same image as the Docker example above; only the mount flag differs. --- diff --git a/assistent/gpt_builder/consolidated/bf4_notebooks.md b/assistent/gpt_builder/consolidated/bf4_notebooks.md index 4871f09..2af7c11 100644 --- a/assistent/gpt_builder/consolidated/bf4_notebooks.md +++ b/assistent/gpt_builder/consolidated/bf4_notebooks.md @@ -185,7 +185,7 @@ missing source or a version mismatch are printed, not raised. If you prefer a container to the module: ```bash -apptainer pull bf4.sif docker://ghcr.io/ritchielab/biofilter-hpc:latest +apptainer pull bf4.sif docker://ghcr.io/ritchielab/biofilter:latest apptainer run \ --bind /project/hall_shared/datasets/biofilter/:/bundle:ro \ @@ -1139,10 +1139,10 @@ from pathlib import Path from biofilter import Biofilter -BUNDLE = "/Users/andrerico/Works/Sys/biofilter_430/biofilter_data/bundles/20260914" # change this to the path of your biofilter_data bundle +BUNDLE = None # set a path to override; None reads [database] bundle from .biofilter.toml REPORT = "annotate_gene" -bf = Biofilter(bundle=BUNDLE, debug_mode=False) +bf = Biofilter(bundle=BUNDLE, debug_mode=False) if BUNDLE else Biofilter(debug_mode=False) # Results land here whatever directory the kernel was started in — VS Code # and Jupyter disagree about that, and a bare filename ends up wherever diff --git a/notebooks/templates/reports__annotate_gene.ipynb b/notebooks/templates/reports__annotate_gene.ipynb index 2bc3e5e..e1b1f9f 100644 --- a/notebooks/templates/reports__annotate_gene.ipynb +++ b/notebooks/templates/reports__annotate_gene.ipynb @@ -63,10 +63,10 @@ "\n", "from biofilter import Biofilter\n", "\n", - "BUNDLE = \"/Users/andrerico/Works/Sys/biofilter_430/biofilter_data/bundles/20260914\" # change this to the path of your biofilter_data bundle\n", + "BUNDLE = None # set a path to override; None reads [database] bundle from .biofilter.toml\n", "REPORT = \"annotate_gene\"\n", "\n", - "bf = Biofilter(bundle=BUNDLE, debug_mode=False)\n", + "bf = Biofilter(bundle=BUNDLE, debug_mode=False) if BUNDLE else Biofilter(debug_mode=False)\n", "\n", "# Results land here whatever directory the kernel was started in \u2014 VS Code\n", "# and Jupyter disagree about that, and a bare filename ends up wherever\n", diff --git a/poetry.lock b/poetry.lock index f6fb324..5541c95 100644 --- a/poetry.lock +++ b/poetry.lock @@ -51,6 +51,17 @@ files = [ astroid = ["astroid (>=2,<5)"] test = ["astroid (>=2,<5)", "pytest (<9.0)", "pytest-cov", "pytest-xdist"] +[[package]] +name = "attrs" +version = "26.1.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.9" +files = [ + {file = "attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309"}, + {file = "attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32"}, +] + [[package]] name = "babel" version = "2.18.0" @@ -133,6 +144,24 @@ d = ["aiohttp (>=3.10)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "bleach" +version = "6.4.0" +description = "An easy safelist-based HTML-sanitizing tool." +optional = false +python-versions = ">=3.10" +files = [ + {file = "bleach-6.4.0-py3-none-any.whl", hash = "sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081"}, + {file = "bleach-6.4.0.tar.gz", hash = "sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452"}, +] + +[package.dependencies] +tinycss2 = {version = ">=1.1.0", optional = true, markers = "extra == \"css\""} +webencodings = "*" + +[package.extras] +css = ["tinycss2 (>=1.1.0)"] + [[package]] name = "cachetools" version = "7.0.5" @@ -267,42 +296,6 @@ files = [ [package.dependencies] pycparser = {version = "*", markers = "implementation_name != \"PyPy\""} -[[package]] -name = "chardet" -version = "7.2.0" -description = "Universal character encoding detector" -optional = false -python-versions = ">=3.10" -files = [ - {file = "chardet-7.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:556d6f81bd4131f7b2d4aa535f3061cd381853d4db7ea5c0a15dd5f1a3f39b66"}, - {file = "chardet-7.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8b4c05733a517a2f53beb8d740cd6c5a1f4387c3dcbeb78380b848498fee8a6"}, - {file = "chardet-7.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce80e8b62bb88135d36b9d4b95a6d9624ea862090bfd0228f9fee4a6aafaffc8"}, - {file = "chardet-7.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8190584663b8c051db28be5174d1c5774d7b7a5112e47152c02fd50bdf6405ad"}, - {file = "chardet-7.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:dfcf826f413be2d94605ecb2089f29e189cf6ed9baa30d9b2c8868da2e142398"}, - {file = "chardet-7.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8685b331c4896e9135bd748387f713dd53c019475ae1b8238b8f59be1668acd"}, - {file = "chardet-7.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa14cc0e7d2142dd313524b3a339e15cbd8b7a8a7e11a560686e0b6f58038ec9"}, - {file = "chardet-7.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c51a3d8aa3c162be0495404b39bb1c137b44a634c1f46e2909e2c6a60349c00"}, - {file = "chardet-7.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:347ed77bb5eed8929fae7482671690a15c731d66808f1ff0ce7d22224ca7ec79"}, - {file = "chardet-7.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:d298762002a6b6e81dbcc81ade9e0882e579e968f4801daf4d8ffd6a31b99552"}, - {file = "chardet-7.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c4604344380a6f9b982c28855c1edfd23a45a2c9142b9a34bc0c08986049f398"}, - {file = "chardet-7.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:195c54d8f04a7a9c321cb7cebececa35b1c818c7aa7c195086bae10fcbb3391f"}, - {file = "chardet-7.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ddd03a67fca8c91287f8718dfbe3f94c2c1aa1fd3a82433b693f5b868dedf319"}, - {file = "chardet-7.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f6af0fa005b9488c8fbf8fec2ad7023531970320901d6334c50844ccca9b117"}, - {file = "chardet-7.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:e8853c71ea1261bcc1b8f8b171acb7c272a5cfd06b57729c460241ee38705049"}, - {file = "chardet-7.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6cdbe9404534cda0d28f172e91fa50db7655ae6262d093b0337a5aa47a47a5f6"}, - {file = "chardet-7.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:427d091994456cc16dbd1e20ae73fee068b9a31f3c90b75072f722d5dbbf156f"}, - {file = "chardet-7.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cad2cd094dfb14cfcb86b0a77568d23375b0005ea0144a726910df6f5c8a46b8"}, - {file = "chardet-7.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23e6acd1a58050d7c2aeecca700c0cf27b5ec4f6153a82c3b51c31b94c6ebfad"}, - {file = "chardet-7.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:dc5d034faa5b4a2a3af54e24881b2caef9b41fea00a4dddccf97a1e8ec51a213"}, - {file = "chardet-7.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:719c572c4751c201f42134bd2aa0826928ed5113d29dfa482338c1a89bb925fa"}, - {file = "chardet-7.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:13a94d2c0dace263b8dcb61593c165d5749d60e2e2314231938eb87755c9de9f"}, - {file = "chardet-7.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1f081a0f3fce8e1c8f5d6b3691a4960aacc33f213f77ef8b89a6b5f0af4cadf"}, - {file = "chardet-7.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b56152a17d19249388ae99a85a31c35bb8d5b421b90581226de34b2b316be806"}, - {file = "chardet-7.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:7077dc2435b95163db4206aa71ebc329da5bcddb8bfce69440ff8ecf637400bf"}, - {file = "chardet-7.2.0-py3-none-any.whl", hash = "sha256:f8ea866b9fbd8df5f19032d765a4d81dcbf6194a3c7388b44d378d02c9784170"}, - {file = "chardet-7.2.0.tar.gz", hash = "sha256:4ef7292b1342ea805c32cce58a45db204f59d080ed311d6cdaa7ca747fcc0cd5"}, -] - [[package]] name = "charset-normalizer" version = "3.4.6" @@ -824,6 +817,17 @@ files = [ {file = "decorator-5.3.1.tar.gz", hash = "sha256:4cbcdd55a6efadb9dbea26b858f4fb3264567b52d69ca0d25b721b553f60ea82"}, ] +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + [[package]] name = "dill" version = "0.4.1" @@ -988,6 +992,20 @@ files = [ [package.extras] tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] +[[package]] +name = "fastjsonschema" +version = "2.22.2" +description = "Fastest Python implementation of JSON schema" +optional = false +python-versions = ">=3.10" +files = [ + {file = "fastjsonschema-2.22.2-py3-none-any.whl", hash = "sha256:0fb3915616adac85ccfdd737d26be1089845d2019819505b42d39888458f74d4"}, + {file = "fastjsonschema-2.22.2.tar.gz", hash = "sha256:72064e12356a7d6ef02165be2946b9abadbdf238536e07eb587e3dbaa33099cf"}, +] + +[package.extras] +devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] + [[package]] name = "filelock" version = "3.25.2" @@ -1308,6 +1326,41 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "jsonschema" +version = "4.26.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.10" +files = [ + {file = "jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce"}, + {file = "jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.25.0" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "rfc3987-syntax (>=1.1.0)", "uri-template", "webcolors (>=24.6.0)"] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.9" +files = [ + {file = "jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe"}, + {file = "jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + [[package]] name = "jupyter-client" version = "8.10.0" @@ -1351,6 +1404,17 @@ traitlets = ">=5.3" docs = ["intersphinx-registry", "myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-spelling", "traitlets"] test = ["ipykernel", "pre-commit", "pytest (<9)", "pytest-cov", "pytest-timeout"] +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +description = "Pygments theme using JupyterLab CSS variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780"}, + {file = "jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d"}, +] + [[package]] name = "kiwisolver" version = "1.5.0" @@ -1910,6 +1974,20 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "mistune" +version = "3.3.4" +description = "A sane and fast Markdown parser with useful plugins and renderers" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mistune-3.3.4-py3-none-any.whl", hash = "sha256:ee015381e955e370962968befe1d729ab60fafb6a715ac6751763fbce38c8d4a"}, + {file = "mistune-3.3.4.tar.gz", hash = "sha256:58b5c96d6fcb61190dfe5fae498d2b2065f99cf61e9649418fd54cf1ada86dfe"}, +] + +[package.dependencies] +typing-extensions = {version = "*", markers = "python_version < \"3.11\""} + [[package]] name = "mypy-extensions" version = "1.1.0" @@ -1947,6 +2025,85 @@ rtd = ["ipython", "sphinx (>=7)", "sphinx-autodoc2 (>=0.5.0,<0.6.0)", "sphinx-bo testing = ["beautifulsoup4", "coverage[toml]", "defusedxml", "pygments (<2.19)", "pytest (>=8,<9)", "pytest-cov", "pytest-param-files (>=0.6.0,<0.7.0)", "pytest-regressions", "sphinx-pytest"] testing-docutils = ["pygments", "pytest (>=8,<9)", "pytest-param-files (>=0.6.0,<0.7.0)"] +[[package]] +name = "nbclient" +version = "0.11.0" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +optional = false +python-versions = ">=3.10.0" +files = [ + {file = "nbclient-0.11.0-py3-none-any.whl", hash = "sha256:ef7fa0d59d6e1d41103933d8a445a18d5de860ca6b613b87b8574accdb3c2895"}, + {file = "nbclient-0.11.0.tar.gz", hash = "sha256:04a134a5b087f2c5887f228aca155db50169b8cd9334dee6942c8e927e56081a"}, +] + +[package.dependencies] +jupyter-client = ">=7.0.0" +jupyter-core = ">=5.4.0" +nbformat = ">=5.2.0" +traitlets = ">=5.13" + +[package.extras] +dev = ["pre-commit"] +docs = ["autodoc-traits", "flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "mock", "moto", "myst-parser", "nbconvert (>=7.1.0)", "pytest (>=9.0.1,<10)", "pytest-asyncio (>=1.3.0)", "pytest-cov (>=4.0)", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling", "testpath", "xmltodict"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.1.0)", "pytest (>=9.0.1,<10)", "pytest-asyncio (>=1.3.0)", "pytest-cov (>=4.0)", "testpath", "xmltodict"] + +[[package]] +name = "nbconvert" +version = "7.17.1" +description = "Convert Jupyter Notebooks (.ipynb files) to other formats." +optional = false +python-versions = ">=3.9" +files = [ + {file = "nbconvert-7.17.1-py3-none-any.whl", hash = "sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8"}, + {file = "nbconvert-7.17.1.tar.gz", hash = "sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2"}, +] + +[package.dependencies] +beautifulsoup4 = "*" +bleach = {version = "!=5.0.0", extras = ["css"]} +defusedxml = "*" +jinja2 = ">=3.0" +jupyter-core = ">=4.7" +jupyterlab-pygments = "*" +markupsafe = ">=2.0" +mistune = ">=2.0.3,<4" +nbclient = ">=0.5.0" +nbformat = ">=5.7" +packaging = "*" +pandocfilters = ">=1.4.1" +pygments = ">=2.4.1" +traitlets = ">=5.1" + +[package.extras] +all = ["flaky", "intersphinx-registry", "ipykernel", "ipython", "ipywidgets (>=7.5)", "myst-parser", "nbsphinx (>=0.2.12)", "playwright", "pydata-sphinx-theme", "pyqtwebengine (>=5.15)", "pytest (>=7)", "sphinx (>=5.0.2)", "sphinxcontrib-spelling", "tornado (>=6.1)"] +docs = ["intersphinx-registry", "ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (>=5.0.2)", "sphinxcontrib-spelling"] +qtpdf = ["pyqtwebengine (>=5.15)"] +qtpng = ["pyqtwebengine (>=5.15)"] +serve = ["tornado (>=6.1)"] +test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest (>=7)"] +webpdf = ["playwright"] + +[[package]] +name = "nbformat" +version = "5.11.1" +description = "The Jupyter Notebook format" +optional = false +python-versions = ">=3.10" +files = [ + {file = "nbformat-5.11.1-py3-none-any.whl", hash = "sha256:cc6698fa75f4fab8755ead786317815f13a6fee3b53311c0abb1a8b51d52f7ec"}, + {file = "nbformat-5.11.1.tar.gz", hash = "sha256:32d4521c68c6e7d5b29c76defaeed9f42ea733142b9b19f88277ce10390b9c4d"}, +] + +[package.dependencies] +fastjsonschema = ">=2.15" +jsonschema = ">=2.6" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +traitlets = ">=5.1" + +[package.extras] +docs = ["intersphinx-registry", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["packaging", "pre-commit", "pytest", "testpath"] + [[package]] name = "nest-asyncio2" version = "1.7.2" @@ -2038,13 +2195,13 @@ et-xmlfile = "*" [[package]] name = "packaging" -version = "24.1" +version = "26.3" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c"}, + {file = "packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79"}, ] [[package]] @@ -2146,6 +2303,17 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.9.2)"] +[[package]] +name = "pandocfilters" +version = "1.5.1" +description = "Utilities for writing pandoc filters in python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}, + {file = "pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}, +] + [[package]] name = "parso" version = "0.8.7" @@ -2599,22 +2767,18 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pyproject-api" -version = "1.8.0" +version = "1.11.2" description = "API to interact with the python pyproject.toml based projects" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" files = [ - {file = "pyproject_api-1.8.0-py3-none-any.whl", hash = "sha256:3d7d347a047afe796fd5d1885b1e391ba29be7169bd2f102fcd378f04273d228"}, - {file = "pyproject_api-1.8.0.tar.gz", hash = "sha256:77b8049f2feb5d33eefcc21b57f1e279636277a8ac8ad6b5871037b243778496"}, + {file = "pyproject_api-1.11.2-py3-none-any.whl", hash = "sha256:69040bb421a3d502217bf9d5f92a94e65e1db3fe25b641d6064b2b5b9880428b"}, + {file = "pyproject_api-1.11.2.tar.gz", hash = "sha256:7bff8690a101f5f0bac3221475d214018f196ae5eea3af9c9879f4d682a3fd60"}, ] [package.dependencies] -packaging = ">=24.1" -tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -docs = ["furo (>=2024.8.6)", "sphinx-autodoc-typehints (>=2.4.1)"] -testing = ["covdefaults (>=2.3)", "pytest (>=8.3.3)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "setuptools (>=75.1)"] +packaging = ">=25" +tomli = {version = ">=2.3", markers = "python_version < \"3.11\""} [[package]] name = "pyreadline3" @@ -2669,22 +2833,17 @@ six = ">=1.5" [[package]] name = "python-discovery" -version = "1.2.0" +version = "1.6.1" description = "Python interpreter discovery" optional = false python-versions = ">=3.8" files = [ - {file = "python_discovery-1.2.0-py3-none-any.whl", hash = "sha256:1e108f1bbe2ed0ef089823d28805d5ad32be8e734b86a5f212bf89b71c266e4a"}, - {file = "python_discovery-1.2.0.tar.gz", hash = "sha256:7d33e350704818b09e3da2bd419d37e21e7c30db6e0977bb438916e06b41b5b1"}, + {file = "python_discovery-1.6.1-py3-none-any.whl", hash = "sha256:d43fcdef879fe795352bd13ccf8d185ba5a9f86f36cfcd00529f596e737442b3"}, + {file = "python_discovery-1.6.1.tar.gz", hash = "sha256:cf87d3627dfb4412437fdd5b13eae402607722998d21567993aedbc59b23c15e"}, ] [package.dependencies] filelock = ">=3.15.4" -platformdirs = ">=4.3.6,<5" - -[package.extras] -docs = ["furo (>=2025.12.19)", "sphinx (>=9.1)", "sphinx-autodoc-typehints (>=3.6.3)", "sphinxcontrib-mermaid (>=2)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.5.4)", "pytest (>=8.3.5)", "pytest-mock (>=3.14)", "setuptools (>=75.1)"] [[package]] name = "python-dotenv" @@ -2938,6 +3097,22 @@ files = [ [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} +[[package]] +name = "referencing" +version = "0.37.0" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.10" +files = [ + {file = "referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231"}, + {file = "referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" +typing-extensions = {version = ">=4.4.0", markers = "python_version < \"3.13\""} + [[package]] name = "requests" version = "2.32.5" @@ -2959,6 +3134,130 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "rpds-py" +version = "0.30.0" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.10" +files = [ + {file = "rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288"}, + {file = "rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221"}, + {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7"}, + {file = "rpds_py-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff"}, + {file = "rpds_py-0.30.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7"}, + {file = "rpds_py-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139"}, + {file = "rpds_py-0.30.0-cp310-cp310-win32.whl", hash = "sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464"}, + {file = "rpds_py-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169"}, + {file = "rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425"}, + {file = "rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d"}, + {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038"}, + {file = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7"}, + {file = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed"}, + {file = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85"}, + {file = "rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c"}, + {file = "rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825"}, + {file = "rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229"}, + {file = "rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad"}, + {file = "rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6"}, + {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51"}, + {file = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5"}, + {file = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e"}, + {file = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394"}, + {file = "rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf"}, + {file = "rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b"}, + {file = "rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e"}, + {file = "rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2"}, + {file = "rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e"}, + {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d"}, + {file = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7"}, + {file = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31"}, + {file = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95"}, + {file = "rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d"}, + {file = "rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15"}, + {file = "rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1"}, + {file = "rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a"}, + {file = "rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9"}, + {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0"}, + {file = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94"}, + {file = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08"}, + {file = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27"}, + {file = "rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6"}, + {file = "rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d"}, + {file = "rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0"}, + {file = "rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07"}, + {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f"}, + {file = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65"}, + {file = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f"}, + {file = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53"}, + {file = "rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed"}, + {file = "rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950"}, + {file = "rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6"}, + {file = "rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb"}, + {file = "rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8"}, + {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5"}, + {file = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404"}, + {file = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856"}, + {file = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40"}, + {file = "rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0"}, + {file = "rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4"}, + {file = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e"}, + {file = "rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84"}, +] + [[package]] name = "six" version = "1.17.0" @@ -3379,6 +3678,24 @@ files = [ {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, ] +[[package]] +name = "tinycss2" +version = "1.5.1" +description = "A tiny CSS parser" +optional = false +python-versions = ">=3.10" +files = [ + {file = "tinycss2-1.5.1-py3-none-any.whl", hash = "sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661"}, + {file = "tinycss2-1.5.1.tar.gz", hash = "sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957"}, +] + +[package.dependencies] +webencodings = ">=0.4" + +[package.extras] +doc = ["furo", "sphinx"] +test = ["pytest", "ruff"] + [[package]] name = "toml" version = "0.10.2" @@ -3446,6 +3763,17 @@ files = [ {file = "tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c"}, ] +[[package]] +name = "tomli-w" +version = "1.2.0" +description = "A lil' TOML writer" +optional = false +python-versions = ">=3.9" +files = [ + {file = "tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90"}, + {file = "tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021"}, +] + [[package]] name = "tomlkit" version = "0.14.0" @@ -3478,30 +3806,32 @@ files = [ [[package]] name = "tox" -version = "4.23.2" +version = "4.61.5" description = "tox is a generic virtualenv management and test command line tool" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" files = [ - {file = "tox-4.23.2-py3-none-any.whl", hash = "sha256:452bc32bb031f2282881a2118923176445bac783ab97c874b8770ab4c3b76c38"}, - {file = "tox-4.23.2.tar.gz", hash = "sha256:86075e00e555df6e82e74cfc333917f91ecb47ffbc868dcafbd2672e332f4a2c"}, + {file = "tox-4.61.5-py3-none-any.whl", hash = "sha256:5f9b109fa0a60b7ccb812e8dacbcf7a06b9a633fa90ae97198334b3464b2f133"}, + {file = "tox-4.61.5.tar.gz", hash = "sha256:d1f535a6ca4827c087e0a2a173dd74621d6e1688c740c8dd44e0377480020431"}, ] [package.dependencies] -cachetools = ">=5.5" -chardet = ">=5.2" +cachetools = ">=7.0.3" colorama = ">=0.4.6" -filelock = ">=3.16.1" -packaging = ">=24.1" -platformdirs = ">=4.3.6" -pluggy = ">=1.5" -pyproject-api = ">=1.8" -tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.12.2", markers = "python_version < \"3.11\""} -virtualenv = ">=20.26.6" +filelock = ">=3.25" +packaging = ">=26" +platformdirs = ">=4.9.4" +pluggy = ">=1.6" +pyproject-api = ">=1.10" +python-discovery = ">=1.4.4" +tomli = {version = ">=2.4", markers = "python_version < \"3.11\""} +tomli-w = ">=1.2" +typing-extensions = {version = ">=4.15", markers = "python_version < \"3.13\""} +virtualenv = ">=21.1" [package.extras] -test = ["devpi-process (>=1.0.2)", "pytest (>=8.3.3)", "pytest-mock (>=3.14)"] +completion = ["argcomplete (>=3.6.3)"] +testing = ["devpi-process (>=1.1.1)", "pytest (>=9.0.2)", "pytest-mock (>=3.15.1)"] [[package]] name = "tqdm" @@ -3605,20 +3935,20 @@ zstd = ["backports-zstd (>=1.0.0)"] [[package]] name = "virtualenv" -version = "21.2.0" +version = "21.7.14" description = "Virtual Python Environment builder" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "virtualenv-21.2.0-py3-none-any.whl", hash = "sha256:1bd755b504931164a5a496d217c014d098426cddc79363ad66ac78125f9d908f"}, - {file = "virtualenv-21.2.0.tar.gz", hash = "sha256:1720dc3a62ef5b443092e3f499228599045d7fea4c79199770499df8becf9098"}, + {file = "virtualenv-21.7.14-py3-none-any.whl", hash = "sha256:ac2b2b3755da16aed6302de00ecd0cc43ecc0f295c3f84c064969cd70869ba05"}, + {file = "virtualenv-21.7.14.tar.gz", hash = "sha256:6f14bcaeb6c3438cd8c8cf3ab1805973592fb900e9b724427d1102aaa3db7fbb"}, ] [package.dependencies] distlib = ">=0.3.7,<1" filelock = {version = ">=3.24.2,<4", markers = "python_version >= \"3.10\""} platformdirs = ">=3.9.1,<5" -python-discovery = ">=1" +python-discovery = ">=1.6" typing-extensions = {version = ">=4.13.2", markers = "python_version < \"3.11\""} [[package]] @@ -3632,6 +3962,21 @@ files = [ {file = "wcwidth-0.8.3.tar.gz", hash = "sha256:d128512515fbf4612e0ff21fd6380399210318b7b54a9af59dff8454cf9730eb"}, ] +[[package]] +name = "webencodings" +version = "0.6.1" +description = "Character encoding aliases for legacy web content" +optional = false +python-versions = ">=3.10" +files = [ + {file = "webencodings-0.6.1-py3-none-any.whl", hash = "sha256:7fab6269c8bf237c657876b52058ccb182e861518d1c695c1a9aaa8c1c105d5b"}, + {file = "webencodings-0.6.1.tar.gz", hash = "sha256:565f9ad031c702dae404e27a099e3e09186a3ab1b9520f06d215502b651fd910"}, +] + +[package.extras] +doc = ["furo", "sphinx"] +test = ["pytest", "ruff"] + [[package]] name = "wrapt" version = "2.1.2" @@ -3737,4 +4082,4 @@ dev = ["pytest", "setuptools"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "d9b3b38c59097c8cc941a2f070514d01c484da045172bfb80c9a5a548686f050" +content-hash = "5579fddf9da46571e370590cc36c8ff3762c83f9eb7cd020471fde6a111b2b5d" diff --git a/pyproject.toml b/pyproject.toml index d6efbe8..2dac862 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ biofilter = "biofilter.api.cli.main:main" [tool.poetry.dependencies] python = "^3.10" click = "8.1.7" -packaging = "24.1" +packaging = ">=24.1" colorama = "^0.4.6" tqdm = "^4.67.1" sqlalchemy = "^2.0.37" @@ -36,7 +36,7 @@ coverage = "^7.6.8" pytest = "^8.3.4" sphinx = "^8.1.3" sphinx-rtd-theme = "^3.0.2" -tox = "^4.23.2" +tox = "^4.61.5" sphinx-material = "^0.0.36" pylint = "^3.3.3" myst-parser = "^4.0.1" @@ -44,10 +44,11 @@ linkify-it-py = "^2.0.3" testcontainers = "^4.14.1" sphinxcontrib-mermaid = "^2.0.1" ipykernel = "^7.3.0" +nbconvert = "^7.17.1" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.tox] -envlist = "py310,py311,py312" +envlist = "py310,py311,py312,py313" diff --git a/tox.ini b/tox.ini index aa488c7..8175ba0 100644 --- a/tox.ini +++ b/tox.ini @@ -1,27 +1,27 @@ [tox] -envlist = py310, py311, py312 +envlist = py310, py311, py312, py313 -# Define the test environment for each Python version -# Replace the path with the path to your Python version -# You can find the path to your Python version by running `which python` +# tox builds the package with poetry-core and installs it together with the +# runtime dependencies resolved from pyproject.toml, so the envs only need the +# test-only extras on top. Do not add `poetry install` back here: it is +# redundant, and poetry sharing an env with the package under test makes the +# two compete over common dependencies such as `packaging`. + +[testenv] +deps = pytest +commands = pytest {posargs:tests/} + +# basepython is pinned per interpreter because the 3.10-3.12 builds come from +# pyenv and 3.13 from Homebrew; adjust the paths for your own machine. [testenv:py310] basepython = /Users/andrerico/.pyenv/versions/3.10.3/bin/python -deps = poetry -commands = - poetry install --no-root - pytest tests/ [testenv:py311] basepython = /Users/andrerico/.pyenv/versions/3.11.9/bin/python -deps = poetry -commands = - poetry install --no-root - pytest tests/ [testenv:py312] basepython = /Users/andrerico/.pyenv/versions/3.12.3/bin/python -deps = poetry -commands = - poetry install --no-root - pytest tests/ + +[testenv:py313] +basepython = /opt/homebrew/bin/python3.13