From 82c2f3f483e0fc36ab5de62062f81b35f5dc2d1e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 22 May 2023 16:13:55 -0400 Subject: [PATCH 001/147] ci: fix release-drafter config (#78) --- .github/workflows/release-drafter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index 8c79f11..e60ebc1 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -4,7 +4,7 @@ on: push: # branches to consider in the event; optional, defaults to all branches: - - master + - main jobs: update_release_draft: From e64e1e06e248d6277e4f806d1742f5e328c49901 Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Tue, 23 May 2023 23:15:12 -0300 Subject: [PATCH 002/147] ci: fix name of release-drafter config file (#79) The action looks specifically for ".yml", and not ".yaml". --- .github/{release-drafter.yaml => release-drafter.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{release-drafter.yaml => release-drafter.yml} (100%) diff --git a/.github/release-drafter.yaml b/.github/release-drafter.yml similarity index 100% rename from .github/release-drafter.yaml rename to .github/release-drafter.yml From d38e78c7615c63fa77459fa92d2516691073291a Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 25 May 2023 07:26:32 -0400 Subject: [PATCH 003/147] meta: dynamic versioning (#80) Co-authored-by: Tiago Nobrega --- .gitignore | 3 +++ pyproject.toml | 5 ++++- starcraft/__init__.py | 16 ++++++++++++++-- tests/unit/test_init.py | 10 +++++++--- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index e7dc10d..b19a46a 100644 --- a/.gitignore +++ b/.gitignore @@ -136,3 +136,6 @@ dmypy.json # direnv .envrc + +# Ignore version module generated by setuptools_scm +/*/_version.py diff --git a/pyproject.toml b/pyproject.toml index 31aff7c..66b7753 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,6 +53,9 @@ build-backend = "setuptools.build_meta" [tool.setuptools.dynamic] readme = {file = "README.rst"} +[tool.setuptools_scm] +write_to = "starcraft/_version.py" + [tool.setuptools.packages.find] exclude = [ "dist", @@ -165,6 +168,7 @@ extend-select = [ # Annotations: https://github.com/charliermarsh/ruff#flake8-annotations-ann "ANN0", # Type annotations for arguments other than `self` and `cls` "ANN2", # Return type annotations + "B026", # Keyword arguments must come after starred arguments # flake8-bandit: security testing. https://github.com/charliermarsh/ruff#flake8-bandit-s # https://bandit.readthedocs.io/en/latest/plugins/index.html#complete-test-plugin-listing "S101", "S102", # assert or exec @@ -177,7 +181,6 @@ extend-select = [ "S701", # jinja2 templates without autoescape "B0", # Common mistakes and typos. "RUF001", "RUF002", "RUF003", # Ambiguous unicode characters - "RUF004", # Keyword arguments must come after starred arguments "RUF005", # Encourages unpacking rather than concatenation "RUF100", # #noqa directive that doesn't flag anything. ] diff --git a/starcraft/__init__.py b/starcraft/__init__.py index 3d64fc0..4e75351 100644 --- a/starcraft/__init__.py +++ b/starcraft/__init__.py @@ -14,10 +14,17 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Starcraft package demo.""" -from importlib.metadata import version from typing import List, Optional, Any -__version__ = version(__name__) +try: + from ._version import __version__ +except ImportError: # pragma: no cover + from importlib.metadata import version, PackageNotFoundError + + try: + __version__ = version("starcraft") + except PackageNotFoundError: + __version__ = "dev" def hello(people: Optional[List[Any]] = None) -> None: @@ -26,3 +33,8 @@ def hello(people: Optional[List[Any]] = None) -> None: if people: for person in people: print(f"Hello {person}!") + + +__all__ = [ + "__version__", +] diff --git a/tests/unit/test_init.py b/tests/unit/test_init.py index 78d4114..2aeec01 100644 --- a/tests/unit/test_init.py +++ b/tests/unit/test_init.py @@ -16,13 +16,17 @@ """Basic Starcraft package demo unit tests.""" from unittest import mock -from starcraft import hello +import starcraft + + +def test_version(): + assert starcraft.__version__ is not None def test_hello(mocker): mocker.patch("builtins.print") - hello() + starcraft.hello() print.assert_called_once_with("Hello *craft team!") @@ -30,7 +34,7 @@ def test_hello(mocker): def test_hello_people(mocker): mocker.patch("builtins.print") - hello(["people"]) + starcraft.hello(["people"]) print.assert_has_calls( [ From ba60c11dcd216b804f2135bcba4407fc62560760 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 21:14:34 -0400 Subject: [PATCH 004/147] chore(deps): update development dependencies (non-major) (#83) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 66b7753..0f29769 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,9 +17,9 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ - "coverage[toml]==7.2.5", + "coverage[toml]==7.2.7", "pytest==7.3.1", - "pytest-cov==4.0.0", + "pytest-cov==4.1.0", "pytest-mock==3.10.0", ] lint = [ @@ -30,7 +30,7 @@ lint = [ ] types = [ "mypy[reports]==1.3.0", - "pyright==1.1.309", + "pyright==1.1.311", ] docs = [ "furo==2023.5.20", From b5cda0d0f4959e34fe077a670ec84a82212cdd95 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 5 Jun 2023 21:24:33 -0400 Subject: [PATCH 005/147] lint: stricter ruff rules (#55) --- pyproject.toml | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0f29769..90810c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -142,26 +142,36 @@ select = [ # Base linting rule selections. # failures with ruff updates. "F", # The rules built into Flake8 "E", "W", # pycodestyle errors and warnings - "D", # Implement pydocstyle checking as well. "I", # isort checking - "PLC", "PLE", "PLR", "PLW", # Pylint "N", # PEP8 naming + "D", # Implement pydocstyle checking as well. + "UP", # Pyupgrade - note that some of are excluded below due to Python versions "YTT", # flake8-2020: Misuse of `sys.version` and `sys.version_info` + "ANN", # Type annotations. "BLE", # Do not catch blind exceptions "FBT", # Disallow boolean positional arguments (make them keyword-only) + "B0", # Common mistakes and typos. "A", # Shadowing built-ins. "C4", # Encourage comprehensions, which tend to be faster than alternatives. "T10", # Don't call the debugger in production code "ISC", # Implicit string concatenation that can cause subtle issues "ICN", # Only use common conventions for import aliases. + "INP", # Implicit namespace packages + "PYI", # Linting for type stubs. + "PT", # Pytest "Q", # Consistent quotations + "RSE", # Errors on pytest raises. "RET", # Simpler logic after return, raise, continue or break - "UP018", "C408", # Convert type calls to literals. The latest pylint enforces this, but ruff has auto-fixes. + "SIM", # Code simplification + "TCH", # Guard imports only used for type checking behind a type-checkning block. + "ARG", # Unused arguments + "PTH", # Migrate to pathlib + "ERA", # Don't check in commented out code + "PGH", # Pygrep hooks + "PL", # Pylint + "TRY", # Cleaner try/except, ] extend-select = [ - # These sets are still frequently getting new rules. - # Therefore, they're getting frozen with the current rules so we can - # upgrade ruff without breaking linting. # Pyupgrade: https://github.com/charliermarsh/ruff#pyupgrade-up "UP00", "UP01", "UP02", "UP030", "UP032", "UP033", # "UP034", # Very new, not yet enabled in ruff 0.0.227 @@ -175,16 +185,19 @@ extend-select = [ "S103", "S108", # File permissions and tempfiles - use #noqa to silence when appropriate. "S104", # Network binds "S105", "S106", "S107", # Hardcoded passwords + "S110", # try-except-pass (use contextlib.suppress instead) "S113", # Requests calls without timeouts + "S3", # Serialising, deserialising, hashing, crypto, etc. "S506", # Unsafe YAML load "S508", "S509", # Insecure SNMP "S701", # jinja2 templates without autoescape - "B0", # Common mistakes and typos. "RUF001", "RUF002", "RUF003", # Ambiguous unicode characters "RUF005", # Encourages unpacking rather than concatenation - "RUF100", # #noqa directive that doesn't flag anything. + "RUF008", # Do not use mutable default values for dataclass attributes + "RUF100", # #noqa directive that doesn't flag anything ] ignore = [ + "ANN10", # Type annotations for `self` and `cls` #"E203", # Whitespace before ":" -- Commented because ruff doesn't currently check E203 "E501", # Line too long (reason: black will automatically fix this for us) "D105", # Missing docstring in magic method (reason: magic methods already have definitions) @@ -194,6 +207,8 @@ ignore = [ "D215", # Section underline is over-indented (reason: pep257 default) "A003", # Class attribute shadowing built-in (reason: Class attributes don't often get bare references) + # Ignored due to common usage in current code + "TRY003", # Avoid specifying long messages outside the exception class ] [tool.ruff.per-file-ignores] From 43f86dab030429e8192ee59bed253cc062bed117 Mon Sep 17 00:00:00 2001 From: Callahan Date: Wed, 7 Jun 2023 16:19:37 -0500 Subject: [PATCH 006/147] tests: move starbase tests to sub-directories (#85) This allows starbase to have its own tests and allow for cleaner merges of starbase into other repositories. Signed-off-by: Callahan Kovacs --- tests/integration/starbase/__init__.py | 0 tests/integration/{ => starbase}/test_init.py | 0 tests/unit/starbase/__init__.py | 0 tests/unit/{ => starbase}/test_init.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/integration/starbase/__init__.py rename tests/integration/{ => starbase}/test_init.py (100%) create mode 100644 tests/unit/starbase/__init__.py rename tests/unit/{ => starbase}/test_init.py (100%) diff --git a/tests/integration/starbase/__init__.py b/tests/integration/starbase/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/integration/test_init.py b/tests/integration/starbase/test_init.py similarity index 100% rename from tests/integration/test_init.py rename to tests/integration/starbase/test_init.py diff --git a/tests/unit/starbase/__init__.py b/tests/unit/starbase/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/test_init.py b/tests/unit/starbase/test_init.py similarity index 100% rename from tests/unit/test_init.py rename to tests/unit/starbase/test_init.py From e150fe20654c3047e29364861082404372a3e4f8 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 8 Jun 2023 16:43:26 -0400 Subject: [PATCH 007/147] ci: configure tox to disable listing dependencies (#87) --- .github/workflows/tests.yaml | 10 ++++++---- tox.ini | 4 +++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 008a38d..2f2902e 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -28,7 +28,7 @@ jobs: sudo snap install --no-wait shellcheck echo "::endgroup::" echo "::group::pip install" - python -m pip install 'tox>=4' tox-gh + python -m pip install tox echo "::endgroup::" echo "::group::Create virtual environments for linting processes." tox run -m lint --notest @@ -37,7 +37,7 @@ jobs: snap watch --last=install echo "::endgroup::" - name: Run Linters - run: tox run -m lint + run: tox run --skip-pkg-install --no-list-dependencies -m lint tests: strategy: matrix: @@ -59,13 +59,15 @@ jobs: - name: Configure environment run: | echo "::group::pip install" - python -m pip install 'tox>=4' tox-gh + python -m pip install tox echo "::endgroup::" mkdir -p results - name: Setup Tox environments run: tox run -m tests --notest - name: Test with tox - run: tox run-parallel --parallel all --parallel-no-spinner --skip-pkg-install --result-json results/tox-${{ matrix.platform }}.json -m tests -- --no-header --quiet -rN + run: .tox/.tox/bin/tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m tests + env: + PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload code coverage uses: codecov/codecov-action@v3 with: diff --git a/tox.ini b/tox.ini index 97fc5fb..e7fc7dc 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ env_list = # Environments to run when called with no parameters. lint-{black,ruff,pyright,shellcheck,codespell,docs} test-{py38,py310,py311} -minversion = 4.5 +minversion = 4.6 # Tox will use these requirements to bootstrap a venv if necessary. # tox-igore-env-name-mismatch allows us to have one virtualenv for all linting. # By setting requirements here, we make this INI file compatible with older @@ -12,6 +12,8 @@ minversion = 4.5 requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 + # renovate: datasource=pypi + tox-gh==1.0.0 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From 7ab2ef4a705754968ac685753f4a6bcd74d5e78e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 9 Jun 2023 01:21:57 -0400 Subject: [PATCH 008/147] ci: cache pip packages (#88) --- .github/workflows/tests.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 2f2902e..f909897 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -20,6 +20,7 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.10' + cache: 'pip' - name: Configure environment run: | echo "::group::Begin snap install" @@ -56,6 +57,7 @@ jobs: 3.10 3.11 3.12-dev + cache: 'pip' - name: Configure environment run: | echo "::group::pip install" From 201327e7d4878e123c6a829c771a4fc8158f4fe8 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 9 Jun 2023 14:33:26 -0400 Subject: [PATCH 009/147] tox/ci: update Python versions tested (#89) --- .github/workflows/tests.yaml | 3 +-- tox.ini | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index f909897..715395e 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -19,7 +19,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v4 with: - python-version: '3.10' + python-version: '3.11' cache: 'pip' - name: Configure environment run: | @@ -53,7 +53,6 @@ jobs: with: python-version: | 3.8 - 3.9 3.10 3.11 3.12-dev diff --git a/tox.ini b/tox.ini index e7fc7dc..0ae3456 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] env_list = # Environments to run when called with no parameters. lint-{black,ruff,pyright,shellcheck,codespell,docs} - test-{py38,py310,py311} + test-{py38,py310,py311,py312} minversion = 4.6 # Tox will use these requirements to bootstrap a venv if necessary. # tox-igore-env-name-mismatch allows us to have one virtualenv for all linting. @@ -38,14 +38,14 @@ commands_pre = mkdir -p results base = testenv, test description = Run unit tests with pytest labels = - py38, py310, py311: tests, unit-tests + py38, py310, py311, py312: tests, unit-tests commands = pytest {tty:--color=yes} --cov --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml tests/unit {posargs} [testenv:integration-{py38,py39,py310,py311,py312}] base = testenv, test description = Run integration tests with pytest labels = - py38, py310, py311: tests, integration-tests + py38, py310, py311, py312: tests, integration-tests commands = pytest {tty:--color=yes} --junit-xml=results/test-results-{env_name}.xml tests/integration {posargs} [lint] # Standard linting configuration From f3c4f888b63e76f90c52f4fa157ed2cea2f87324 Mon Sep 17 00:00:00 2001 From: Callahan Date: Fri, 9 Jun 2023 14:38:27 -0500 Subject: [PATCH 010/147] lint: ignore ruff SIM117 (#90) Signed-off-by: Callahan Kovacs --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 90810c1..bff87a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -206,6 +206,8 @@ ignore = [ "D213", # Multi-line docstring summary should start at the second line (reason: pep257 default) "D215", # Section underline is over-indented (reason: pep257 default) "A003", # Class attribute shadowing built-in (reason: Class attributes don't often get bare references) + "SIM117", # Use a single `with` statement with multiple contexts instead of nested `with` statements + # (reason: this creates long lines that get wrapped and reduces readability) # Ignored due to common usage in current code "TRY003", # Avoid specifying long messages outside the exception class From afc42465dc31e3987f6484d0fb5e3e8b6202f387 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Jun 2023 16:40:07 -0400 Subject: [PATCH 011/147] chore(deps): update dependency tox-gh to v1.2.0 (#92) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 0ae3456..11381b3 100644 --- a/tox.ini +++ b/tox.ini @@ -13,7 +13,7 @@ requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 # renovate: datasource=pypi - tox-gh==1.0.0 + tox-gh==1.2.0 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From f40aae97c4ee708dc09ea5256c860abbbe5dd830 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Jun 2023 16:40:26 -0400 Subject: [PATCH 012/147] chore(deps): update dependency lint/ruff to v0.0.272 (#91) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index bff87a1..b3c16b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ dev = [ lint = [ "black==23.3.0", "codespell[toml]==2.2.4", - "ruff==0.0.269", + "ruff==0.0.272", "yamllint==1.32.0" ] types = [ From 0b9e9cfe890c15d81b1624cdb1bfece53becc7f1 Mon Sep 17 00:00:00 2001 From: Callahan Date: Tue, 13 Jun 2023 10:20:45 -0500 Subject: [PATCH 013/147] meta: update versioning scheme (#86) Signed-off-by: Callahan Kovacs --- pyproject.toml | 13 +++++ tests/integration/starbase/test_version.py | 65 ++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/integration/starbase/test_version.py diff --git a/pyproject.toml b/pyproject.toml index b3c16b2..98b3d43 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,6 +55,19 @@ readme = {file = "README.rst"} [tool.setuptools_scm] write_to = "starcraft/_version.py" +# the version comes from the latest annotated git tag formatted as 'X.Y.Z' +# standard version scheme: +# 'X.Y.Z.post+g' +# scheme when no tags exist: +# '0.0.post+g +# scheme when no tags exist and working dir is dirty: +# '0.0.post+g.d' +version_scheme = "post-release" +# deviations from the default 'git describe' command: +# - only match annotated tags +# - only match tags formatted as 'X.Y.Z' +# - exclude '+dirty' suffix +git_describe_command = "git describe --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*'" [tool.setuptools.packages.find] exclude = [ diff --git a/tests/integration/starbase/test_version.py b/tests/integration/starbase/test_version.py new file mode 100644 index 0000000..36a48d3 --- /dev/null +++ b/tests/integration/starbase/test_version.py @@ -0,0 +1,65 @@ +# This file is part of starcraft. +# +# Copyright 2023 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License version 3, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +"""Starcraft versioning tests.""" +import re +import subprocess + +import pytest +import starcraft + + +def _repo_has_version_tag() -> bool: + """Returns True if the repo has a git tag usable for versioning.""" + git_describe_command = [ + "git", + "describe", + "--always", + "--long", + "--match", + "[0-9]*.[0-9]*.[0-9]*", + "--exclude", + "*[^0-9.]*", + ] + output = subprocess.run( + git_describe_command, check=True, capture_output=True, text=True + ).stdout.rstrip("\n") + + # match on 'X.Y.Z--g' + return bool(re.fullmatch(r"\d+\.\d+\.\d+-\d+-g[0-9a-f]+", output)) + + +@pytest.mark.skipif( + _repo_has_version_tag(), reason="Skipping because project was versioned from a tag." +) +def test_version_without_tags(): + """Validate version format when no valid tag are present.""" + version = starcraft.__version__ + + # match on '0.0.post+g' + # or '0.0.post+g.d' + assert re.fullmatch(r"\d+\.\d+\.post\d+\+g[0-9a-f]+(\.d[0-9]*)?", version) + + +@pytest.mark.skipif( + not _repo_has_version_tag(), + reason="Skipping because project was not versioned from a tag.", +) +def test_version_with_tags(): + """Version should be properly formatted when a valid tag exists.""" + version = starcraft.__version__ + + # match on 'X.Y.Z.post+g' + assert re.fullmatch(r"\d+\.\d+\.\d+\.post\d+\+g[0-9a-f]+", version) From 296c5dd9333086c10bb32aa3f80fcf9539defce4 Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Wed, 14 Jun 2023 18:00:13 -0300 Subject: [PATCH 014/147] lint: fix mypy config to 'recurse' (#94) `module = ["starcraft"]` only checks checks the `starcraft` main package, and not any sub-packages and modules. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 98b3d43..1644008 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -131,7 +131,7 @@ disallow_untyped_decorators = true disallow_any_generics = true [[tool.mypy.overrides]] -module = ["starcraft"] +module = ["starcraft.*"] disallow_untyped_defs = true no_implicit_optional = true From 72c7781ee03c17a3bef75a38bb93e6ff0dde3402 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Jun 2023 17:58:27 -0400 Subject: [PATCH 015/147] chore(deps): update development dependencies (non-major) (#95) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1644008..f9aaf80 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ "coverage[toml]==7.2.7", - "pytest==7.3.1", + "pytest==7.3.2", "pytest-cov==4.1.0", "pytest-mock==3.10.0", ] @@ -30,7 +30,7 @@ lint = [ ] types = [ "mypy[reports]==1.3.0", - "pyright==1.1.311", + "pyright==1.1.313", ] docs = [ "furo==2023.5.20", From 8c64fc4609ad41763fcbf0e2fc9c8c48b77e1cd4 Mon Sep 17 00:00:00 2001 From: Callahan Date: Fri, 16 Jun 2023 14:44:15 -0500 Subject: [PATCH 016/147] meta: add dirty flag to versioning scheme (#96) --- pyproject.toml | 17 +++++++++-------- .../integration/{starbase => }/test_version.py | 9 ++++++--- 2 files changed, 15 insertions(+), 11 deletions(-) rename tests/integration/{starbase => }/test_version.py (85%) diff --git a/pyproject.toml b/pyproject.toml index f9aaf80..d0b9329 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,18 +56,19 @@ readme = {file = "README.rst"} [tool.setuptools_scm] write_to = "starcraft/_version.py" # the version comes from the latest annotated git tag formatted as 'X.Y.Z' -# standard version scheme: -# 'X.Y.Z.post+g' -# scheme when no tags exist: -# '0.0.post+g -# scheme when no tags exist and working dir is dirty: -# '0.0.post+g.d' +# version scheme: +# - X.Y.Z.post+g.d<%Y%m%d> +# parts of scheme: +# - X.Y.Z - most recent git tag +# - post+g - present when current commit is not tagged +# - .d<%Y%m%d> - present when working dir is dirty +# version scheme when no tags exist: +# - 0.0.post+g version_scheme = "post-release" # deviations from the default 'git describe' command: # - only match annotated tags # - only match tags formatted as 'X.Y.Z' -# - exclude '+dirty' suffix -git_describe_command = "git describe --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*'" +git_describe_command = "git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*'" [tool.setuptools.packages.find] exclude = [ diff --git a/tests/integration/starbase/test_version.py b/tests/integration/test_version.py similarity index 85% rename from tests/integration/starbase/test_version.py rename to tests/integration/test_version.py index 36a48d3..68f4acc 100644 --- a/tests/integration/starbase/test_version.py +++ b/tests/integration/test_version.py @@ -49,7 +49,7 @@ def test_version_without_tags(): version = starcraft.__version__ # match on '0.0.post+g' - # or '0.0.post+g.d' + # or '0.0.post+g.d<%Y%m%d>' assert re.fullmatch(r"\d+\.\d+\.post\d+\+g[0-9a-f]+(\.d[0-9]*)?", version) @@ -61,5 +61,8 @@ def test_version_with_tags(): """Version should be properly formatted when a valid tag exists.""" version = starcraft.__version__ - # match on 'X.Y.Z.post+g' - assert re.fullmatch(r"\d+\.\d+\.\d+\.post\d+\+g[0-9a-f]+", version) + # match on 'X.Y.Z' + # or 'X.Y.Z.d<%Y%m%d>' + # or 'X.Y.Z.post+g' + # or 'X.Y.Z.post+g.d<%Y%m%d>' + assert re.fullmatch(r"\d+\.\d+\.\d+(\.post\d+\+g[0-9a-f]+)?(\.d[0-9]*)?", version) From 0f6657d77982007f7ced73f61dc0f08010655091 Mon Sep 17 00:00:00 2001 From: Callahan Date: Tue, 20 Jun 2023 11:27:30 -0500 Subject: [PATCH 017/147] ci: lint docs in all directories (#98) Files like README.md and HACKING.md are linted by sphinx-lint. Signed-off-by: Callahan Kovacs --- .gitignore | 3 +++ HACKING.rst | 44 +++++++++++++++++++++++++++++++++----------- README.rst | 21 +++++++++++++-------- tox.ini | 7 ++++++- 4 files changed, 55 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index b19a46a..4cb5044 100644 --- a/.gitignore +++ b/.gitignore @@ -139,3 +139,6 @@ dmypy.json # Ignore version module generated by setuptools_scm /*/_version.py + +# Visual Studio Code +.vscode/ diff --git a/HACKING.rst b/HACKING.rst index 527d4c0..122b1d4 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -2,23 +2,32 @@ Starcraft ********* -Welcome to Starcraft! We hope this document helps you get started. Before contributing any code, please sign the `Canonical contributor licence agreement`_. +Welcome to Starcraft! We hope this document helps you get started. Before +contributing any code, please sign the `Canonical contributor licence +agreement`_. Setting up a development environment ------------------------------------ -We use a forking, feature-based workflow, so you should start by forking the repository. Once you've done that, clone the project to your computer using git clone's ``--recurse-submodules`` parameter. (See more on the `git submodules`_ documentation.) +We use a forking, feature-based workflow, so you should start by forking the +repository. Once you've done that, clone the project to your computer using git +clone's ``--recurse-submodules`` parameter. (See more on the `git submodules`_ +documentation.) Tooling ======= -We use a large number of tools for our project. Most of these are installed for you with tox, but you'll need to install: +We use a large number of tools for our project. Most of these are installed for +you with tox, but you'll need to install: -- Python 3.8 (default on Ubuntu 20.04, available on Ubuntu 22.04 through the deadsnakes_ PPA) with setuptools. +- Python 3.8 (default on Ubuntu 20.04, available on Ubuntu 22.04 through the + deadsnakes_ PPA) with setuptools. - tox_ version 4 or later. (3.8+ will automatically provision a v4 virtualenv) -- Pyright_ (it's recommended you install with ``snap install --classic pyright``) +- Pyright_ (it's recommended you install with ``snap install --classic + pyright``) - ShellCheck_ (also available via snap: ``snap install shellcheck``) - pre-commit_ -Once you have all of those installed, you can install the necessary virtual environments for this repository using tox. +Once you have all of those installed, you can install the necessary virtual +environments for this repository using tox. Other tools ########### @@ -33,7 +42,10 @@ A complete list is kept in our pyproject.toml_ file in dev dependencies. Initial Setup ############# -After cloning the repository but before making any changes, it's worth ensuring that the tests, linting and tools all run on your machine. Running ``tox`` with no parameters will create the necessary virtual environments for linting and testing and run those:: +After cloning the repository but before making any changes, it's worth ensuring +that the tests, linting and tools all run on your machine. Running ``tox`` with +no parameters will create the necessary virtual environments for linting and +testing and run those:: tox @@ -41,11 +53,19 @@ If you want to install the environments but not run the tests, you can run:: tox --notest -If you'd like to run the tests with a newer version of Python, you can pass a specific environment. You must have an appropriately versioned Python interpreter installed. For example, to run with Python 3.10, run:: +If you'd like to run the tests with a newer version of Python, you can pass a +specific environment. You must have an appropriately versioned Python +interpreter installed. For example, to run with Python 3.10, run:: tox -e test-py310 -While the use of pre-commit_ is optional, it is highly encouraged, as it runs automatic fixes for files when `git commit` is called, including code formatting with ``black`` and ``ruff``. The versions available in ``apt`` from Debian 11 (bullseye), Ubuntu 22.04 (jammy) and newer are sufficient, but you can also install the latest with ``pip install pre-commit``. Once you've installed it, run ``pre-commit install`` in this git repository to install the pre-commit hooks. +While the use of pre-commit_ is optional, it is highly encouraged, as it runs +automatic fixes for files when ``git commit`` is called, including code +formatting with ``black`` and ``ruff``. The versions available in ``apt`` from +Debian 11 (bullseye), Ubuntu 22.04 (jammy) and newer are sufficient, but you can +also install the latest with ``pip install pre-commit``. Once you've installed +it, run ``pre-commit install`` in this git repository to install the pre-commit +hooks. Tox environments and labels ########################### @@ -59,13 +79,15 @@ We group tox environments with the following labels: * ``integration-tests``: Same as above but for integration tests * ``tests``: The union of ``unit-tests`` and ``integration-tests`` -For each of these, you can see which environments will be run with ``tox list``. For example: +For each of these, you can see which environments will be run with ``tox list``. +For example:: tox list -m lint You can also see all the environments by simply running ``tox list`` -Running ``tox run -m format`` and ``tox run -m lint`` before committing code is recommended. +Running ``tox run -m format`` and ``tox run -m lint`` before committing code is +recommended. .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ diff --git a/README.rst b/README.rst index 7e61560..5c5c87e 100644 --- a/README.rst +++ b/README.rst @@ -6,7 +6,9 @@ A base repository for Starcraft projects. Description ----------- -This project is designed to act as the basis for any future starcraft projects as well as a testbed for any tooling changes we want to make before merging them into other projects. +This project is designed to act as the basis for any future starcraft projects +as well as a testbed for any tooling changes we want to make before merging +them into other projects. Structure --------- @@ -20,14 +22,17 @@ How to create a new project --------------------------- [TODO: Make this a template repository.] -1. [Use this template](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template) to create your repository. -2. Ensure the ``LICENSE`` file represents the current best practices from the Canonical legal team for the specific project you intend to release. (LGPL v3 for libraries, GPL v3 for applications.) -3. Rename any files or directories and ensure references are updated. -4. Replace any appropriate `starcraft` references with the appropriate name. -5. Put correct contact information into CODE_OF_CONDUCT.md -6. Write a new README -7. Import your documentation to ReadTheDocs_. +#. `Use this template`_ to create your repository. +#. Ensure the ``LICENSE`` file represents the current best practices from the + Canonical legal team for the specific project you intend to release. (LGPL v3 + for libraries, GPL v3 for applications.) +#. Rename any files or directories and ensure references are updated. +#. Replace any appropriate ``starcraft`` references with the appropriate name. +#. Put correct contact information into CODE_OF_CONDUCT.md +#. Write a new README +#. Import your documentation to ReadTheDocs_. .. _EditorConfig: https://editorconfig.org/ .. _pre-commit: https://pre-commit.com/ .. _ReadTheDocs: https://docs.readthedocs.io/en/stable/intro/import-guide.html +.. _use this template: https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template diff --git a/tox.ini b/tox.ini index 11381b3..7e1c3dc 100644 --- a/tox.ini +++ b/tox.ini @@ -116,8 +116,13 @@ description = Build documentation with an autoupdating server base = docs commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} -W --watch {tox_root}/starcraft {tox_root}/docs {tox_root}/docs/_build +[lint-docs] +find = git ls-files + [testenv:lint-docs] description = Lint the documentation with sphinx-lint base = docs -commands = sphinx-lint --ignore docs/_build --max-line-length 80 -e all {posargs} docs/ labels = lint +allowlist_externals = bash, xargs +commands_pre = bash -c '{[lint-docs]find} > {env_tmp_dir}/lint_docs_files' +commands = xargs --no-run-if-empty --arg-file {env_tmp_dir}/lint_docs_files sphinx-lint --max-line-length 80 --enable all {posargs} From 9985d46f34a5de6719022683caa1f91b3e379fcc Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Tue, 20 Jun 2023 14:06:07 -0300 Subject: [PATCH 018/147] tools: fix 'setuptools.package.find' directive (#97) The directive is finnicky with regards to globbing, so the tests and docs were being included in the final wheel package. --- pyproject.toml | 9 +-- tests/integration/starbase/test_setuptools.py | 55 +++++++++++++++++++ 2 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 tests/integration/starbase/test_setuptools.py diff --git a/pyproject.toml b/pyproject.toml index d0b9329..d67bca0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ + "build", "coverage[toml]==7.2.7", "pytest==7.3.2", "pytest-cov==4.1.0", @@ -71,13 +72,7 @@ version_scheme = "post-release" git_describe_command = "git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*'" [tool.setuptools.packages.find] -exclude = [ - "dist", - "docs", - "results", - "tests", -] - +include = ["starcraft"] [tool.black] target-version = ["py38"] diff --git a/tests/integration/starbase/test_setuptools.py b/tests/integration/starbase/test_setuptools.py new file mode 100644 index 0000000..60a3826 --- /dev/null +++ b/tests/integration/starbase/test_setuptools.py @@ -0,0 +1,55 @@ +# This file is part of starcraft. +# +# Copyright 2023 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License version 3, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +"""Starcraft integration tests related to building the package.""" +import re +import subprocess +from pathlib import Path +from zipfile import ZipFile + + +def test_packages(tmp_path, request): + """Check wheel generation from our pyproject.toml""" + root_dir = Path(request.config.rootdir) + out_dir = tmp_path + subprocess.check_call(["python3", "-m", "build", "--outdir", out_dir, root_dir]) + wheels = list(tmp_path.glob("*.whl")) + assert len(wheels) == 1 + wheel = wheels[0] + + starcraft_files = [] + + dist_files = [] + dist_info_re = re.compile("starcraft-.*.dist-info") + + invalid = [] + + with ZipFile(wheel) as wheel_zip: + names = [Path(p) for p in wheel_zip.namelist()] + assert len(names) > 1 + for name in names: + top = name.parts[0] + if top == "starcraft": + starcraft_files.append(name) + elif dist_info_re.match(top): + dist_files.append(top) + else: + invalid = [] + + # Only the top-level "starcraft" dir should be present, plus the + # starcraft-xyz-dist-info/ entries. + assert starcraft_files, "No 'starcraft' modules were packaged!" + assert dist_files, "The dist-info directory was not created!" + assert not invalid, f"Invalid files were packaged: {invalid}" From 25d1c1033e218d38722d9f988ce6193d829e505c Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Wed, 21 Jun 2023 08:35:44 -0300 Subject: [PATCH 019/147] tests: provide a fixture with the project's 'main' module (#99) The idea is this: since we have a few tests that are worth running in "downstream" projects (those that merge starbase periodically), instead of having to adapt every test individually in every downstream project we'll use a fixture (project_main_module) that provides the imported module object. So in starbase is returns the 'starcraft' module. The tests are then updated to use this fixture instead of importing the module directly. Downstream projects therefore only need to update the fixture's implementation and the tests will (well, should) work. --- tests/conftest.py | 36 +++++++++++++++++++ .../{starbase => }/test_setuptools.py | 22 ++++++------ tests/integration/test_version.py | 13 +++---- 3 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 tests/conftest.py rename tests/integration/{starbase => }/test_setuptools.py (74%) diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..8240a38 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,36 @@ +# Copyright 2023 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License version 3, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +import types + +import pytest + + +@pytest.fixture() +def project_main_module() -> types.ModuleType: + """Fixture that returns the project's principal package (imported). + + This fixture should be rewritten by "downstream" projects to return the correct + module. Then, every test that uses this fixture will correctly test against the + downstream project. + """ + try: + # This should be the project's main package; downstream projects must update this. + import starcraft + + main_module = starcraft + except ImportError: + pytest.fail( + "Failed to import the project's main module: check if it needs updating" + ) + return main_module diff --git a/tests/integration/starbase/test_setuptools.py b/tests/integration/test_setuptools.py similarity index 74% rename from tests/integration/starbase/test_setuptools.py rename to tests/integration/test_setuptools.py index 60a3826..5bd5528 100644 --- a/tests/integration/starbase/test_setuptools.py +++ b/tests/integration/test_setuptools.py @@ -1,5 +1,3 @@ -# This file is part of starcraft. -# # Copyright 2023 Canonical Ltd. # # This program is free software: you can redistribute it and/or modify it @@ -13,14 +11,14 @@ # # You should have received a copy of the GNU General Public License along # with this program. If not, see . -"""Starcraft integration tests related to building the package.""" +"""Integration tests related to building the package.""" import re import subprocess from pathlib import Path from zipfile import ZipFile -def test_packages(tmp_path, request): +def test_packages(project_main_module, tmp_path, request): """Check wheel generation from our pyproject.toml""" root_dir = Path(request.config.rootdir) out_dir = tmp_path @@ -29,10 +27,12 @@ def test_packages(tmp_path, request): assert len(wheels) == 1 wheel = wheels[0] - starcraft_files = [] + main_module = project_main_module.__name__ + + project_files = [] dist_files = [] - dist_info_re = re.compile("starcraft-.*.dist-info") + dist_info_re = re.compile(f"{main_module}-.*.dist-info") invalid = [] @@ -41,15 +41,15 @@ def test_packages(tmp_path, request): assert len(names) > 1 for name in names: top = name.parts[0] - if top == "starcraft": - starcraft_files.append(name) + if top == main_module: + project_files.append(name) elif dist_info_re.match(top): dist_files.append(top) else: invalid = [] - # Only the top-level "starcraft" dir should be present, plus the - # starcraft-xyz-dist-info/ entries. - assert starcraft_files, "No 'starcraft' modules were packaged!" + # Only the top-level "project_name" dir should be present, plus the + # project_name-xyz-dist-info/ entries. + assert project_files, f"No '{main_module}' modules were packaged!" assert dist_files, "The dist-info directory was not created!" assert not invalid, f"Invalid files were packaged: {invalid}" diff --git a/tests/integration/test_version.py b/tests/integration/test_version.py index 68f4acc..fb7cabb 100644 --- a/tests/integration/test_version.py +++ b/tests/integration/test_version.py @@ -1,5 +1,3 @@ -# This file is part of starcraft. -# # Copyright 2023 Canonical Ltd. # # This program is free software: you can redistribute it and/or modify it @@ -13,12 +11,11 @@ # # You should have received a copy of the GNU General Public License along # with this program. If not, see . -"""Starcraft versioning tests.""" +"""Versioning tests.""" import re import subprocess import pytest -import starcraft def _repo_has_version_tag() -> bool: @@ -44,9 +41,9 @@ def _repo_has_version_tag() -> bool: @pytest.mark.skipif( _repo_has_version_tag(), reason="Skipping because project was versioned from a tag." ) -def test_version_without_tags(): +def test_version_without_tags(project_main_module): """Validate version format when no valid tag are present.""" - version = starcraft.__version__ + version = project_main_module.__version__ # match on '0.0.post+g' # or '0.0.post+g.d<%Y%m%d>' @@ -57,9 +54,9 @@ def test_version_without_tags(): not _repo_has_version_tag(), reason="Skipping because project was not versioned from a tag.", ) -def test_version_with_tags(): +def test_version_with_tags(project_main_module): """Version should be properly formatted when a valid tag exists.""" - version = starcraft.__version__ + version = project_main_module.__version__ # match on 'X.Y.Z' # or 'X.Y.Z.d<%Y%m%d>' From 61afd7e59303aa431027c32054e9fea789c93f61 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 22 Jun 2023 10:50:37 -0400 Subject: [PATCH 020/147] coverage: automatically exclude type checking blocks (#100) --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index d67bca0..58ff762 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,6 +104,9 @@ omit = ["tests/**"] [tool.coverage.report] skip_empty = true fail_under = 80 +exclude_also = [ + "if (typing\\.)?TYPE_CHECKING:", +] [tool.pyright] strict = ["starcraft"] From ab5e737573ed94872534f396fb2fc04f57b0870f Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 22 Jun 2023 10:50:45 -0400 Subject: [PATCH 021/147] ruff: remove type-checking guard blocks (#101) --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 58ff762..265c37a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -175,7 +175,8 @@ select = [ # Base linting rule selections. "RSE", # Errors on pytest raises. "RET", # Simpler logic after return, raise, continue or break "SIM", # Code simplification - "TCH", # Guard imports only used for type checking behind a type-checkning block. + "TCH004", # Remove imports from type-checking guard blocks if used at runtime + "TCH005", # Delete empty type-checking blocks "ARG", # Unused arguments "PTH", # Migrate to pathlib "ERA", # Don't check in commented out code From 3f7c6fa48b57f7dd9635c4d886efa420f7672e4a Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 22 Jun 2023 12:08:10 -0400 Subject: [PATCH 022/147] tox: pass CI environment variable (#102) --- tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tox.ini b/tox.ini index 7e1c3dc..1ed4fb0 100644 --- a/tox.ini +++ b/tox.ini @@ -27,6 +27,8 @@ env_tmp_dir = {user_tmp_dir:{env:XDG_RUNTIME_DIR:{work_dir}}}/tox_tmp/{env_name} set_env = TMPDIR={env_tmp_dir} COVERAGE_FILE={env_tmp_dir}/.coverage_{env_name} +pass_env = + CI [test] # Base configuration for unit and integration tests package = editable From 6363b319a83fd1566f7ad5f3a15584d38ed724d4 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 23 Jun 2023 12:08:18 -0400 Subject: [PATCH 023/147] tools: Add release GH action (#103) Co-authored-by: Tiago Nobrega --- .github/workflows/release-publish.yaml | 59 ++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/release-publish.yaml diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml new file mode 100644 index 0000000..2b1071d --- /dev/null +++ b/.github/workflows/release-publish.yaml @@ -0,0 +1,59 @@ +name: Release +on: + push: + tags: + # These tags should be protected, remember to enable the rule: + # https://github.com/canonical/starbase/settings/tag_protection + - "[0-9]+.[0-9]+.[0-9]+" + +permissions: + contents: write + +jobs: + source-wheel: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" + cache: "pip" + check-latest: true + - name: Build packages + run: | + pip install build twine + python3 -m build + twine check dist/* + - name: Upload pypi packages artifact + uses: actions/upload-artifact@v3 + with: + name: pypi-packages + path: dist/ + pypi: + needs: ["source-wheel"] + runs-on: ubuntu-latest + steps: + - name: Get packages + uses: actions/download-artifact@v3 + with: + name: pypi-packages + path: dist/ + - name: Publish to pypi + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.PYPI_API_TOKEN }} + github-release: + needs: ["source-wheel"] + runs-on: ubuntu-latest + steps: + - name: Get pypi artifacts + uses: actions/download-artifact@v3 + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: | + ** From 376982312a73adae4a58679db9a07cd09fd7c8ca Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 26 Jun 2023 10:39:20 -0400 Subject: [PATCH 024/147] pyproject: only include the actual package in wheel file (#108) Fixes #84 --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 265c37a..3b44ba0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,8 @@ version_scheme = "post-release" git_describe_command = "git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*'" [tool.setuptools.packages.find] -include = ["starcraft"] +include = ["*craft*"] +namespaces = false [tool.black] target-version = ["py38"] From 8b8fed8dc1ed22a50d3f109661f7c562cf00f5e7 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 28 Jun 2023 20:37:12 -0400 Subject: [PATCH 025/147] tox: improve UX (#106) --- HACKING.rst | 11 ++++------- pyproject.toml | 1 - tox.ini | 50 ++++++++++++++++++++++++++++++++++---------------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/HACKING.rst b/HACKING.rst index 122b1d4..74de28d 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -20,11 +20,8 @@ you with tox, but you'll need to install: - Python 3.8 (default on Ubuntu 20.04, available on Ubuntu 22.04 through the deadsnakes_ PPA) with setuptools. -- tox_ version 4 or later. (3.8+ will automatically provision a v4 virtualenv) -- Pyright_ (it's recommended you install with ``snap install --classic - pyright``) +- tox_ version 3.8 or later - ShellCheck_ (also available via snap: ``snap install shellcheck``) -- pre-commit_ Once you have all of those installed, you can install the necessary virtual environments for this repository using tox. @@ -57,7 +54,7 @@ If you'd like to run the tests with a newer version of Python, you can pass a specific environment. You must have an appropriately versioned Python interpreter installed. For example, to run with Python 3.10, run:: - tox -e test-py310 + tox -e test-py3.10 While the use of pre-commit_ is optional, it is highly encouraged, as it runs automatic fixes for files when ``git commit`` is called, including code @@ -75,8 +72,8 @@ We group tox environments with the following labels: * ``format``: Runs all code formatters with auto-fixing * ``type``: Runs all type checkers * ``lint``: Runs all linters (including type checkers) -* ``unit-tests``: Runs unit tests in Python versions on supported LTS's + latest -* ``integration-tests``: Same as above but for integration tests +* ``unit-tests``: Runs unit tests in several supported Python versions +* ``integration-tests``: Run integration tests in several Python versions * ``tests``: The union of ``unit-tests`` and ``integration-tests`` For each of these, you can see which environments will be run with ``tox list``. diff --git a/pyproject.toml b/pyproject.toml index 3b44ba0..11f0da1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,7 +104,6 @@ omit = ["tests/**"] [tool.coverage.report] skip_empty = true -fail_under = 80 exclude_also = [ "if (typing\\.)?TYPE_CHECKING:", ] diff --git a/tox.ini b/tox.ini index 1ed4fb0..22ab1bf 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,12 @@ [tox] env_list = # Environments to run when called with no parameters. - lint-{black,ruff,pyright,shellcheck,codespell,docs} - test-{py38,py310,py311,py312} + format-{black,ruff,codespell} + pre-commit + lint-{black,ruff,mypy,pyright,shellcheck,codespell,docs,yaml} + unit-py3.{8,10,11} + integration-py3.10 +# Integration tests probably take a while, so we're only running them on Python +# 3.10, which is included in core22. minversion = 4.6 # Tox will use these requirements to bootstrap a venv if necessary. # tox-igore-env-name-mismatch allows us to have one virtualenv for all linting. @@ -29,26 +34,28 @@ set_env = COVERAGE_FILE={env_tmp_dir}/.coverage_{env_name} pass_env = CI + CRAFT_* + PYTEST_ADDOPTS [test] # Base configuration for unit and integration tests package = editable extras = dev allowlist_externals = mkdir -commands_pre = mkdir -p results +commands_pre = mkdir -p {tox_root}/results -[testenv:test-{py38,py39,py310,py311,py312}] # Configuration for all tests using pytest +[testenv:{unit,integration}-py3.{8,9,10,11,12}] # Configuration for all tests using pytest base = testenv, test -description = Run unit tests with pytest +description = + unit: Run unit tests with pytest + integration: Run integration tests with pytest labels = - py38, py310, py311, py312: tests, unit-tests -commands = pytest {tty:--color=yes} --cov --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml tests/unit {posargs} - -[testenv:integration-{py38,py39,py310,py311,py312}] -base = testenv, test -description = Run integration tests with pytest -labels = - py38, py310, py311, py312: tests, integration-tests -commands = pytest {tty:--color=yes} --junit-xml=results/test-results-{env_name}.xml tests/integration {posargs} + py3.{8,10,11}: tests + unit-py3.{8,10,11}: unit-tests + integration-py3.{8,10,11}: integration-tests +change_dir = + unit: tests/unit + integration: tests/integration +commands = pytest {tty:--color=yes} --cov={tox_root}/starcraft --cov-config={tox_root}/pyproject.toml --cov-report=xml:{tox_root}/results/coverage-{env_name}.xml --junit-xml={tox_root}/results/test-results-{env_name}.xml {posargs} [lint] # Standard linting configuration package = editable @@ -84,7 +91,7 @@ labels = lint, type allowlist_externals = mypy: mkdir commands_pre = - mypy: mkdir -p .mypy_cache + mypy: mkdir -p {tox_root}/.mypy_cache commands = pyright: pyright {posargs} mypy: mypy --install-types --non-interactive {posargs:.} @@ -98,12 +105,23 @@ commands = ruff: ruff --fix --respect-gitignore {posargs} . codespell: codespell --toml {tox_root}/pyproject.toml --write-changes {posargs} +[testenv:pre-commit] +base = +deps = pre-commit +package = skip +no_package = true +env_dir = {work_dir}/pre-commit +runner = ignore_env_name_mismatch +description = Run pre-commit on staged files or arbitrary pre-commit commands (tox run -e pre-commit -- [args]) +commands = pre-commit {posargs:run} + [docs] # Sphinx documentation configuration extras = docs package = editable no_package = true env_dir = {work_dir}/docs runner = ignore_env_name_mismatch +source_dir = {tox_root}/{project_name} [testenv:build-docs] description = Build sphinx documentation @@ -116,7 +134,7 @@ commands = sphinx-build {posargs:-b html} -W {tox_root}/docs {tox_root}/docs/_bu [testenv:autobuild-docs] description = Build documentation with an autoupdating server base = docs -commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} -W --watch {tox_root}/starcraft {tox_root}/docs {tox_root}/docs/_build +commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} -W --watch {source_dir} {tox_root}/docs {tox_root}/docs/_build [lint-docs] find = git ls-files From 3244cc2ff1abf41ed7c4b6baea0b60ca1d2364ea Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 28 Jun 2023 20:37:50 -0400 Subject: [PATCH 026/147] ci: separate unit and integration tests (#107) --- .github/workflows/tests.yaml | 48 ++++++++++++++++++++++++---- tests/integration/test_setuptools.py | 5 ++- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 715395e..94f0e58 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -1,4 +1,4 @@ -name: Tests, linting, etc. +name: test on: push: branches: @@ -9,7 +9,7 @@ on: pull_request: jobs: - linters: + lint: runs-on: ubuntu-latest steps: - name: Checkout @@ -39,16 +39,16 @@ jobs: echo "::endgroup::" - name: Run Linters run: tox run --skip-pkg-install --no-list-dependencies -m lint - tests: + unit: strategy: matrix: - platform: [ubuntu-20.04, ubuntu-22.04] + platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Set up Python versions on ${{ matrix.platform }} + - name: Set up Python uses: actions/setup-python@v4 with: python-version: | @@ -66,7 +66,7 @@ jobs: - name: Setup Tox environments run: tox run -m tests --notest - name: Test with tox - run: .tox/.tox/bin/tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m tests + run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m unit-tests env: PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload code coverage @@ -80,3 +80,39 @@ jobs: with: name: test-results-${{ matrix.platform }} path: results/ + integration: + strategy: + matrix: + platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] + runs-on: ${{ matrix.platform }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: | + 3.8 + 3.10 + 3.11 + 3.12-dev + cache: 'pip' + - name: Configure environment + run: | + echo "::group::pip install" + python -m pip install tox + echo "::endgroup::" + mkdir -p results + - name: Setup Tox environments + run: tox run -m tests --notest + - name: Test with tox + run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m integration-tests + env: + PYTEST_ADDOPTS: "--no-header -vv -rN" + - name: Upload test results + if: success() || failure() + uses: actions/upload-artifact@v3 + with: + name: test-results-${{ matrix.platform }} + path: results/ diff --git a/tests/integration/test_setuptools.py b/tests/integration/test_setuptools.py index 5bd5528..fda323f 100644 --- a/tests/integration/test_setuptools.py +++ b/tests/integration/test_setuptools.py @@ -14,6 +14,7 @@ """Integration tests related to building the package.""" import re import subprocess +import sys from pathlib import Path from zipfile import ZipFile @@ -22,7 +23,9 @@ def test_packages(project_main_module, tmp_path, request): """Check wheel generation from our pyproject.toml""" root_dir = Path(request.config.rootdir) out_dir = tmp_path - subprocess.check_call(["python3", "-m", "build", "--outdir", out_dir, root_dir]) + subprocess.check_call( + [sys.executable, "-m", "build", "--outdir", out_dir, root_dir] + ) wheels = list(tmp_path.glob("*.whl")) assert len(wheels) == 1 wheel = wheels[0] From 41f01241c112c3ed44665d240e2b636a0b4d178e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 3 Jul 2023 12:54:04 -0400 Subject: [PATCH 027/147] ci: make release publisher workflow fetch correct tags (#110) --- .github/workflows/release-publish.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 2b1071d..4ee72f5 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -15,13 +15,14 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 - with: - fetch-depth: 0 + - name: Fetch tag annotations + run: | + git fetch --force --tags --depth 1 + git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*' - name: Setup Python uses: actions/setup-python@v4 with: python-version: "3.11" - cache: "pip" check-latest: true - name: Build packages run: | From c6349866c91bed00a35e281a035427681a91ac51 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 6 Jul 2023 15:25:48 -0400 Subject: [PATCH 028/147] renovate: fix scheduling (#113) --- .github/renovate.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index fa9af8d..09d90fa 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -91,8 +91,8 @@ } ], timezone: "Etc/UTC", - automergeSchedule: "every weekend", - schedule: "every weekend", + automergeSchedule: ["every weekend"], + schedule: ["every weekend"], prConcurrentLimit: 2, // No more than 2 open PRs at a time. prCreation: "not-pending", // Wait until status checks have completed before raising the PR prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. From 6a8bb7f2a49b01e23c951fdc7f0486eb05b84fa6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 20:05:02 -0400 Subject: [PATCH 029/147] chore(deps): update development dependencies (non-major) (#115) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 11f0da1..40d701b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,19 +19,19 @@ starcraft-hello = "starcraft:hello" dev = [ "build", "coverage[toml]==7.2.7", - "pytest==7.3.2", + "pytest==7.4.0", "pytest-cov==4.1.0", - "pytest-mock==3.10.0", + "pytest-mock==3.11.1", ] lint = [ "black==23.3.0", - "codespell[toml]==2.2.4", + "codespell[toml]==2.2.5", "ruff==0.0.272", "yamllint==1.32.0" ] types = [ - "mypy[reports]==1.3.0", - "pyright==1.1.313", + "mypy[reports]==1.4.1", + "pyright==1.1.316", ] docs = [ "furo==2023.5.20", From 5faae7360bc1ab2b57a79c296e772a4a3323c523 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:07:09 -0400 Subject: [PATCH 030/147] chore(deps): update release-drafter/release-drafter action to v5.24.0 (#117) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-drafter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index e60ebc1..0ee433a 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Release Drafter - uses: release-drafter/release-drafter@v5.23.0 + uses: release-drafter/release-drafter@v5.24.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From be3ae62f3a4fa43ac8f1eb34198d20005f038828 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:10:34 -0400 Subject: [PATCH 031/147] chore(deps): update dependency lint/ruff to v0.0.284 (#119) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 40d701b..e78dc7f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.3.0", "codespell[toml]==2.2.5", - "ruff==0.0.272", + "ruff==0.0.284", "yamllint==1.32.0" ] types = [ From 366e466ff77d1962fbf7b47ef7deb15067ec9273 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:12:51 -0400 Subject: [PATCH 032/147] chore(deps): update dependency tox-gh to v1.3.1 (#121) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 22ab1bf..5720048 100644 --- a/tox.ini +++ b/tox.ini @@ -18,7 +18,7 @@ requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 # renovate: datasource=pypi - tox-gh==1.2.0 + tox-gh==1.3.1 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From 2a28541133a6c30f8543fc909777cde2ae4f6e52 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:13:24 -0400 Subject: [PATCH 033/147] chore(deps): update documentation dependencies (#120) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e78dc7f..581d1ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,14 +34,14 @@ types = [ "pyright==1.1.316", ] docs = [ - "furo==2023.5.20", + "furo==2023.7.26", "sphinx>=6.2.1,<7.0", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", - "sphinx-design==0.4.1", + "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", - "sphinx-toolbox==3.4.0", - "sphinx-lint==0.6.7", + "sphinx-toolbox==3.5.0", + "sphinx-lint==0.6.8", ] [build-system] From 3fca437590325e31c8d914ef21662427a6559596 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 23:13:37 +0000 Subject: [PATCH 034/147] chore(deps): update dependency docs/sphinx to v7 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 581d1ac..9e81d15 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ types = [ ] docs = [ "furo==2023.7.26", - "sphinx>=6.2.1,<7.0", + "sphinx>=7.1.2,<7.2", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", "sphinx-design==0.5.0", From 841c322f7af48fa1cf8ca5a7ed92d143ad196bce Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 15 Aug 2023 19:14:13 -0400 Subject: [PATCH 035/147] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9e81d15..05fa059 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ types = [ ] docs = [ "furo==2023.7.26", - "sphinx>=7.1.2,<7.2", + "sphinx>=7.1.2,<8", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", "sphinx-design==0.5.0", From 9d017f31d0ffedb35197c855bd3b70cbb92a1ad5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 20:13:50 -0500 Subject: [PATCH 036/147] chore(deps): update dependency docs/furo to v2023.8.19 (#122) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 05fa059..88f7582 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ types = [ "pyright==1.1.316", ] docs = [ - "furo==2023.7.26", + "furo==2023.8.19", "sphinx>=7.1.2,<8", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", From 25c3c1da632b8e969f6cc9eca19c6934896a0b56 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 20:14:24 -0500 Subject: [PATCH 037/147] chore(deps): update dependency lint/ruff to v0.0.285 (#123) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 88f7582..c9bb1bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.3.0", "codespell[toml]==2.2.5", - "ruff==0.0.284", + "ruff==0.0.285", "yamllint==1.32.0" ] types = [ From a91362927fce694a957606c2fdca5bf9a275f9f5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 20:39:35 -0500 Subject: [PATCH 038/147] chore(deps): update development dependencies (non-major) (#124) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c9bb1bb..35c03cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,20 +18,20 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ "build", - "coverage[toml]==7.2.7", + "coverage[toml]==7.3.0", "pytest==7.4.0", "pytest-cov==4.1.0", "pytest-mock==3.11.1", ] lint = [ - "black==23.3.0", + "black==23.7.0", "codespell[toml]==2.2.5", "ruff==0.0.285", "yamllint==1.32.0" ] types = [ - "mypy[reports]==1.4.1", - "pyright==1.1.316", + "mypy[reports]==1.5.1", + "pyright==1.1.323", ] docs = [ "furo==2023.8.19", From 83227685d592ac6383932def727447bd0516bb4e Mon Sep 17 00:00:00 2001 From: Sergio Schvezov Date: Thu, 24 Aug 2023 20:10:52 -0300 Subject: [PATCH 039/147] docs: add conventional commits as part of the style Signed-off-by: Sergio Schvezov --- HACKING.rst | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/HACKING.rst b/HACKING.rst index 74de28d..2ea5ee1 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -86,6 +86,33 @@ You can also see all the environments by simply running ``tox list`` Running ``tox run -m format`` and ``tox run -m lint`` before committing code is recommended. +Code Style +========== + +Commits +####### + +Format your commits following the conventional_ commit style. + +Optionally, use the parens to scope to a particular component where +applicable. + +See below for some examples of commit headings:: + + feat: inherit context from services + test: increase unit test stability + fix: check foo before running bar + feat(daemon): foo the bar correctly in the baz + test(daemon): ensure the foo bars correctly in the baz + fix(test): mock class Foo + ci(snap): upload the snap artefacts to Github + chore(deps): update go.mod dependencies + + +Recommended prefixes are: ``fix:``, ``feat:``, ``build:``, ``chore:``, ``ci:``, +``docs:``, ``style:``, ``refactor:``, ``perf:`` and ``test:`` + + .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ .. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa @@ -97,3 +124,4 @@ recommended. .. _ruff: https://github.com/charliermarsh/ruff .. _ShellCheck: https://www.shellcheck.net/ .. _tox: https://tox.wiki +.. _conventional: https://www.conventionalcommits.org/en/v1.0.0/#summary From fe1f9b0748f938d6ca3497cf3d12750b0289ed33 Mon Sep 17 00:00:00 2001 From: Sergio Schvezov Date: Thu, 24 Aug 2023 20:12:17 -0300 Subject: [PATCH 040/147] ci: check for conventional commits Signed-off-by: Sergio Schvezov --- .github/workflows/tests.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 94f0e58..1e20500 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -16,6 +16,8 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 0 + - name: conventional commits + uses: webiny/action-conventional-commits@v1.1.0 - name: Setup Python uses: actions/setup-python@v4 with: From 6577523861657c1a980eba9f3a82bfa562bdde14 Mon Sep 17 00:00:00 2001 From: Callahan Date: Mon, 11 Sep 2023 09:52:41 -0500 Subject: [PATCH 041/147] ci(renovate): allow more branches (#126) Signed-off-by: Callahan Kovacs --- .github/renovate.json5 | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 09d90fa..dc37ae5 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -94,6 +94,7 @@ automergeSchedule: ["every weekend"], schedule: ["every weekend"], prConcurrentLimit: 2, // No more than 2 open PRs at a time. + branchConcurrentLimit: 20, // No more than 20 open branches at a time. prCreation: "not-pending", // Wait until status checks have completed before raising the PR prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. prHourlyLimit: 1, // No more than 1 PR per hour. From de65e53a9e7a5ccf9e812d633dec97f787844673 Mon Sep 17 00:00:00 2001 From: Callahan Date: Tue, 19 Sep 2023 11:56:20 -0500 Subject: [PATCH 042/147] ci(renovate): run tests on renovate branches (#127) Signed-off-by: Callahan Kovacs --- .github/workflows/tests.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 1e20500..e549903 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -6,6 +6,7 @@ on: - "feature/*" - "hotfix/*" - "release/*" + - "renovate/*" pull_request: jobs: From edf7d5a7bb668fe9c279e30d8664df9e584ceb5d Mon Sep 17 00:00:00 2001 From: Callahan Date: Thu, 21 Sep 2023 12:41:06 -0500 Subject: [PATCH 043/147] chore: skip typing checkers in "_version.py" (#128) Signed-off-by: Callahan Kovacs --- pyproject.toml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 35c03cd..265c3be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]==1.5.1", - "pyright==1.1.323", + "pyright==1.1.327", ] docs = [ "furo==2023.8.19", @@ -112,6 +112,12 @@ exclude_also = [ strict = ["starcraft"] pythonVersion = "3.8" pythonPlatform = "Linux" +exclude = [ + "**/.*", + "**/__pycache__", + # pyright might not like the annotations generated by setuptools_scm + "**/_version.py", +] [tool.mypy] python_version = "3.8" From 04f5a63ad63860d9b8e82c1027dec850acbdbe22 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:18:19 -0400 Subject: [PATCH 044/147] chore(deps): update dependency docs/furo to v2023.9.10 (#129) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 265c3be..fd69f45 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ types = [ "pyright==1.1.327", ] docs = [ - "furo==2023.8.19", + "furo==2023.9.10", "sphinx>=7.1.2,<8", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", From 4e97b3f2f40ac3948f8d619c84e349828636a128 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:44:46 -0400 Subject: [PATCH 045/147] chore(deps): update dependency lint/ruff to v0.0.290 (#130) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fd69f45..01d653f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.7.0", "codespell[toml]==2.2.5", - "ruff==0.0.285", + "ruff==0.0.290", "yamllint==1.32.0" ] types = [ From 3d0965364a6f3d26da8b8f6e5891d4c3bb9735ce Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 2 Oct 2023 16:47:24 -0400 Subject: [PATCH 046/147] style: ensure ruff picks up pydantic.validator for class methods (#134) see: https://docs.astral.sh/ruff/settings/#pep8-naming-classmethod-decorators --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 01d653f..20ab919 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -232,6 +232,10 @@ ignore = [ "TRY003", # Avoid specifying long messages outside the exception class ] +[tool.ruff.pep8-naming] +# Allow Pydantic's `@validator` decorator to trigger class method treatment. +classmethod-decorators = ["pydantic.validator"] + [tool.ruff.per-file-ignores] "tests/**.py" = [ # Some things we want for the moin project are unnecessary in tests. "D", # Ignore docstring rules in tests From aa095b1ddf21d02240810dac02dee958771ee3e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 06:49:19 -0400 Subject: [PATCH 047/147] chore(deps): update actions/checkout action to v4 (#132) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docs.yaml | 2 +- .github/workflows/release-publish.yaml | 2 +- .github/workflows/tests.yaml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 4026a0d..cdbc402 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Python diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 4ee72f5..66cf873 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Fetch tag annotations run: | git fetch --force --tags --depth 1 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index e549903..26c5ebd 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: conventional commits @@ -48,7 +48,7 @@ jobs: platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python @@ -89,7 +89,7 @@ jobs: platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python From c3c3313364eb9ece4a2b639ba9c9e1ddae22173f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 06:54:26 -0400 Subject: [PATCH 048/147] chore(deps): update dependency lint/ruff to v0.0.291 (#131) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 20ab919..cf4e375 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.7.0", "codespell[toml]==2.2.5", - "ruff==0.0.290", + "ruff==0.0.291", "yamllint==1.32.0" ] types = [ From a8e334e8af5e6544aadebaeffb44b6de40f9183f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:00:32 -0400 Subject: [PATCH 049/147] chore(deps): update dependency lint/ruff to v0.1.0 (#138) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cf4e375..00b4eea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.7.0", "codespell[toml]==2.2.5", - "ruff==0.0.291", + "ruff==0.1.0", "yamllint==1.32.0" ] types = [ From e668f36c40813c26314bd52515ba2914f1b820bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Oct 2023 13:53:29 -0400 Subject: [PATCH 050/147] chore(deps): update release-drafter/release-drafter action to v5.25.0 (#140) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-drafter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index 0ee433a..3ae8faa 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Release Drafter - uses: release-drafter/release-drafter@v5.24.0 + uses: release-drafter/release-drafter@v5.25.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 62cafdac25014ce81216697152472b47a39e01d6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Oct 2023 14:05:00 -0400 Subject: [PATCH 051/147] chore(deps): update dependency docs/sphinx-lint to v0.8.1 (#141) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 00b4eea..35da2da 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ docs = [ "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", "sphinx-toolbox==3.5.0", - "sphinx-lint==0.6.8", + "sphinx-lint==0.8.1", ] [build-system] From 6f1c345b1f6f486c697de03d6c68e0c30fa3712c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Oct 2023 16:25:40 -0400 Subject: [PATCH 052/147] chore(deps): update development dependencies (non-major) (#137) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 35da2da..c3f2037 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,20 +18,20 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ "build", - "coverage[toml]==7.3.0", - "pytest==7.4.0", + "coverage[toml]==7.3.2", + "pytest==7.4.2", "pytest-cov==4.1.0", - "pytest-mock==3.11.1", + "pytest-mock==3.12.0", ] lint = [ - "black==23.7.0", - "codespell[toml]==2.2.5", + "black==23.10.0", + "codespell[toml]==2.2.6", "ruff==0.1.0", "yamllint==1.32.0" ] types = [ - "mypy[reports]==1.5.1", - "pyright==1.1.327", + "mypy[reports]==1.6.1", + "pyright==1.1.332", ] docs = [ "furo==2023.9.10", From 6b79ebe2df5e6d0b095926c8da451fab7a3e5f29 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 22 Oct 2023 11:03:49 -0400 Subject: [PATCH 053/147] chore(deps): update dependency lint/ruff to v0.1.1 (#142) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c3f2037..91f3fed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.10.0", "codespell[toml]==2.2.6", - "ruff==0.1.0", + "ruff==0.1.1", "yamllint==1.32.0" ] types = [ From eae252843010193e62439b1e416b9043b3816a96 Mon Sep 17 00:00:00 2001 From: Callahan Date: Sun, 5 Nov 2023 06:20:49 -0600 Subject: [PATCH 054/147] ci: colorize tox (#145) Signed-off-by: Callahan Kovacs --- .github/workflows/docs.yaml | 4 ++-- .github/workflows/tests.yaml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index cdbc402..8090655 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -27,9 +27,9 @@ jobs: - name: Install Tox run: pip install tox - name: Lint documentation - run: tox run -e lint-docs + run: tox run --colored yes -e lint-docs - name: Build documentation - run: tox run -e build-docs + run: tox run --colored yes -e build-docs - name: Upload documentation uses: actions/upload-artifact@v3 with: diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 26c5ebd..a953f6e 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -35,13 +35,13 @@ jobs: python -m pip install tox echo "::endgroup::" echo "::group::Create virtual environments for linting processes." - tox run -m lint --notest + tox run --colored yes -m lint --notest echo "::endgroup::" echo "::group::Wait for snap to complete" snap watch --last=install echo "::endgroup::" - name: Run Linters - run: tox run --skip-pkg-install --no-list-dependencies -m lint + run: tox run --skip-pkg-install --no-list-dependencies --colored yes -m lint unit: strategy: matrix: @@ -67,9 +67,9 @@ jobs: echo "::endgroup::" mkdir -p results - name: Setup Tox environments - run: tox run -m tests --notest + run: tox run --colored yes -m tests --notest - name: Test with tox - run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m unit-tests + run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json --colored yes -m unit-tests env: PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload code coverage @@ -108,9 +108,9 @@ jobs: echo "::endgroup::" mkdir -p results - name: Setup Tox environments - run: tox run -m tests --notest + run: tox run --colored yes -m tests --notest - name: Test with tox - run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m integration-tests + run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json --colored yes -m integration-tests env: PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload test results From f78477e6db2afb3314cb0be80cf051ce9e3ac6e8 Mon Sep 17 00:00:00 2001 From: Sheng Yu Date: Sun, 5 Nov 2023 07:21:27 -0500 Subject: [PATCH 055/147] feat(ruff): allow use Any in star args and kwargs (#144) --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 91f3fed..f2a6b7e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -232,6 +232,9 @@ ignore = [ "TRY003", # Avoid specifying long messages outside the exception class ] +[tool.ruff.flake8-annotations] +allow-star-arg-any = true + [tool.ruff.pep8-naming] # Allow Pydantic's `@validator` decorator to trigger class method treatment. classmethod-decorators = ["pydantic.validator"] From bd97d8309b45157be4b43d1d6817acc52474d41f Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Sun, 5 Nov 2023 16:00:18 +0200 Subject: [PATCH 056/147] chore(deps): include ruff in dev updates (#146) Now that ruff has had a 0.1 release it should be updatable with our other linters. --- .github/renovate.json5 | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index dc37ae5..43d5069 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -39,7 +39,6 @@ "lint", "types" ], - excludePackagePatterns: ["ruff"], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: -1, automerge: true @@ -64,12 +63,6 @@ matchDepTypes: ["devDependencies"], matchUpdateTypes: ["major"], prPriority: -3 - }, - { - // Ruff is still unstable, so update it separately. - groupName: "ruff", - matchPackagePatterns: ["^(lint/)?ruff$"], - prPriority: -3 } ], regexManagers: [ From 406c05612f4b96c1fe2c646e85a23fa36767592c Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Sun, 5 Nov 2023 16:04:22 +0200 Subject: [PATCH 057/147] chore: update renovate config (#143) --- .github/renovate.json5 | 17 +++++++++----- .github/workflows/check-renovate.yaml | 33 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/check-renovate.yaml diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 43d5069..abbfa12 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -10,7 +10,7 @@ // Automerge patches, pin changes and digest changes. // Also groups these changes together. groupName: "bugfixes", - excludePackagePrefixes: ["dev", "lint", "types"], + excludePackagePrefixes: ["lint", "types"], matchUpdateTypes: ["patch", "pin", "digest"], prPriority: 3, // Patches should go first! automerge: true @@ -23,13 +23,18 @@ prPriority: 2 }, { - // GitHub Actions are higher priority to update than most dependencies. + // GitHub Actions are higher priority to update than most dependencies since they don't tend to break things. groupName: "GitHub Actions", matchManagers: ["github-actions"], prPriority: 1, automerge: true, }, // Everything not in one of these rules gets priority 0 and falls here. + { + //Do all pydantic-related updates together + groupName: "pydantic etc.", + matchPackagePatterns: ["^pydantic"], + }, { // Minor changes can be grouped and automerged for dev dependencies, but are also deprioritised. groupName: "development dependencies (non-major)", @@ -47,8 +52,8 @@ // Documentation related updates groupName: "documentation dependencies", groupSlug: "doc-dependencies", - matchPackageNames: ["Sphinx"], - matchPackagePatterns: ["^[Ss]phinx.*$", "^furo$"], + matchPackageNames: ["Sphinx", "furo"], + matchPackagePatterns: ["[Ss]phinx.*$"], matchPackagePrefixes: ["docs"], }, { @@ -84,12 +89,12 @@ } ], timezone: "Etc/UTC", - automergeSchedule: ["every weekend"], schedule: ["every weekend"], prConcurrentLimit: 2, // No more than 2 open PRs at a time. branchConcurrentLimit: 20, // No more than 20 open branches at a time. prCreation: "not-pending", // Wait until status checks have completed before raising the PR prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. prHourlyLimit: 1, // No more than 1 PR per hour. - stabilityDays: 2 // Wait 2 days from release before updating. + stabilityDays: 2, // Wait 2 days from release before updating. + automergeStrategy: "squash" // Squash & rebase when auto-merging. } diff --git a/.github/workflows/check-renovate.yaml b/.github/workflows/check-renovate.yaml new file mode 100644 index 0000000..84466fa --- /dev/null +++ b/.github/workflows/check-renovate.yaml @@ -0,0 +1,33 @@ +name: Renovate check +on: + pull_request: + paths: + - ".github/workflows/check-renovate.yaml" + - ".github/renovate.json5" + + # Allows triggering the workflow manually from the Actions tab + workflow_dispatch: + inputs: + enable_ssh_access: + type: boolean + description: 'Enable ssh access' + required: false + default: false + +jobs: + renovate: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install renovate + run: npm install --global renovate + - name: Enable ssh access + uses: mxschmitt/action-tmate@v3 + if: ${{ inputs.enable_ssh_access }} + - name: Check renovate config + run: renovate-config-validator .github/renovate.json5 + - name: Renovate dry-run + run: renovate --dry-run --autodiscover + env: + RENOVATE_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 624e393a43d3675f750e399b670c3a33f8f64344 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 9 Nov 2023 11:11:12 +0200 Subject: [PATCH 058/147] build: run Renovate immediately on craft-* patch releases (#147) --- .github/renovate.json5 | 20 ++++++++++++++++++++ .github/workflows/check-renovate.yaml | 2 ++ 2 files changed, 22 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index abbfa12..bb67d88 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -6,6 +6,26 @@ fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$"] }, packageRules: [ + { + // Internal package minor patch updates get top priority, with auto-merging + groupName: "internal package patch releases", + matchPackagePatterns: ["^craft-.*"], + matchUpdateTypes: ["minor", "patch", "pin", "digest"], + prPriority: 10, + automerge: true, + minimumReleaseAge: "0 seconds", + schedule: ["at any time"], + }, + { + // Same as above, but for hotfix branches, only for patch, and without auto-merging. + groupName: "internal package patch releases (hotfix)", + matchPackagePatterns: ["^craft-.*"], + matchUpdateTypes: ["patch", "pin", "digest"], + prPriority: 10, + minimumReleaseAge: "0 seconds", + schedule: ["at any time"], + matchBaseBranches: ["/^hotfix/.*/"], // All hotfix branches + }, { // Automerge patches, pin changes and digest changes. // Also groups these changes together. diff --git a/.github/workflows/check-renovate.yaml b/.github/workflows/check-renovate.yaml index 84466fa..8cf7d22 100644 --- a/.github/workflows/check-renovate.yaml +++ b/.github/workflows/check-renovate.yaml @@ -25,6 +25,8 @@ jobs: - name: Enable ssh access uses: mxschmitt/action-tmate@v3 if: ${{ inputs.enable_ssh_access }} + with: + limit-access-to-actor: true - name: Check renovate config run: renovate-config-validator .github/renovate.json5 - name: Renovate dry-run From 4ca930b5eac48a2a44fb0412d9eccd32b7538d52 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 10 Nov 2023 14:52:22 +0200 Subject: [PATCH 059/147] style(lint): bump max function args to 8 (#149) fixes #133 --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index f2a6b7e..5dfd5f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -235,6 +235,9 @@ ignore = [ [tool.ruff.flake8-annotations] allow-star-arg-any = true +[tool.ruf.lint.pylint] +max-args = 8 + [tool.ruff.pep8-naming] # Allow Pydantic's `@validator` decorator to trigger class method treatment. classmethod-decorators = ["pydantic.validator"] From b58ed6f3c15ecedc44a8b467d2088cb3477dfb64 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 10 Nov 2023 14:57:43 +0200 Subject: [PATCH 060/147] style(lint): private member access (#150) --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 5dfd5f7..182d741 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -180,6 +180,7 @@ select = [ # Base linting rule selections. "Q", # Consistent quotations "RSE", # Errors on pytest raises. "RET", # Simpler logic after return, raise, continue or break + "SLF", # Prevent accessing private class members. "SIM", # Code simplification "TCH004", # Remove imports from type-checking guard blocks if used at runtime "TCH005", # Delete empty type-checking blocks @@ -250,6 +251,7 @@ classmethod-decorators = ["pydantic.validator"] "S103", # Allow `os.chmod` setting a permissive mask `0o555` on file or directory "S108", # Allow Probable insecure usage of temporary file or directory "PLR0913", # Allow many arguments for test functions + "SLF", # Allow accessing private members in tests ] # isort leaves init files alone by default, this makes ruff ignore them too. "__init__.py" = ["I001"] From 073e45046dad5718d00365d7f5d76fc191b3ed9a Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 17 Nov 2023 17:35:41 -0500 Subject: [PATCH 061/147] style(lint): disable magic value check in tests (#151) fixes #148 --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 182d741..52c5d33 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -251,6 +251,7 @@ classmethod-decorators = ["pydantic.validator"] "S103", # Allow `os.chmod` setting a permissive mask `0o555` on file or directory "S108", # Allow Probable insecure usage of temporary file or directory "PLR0913", # Allow many arguments for test functions + "PLR2004", # Allow magic values in tests "SLF", # Allow accessing private members in tests ] # isort leaves init files alone by default, this makes ruff ignore them too. From a48d59085304269635446ecebda5eeb8178937a9 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 20 Nov 2023 12:35:54 -0500 Subject: [PATCH 062/147] style: stricter ruff linters (#139) --- pyproject.toml | 67 +++++++++++++++++----------- tests/conftest.py | 2 +- tests/integration/test_setuptools.py | 2 +- tests/integration/test_version.py | 8 +++- tests/unit/starbase/test_init.py | 2 +- tox.ini | 2 +- 6 files changed, 50 insertions(+), 33 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 52c5d33..4d5f893 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -166,15 +166,36 @@ select = [ # Base linting rule selections. "UP", # Pyupgrade - note that some of are excluded below due to Python versions "YTT", # flake8-2020: Misuse of `sys.version` and `sys.version_info` "ANN", # Type annotations. + "ASYNC", # Catching blocking calls in async functions + # flake8-bandit: security testing. https://docs.astral.sh/ruff/rules/#flake8-bandit-s + # https://bandit.readthedocs.io/en/latest/plugins/index.html#complete-test-plugin-listing + "S101", "S102", # assert or exec + "S103", "S108", # File permissions and tempfiles - use #noqa to silence when appropriate. + "S104", # Network binds + "S105", "S106", "S107", # Hardcoded passwords + "S110", # try-except-pass (use contextlib.suppress instead) + "S113", # Requests calls without timeouts + "S3", # Serialising, deserialising, hashing, crypto, etc. + "S5", # Unsafe cryptography or YAML loading. + "S602", # Subprocess call with shell=true + "S701", # jinja2 templates without autoescape "BLE", # Do not catch blind exceptions "FBT", # Disallow boolean positional arguments (make them keyword-only) "B0", # Common mistakes and typos. "A", # Shadowing built-ins. + "COM", # Trailing commas "C4", # Encourage comprehensions, which tend to be faster than alternatives. "T10", # Don't call the debugger in production code "ISC", # Implicit string concatenation that can cause subtle issues "ICN", # Only use common conventions for import aliases. "INP", # Implicit namespace packages + # flake8-pie: miscellaneous linters (enabled individually because they're not really related) + "PIE790", # Unnecessary pass statement + "PIE794", # Multiple definitions of class field + "PIE796", # Duplicate value in an enum (reasonable to noqa for backwards compatibility) + "PIE804", # Don't use a dict with unnecessary kwargs + "PIE807", # prefer `list` over `lambda: []` + "PIE810", # Use a tuple rather than multiple calls. E.g. `mystr.startswith(("Hi", "Hello"))` "PYI", # Linting for type stubs. "PT", # Pytest "Q", # Consistent quotations @@ -182,39 +203,28 @@ select = [ # Base linting rule selections. "RET", # Simpler logic after return, raise, continue or break "SLF", # Prevent accessing private class members. "SIM", # Code simplification + "TID", # Tidy imports + # The team have chosen to only use type-checking blocks when necessary to prevent circular imports. + # As such, the only enabled type-checking checks are those that warn of an import that needs to be + # removed from a type-checking block. "TCH004", # Remove imports from type-checking guard blocks if used at runtime "TCH005", # Delete empty type-checking blocks "ARG", # Unused arguments "PTH", # Migrate to pathlib + "FIX", # All TODOs, FIXMEs, etc. should be turned into issues instead. "ERA", # Don't check in commented out code "PGH", # Pygrep hooks "PL", # Pylint "TRY", # Cleaner try/except, -] -extend-select = [ - # Pyupgrade: https://github.com/charliermarsh/ruff#pyupgrade-up - "UP00", "UP01", "UP02", "UP030", "UP032", "UP033", - # "UP034", # Very new, not yet enabled in ruff 0.0.227 - # Annotations: https://github.com/charliermarsh/ruff#flake8-annotations-ann - "ANN0", # Type annotations for arguments other than `self` and `cls` - "ANN2", # Return type annotations - "B026", # Keyword arguments must come after starred arguments - # flake8-bandit: security testing. https://github.com/charliermarsh/ruff#flake8-bandit-s - # https://bandit.readthedocs.io/en/latest/plugins/index.html#complete-test-plugin-listing - "S101", "S102", # assert or exec - "S103", "S108", # File permissions and tempfiles - use #noqa to silence when appropriate. - "S104", # Network binds - "S105", "S106", "S107", # Hardcoded passwords - "S110", # try-except-pass (use contextlib.suppress instead) - "S113", # Requests calls without timeouts - "S3", # Serialising, deserialising, hashing, crypto, etc. - "S506", # Unsafe YAML load - "S508", "S509", # Insecure SNMP - "S701", # jinja2 templates without autoescape + "FLY", # Detect things that would be better as f-strings. + "PERF", # Catch things that can slow down the application like unnecessary casts to list. "RUF001", "RUF002", "RUF003", # Ambiguous unicode characters "RUF005", # Encourages unpacking rather than concatenation "RUF008", # Do not use mutable default values for dataclass attributes + "RUF011", # Don't use static keys in dict comprehensions. + "RUF013", # Prohibit implicit Optionals (PEP 484) "RUF100", # #noqa directive that doesn't flag anything + "RUF200", # If ruff fails to parse pyproject.toml... ] ignore = [ "ANN10", # Type annotations for `self` and `cls` @@ -241,18 +251,21 @@ max-args = 8 [tool.ruff.pep8-naming] # Allow Pydantic's `@validator` decorator to trigger class method treatment. -classmethod-decorators = ["pydantic.validator"] +classmethod-decorators = ["pydantic.validator", "pydantic.root_validator"] [tool.ruff.per-file-ignores] "tests/**.py" = [ # Some things we want for the moin project are unnecessary in tests. "D", # Ignore docstring rules in tests - "ANN", # Ignore type annotations in tests + "ANN", # Ignore type annotations in tests + "ARG", # Allow unused arguments in tests (e.g. for fake functions/methods/classes) "S101", # Allow assertions in tests "S103", # Allow `os.chmod` setting a permissive mask `0o555` on file or directory "S108", # Allow Probable insecure usage of temporary file or directory - "PLR0913", # Allow many arguments for test functions + "PLR0913", # Allow many arguments for test functions (useful if we need many fixtures) "PLR2004", # Allow magic values in tests - "SLF", # Allow accessing private members in tests + "SLF", # Allow accessing private members from tests. +] +"__init__.py" = [ + "I001", # isort leaves init files alone by default, this makes ruff ignore them too. + "F401", # Allows unused imports in __init__ files. ] -# isort leaves init files alone by default, this makes ruff ignore them too. -"__init__.py" = ["I001"] diff --git a/tests/conftest.py b/tests/conftest.py index 8240a38..9bceb63 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -31,6 +31,6 @@ def project_main_module() -> types.ModuleType: main_module = starcraft except ImportError: pytest.fail( - "Failed to import the project's main module: check if it needs updating" + "Failed to import the project's main module: check if it needs updating", ) return main_module diff --git a/tests/integration/test_setuptools.py b/tests/integration/test_setuptools.py index fda323f..d40f9ac 100644 --- a/tests/integration/test_setuptools.py +++ b/tests/integration/test_setuptools.py @@ -24,7 +24,7 @@ def test_packages(project_main_module, tmp_path, request): root_dir = Path(request.config.rootdir) out_dir = tmp_path subprocess.check_call( - [sys.executable, "-m", "build", "--outdir", out_dir, root_dir] + [sys.executable, "-m", "build", "--outdir", out_dir, root_dir], ) wheels = list(tmp_path.glob("*.whl")) assert len(wheels) == 1 diff --git a/tests/integration/test_version.py b/tests/integration/test_version.py index fb7cabb..411b311 100644 --- a/tests/integration/test_version.py +++ b/tests/integration/test_version.py @@ -31,7 +31,10 @@ def _repo_has_version_tag() -> bool: "*[^0-9.]*", ] output = subprocess.run( - git_describe_command, check=True, capture_output=True, text=True + git_describe_command, + check=True, + capture_output=True, + text=True, ).stdout.rstrip("\n") # match on 'X.Y.Z--g' @@ -39,7 +42,8 @@ def _repo_has_version_tag() -> bool: @pytest.mark.skipif( - _repo_has_version_tag(), reason="Skipping because project was versioned from a tag." + _repo_has_version_tag(), + reason="Skipping because project was versioned from a tag.", ) def test_version_without_tags(project_main_module): """Validate version format when no valid tag are present.""" diff --git a/tests/unit/starbase/test_init.py b/tests/unit/starbase/test_init.py index 2aeec01..d124894 100644 --- a/tests/unit/starbase/test_init.py +++ b/tests/unit/starbase/test_init.py @@ -40,5 +40,5 @@ def test_hello_people(mocker): [ mock.call("Hello *craft team!"), mock.call("Hello people!"), - ] + ], ) diff --git a/tox.ini b/tox.ini index 5720048..a99a7ba 100644 --- a/tox.ini +++ b/tox.ini @@ -77,7 +77,7 @@ commands_pre = shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' commands = black: black --check --diff {tty:--color} {posargs} . - ruff: ruff check --respect-gitignore {posargs} . + ruff: ruff check --respect-gitignore {posargs:.} shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck codespell: codespell --toml {tox_root}/pyproject.toml {posargs} yaml: yamllint {posargs} . From cc5a039f7c9f057cf66637994848194a4edb0a55 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 11:55:29 -0500 Subject: [PATCH 063/147] chore(deps): update development dependencies (non-major) (#153) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4d5f893..12b2cf4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,19 +19,19 @@ starcraft-hello = "starcraft:hello" dev = [ "build", "coverage[toml]==7.3.2", - "pytest==7.4.2", + "pytest==7.4.3", "pytest-cov==4.1.0", "pytest-mock==3.12.0", ] lint = [ - "black==23.10.0", + "black==23.11.0", "codespell[toml]==2.2.6", - "ruff==0.1.1", - "yamllint==1.32.0" + "ruff==0.1.6", + "yamllint==1.33.0" ] types = [ - "mypy[reports]==1.6.1", - "pyright==1.1.332", + "mypy[reports]==1.7.1", + "pyright==1.1.337", ] docs = [ "furo==2023.9.10", From 0eead768f55476928f89a241ecb0f857f6f176fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 17:46:05 -0300 Subject: [PATCH 064/147] chore(deps): update dependency docs/sphinx-lint to v0.9.0 (#152) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 12b2cf4..d2c207f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ docs = [ "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", "sphinx-toolbox==3.5.0", - "sphinx-lint==0.8.1", + "sphinx-lint==0.9.0", ] [build-system] From 36a4cbf683d3c99cbd4f3f8fc2770b764d4b1834 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 3 Dec 2023 20:39:14 -0500 Subject: [PATCH 065/147] chore(deps): update dependency types/pyright to v1.1.338 (#155) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d2c207f..7774417 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]==1.7.1", - "pyright==1.1.337", + "pyright==1.1.338", ] docs = [ "furo==2023.9.10", From 54ea9f511bd1bc4f857a27c6fc8c986df67ae9f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:06:24 -0500 Subject: [PATCH 066/147] chore(deps): update webiny/action-conventional-commits action to v1.2.0 (#154) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index a953f6e..726d405 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -18,7 +18,7 @@ jobs: with: fetch-depth: 0 - name: conventional commits - uses: webiny/action-conventional-commits@v1.1.0 + uses: webiny/action-conventional-commits@v1.2.0 - name: Setup Python uses: actions/setup-python@v4 with: From 46e9d222a5e577d15719dae32b4cab4fc099d31b Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 5 Dec 2023 15:31:52 -0500 Subject: [PATCH 067/147] chore: make renovate update pre-commit-config (#156) --- .github/renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index bb67d88..f94e60e 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -3,7 +3,7 @@ extends: ["config:base"], labels: ["dependencies"], // For convenient searching in GitHub pip_requirements: { - fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$"] + fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$", "^.pre-commit-config.yaml$"] }, packageRules: [ { From 86b756888f172cc40c90750503655efb2b25e084 Mon Sep 17 00:00:00 2001 From: Callahan Date: Thu, 7 Dec 2023 15:19:59 -0600 Subject: [PATCH 068/147] chore: use new mypy config `extra_checks` (#158) `strict_concatenate` has been deprecated in favor of `extra_checks` Signed-off-by: Callahan Kovacs --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7774417..d0a50dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -129,7 +129,7 @@ exclude = [ warn_unused_configs = true warn_redundant_casts = true strict_equality = true -strict_concatenate = true +extra_checks = true warn_return_any = true disallow_subclassing_any = true disallow_untyped_decorators = true From 5d460276fa84e3689c6541455acf86212f248515 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 11:58:20 -0500 Subject: [PATCH 069/147] chore(deps): update actions/setup-python action to v5 (#161) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docs.yaml | 2 +- .github/workflows/release-publish.yaml | 2 +- .github/workflows/tests.yaml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 8090655..0e3e3bc 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -21,7 +21,7 @@ jobs: with: fetch-depth: 0 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install Tox diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 66cf873..55ac7a4 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -20,7 +20,7 @@ jobs: git fetch --force --tags --depth 1 git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*' - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.11" check-latest: true diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 726d405..84b42a8 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -20,7 +20,7 @@ jobs: - name: conventional commits uses: webiny/action-conventional-commits@v1.2.0 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' @@ -52,7 +52,7 @@ jobs: with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: | 3.8 @@ -93,7 +93,7 @@ jobs: with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: | 3.8 From 0d328c440d99bde86a2a213bc679eba7d1a4954f Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 12 Dec 2023 11:52:05 -0500 Subject: [PATCH 070/147] style: ignore docstring requirements for overrides (#159) --- pyproject.toml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d0a50dd..64b5cc1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -246,7 +246,17 @@ ignore = [ [tool.ruff.flake8-annotations] allow-star-arg-any = true -[tool.ruf.lint.pylint] +[tool.ruff.lint.pydocstyle] +ignore-decorators = [ # Functions with these decorators don't have to have docstrings. + "typing.overload", # Default configuration + # The next four are all variations on override, so child classes don't have to repeat parent classes' docstrings. + "overrides.override", + "overrides.overrides", + "typing.override", + "typing_extensions.override", +] + +[tool.ruff.lint.pylint] max-args = 8 [tool.ruff.pep8-naming] From 4b2c78e23d9d3325cc0f5c8a95fea7f68d93157f Mon Sep 17 00:00:00 2001 From: Callahan Date: Fri, 15 Dec 2023 12:08:01 -0600 Subject: [PATCH 071/147] docs(HACKING): update commit message guidelines (#162) Signed-off-by: Callahan Kovacs --- .github/renovate.json5 | 3 +- .github/workflows/tests.yaml | 2 + HACKING.rst | 172 ++++++++++++++++++++++++++++++++--- 3 files changed, 165 insertions(+), 12 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index f94e60e..2984fef 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -116,5 +116,6 @@ prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. prHourlyLimit: 1, // No more than 1 PR per hour. stabilityDays: 2, // Wait 2 days from release before updating. - automergeStrategy: "squash" // Squash & rebase when auto-merging. + automergeStrategy: "squash", // Squash & rebase when auto-merging. + semanticCommitType: "build" // use `build` as commit header type (i.e. `build(deps): `) } diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 84b42a8..b22201b 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -19,6 +19,8 @@ jobs: fetch-depth: 0 - name: conventional commits uses: webiny/action-conventional-commits@v1.2.0 + with: + allowed-commit-types: "build,chore,ci,docs,feat,fix,perf,refactor,style,test" - name: Setup Python uses: actions/setup-python@v5 with: diff --git a/HACKING.rst b/HACKING.rst index 2ea5ee1..7001e32 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -86,18 +86,153 @@ You can also see all the environments by simply running ``tox list`` Running ``tox run -m format`` and ``tox run -m lint`` before committing code is recommended. -Code Style -========== - Commits -####### +------- + +Commit messages are based on the `conventional commit`_ style:: + + (): + + + + + +The commit is divided into three sections: a header, body, and footer. + +Header +====== + +The header is required and consists of three subsections: a type, +optional scope, and description. The header must be 72 characters or less. + +Types +##### + +``ci`` +"""""" + +Commits that affect the CI/CD pipeline. + +``build`` +""""""""" + +Commits that affect the build of an application or library. + +This includes dependency updates, which should use the ``deps`` scope +(``build(deps):``). + +``feat`` +"""""""" + +Commits that add a new feature for the user. + +``fix`` +""""""" + +Commits that fix a bug or regression. + +``perf`` +"""""""" + +Commits that improve performance without changing the API or external behavior. + +``refactor`` +""""""""""""" + +Commits that refactor code. + +Using `Martin Fowler's definition`_, refactor means "*a change made +to the internal structure of software to make it easier to understand and +cheaper to modify without changing its observable behavior.*" + +``style`` +"""""""""" + +Commits that change the syntax, format, or aesthics of any text the codebase. +The meaning of the text should not change. + +Examples include: +* automatic changes from tools like ``black`` and ``ruff format`` +* changes to documentation that don't affect the meaning +* correcting a typo + +``test`` +"""""""" + +Commits that improve, add, or remove tests. -Format your commits following the conventional_ commit style. +``docs`` +"""""""" -Optionally, use the parens to scope to a particular component where -applicable. +Commits that affect the contents of the documentation. -See below for some examples of commit headings:: +Changes to how documentation is built should use ``build(docs)::``. + +Changes to how the documentation is built in the CI/CD pipeline should use +the ``ci(docs):``. + +``chore`` +""""""""" + +Miscellaneous commits that don't fit into any other type. + +Examples include: + +* edits to a comment or docstring +* type changes +* accommodating a developer-facing deprecation warning +* many *small* fixes for an existing PR +* merge commits (``chore(merge):``) + +Choosing the right type +""""""""""""""""""""""" + +Sometimes, multiple types may be appropriate for a PR. + +This may signal that a commit is doing more than one thing and should be +broken into multiple smaller commits. For example, a commit should not refactor +code and fix a bug. This should be two separate commits. + +In other scenarios, multiple types could be appropriate because of the nature +of the commit. This can happen with ``test`` and ``docs``, which can be used +as types or scopes. + +The types above are ordered by descending priority. The first appropriate type +should be used. + +For example, refactoring a test suite could have the header +``test(project): reorganize tests`` or +``refactor(test): reorganize project tests``. ``refactor`` has a higher +priority than ``test``, so the latter option is correct. + + +Scope +##### + +A scope is an optional part of the commit header. It adds additional context +by specifying what part of the codebase will be affected. + +It should be a tangible part of the codebase, like a directory, module, or +class name. + +If a commit affects many areas of the codebase, the scope should be omitted; +``many`` is not an accepted scope. + +Description +########### + +The description is written in the imperative mood (present tense, second +person). The description should complete the following sentence:: + + If applied, this commit will . + +The description does not begin with capital letter (unless it's a proper +noun) and does not end with puncuation mark. + +Examples +######## + +Examples of commit headings:: feat: inherit context from services test: increase unit test stability @@ -108,15 +243,31 @@ See below for some examples of commit headings:: ci(snap): upload the snap artefacts to Github chore(deps): update go.mod dependencies +Body +==== + +The body is an optional section of the commit to provide more context. +It should be succinct (no more than 3-4 sentences) and may reference relevant +bugs and issues. + +Footer +====== + +The footer is an optional section of the commit message that can mention the +signer and co-authors of the commit. + +Example footers:: -Recommended prefixes are: ``fix:``, ``feat:``, ``build:``, ``chore:``, ``ci:``, -``docs:``, ``style:``, ``refactor:``, ``perf:`` and ``test:`` + Signed-off-by: <> + Co-authored-by: <> .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ +.. _`conventional commit`: https://www.conventionalcommits.org/en/v1.0.0/#summary .. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa .. _`git submodules`: https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules +.. _`Martin Fowler's definition`: https://refactoring.com/ .. _pre-commit: https://pre-commit.com/ .. _pyproject.toml: ./pyproject.toml .. _Pyright: https://github.com/microsoft/pyright @@ -124,4 +275,3 @@ Recommended prefixes are: ``fix:``, ``feat:``, ``build:``, ``chore:``, ``ci:``, .. _ruff: https://github.com/charliermarsh/ruff .. _ShellCheck: https://www.shellcheck.net/ .. _tox: https://tox.wiki -.. _conventional: https://www.conventionalcommits.org/en/v1.0.0/#summary From ade6eba0d6be1a357cb23c56a3518171ce2c6142 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 4 Jan 2024 09:09:47 -0500 Subject: [PATCH 072/147] ci(deps): update artifact actions (#164) --- .github/workflows/docs.yaml | 2 +- .github/workflows/release-publish.yaml | 4 ++-- .github/workflows/tests.yaml | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 0e3e3bc..c2b688c 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -31,7 +31,7 @@ jobs: - name: Build documentation run: tox run --colored yes -e build-docs - name: Upload documentation - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: docs path: docs/_build/ diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 55ac7a4..27aff74 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -30,7 +30,7 @@ jobs: python3 -m build twine check dist/* - name: Upload pypi packages artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: pypi-packages path: dist/ @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Get packages - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: pypi-packages path: dist/ diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b22201b..11d2abc 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -81,9 +81,9 @@ jobs: files: coverage*.xml - name: Upload test results if: success() || failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: test-results-${{ matrix.platform }} + name: unit-test-results-${{ matrix.platform }} path: results/ integration: strategy: @@ -117,7 +117,7 @@ jobs: PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload test results if: success() || failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: test-results-${{ matrix.platform }} + name: integration-test-results-${{ matrix.platform }} path: results/ From 8931c9ab5acb27b355781339abb6c4a326e49e62 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 14:02:02 -0500 Subject: [PATCH 073/147] chore(deps): update actions/download-artifact action to v4 (#163) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-publish.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 27aff74..a387c29 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -52,7 +52,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Get pypi artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 - name: Release uses: softprops/action-gh-release@v1 with: From d6130fd12f9f4665b3acfb47facae4ec0bbed852 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 4 Jan 2024 16:23:53 -0500 Subject: [PATCH 074/147] ci(deps): make renovate update pyright separately. (#165) --- .github/renovate.json5 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 2984fef..32cff51 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -88,6 +88,12 @@ matchDepTypes: ["devDependencies"], matchUpdateTypes: ["major"], prPriority: -3 + }, + { + // Pyright makes regular breaking changes in patch releases, so we separate these + // and do them independently. + matchPackageNames: ["pyright"], + prPriority: -4 } ], regexManagers: [ From 48adeaf5b93b260c88cc3af959ed9294d076bbe6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:56:00 -0500 Subject: [PATCH 075/147] chore(deps): update dependency docs/sphinx-lint to v0.9.1 (#166) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 64b5cc1..03eb28f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ docs = [ "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", "sphinx-toolbox==3.5.0", - "sphinx-lint==0.9.0", + "sphinx-lint==0.9.1", ] [build-system] From cf0b86cee65806cf387ff254d5611ec410cf557c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 14:50:54 -0500 Subject: [PATCH 076/147] chore(deps): update dependency setuptools to v67.8.0 (#167) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 03eb28f..0120bdb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ docs = [ [build-system] requires = [ - "setuptools==67.7.2", + "setuptools==67.8.0", "setuptools_scm[toml]>=7.1" ] build-backend = "setuptools.build_meta" From a1c10a749224d9dace81e2b7262d680b102ba2a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 08:55:45 -0500 Subject: [PATCH 077/147] chore(deps): update dependency setuptools to v69 (#168) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0120bdb..97f3d54 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ docs = [ [build-system] requires = [ - "setuptools==67.8.0", + "setuptools==69.0.3", "setuptools_scm[toml]>=7.1" ] build-backend = "setuptools.build_meta" From 621a10514d86c02d6b05371ae07822eac354ab9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 00:04:06 -0500 Subject: [PATCH 078/147] chore(deps): update dependency lint/black to v24 (#169) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 97f3d54..7b20e1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,7 @@ dev = [ "pytest-mock==3.12.0", ] lint = [ - "black==23.11.0", + "black==24.1.0", "codespell[toml]==2.2.6", "ruff==0.1.6", "yamllint==1.33.0" From f46054709551b9e9e9ebb89148bc566c1dd7b028 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 22:53:19 -0500 Subject: [PATCH 079/147] chore(deps): update dependency docs/furo to v2024 (#173) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7b20e1d..997758c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ types = [ "pyright==1.1.338", ] docs = [ - "furo==2023.9.10", + "furo==2024.1.29", "sphinx>=7.1.2,<8", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", From 2d56dce04ff1ca14dff28f68a5ba4f8a0df9757c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 03:53:45 +0000 Subject: [PATCH 080/147] chore(deps): update webiny/action-conventional-commits action to v1.3.0 --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 11d2abc..89d62b3 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -18,7 +18,7 @@ jobs: with: fetch-depth: 0 - name: conventional commits - uses: webiny/action-conventional-commits@v1.2.0 + uses: webiny/action-conventional-commits@v1.3.0 with: allowed-commit-types: "build,chore,ci,docs,feat,fix,perf,refactor,style,test" - name: Setup Python From 20eb12967d9eccc494506ebbd5def38d71ac2817 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 31 Jan 2024 06:17:12 -0500 Subject: [PATCH 081/147] build(deps): update pyright (#170) * Disable pyright complaints for mocks * Move `types/pyright` into renovate's pyright group --- .github/renovate.json5 | 2 +- pyproject.toml | 2 +- tests/unit/starbase/test_init.py | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 32cff51..a51c1e6 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -92,7 +92,7 @@ { // Pyright makes regular breaking changes in patch releases, so we separate these // and do them independently. - matchPackageNames: ["pyright"], + matchPackageNames: ["pyright", "types/pyright"], prPriority: -4 } ], diff --git a/pyproject.toml b/pyproject.toml index 997758c..81895bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]==1.7.1", - "pyright==1.1.338", + "pyright==1.1.349", ] docs = [ "furo==2024.1.29", diff --git a/tests/unit/starbase/test_init.py b/tests/unit/starbase/test_init.py index d124894..ca98cfd 100644 --- a/tests/unit/starbase/test_init.py +++ b/tests/unit/starbase/test_init.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Basic Starcraft package demo unit tests.""" +# pyright: reportFunctionMemberAccess=false from unittest import mock import starcraft From 3feb312f9d94e474b3181a2bcc37617b46e8d2f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 14:52:49 -0300 Subject: [PATCH 082/147] chore(deps): update development dependencies (non-major) (#174) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 81895bd..f39df12 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,19 +18,19 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ "build", - "coverage[toml]==7.3.2", - "pytest==7.4.3", + "coverage[toml]==7.4.1", + "pytest==7.4.4", "pytest-cov==4.1.0", "pytest-mock==3.12.0", ] lint = [ - "black==24.1.0", + "black==24.1.1", "codespell[toml]==2.2.6", - "ruff==0.1.6", + "ruff==0.1.14", "yamllint==1.33.0" ] types = [ - "mypy[reports]==1.7.1", + "mypy[reports]==1.8.0", "pyright==1.1.349", ] docs = [ From ceb64e2bfb97d6138ae74d625dcd33d5b043ae9b Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Wed, 31 Jan 2024 15:11:30 -0300 Subject: [PATCH 083/147] ci: fix regex for pre-commit-config.yaml (#175) --- .github/renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index a51c1e6..02e0c28 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -110,7 +110,7 @@ fileMatch: [".pre-commit-config.yaml"], depTypeTemplate: "devDependencies", matchStrings: [ - "# renovate: datasource=(?\\S+);\\s*depName=(?.*?)\n\s+rev: \"v?(?.*?)\"" + "# renovate: datasource=(?\\S+);\\s*depName=(?.*?)\n\\s+rev: \"v?(?.*?)\"" ] } ], From d79b26bcfdcd476f780798b58f9e15b69bef7fad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 13:16:28 -0500 Subject: [PATCH 084/147] chore(deps): update dependency dev/pytest to v8 (#172) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f39df12..746b671 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ starcraft-hello = "starcraft:hello" dev = [ "build", "coverage[toml]==7.4.1", - "pytest==7.4.4", + "pytest==8.0.0", "pytest-cov==4.1.0", "pytest-mock==3.12.0", ] From 9815d93a0767231f3245e206abb1a27bc910e665 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:02:14 -0500 Subject: [PATCH 085/147] chore(deps): update dependency black to v24 (#176) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5a9b3a4..8ff3157 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,7 @@ repos: args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black # renovate: datasource=pypi;depName=black - rev: "23.3.0" + rev: "24.1.1" hooks: - id: black - repo: https://github.com/adrienverge/yamllint.git From c6d29c32a697c1b5170392fc5ce224ca62edfd2a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:28:58 -0500 Subject: [PATCH 086/147] chore(deps): update dependency ruff to v0.1.15 (#177) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8ff3157..28fa874 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: - id: mixed-line-ending - repo: https://github.com/charliermarsh/ruff-pre-commit # renovate: datasource=pypi;depName=ruff - rev: "v0.0.267" + rev: "v0.1.15" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 0cfc30a4ef787520405cf48babeee3d5852a35a6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:29:24 -0500 Subject: [PATCH 087/147] chore(deps): update dependency yamllint to v1.33.0 (#178) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 28fa874..f90f393 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,6 +25,6 @@ repos: - id: black - repo: https://github.com/adrienverge/yamllint.git # renovate: datasource=pypi;depName=yamllint - rev: "v1.31.0" + rev: "v1.33.0" hooks: - id: yamllint From 5a0b0ea9ae528e9682745196e2940c4038446abd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:06:56 -0500 Subject: [PATCH 088/147] chore(deps): update dependency lint/ruff to v0.2.0 (#181) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 746b671..5c17f08 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==24.1.1", "codespell[toml]==2.2.6", - "ruff==0.1.14", + "ruff==0.2.0", "yamllint==1.33.0" ] types = [ From 4d11ec48cb2568086d011590f3a44167646e46f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:07:14 +0000 Subject: [PATCH 089/147] chore(deps): update github actions --- .github/workflows/release-drafter.yaml | 2 +- .github/workflows/tests.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index 3ae8faa..4c6db3e 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Release Drafter - uses: release-drafter/release-drafter@v5.25.0 + uses: release-drafter/release-drafter@v6.0.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 89d62b3..42dce53 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -75,7 +75,7 @@ jobs: env: PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload code coverage - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: directory: ./results/ files: coverage*.xml From f6db1eb7e673e4be3404f6a6db4c8fb4e0cbdf82 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 5 Feb 2024 12:38:12 -0500 Subject: [PATCH 090/147] chore: make pre-commit linters use lint group for renovate (#183) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f90f393..c44e4de 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,18 +13,18 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/charliermarsh/ruff-pre-commit - # renovate: datasource=pypi;depName=ruff + # renovate: datasource=pypi;depName=lint/ruff rev: "v0.1.15" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black - # renovate: datasource=pypi;depName=black + # renovate: datasource=pypi;depName=lint/black rev: "24.1.1" hooks: - id: black - repo: https://github.com/adrienverge/yamllint.git - # renovate: datasource=pypi;depName=yamllint + # renovate: datasource=pypi;depName=lint/yamllint rev: "v1.33.0" hooks: - id: yamllint From 234b360057791c38fdb8430afd2c405537979464 Mon Sep 17 00:00:00 2001 From: Callahan Date: Mon, 5 Feb 2024 14:49:52 -0600 Subject: [PATCH 091/147] docs(HACKING): clarify commit header for merges (#184) Signed-off-by: Callahan Kovacs --- HACKING.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/HACKING.rst b/HACKING.rst index 7001e32..945cf96 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -182,7 +182,10 @@ Examples include: * type changes * accommodating a developer-facing deprecation warning * many *small* fixes for an existing PR -* merge commits (``chore(merge):``) +* merge commits (``chore(merge): '' into ''``) + + * the remote name should not be included (i.e. use ``'main'`` + instead of ``'origin/main'``) Choosing the right type """"""""""""""""""""""" From 5b1422bc123b12f7213982fed24d9836f16bd86e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 6 Feb 2024 09:34:58 -0500 Subject: [PATCH 092/147] ci(renovate): fix pre-commit dependency manager (#185) --- .github/renovate.json5 | 5 +++-- .pre-commit-config.yaml | 7 ++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 02e0c28..9c4bd55 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -108,9 +108,10 @@ { // .pre-commit-config.yaml version updates fileMatch: [".pre-commit-config.yaml"], - depTypeTemplate: "devDependencies", + datasourceTemplate: "pypi", + depTypeTemplate: "lint", matchStrings: [ - "# renovate: datasource=(?\\S+);\\s*depName=(?.*?)\n\\s+rev: \"v?(?.*?)\"" + "- repo: .*/<(?\\S+)\\s*\\n\\s*rev:\s+\"?v?(?\\S*)\"?", ] } ], diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c44e4de..f84e07a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: "v4.4.0" hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -12,19 +12,16 @@ repos: - id: check-toml - id: fix-byte-order-marker - id: mixed-line-ending - - repo: https://github.com/charliermarsh/ruff-pre-commit - # renovate: datasource=pypi;depName=lint/ruff + - repo: https://github.com/astral-sh/ruff-pre-commit rev: "v0.1.15" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black - # renovate: datasource=pypi;depName=lint/black rev: "24.1.1" hooks: - id: black - repo: https://github.com/adrienverge/yamllint.git - # renovate: datasource=pypi;depName=lint/yamllint rev: "v1.33.0" hooks: - id: yamllint From 64dc591c581c3b43911fc21ac1f8570bfcc5931c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Feb 2024 17:06:15 -0500 Subject: [PATCH 093/147] chore(deps): update dependency docs/sphinx-autobuild to v2024 (#187) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5c17f08..a00fc27 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ types = [ docs = [ "furo==2024.1.29", "sphinx>=7.1.2,<8", - "sphinx-autobuild==2021.3.14", + "sphinx-autobuild==2024.2.4", "sphinx-copybutton==0.5.2", "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", From 455aa11710a82a74b2e55b4c9b6634daaf88e652 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Feb 2024 17:06:45 -0500 Subject: [PATCH 094/147] chore(deps): update development dependencies (non-major) (#186) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a00fc27..6a269c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,12 +26,12 @@ dev = [ lint = [ "black==24.1.1", "codespell[toml]==2.2.6", - "ruff==0.2.0", - "yamllint==1.33.0" + "ruff==0.2.1", + "yamllint==1.34.0" ] types = [ "mypy[reports]==1.8.0", - "pyright==1.1.349", + "pyright==1.1.350", ] docs = [ "furo==2024.1.29", From 9d271a7c08bd20002a5fb273b9a9fd446f3bc335 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 16 Feb 2024 11:34:18 -0500 Subject: [PATCH 095/147] build: loosen requirements (#190) The modified dependencies are known to be sufficiently stable that the given version ranges are unlikely to cause breakages. --- pyproject.toml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6a269c5..e49e22e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,35 +18,35 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ "build", - "coverage[toml]==7.4.1", - "pytest==8.0.0", - "pytest-cov==4.1.0", - "pytest-mock==3.12.0", + "coverage[toml]~=7.4", + "pytest~=8.0", + "pytest-cov~=4.1", + "pytest-mock~=3.12", ] lint = [ - "black==24.1.1", - "codespell[toml]==2.2.6", - "ruff==0.2.1", - "yamllint==1.34.0" + "black~=24.1", + "codespell[toml]~=2.2", + "ruff~=0.2.1", + "yamllint~=1.34" ] types = [ - "mypy[reports]==1.8.0", + "mypy[reports]~=1.8.0", "pyright==1.1.350", ] docs = [ "furo==2024.1.29", - "sphinx>=7.1.2,<8", - "sphinx-autobuild==2024.2.4", + "sphinx~=7.1", + "sphinx-autobuild~=2024.2", "sphinx-copybutton==0.5.2", "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", - "sphinx-toolbox==3.5.0", + "sphinx-toolbox~=3.5", "sphinx-lint==0.9.1", ] [build-system] requires = [ - "setuptools==69.0.3", + "setuptools>=69.0", "setuptools_scm[toml]>=7.1" ] build-backend = "setuptools.build_meta" From 826a08e26eaa745446c7eead519690d4c9bb9fa6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:14:35 -0500 Subject: [PATCH 096/147] chore(deps): update dependency types/pyright to v1.1.351 (#189) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e49e22e..e98240f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]~=1.8.0", - "pyright==1.1.350", + "pyright==1.1.351", ] docs = [ "furo==2024.1.29", From 2130cd0b5f85324fafb7c2416a35d3471762495b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 19:54:27 -0500 Subject: [PATCH 097/147] chore(deps): update development dependencies (non-major) (#191) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e98240f..a7fb1f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,12 +26,12 @@ dev = [ lint = [ "black~=24.1", "codespell[toml]~=2.2", - "ruff~=0.2.1", + "ruff~=0.3.0", "yamllint~=1.34" ] types = [ "mypy[reports]~=1.8.0", - "pyright==1.1.351", + "pyright==1.1.352", ] docs = [ "furo==2024.1.29", From d319ea93beca59ffbf0c5bbfe653ff956bb17c2a Mon Sep 17 00:00:00 2001 From: Callahan Date: Mon, 4 Mar 2024 20:07:26 -0600 Subject: [PATCH 098/147] chore: update ruff settings (#192) Signed-off-by: Callahan Kovacs --- pyproject.toml | 10 +++++----- tox.ini | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a7fb1f8..181882a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -153,7 +153,7 @@ extend-exclude = [ "__pycache__", ] # Follow ST063 - Maintaining and updating linting specifications for updating these. -select = [ # Base linting rule selections. +lint.select = [ # Base linting rule selections. # See the internal document for discussion: # https://docs.google.com/document/d/1i1n8pDmFmWi4wTDpk-JfnWCVUThPJiggyPi2DYwBBu4/edit # All sections here are stable in ruff and shouldn't randomly introduce @@ -226,7 +226,7 @@ select = [ # Base linting rule selections. "RUF100", # #noqa directive that doesn't flag anything "RUF200", # If ruff fails to parse pyproject.toml... ] -ignore = [ +lint.ignore = [ "ANN10", # Type annotations for `self` and `cls` #"E203", # Whitespace before ":" -- Commented because ruff doesn't currently check E203 "E501", # Line too long (reason: black will automatically fix this for us) @@ -243,7 +243,7 @@ ignore = [ "TRY003", # Avoid specifying long messages outside the exception class ] -[tool.ruff.flake8-annotations] +[tool.ruff.lint.flake8-annotations] allow-star-arg-any = true [tool.ruff.lint.pydocstyle] @@ -259,11 +259,11 @@ ignore-decorators = [ # Functions with these decorators don't have to have docs [tool.ruff.lint.pylint] max-args = 8 -[tool.ruff.pep8-naming] +[tool.ruff.lint.pep8-naming] # Allow Pydantic's `@validator` decorator to trigger class method treatment. classmethod-decorators = ["pydantic.validator", "pydantic.root_validator"] -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "tests/**.py" = [ # Some things we want for the moin project are unnecessary in tests. "D", # Ignore docstring rules in tests "ANN", # Ignore type annotations in tests diff --git a/tox.ini b/tox.ini index a99a7ba..e528613 100644 --- a/tox.ini +++ b/tox.ini @@ -102,7 +102,7 @@ base = testenv, lint labels = format commands = black: black {tty:--color} {posargs} . - ruff: ruff --fix --respect-gitignore {posargs} . + ruff: ruff check --fix --respect-gitignore {posargs} . codespell: codespell --toml {tox_root}/pyproject.toml --write-changes {posargs} [testenv:pre-commit] From c9c4de153f36647bb07fac864f08a2e7274a6ee9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 13:43:55 -0400 Subject: [PATCH 099/147] chore(deps): update development dependencies (non-major) (#193) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 181882a..b12ecaa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,8 +30,8 @@ lint = [ "yamllint~=1.34" ] types = [ - "mypy[reports]~=1.8.0", - "pyright==1.1.352", + "mypy[reports]~=1.9.0", + "pyright==1.1.355", ] docs = [ "furo==2024.1.29", From ef54940298fcda86c4dec30679695d77f65910dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 13:57:06 -0400 Subject: [PATCH 100/147] chore(deps): update softprops/action-gh-release action to v2 (#194) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-publish.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index a387c29..4d30ed0 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -54,7 +54,7 @@ jobs: - name: Get pypi artifacts uses: actions/download-artifact@v4 - name: Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: files: | ** From bf22cfe3e91191f8a2778a0e2afbd6180d534a0c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 08:52:16 -0300 Subject: [PATCH 101/147] chore(deps): update dependency dev/pytest-cov to v5 (#195) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b12ecaa..6929eb1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ dev = [ "build", "coverage[toml]~=7.4", "pytest~=8.0", - "pytest-cov~=4.1", + "pytest-cov~=5.0", "pytest-mock~=3.12", ] lint = [ From 5d10b2a8c67d05994ce964a60d2b18abcd3435a9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:43:51 -0400 Subject: [PATCH 102/147] chore(deps): update dependency types/pyright to v1.1.356 (#196) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6929eb1..5deca2b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]~=1.9.0", - "pyright==1.1.355", + "pyright==1.1.356", ] docs = [ "furo==2024.1.29", From 955f4455e49f169418c042c5641c24ef53a8d2bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 17:18:45 -0400 Subject: [PATCH 103/147] chore(deps): update dependency types/pyright to v1.1.357 (#198) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5deca2b..c3a8927 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]~=1.9.0", - "pyright==1.1.356", + "pyright==1.1.357", ] docs = [ "furo==2024.1.29", From 56b1e71cab36bd54ae0b15446ca58486087dd7ce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 15:50:27 -0400 Subject: [PATCH 104/147] chore(deps): update dependency types/pyright to v1.1.358 (#202) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c3a8927..9362313 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]~=1.9.0", - "pyright==1.1.357", + "pyright==1.1.358", ] docs = [ "furo==2024.1.29", From 09b91ba2f9badbb2edde5c5659e252e6d1e893d0 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 23 Apr 2024 12:44:24 -0400 Subject: [PATCH 105/147] chore: use ruff snap (#204) --- .github/workflows/tests.yaml | 2 +- HACKING.rst | 2 +- pyproject.toml | 1 - tox.ini | 5 +++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 42dce53..aecafab 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,7 +31,7 @@ jobs: echo "::group::Begin snap install" echo "Installing snaps in the background while running apt and pip..." sudo snap install --no-wait --classic pyright - sudo snap install --no-wait shellcheck + sudo snap install --no-wait shellcheck ruff echo "::endgroup::" echo "::group::pip install" python -m pip install tox diff --git a/HACKING.rst b/HACKING.rst index 945cf96..4477e26 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -22,6 +22,7 @@ you with tox, but you'll need to install: deadsnakes_ PPA) with setuptools. - tox_ version 3.8 or later - ShellCheck_ (also available via snap: ``snap install shellcheck``) +- ruff_ (also available via snap: ``snap install ruff``) Once you have all of those installed, you can install the necessary virtual environments for this repository using tox. @@ -32,7 +33,6 @@ Some other tools we use for code quality include: - Black_ for code formatting - pytest_ for testing -- ruff_ for linting (and some additional formatting) A complete list is kept in our pyproject.toml_ file in dev dependencies. diff --git a/pyproject.toml b/pyproject.toml index 9362313..0f6bb4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,6 @@ dev = [ lint = [ "black~=24.1", "codespell[toml]~=2.2", - "ruff~=0.3.0", "yamllint~=1.34" ] types = [ diff --git a/tox.ini b/tox.ini index e528613..90f7880 100644 --- a/tox.ini +++ b/tox.ini @@ -62,6 +62,9 @@ package = editable extras = lint env_dir = {work_dir}/linting runner = ignore_env_name_mismatch +allowlist_externals = + shellcheck: bash, xargs + ruff: ruff [shellcheck] find = git ls-files @@ -71,8 +74,6 @@ filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: description = Lint the source code base = testenv, lint labels = lint -allowlist_externals = - shellcheck: bash, xargs commands_pre = shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' commands = From 06f6913038c22f48545cc29d7b2b42f3c3eb6214 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:05:11 -0400 Subject: [PATCH 106/147] chore(deps): update dependency types/pyright to v1.1.359 (#206) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0f6bb4b..cf7d295 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ lint = [ ] types = [ "mypy[reports]~=1.9.0", - "pyright==1.1.358", + "pyright==1.1.359", ] docs = [ "furo==2024.1.29", From 919199006dcd367c8ea6e919f564f3660b2045dd Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 24 Apr 2024 15:59:31 -0400 Subject: [PATCH 107/147] ci: update Python versions --- .github/workflows/tests.yaml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index aecafab..c505063 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -24,7 +24,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' cache: 'pip' - name: Configure environment run: | @@ -57,10 +57,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.8 3.10 - 3.11 - 3.12-dev + 3.12 + 3.13-dev cache: 'pip' - name: Configure environment run: | @@ -98,10 +97,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.8 3.10 - 3.11 - 3.12-dev + 3.12 + 3.13-dev cache: 'pip' - name: Configure environment run: | From 54b8fab4981f0b878d6f49e1db91b4b7e41e396e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 24 Apr 2024 16:02:38 -0400 Subject: [PATCH 108/147] build: update minimum Python version to 3.10 --- pyproject.toml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cf7d295..77bdb73 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,9 +8,10 @@ classifiers = [ "Development Status :: 1 - Planning", "License :: OSI Approved :: GNU General Public License (GPL)", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.12", ] -requires-python = ">=3.8" +requires-python = ">=3.10" [project.scripts] starcraft-hello = "starcraft:hello" @@ -75,7 +76,7 @@ include = ["*craft*"] namespaces = false [tool.black] -target-version = ["py38"] +target-version = ["py310"] [tool.codespell] ignore-words-list = "buildd,crate,keyserver,comandos,ro,dedent,dedented" @@ -109,7 +110,7 @@ exclude_also = [ [tool.pyright] strict = ["starcraft"] -pythonVersion = "3.8" +pythonVersion = "3.10" pythonPlatform = "Linux" exclude = [ "**/.*", @@ -119,7 +120,7 @@ exclude = [ ] [tool.mypy] -python_version = "3.8" +python_version = "3.10" exclude = [ "build", "tests", @@ -145,7 +146,7 @@ strict = false [tool.ruff] line-length = 88 -target-version = "py38" +target-version = "py310" src = ["starcraft", "tests"] extend-exclude = [ "docs", From 51a7a95f963dc1484171a9f2601a0b5420f59a82 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 24 Apr 2024 16:06:24 -0400 Subject: [PATCH 109/147] style: autoformat --- starcraft/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/starcraft/__init__.py b/starcraft/__init__.py index 4e75351..7a07a1f 100644 --- a/starcraft/__init__.py +++ b/starcraft/__init__.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Starcraft package demo.""" -from typing import List, Optional, Any +from typing import Any try: from ._version import __version__ @@ -27,7 +27,7 @@ __version__ = "dev" -def hello(people: Optional[List[Any]] = None) -> None: +def hello(people: list[Any] | None = None) -> None: """Says hello.""" print("Hello *craft team!") if people: From de9999bb0df912ae23ec40ea64d02f0918c1912d Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 24 Apr 2024 16:06:34 -0400 Subject: [PATCH 110/147] chore: update python versions ruff uses --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 90f7880..a0a9775 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ env_list = # Environments to run when called with no parameters. format-{black,ruff,codespell} pre-commit lint-{black,ruff,mypy,pyright,shellcheck,codespell,docs,yaml} - unit-py3.{8,10,11} + unit-py3.{10,12} integration-py3.10 # Integration tests probably take a while, so we're only running them on Python # 3.10, which is included in core22. From a5b35eac80c9857daf0446a2df50c97e724b2145 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 24 Apr 2024 16:09:01 -0400 Subject: [PATCH 111/147] chore: update tox python versions --- tox.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index a0a9775..b3a1d6b 100644 --- a/tox.ini +++ b/tox.ini @@ -49,9 +49,9 @@ description = unit: Run unit tests with pytest integration: Run integration tests with pytest labels = - py3.{8,10,11}: tests - unit-py3.{8,10,11}: unit-tests - integration-py3.{8,10,11}: integration-tests + py3.{10,12}: tests + unit-py3.{10,12}: unit-tests + integration-py3.{10,12}: integration-tests change_dir = unit: tests/unit integration: tests/integration From 439dad683a2102a6d8fe7e394cdddec405ff1e7d Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 25 Apr 2024 15:48:59 -0400 Subject: [PATCH 112/147] chore: switch to codespell snap (#205) --- .github/workflows/tests.yaml | 2 +- HACKING.rst | 2 ++ pyproject.toml | 3 +-- tox.ini | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index c505063..16f6d0a 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,7 +31,7 @@ jobs: echo "::group::Begin snap install" echo "Installing snaps in the background while running apt and pip..." sudo snap install --no-wait --classic pyright - sudo snap install --no-wait shellcheck ruff + sudo snap install --no-wait codespell shellcheck ruff echo "::endgroup::" echo "::group::pip install" python -m pip install tox diff --git a/HACKING.rst b/HACKING.rst index 4477e26..08a6768 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -22,6 +22,7 @@ you with tox, but you'll need to install: deadsnakes_ PPA) with setuptools. - tox_ version 3.8 or later - ShellCheck_ (also available via snap: ``snap install shellcheck``) +- Codespell_ (also available via snap: ``snap install codespell``) - ruff_ (also available via snap: ``snap install ruff``) Once you have all of those installed, you can install the necessary virtual @@ -267,6 +268,7 @@ Example footers:: .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ +.. _Codespell: https://github.com/codespell-project/codespell .. _`conventional commit`: https://www.conventionalcommits.org/en/v1.0.0/#summary .. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa .. _`git submodules`: https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules diff --git a/pyproject.toml b/pyproject.toml index 77bdb73..3c68f60 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,8 +26,7 @@ dev = [ ] lint = [ "black~=24.1", - "codespell[toml]~=2.2", - "yamllint~=1.34" + "yamllint~=1.34", ] types = [ "mypy[reports]~=1.9.0", diff --git a/tox.ini b/tox.ini index b3a1d6b..58811bf 100644 --- a/tox.ini +++ b/tox.ini @@ -63,6 +63,7 @@ extras = lint env_dir = {work_dir}/linting runner = ignore_env_name_mismatch allowlist_externals = + codespell: codespell shellcheck: bash, xargs ruff: ruff From cd48e13fb1f331dfd494a9b749bfadb8f75028e6 Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Thu, 25 Apr 2024 20:44:38 -0300 Subject: [PATCH 113/147] docs: use canonical-sphinx (#209) --- docs/conf.py | 76 +++++++++++++++++++++++++++++--------------------- pyproject.toml | 5 +--- 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index eeb0257..d3f052d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,47 +1,59 @@ -# Configuration file for the Sphinx documentation builder. +# This file is part of starbase. # -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html +# Copyright 2024 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information +import datetime -project = "starcraft" -copyright = "2023, Canonical" +project = "Starbase" author = "Canonical" -# region General configuration -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration +copyright = "2023-%s, %s" % (datetime.date.today().year, author) + +# region Configuration for canonical-sphinx +ogp_site_url = "https://canonical-starbase.readthedocs-hosted.com/" +ogp_site_name = project +ogp_image = "https://assets.ubuntu.com/v1/253da317-image-document-ubuntudocs.svg" + +html_context = { + "product_page": "github.com/canonical/starbase", + "github_url": "https://github.com/canonical/starbase", +} extensions = [ - "sphinx.ext.intersphinx", - "sphinx.ext.viewcode", - "sphinx.ext.coverage", - "sphinx.ext.doctest", - "sphinx_design", - "sphinx_copybutton", - "sphinx-pydantic", - "sphinx_toolbox", - "sphinx_toolbox.more_autodoc", - "sphinx.ext.autodoc", # Must be loaded after more_autodoc + "canonical_sphinx", ] +# endregion -templates_path = ["_templates"] -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +# region General configuration +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration -show_authors = False +extensions.extend( + [ + "sphinx.ext.intersphinx", + "sphinx.ext.viewcode", + "sphinx.ext.coverage", + "sphinx.ext.doctest", + "sphinx-pydantic", + "sphinx_toolbox", + "sphinx_toolbox.more_autodoc", + "sphinx.ext.autodoc", # Must be loaded after more_autodoc + ] +) # endregion -# region Options for HTML output -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = "furo" -html_static_path = ["_static"] -html_css_files = [ - "css/custom.css", -] - -# endregion # region Options for extensions # Intersphinx extension # https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration @@ -57,6 +69,6 @@ # Github config github_username = "canonical" -github_repository = "starcraft-base" +github_repository = "starbase" # endregion diff --git a/pyproject.toml b/pyproject.toml index 3c68f60..449813c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,11 +33,8 @@ types = [ "pyright==1.1.359", ] docs = [ - "furo==2024.1.29", - "sphinx~=7.1", + "canonical-sphinx~=0.1", "sphinx-autobuild~=2024.2", - "sphinx-copybutton==0.5.2", - "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", "sphinx-toolbox~=3.5", "sphinx-lint==0.9.1", From 3b02fb67811efc1208d30214bdd8f96129a1795a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 12:57:50 -0400 Subject: [PATCH 114/147] chore(deps): update development dependencies (non-major) (#210) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 449813c..bcde580 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,8 +29,8 @@ lint = [ "yamllint~=1.34", ] types = [ - "mypy[reports]~=1.9.0", - "pyright==1.1.359", + "mypy[reports]~=1.10.0", + "pyright==1.1.363", ] docs = [ "canonical-sphinx~=0.1", From aae9d000815aba904acbf44ee9b7a83f5291b7de Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 21 May 2024 16:39:21 -0400 Subject: [PATCH 115/147] style: replace black formatter with ruff format (#212) --- pyproject.toml | 19 +++++++++++++++---- starcraft/__init__.py | 1 + tests/integration/starbase/test_init.py | 1 + tests/integration/test_setuptools.py | 1 + tests/integration/test_version.py | 1 + tests/unit/starbase/test_init.py | 1 + tox.ini | 12 ++++++------ 7 files changed, 26 insertions(+), 10 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bcde580..029b0ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,6 @@ dev = [ "pytest-mock~=3.12", ] lint = [ - "black~=24.1", "yamllint~=1.34", ] types = [ @@ -148,8 +147,15 @@ extend-exclude = [ "docs", "__pycache__", ] + +[tool.ruff.format] +docstring-code-format = true +line-ending = "lf" +quote-style = "double" + +[tool.ruff.lint] # Follow ST063 - Maintaining and updating linting specifications for updating these. -lint.select = [ # Base linting rule selections. +select = [ # Base linting rule selections. # See the internal document for discussion: # https://docs.google.com/document/d/1i1n8pDmFmWi4wTDpk-JfnWCVUThPJiggyPi2DYwBBu4/edit # All sections here are stable in ruff and shouldn't randomly introduce @@ -217,12 +223,12 @@ lint.select = [ # Base linting rule selections. "RUF001", "RUF002", "RUF003", # Ambiguous unicode characters "RUF005", # Encourages unpacking rather than concatenation "RUF008", # Do not use mutable default values for dataclass attributes - "RUF011", # Don't use static keys in dict comprehensions. + "B035", # Don't use static keys in dict comprehensions. "RUF013", # Prohibit implicit Optionals (PEP 484) "RUF100", # #noqa directive that doesn't flag anything "RUF200", # If ruff fails to parse pyproject.toml... ] -lint.ignore = [ +ignore = [ "ANN10", # Type annotations for `self` and `cls` #"E203", # Whitespace before ":" -- Commented because ruff doesn't currently check E203 "E501", # Line too long (reason: black will automatically fix this for us) @@ -235,6 +241,11 @@ lint.ignore = [ "SIM117", # Use a single `with` statement with multiple contexts instead of nested `with` statements # (reason: this creates long lines that get wrapped and reduces readability) + # Ignored due to conflicts with ruff's formatter: + # https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules + "COM812", # Missing trailing comma - mostly the same, but marginal differences. + "ISC001", # Single-line implicit string concatenation. + # Ignored due to common usage in current code "TRY003", # Avoid specifying long messages outside the exception class ] diff --git a/starcraft/__init__.py b/starcraft/__init__.py index 7a07a1f..9ae32cb 100644 --- a/starcraft/__init__.py +++ b/starcraft/__init__.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Starcraft package demo.""" + from typing import Any try: diff --git a/tests/integration/starbase/test_init.py b/tests/integration/starbase/test_init.py index 879210b..1c8a803 100644 --- a/tests/integration/starbase/test_init.py +++ b/tests/integration/starbase/test_init.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Basic Starcraft package demo integration tests.""" + import subprocess diff --git a/tests/integration/test_setuptools.py b/tests/integration/test_setuptools.py index d40f9ac..a27c984 100644 --- a/tests/integration/test_setuptools.py +++ b/tests/integration/test_setuptools.py @@ -12,6 +12,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Integration tests related to building the package.""" + import re import subprocess import sys diff --git a/tests/integration/test_version.py b/tests/integration/test_version.py index 411b311..b1ecda5 100644 --- a/tests/integration/test_version.py +++ b/tests/integration/test_version.py @@ -12,6 +12,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Versioning tests.""" + import re import subprocess diff --git a/tests/unit/starbase/test_init.py b/tests/unit/starbase/test_init.py index ca98cfd..34e92ff 100644 --- a/tests/unit/starbase/test_init.py +++ b/tests/unit/starbase/test_init.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Basic Starcraft package demo unit tests.""" + # pyright: reportFunctionMemberAccess=false from unittest import mock diff --git a/tox.ini b/tox.ini index 58811bf..6b27f37 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,8 @@ [tox] env_list = # Environments to run when called with no parameters. - format-{black,ruff,codespell} + format-{ruff,codespell} pre-commit - lint-{black,ruff,mypy,pyright,shellcheck,codespell,docs,yaml} + lint-{ruff,mypy,pyright,shellcheck,codespell,docs,yaml} unit-py3.{10,12} integration-py3.10 # Integration tests probably take a while, so we're only running them on Python @@ -71,14 +71,14 @@ allowlist_externals = find = git ls-files filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: -[testenv:lint-{black,ruff,shellcheck,codespell,yaml}] +[testenv:lint-{ruff,shellcheck,codespell,yaml}] description = Lint the source code base = testenv, lint labels = lint commands_pre = shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' commands = - black: black --check --diff {tty:--color} {posargs} . + ruff: ruff format --check --diff --respect-gitignore {posargs:.} ruff: ruff check --respect-gitignore {posargs:.} shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck codespell: codespell --toml {tox_root}/pyproject.toml {posargs} @@ -98,12 +98,12 @@ commands = pyright: pyright {posargs} mypy: mypy --install-types --non-interactive {posargs:.} -[testenv:format-{black,ruff,codespell}] +[testenv:format-{ruff,codespell}] description = Automatically format source code base = testenv, lint labels = format commands = - black: black {tty:--color} {posargs} . + ruff: ruff format --respect-gitignore {posargs:.} ruff: ruff check --fix --respect-gitignore {posargs} . codespell: codespell --toml {tox_root}/pyproject.toml --write-changes {posargs} From beee3a822c23392a073c653ac9d7d0b09e8f98ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 26 May 2024 18:43:23 -0400 Subject: [PATCH 116/147] chore(deps): update dependency types/pyright to v1.1.364 (#216) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 029b0ff..aef1358 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.10.0", - "pyright==1.1.363", + "pyright==1.1.364", ] docs = [ "canonical-sphinx~=0.1", From 5b5dbef75992a65d5774de12f4777dc00a1af2dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 07:27:01 -0500 Subject: [PATCH 117/147] chore(deps): update dependency types/pyright to v1.1.365 (#217) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index aef1358..b210287 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.10.0", - "pyright==1.1.364", + "pyright==1.1.365", ] docs = [ "canonical-sphinx~=0.1", From 1acd270801ce3b204dedc61da798f897d7474f78 Mon Sep 17 00:00:00 2001 From: Callahan Date: Tue, 4 Jun 2024 11:26:43 -0500 Subject: [PATCH 118/147] docs(HACKING): document branch names and changelog (#218) Signed-off-by: Callahan Kovacs --- HACKING.rst | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/HACKING.rst b/HACKING.rst index 08a6768..27ff1ae 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -87,6 +87,81 @@ You can also see all the environments by simply running ``tox list`` Running ``tox run -m format`` and ``tox run -m lint`` before committing code is recommended. +Branches +-------- + +Starcraft projects follow the `OneFlow`_ git branching model. + + +Branch names +============ + +The branch name should be brief and less than 200 characters. + +Branch names are formatted as ``/``. + +This naming convention provides a few benefits: + - GitHub workflows can choose which categories they should run on + - GitHub branches rules can be configured per category + - Some IDEs and git tools display categorized branches in a neat and + nested format + +``main`` +######## + +The main branch containing the latest changes. + +``renovate/*`` +############## + +Branches created automatically by the `Renovate bot`_. + +``work/-`` +############################### + +For any work driven by a ticketing system, the ticket should be +part of the branch name. The ticketing system can be built into the repo +like GitHub issues or an external ticketing system. + +For GitHub issue #100 (a ticket to add a README file), the branch would be +called ``work/100-add-readme``. + +For an external ticketing system like Jira, a ticket labeled +``CRAFT-100`` would use a branch called ``work/CRAFT-100-add-readme``. + +``work/`` +###################### + +For any new features, bug fixes, and general work not driven by a ticketing +system. + +``hotfix/X.Y`` +############## + +For hotfixes to an existing minor release. + +For example, hotfixes for Testcraft 2.1 would go to a branch called +``hotfix/2.1``. + +As a departure from OneFlow, hotfix branches for \*craft applications can be +long-lived. This is because \*craft applications are built via Launchpad, +which uses build recipes that follow specific branches. + +After a tagged release of a hotfix branch, the branch should be merged back +to ``main``. + +``merge/`` +######################## + +For commits that merge another branch into the current branch. See the +`chore <#chore>`_ section for information on merge commit headers. + +``release/X.Y.Z`` +################# + +For commits that prepare for a release. These commits should update the +`changelog <#changelog>`_. + Commits ------- @@ -265,6 +340,21 @@ Example footers:: Signed-off-by: <> Co-authored-by: <> +Changelog +--------- + +The changelog is a reference documentation page that gives a human-readable +summary of changes to the project that are relevant to users. + +Each change should be clear in its purpose, whether it is fixing a bug, +adding a feature, or changing an existing behavior. + +Internal changes should not be included in the changelog. For example, +dev dependency updates, CI updates, and style changes should not +be included. + +The changelog should link to the project's GitHub releases page, which +contains an exhaustive list of all commits added to the release. .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ @@ -273,10 +363,12 @@ Example footers:: .. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa .. _`git submodules`: https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules .. _`Martin Fowler's definition`: https://refactoring.com/ +.. _OneFlow: https://www.endoflineblog.com/oneflow-a-git-branching-model-and-workflow .. _pre-commit: https://pre-commit.com/ .. _pyproject.toml: ./pyproject.toml .. _Pyright: https://github.com/microsoft/pyright .. _pytest: https://pytest.org +.. _`Renovate bot`: https://github.com/renovatebot/renovate .. _ruff: https://github.com/charliermarsh/ruff .. _ShellCheck: https://www.shellcheck.net/ .. _tox: https://tox.wiki From cd8da5576e5f8ecb7fe94f81558d2ffde88b20be Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 4 Jun 2024 14:25:32 -0400 Subject: [PATCH 119/147] ci: run tests on Ubuntu 24.04 (#214) https://github.com/actions/runner-images/issues/9848 --- .github/workflows/tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 16f6d0a..4cf530d 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -47,7 +47,7 @@ jobs: unit: strategy: matrix: - platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] + platform: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 @@ -87,7 +87,7 @@ jobs: integration: strategy: matrix: - platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] + platform: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 From 77ce0886a41355b1d8e2b27b4802790320221e68 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 4 Jun 2024 14:25:54 -0400 Subject: [PATCH 120/147] ci: remove deprecated renovate config options (#215) --- .github/renovate.json5 | 14 +++++++------- .github/workflows/check-renovate.yaml | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 9c4bd55..9dcf214 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -30,7 +30,7 @@ // Automerge patches, pin changes and digest changes. // Also groups these changes together. groupName: "bugfixes", - excludePackagePrefixes: ["lint", "types"], + excludeDepPatterns: ["lint/.*", "types/.*"], matchUpdateTypes: ["patch", "pin", "digest"], prPriority: 3, // Patches should go first! automerge: true @@ -38,7 +38,7 @@ { // Update all internal packages in one higher-priority PR groupName: "internal packages", - matchPackagePrefixes: ["craft-", "snap-"], + matchDepPatterns: ["craft-.*", "snap-.*"], matchLanguages: ["python"], prPriority: 2 }, @@ -59,10 +59,10 @@ // Minor changes can be grouped and automerged for dev dependencies, but are also deprioritised. groupName: "development dependencies (non-major)", groupSlug: "dev-dependencies", - matchPackagePrefixes: [ - "dev", - "lint", - "types" + matchDepPatterns: [ + "dev/.*", + "lint/.*", + "types/.*" ], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: -1, @@ -74,7 +74,7 @@ groupSlug: "doc-dependencies", matchPackageNames: ["Sphinx", "furo"], matchPackagePatterns: ["[Ss]phinx.*$"], - matchPackagePrefixes: ["docs"], + matchDepPatterns: ["docs/.*"], }, { // Other major dependencies get deprioritised below minor dev dependencies. diff --git a/.github/workflows/check-renovate.yaml b/.github/workflows/check-renovate.yaml index 8cf7d22..8da9f2b 100644 --- a/.github/workflows/check-renovate.yaml +++ b/.github/workflows/check-renovate.yaml @@ -33,3 +33,4 @@ jobs: run: renovate --dry-run --autodiscover env: RENOVATE_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RENOVATE_USE_BASE_BRANCH_CONFIG: ${{ github.ref }} From 7e0e9421ab48a2fa96d6ea2409ed23bfd4944cd0 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 6 Jun 2024 11:25:56 -0400 Subject: [PATCH 121/147] chore: add Jira sync (#219) --- .github/.jira_sync_config.yaml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/.jira_sync_config.yaml diff --git a/.github/.jira_sync_config.yaml b/.github/.jira_sync_config.yaml new file mode 100644 index 0000000..10f6791 --- /dev/null +++ b/.github/.jira_sync_config.yaml @@ -0,0 +1,22 @@ +settings: + components: + - Starbase + labels: + - Triaged + # Adds a comment with the JIRA ID + add_gh_comment: true + # Reflect changes on JIRA + sync_description: true + # Comments are synced from Github to JIRA + # Nothing goes from JIRA to Github + sync_comments: true + # epic_key: "MTC-296" + jira_project_key: "CRAFT" + status_mapping: + opened: Triaged + closed: done + label_mapping: + enhancement: Story + bug: Bug + spike: Spike + epic: Epic From b727837c37f1f317e2ae389bfcf1aeee30360fb0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 16:26:20 -0400 Subject: [PATCH 122/147] chore(deps): update dependency types/pyright to v1.1.366 (#220) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b210287..c7f3046 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.10.0", - "pyright==1.1.365", + "pyright==1.1.366", ] docs = [ "canonical-sphinx~=0.1", From 1d72f494647c57d9b30ab0301fb72faef050d6bb Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 12 Jun 2024 14:11:15 -0400 Subject: [PATCH 123/147] chore: update line length configuration (#221) --- .editorconfig | 7 +------ tox.ini | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.editorconfig b/.editorconfig index 6056a3e..5a54b3e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,7 +8,7 @@ end_of_line = lf indent_size = 4 indent_style = space insert_final_newline = true -max_line_length = 80 +max_line_length = 88 trim_trailing_whitespace = true [.editorconfig] @@ -29,15 +29,10 @@ indent_size = 2 max_line_length = off [{*.markdown,*.md,*.rst}] -max_line_length = off ij_visual_guides = none [{*.toml,Cargo.lock,Cargo.toml.orig,Gopkg.lock,Pipfile,poetry.lock}] max_line_length = off -[{*.ini, *.cfg}] -max_line_length = off - [{*.yaml,*.yml}] indent_size = 2 -max_line_length = off diff --git a/tox.ini b/tox.ini index 6b27f37..975273e 100644 --- a/tox.ini +++ b/tox.ini @@ -147,4 +147,4 @@ base = docs labels = lint allowlist_externals = bash, xargs commands_pre = bash -c '{[lint-docs]find} > {env_tmp_dir}/lint_docs_files' -commands = xargs --no-run-if-empty --arg-file {env_tmp_dir}/lint_docs_files sphinx-lint --max-line-length 80 --enable all {posargs} +commands = xargs --no-run-if-empty --arg-file {env_tmp_dir}/lint_docs_files sphinx-lint --max-line-length 88 --enable all {posargs} From 3f3b5f6b1268e2365fb9746693aee88d33ea171e Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Wed, 10 Jul 2024 11:29:10 -0300 Subject: [PATCH 124/147] ci: update Release workflow (#224) This commit updates the Release workflow with the following changes: - Use self-hosted jammy machines instead of default Github runners; - Use PyPI's Trusted Publishers to publish, replacing the PYPI_API_TOKEN; - (minor) Constrain the artifacts that are attached to the Github release. --- .github/workflows/release-publish.yaml | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 4d30ed0..fc5fb39 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -11,18 +11,20 @@ permissions: jobs: source-wheel: - runs-on: ubuntu-latest + runs-on: [self-hosted, jammy] steps: - name: Checkout uses: actions/checkout@v4 - name: Fetch tag annotations run: | + # Note: we fetch the tags here instead of using actions/checkout's "fetch-tags" + # because of https://github.com/actions/checkout/issues/1467 git fetch --force --tags --depth 1 git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*' - name: Setup Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" check-latest: true - name: Build packages run: | @@ -36,7 +38,10 @@ jobs: path: dist/ pypi: needs: ["source-wheel"] - runs-on: ubuntu-latest + runs-on: [self-hosted, jammy] + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write steps: - name: Get packages uses: actions/download-artifact@v4 @@ -44,17 +49,22 @@ jobs: name: pypi-packages path: dist/ - name: Publish to pypi + # Note: this action uses PyPI's support for Trusted Publishers + # It needs a configuration on the PyPI project - see: + # https://docs.pypi.org/trusted-publishers/adding-a-publisher/#github-actions uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.PYPI_API_TOKEN }} github-release: needs: ["source-wheel"] - runs-on: ubuntu-latest + runs-on: [self-hosted, jammy] steps: - name: Get pypi artifacts uses: actions/download-artifact@v4 + with: + name: pypi-packages - name: Release uses: softprops/action-gh-release@v2 with: + # Add wheel and source tarball files: | - ** + *.whl + *.tar.gz From dacbdeba087ba777b0d9d2a02c7e7dd7870ca281 Mon Sep 17 00:00:00 2001 From: Callahan Date: Thu, 11 Jul 2024 07:44:23 -0500 Subject: [PATCH 125/147] docs(HACKING): add details on changelog convention (#225) Signed-off-by: Callahan Kovacs --- HACKING.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/HACKING.rst b/HACKING.rst index 27ff1ae..1c3865c 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -343,6 +343,9 @@ Example footers:: Changelog --------- +Scope +===== + The changelog is a reference documentation page that gives a human-readable summary of changes to the project that are relevant to users. @@ -353,9 +356,33 @@ Internal changes should not be included in the changelog. For example, dev dependency updates, CI updates, and style changes should not be included. +Style and format +================ + +Changes should be written in the imperative mood (present tense, second +person) similar to commit headers. + The changelog should link to the project's GitHub releases page, which contains an exhaustive list of all commits added to the release. +Release entries should be sorted by date from newest to oldest. + +Hotfixes +======== + +If an older version gets a hotfix release, subsequent releases should mention +when the hotfix is incorporated. + +For example, consider a package with a previous release ``2.9.0`` and a latest +release of ``3.0.0``. If the ``2.9.0`` receives a hotfix release ``2.9.1`` and +is merged back to ``main``, then the next ``3.x`` release should indicate that +it includes the changes from 2.9.1. + +.. note:: + + 3.0.1 includes changes from the 2.9.1 release. + + .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ .. _Codespell: https://github.com/codespell-project/codespell From 36164586c1962db4b90fdda5f4d5c39517ec9785 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 15:43:10 -0400 Subject: [PATCH 126/147] chore(deps): update dependency types/pyright to v1.1.371 (#222) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c7f3046..9530a46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.10.0", - "pyright==1.1.366", + "pyright==1.1.371", ] docs = [ "canonical-sphinx~=0.1", From 76fac3f72140923d4ccc9e88aa9cabde1d722046 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 15:46:55 -0400 Subject: [PATCH 127/147] chore(deps): update dependency tox-gh to v1.3.2 (#223) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 975273e..be96236 100644 --- a/tox.ini +++ b/tox.ini @@ -18,7 +18,7 @@ requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 # renovate: datasource=pypi - tox-gh==1.3.1 + tox-gh==1.3.2 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From a90bcf78272a909f0f0dbb960c048968e05dd657 Mon Sep 17 00:00:00 2001 From: Matt Culler Date: Thu, 18 Jul 2024 10:29:03 -0400 Subject: [PATCH 128/147] docs: update hacking with explanation for exclamation point (#226) * docs: update hacking with explanation for exclamation point * Update HACKING.rst Co-authored-by: Alex Lowe --------- Co-authored-by: Alex Lowe --- HACKING.rst | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/HACKING.rst b/HACKING.rst index 1c3865c..bc49c40 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -167,11 +167,11 @@ Commits Commit messages are based on the `conventional commit`_ style:: - (): + [(optional scope)][!]: - + [optional body] - + [optional footer] The commit is divided into three sections: a header, body, and footer. @@ -297,6 +297,16 @@ class name. If a commit affects many areas of the codebase, the scope should be omitted; ``many`` is not an accepted scope. +Breaking changes +################ + +If an exclamation point (``!``) is inserted after the type/scope, this means +that the commit introduces a breaking change. Including one or more commits +with an exclamation point in a release will trigger a major version increment. + +Breaking changes may also be indicated by including the words ``BREAKING CHANGE`` +in the commit footer. + Description ########### From 73db57b1229d04839367640b5e7c868d0259113f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:22:22 -0400 Subject: [PATCH 129/147] chore(deps): update development dependencies (non-major) (#227) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9530a46..56ecc57 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,8 +28,8 @@ lint = [ "yamllint~=1.34", ] types = [ - "mypy[reports]~=1.10.0", - "pyright==1.1.371", + "mypy[reports]~=1.11.0", + "pyright==1.1.372", ] docs = [ "canonical-sphinx~=0.1", From d88dde57927483cf6bd2adacea5860b5619642f1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 08:44:31 -0400 Subject: [PATCH 130/147] chore(deps): update dependency pyright to v1.1.375 (#234) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 56ecc57..9b88439 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.372", + "pyright==1.1.375", ] docs = [ "canonical-sphinx~=0.1", From f97274517046856254c662c581068ee92f82da23 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 14 Aug 2024 08:44:54 -0400 Subject: [PATCH 131/147] ci: update renovate config and workflow (#232) Co-authored-by: Callahan --- .github/renovate.json5 | 51 +++++++++++++++++++++------ .github/workflows/check-renovate.yaml | 4 +++ 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 9dcf214..8342105 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,20 +1,22 @@ { // Configuration file for RenovateBot: https://docs.renovatebot.com/configuration-options - extends: ["config:base"], + extends: ["config:recommended", ":semanticCommitTypeAll(build)"], labels: ["dependencies"], // For convenient searching in GitHub + baseBranches: ["$default", "/^hotfix\\/.*/"], pip_requirements: { fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$", "^.pre-commit-config.yaml$"] }, packageRules: [ { // Internal package minor patch updates get top priority, with auto-merging - groupName: "internal package patch releases", + groupName: "internal package minor releases", matchPackagePatterns: ["^craft-.*"], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: 10, automerge: true, minimumReleaseAge: "0 seconds", schedule: ["at any time"], + matchBaseBranches: ["$default"], // Only do minor releases on main }, { // Same as above, but for hotfix branches, only for patch, and without auto-merging. @@ -24,7 +26,7 @@ prPriority: 10, minimumReleaseAge: "0 seconds", schedule: ["at any time"], - matchBaseBranches: ["/^hotfix/.*/"], // All hotfix branches + matchBaseBranches: ["/^hotfix\\/.*/"], // All hotfix branches }, { // Automerge patches, pin changes and digest changes. @@ -39,8 +41,9 @@ // Update all internal packages in one higher-priority PR groupName: "internal packages", matchDepPatterns: ["craft-.*", "snap-.*"], - matchLanguages: ["python"], - prPriority: 2 + matchCategories: ["python"], + prPriority: 2, + matchBaseBranches: ["$default"], // Not for hotfix branches }, { // GitHub Actions are higher priority to update than most dependencies since they don't tend to break things. @@ -64,6 +67,28 @@ "lint/.*", "types/.*" ], + matchPackagePatterns: [ + // Brought from charmcraft. May not be complete. + // This helps group dependencies in requirements-dev.txt files. + "^(.*/)?autoflake$", + "^(.*/)?black$", + "^(.*/)?codespell$", + "^(.*/)?coverage$", + "^(.*/)?flake8$", + "^(.*/)?hypothesis$", + "^(.*/)?mypy$", + "^(.*/)?pycodestyle$", + "^(.*/)?docstyle$", + "^(.*/)?pyfakefs$", + "^(.*/)?pyflakes$", + "^(.*/)?pylint$", + "^(.*/)?pytest", + "^(.*/)?responses$", + "^(.*/)?ruff$", + "^(.*/)?twine$", + "^(.*/)?tox$", + "^(.*/)?types-", + ], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: -1, automerge: true @@ -75,11 +100,13 @@ matchPackageNames: ["Sphinx", "furo"], matchPackagePatterns: ["[Ss]phinx.*$"], matchDepPatterns: ["docs/.*"], + matchBaseBranches: ["$default"], // Not for hotfix branches }, { // Other major dependencies get deprioritised below minor dev dependencies. matchUpdateTypes: ["major"], - prPriority: -2 + prPriority: -2, + matchBaseBranches: ["$default"], // Not for hotfix branches }, { // Major dev dependencies are stone last, but grouped. @@ -87,19 +114,22 @@ groupSlug: "dev-dependencies", matchDepTypes: ["devDependencies"], matchUpdateTypes: ["major"], - prPriority: -3 + prPriority: -3, + matchBaseBranches: ["$default"], // Not for hotfix branches }, { // Pyright makes regular breaking changes in patch releases, so we separate these // and do them independently. matchPackageNames: ["pyright", "types/pyright"], - prPriority: -4 + prPriority: -4, + matchBaseBranches: ["$default"], // Not for hotfix branches } ], - regexManagers: [ + customManagers: [ { // tox.ini can get updates too if we specify for each package. fileMatch: ["tox.ini"], + customType: "regex", depTypeTemplate: "devDependencies", matchStrings: [ "# renovate: datasource=(?\\S+)\n\\s+(?.*?)(\\[[\\w]*\\])*[=><]=?(?.*?)\n" @@ -108,6 +138,7 @@ { // .pre-commit-config.yaml version updates fileMatch: [".pre-commit-config.yaml"], + customType: "regex", datasourceTemplate: "pypi", depTypeTemplate: "lint", matchStrings: [ @@ -122,7 +153,7 @@ prCreation: "not-pending", // Wait until status checks have completed before raising the PR prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. prHourlyLimit: 1, // No more than 1 PR per hour. - stabilityDays: 2, // Wait 2 days from release before updating. + minimumReleaseAge: "2 days", automergeStrategy: "squash", // Squash & rebase when auto-merging. semanticCommitType: "build" // use `build` as commit header type (i.e. `build(deps): `) } diff --git a/.github/workflows/check-renovate.yaml b/.github/workflows/check-renovate.yaml index 8da9f2b..7d13cfb 100644 --- a/.github/workflows/check-renovate.yaml +++ b/.github/workflows/check-renovate.yaml @@ -20,6 +20,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Install node + uses: actions/setup-node@v4 + with: + node-version: 22 - name: Install renovate run: npm install --global renovate - name: Enable ssh access From 6bfb9692056cec85b7aeca04348708d366ad4778 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 27 Aug 2024 11:07:29 -0400 Subject: [PATCH 132/147] style: autoformat with ruff 0.6 (#238) --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 9bceb63..587f0eb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,7 +16,7 @@ import pytest -@pytest.fixture() +@pytest.fixture def project_main_module() -> types.ModuleType: """Fixture that returns the project's principal package (imported). From 2439a13a3394492ff85d04c4afcc8bc28f7e86f2 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 30 Aug 2024 09:19:48 -0400 Subject: [PATCH 133/147] style(lint): autoformat (#239) From e2f3adfb576690f27644b3d845bef4a2c8caa1fd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 12:44:10 -0400 Subject: [PATCH 134/147] build(deps): update dependency pyright to v1.1.378 (#241) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9b88439..1ae1844 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.375", + "pyright==1.1.378", ] docs = [ "canonical-sphinx~=0.1", From 6b7fa704c68c6f7240cf41db6508430c24b5ca0c Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 6 Sep 2024 09:59:15 -0400 Subject: [PATCH 135/147] ci(renovate): enable pre-commit support (#242) --- .github/renovate.json5 | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 8342105..2a7d636 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,10 +1,10 @@ { // Configuration file for RenovateBot: https://docs.renovatebot.com/configuration-options - extends: ["config:recommended", ":semanticCommitTypeAll(build)"], + extends: ["config:recommended", ":semanticCommitTypeAll(build)", ":enablePreCommit"], labels: ["dependencies"], // For convenient searching in GitHub baseBranches: ["$default", "/^hotfix\\/.*/"], pip_requirements: { - fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$", "^.pre-commit-config.yaml$"] + fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$"] }, packageRules: [ { @@ -135,16 +135,6 @@ "# renovate: datasource=(?\\S+)\n\\s+(?.*?)(\\[[\\w]*\\])*[=><]=?(?.*?)\n" ] }, - { - // .pre-commit-config.yaml version updates - fileMatch: [".pre-commit-config.yaml"], - customType: "regex", - datasourceTemplate: "pypi", - depTypeTemplate: "lint", - matchStrings: [ - "- repo: .*/<(?\\S+)\\s*\\n\\s*rev:\s+\"?v?(?\\S*)\"?", - ] - } ], timezone: "Etc/UTC", schedule: ["every weekend"], From 38e8a726ec22e5206ffdaac1a1bdbfccf6ac54f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 8 Sep 2024 08:33:44 -0400 Subject: [PATCH 136/147] build(deps): update dependency pyright to v1.1.379 (#243) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1ae1844..35fb7ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.378", + "pyright==1.1.379", ] docs = [ "canonical-sphinx~=0.1", From 82d7be8ece55ca07476fb325058d8255bd933919 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 8 Sep 2024 08:37:12 -0400 Subject: [PATCH 137/147] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.6.4 (#245) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f84e07a..14a369f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.15" + rev: "v0.6.4" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 96d6635ea7878db1d699bd15d493867027440973 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 8 Sep 2024 08:38:12 -0400 Subject: [PATCH 138/147] build(deps): update pre-commit hook adrienverge/yamllint to v1.35.1 (#244) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 14a369f..7166a78 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,6 +22,6 @@ repos: hooks: - id: black - repo: https://github.com/adrienverge/yamllint.git - rev: "v1.33.0" + rev: "v1.35.1" hooks: - id: yamllint From 33279004921b6e3c6010222a0fe40e7f29c996a2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:39:16 -0400 Subject: [PATCH 139/147] build(deps): update pre-commit hook psf/black to v24.8.0 (#247) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7166a78..d728276 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black - rev: "24.1.1" + rev: "24.8.0" hooks: - id: black - repo: https://github.com/adrienverge/yamllint.git From 4ff207679e7401c3bb57a6de9939a3359ab7f9a0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:39:42 -0400 Subject: [PATCH 140/147] build(deps): update pre-commit hook pre-commit/pre-commit-hooks to v4.6.0 (#246) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d728276..3dac59d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: "v4.4.0" + rev: "v4.6.0" hooks: - id: trailing-whitespace - id: end-of-file-fixer From afb80d1af97fcfe485cdd6b37d098bb79dd145bb Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 13 Sep 2024 20:09:01 -0400 Subject: [PATCH 141/147] chore(renovate): fewer PRs to hotfix branches (#237) Renovate should only PR to hotfix branches for non-dev patch updates. --- .github/renovate.json5 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 2a7d636..a6959dd 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -32,7 +32,11 @@ // Automerge patches, pin changes and digest changes. // Also groups these changes together. groupName: "bugfixes", - excludeDepPatterns: ["lint/.*", "types/.*"], + excludeDepPatterns: [ + "lint/.*", + "types/.*", + "pyright", // Pyright needs to be done separately. + ], matchUpdateTypes: ["patch", "pin", "digest"], prPriority: 3, // Patches should go first! automerge: true @@ -57,6 +61,7 @@ //Do all pydantic-related updates together groupName: "pydantic etc.", matchPackagePatterns: ["^pydantic"], + matchBaseBranches: ["$default"], // Only do minor releases on main }, { // Minor changes can be grouped and automerged for dev dependencies, but are also deprioritised. @@ -91,7 +96,8 @@ ], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: -1, - automerge: true + automerge: true, + matchBaseBranches: ["$default"], // Not for hotfix branches }, { // Documentation related updates From b1ac98026f6bacce34474d45a086845f4f4d473a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 08:05:31 -0400 Subject: [PATCH 142/147] build(deps): update dependency pyright to v1.1.380 (#249) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 35fb7ed..4ec1a88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.379", + "pyright==1.1.380", ] docs = [ "canonical-sphinx~=0.1", From 197eaf7820989e32b3d831fd9e96175ce9060904 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 08:07:45 -0400 Subject: [PATCH 143/147] build(deps): update dependency sphinx-lint to v1 (#250) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4ec1a88..7c50e13 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ docs = [ "sphinx-autobuild~=2024.2", "sphinx-pydantic==0.1.1", "sphinx-toolbox~=3.5", - "sphinx-lint==0.9.1", + "sphinx-lint==1.0.0", ] [build-system] From ce9ccb99d7594415c293ffdf349f087469536b56 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 08:11:48 -0400 Subject: [PATCH 144/147] build(deps): update dependency tox-gh to v1.3.3 (#248) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index be96236..f951b6e 100644 --- a/tox.ini +++ b/tox.ini @@ -18,7 +18,7 @@ requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 # renovate: datasource=pypi - tox-gh==1.3.2 + tox-gh==1.3.3 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From e4faa8c17ddaad2cabddb83fdbd1c5333d7e7a72 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 18:32:13 -0400 Subject: [PATCH 145/147] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.6.5 (#251) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3dac59d..c797584 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.4" + rev: "v0.6.5" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 4525894020b7768615b1712e0193b2646ea2efa6 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 17 Sep 2024 11:22:37 -0400 Subject: [PATCH 146/147] build(tools): add a Makefile that uses uv (#240) --- .gitignore | 1 + Makefile | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 16 +++++++- 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 Makefile diff --git a/.gitignore b/.gitignore index 4cb5044..289a38a 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ coverage.xml *.py,cover .hypothesis/ .pytest_cache/ +.results.*.xml # Translations *.mo diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6dcafe4 --- /dev/null +++ b/Makefile @@ -0,0 +1,106 @@ +PROJECT=starcraft +SOURCES=$(wildcard *.py) $(PROJECT) tests +DOCS=docs + +ifneq ($(OS),Windows_NT) + OS := $(shell uname) +endif + +.PHONY: help +help: ## Show this help. + @printf "%-30s %s\n" "Target" "Description" + @printf "%-30s %s\n" "------" "-----------" + @fgrep " ## " $(MAKEFILE_LIST) | fgrep -v grep | awk -F ': .*## ' '{$$1 = sprintf("%-30s", $$1)} 1' + +.PHONY: setup +setup: ## Set up a development environment +ifeq ($(OS),Linux) + sudo snap install codespell ruff shellcheck + sudo snap install --classic --beta astral-uv + sudo snap alias astral-uv.uv uv + sudo snap alias astral-uv.uvx uvx +else ifeq ($(OS),Windows_NT) + pipx install uv + choco install shellcheck +else ifeq ($(OS),Darwin) + brew install uv + brew install shellcheck +endif +ifneq ($(OS),Linux) + uv tool install codespell + uv tool install ruff + uv tool update-shell +endif + +.PHONY: setup-pre-commit +setup-precommit: ## Set up pre-commit hooks in this repository. +ifeq (, $(shell which pre-commit)) + uv tool install pre-commit +endif + pre-commit install + +.PHONY: autoformat +autoformat: format-ruff format-codespell ## Run all automatic formatters + +.PHONY: lint +lint: lint-ruff lint-codespell lint-mypy lint-pyright lint-shellcheck lint-yaml lint-docs ## Run all linters + +.PHONY: test +test: test-unit test-integration ## Run all tests + +.PHONY: docs +docs: ## Build documentation + uv run --extra docs sphinx-build -b html -W docs docs/_build + +.PHONY: docs-auto +docs-auto: ## Build and host docs with sphinx-autobuild + uv run --extra docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W docs docs/_build + +# Helpful in `help` to split the main targets from things that build +---------------- : ## ---------------- + +.PHONY: format-codespell +format-codespell: ## Fix spelling issues with codespell + uv run codespell --toml pyproject.toml --write-changes $(SOURCES) + +.PHONY: format-ruff +format-ruff: ## Automatically format with ruff + ruff format $(SOURCES) + ruff check --fix $(SOURCES) + +.PHONY: lint-codespell +lint-codespell: ## Check spelling with codespell + uv run codespell --toml pyproject.toml $(SOURCES) + +.PHONY: lint-docs +lint-docs: ## Lint the documentation + uv run --extra docs sphinx-lint --max-line-length 80 --enable all $(DOCS) + +.PHONY: lint-mypy +lint-mypy: ## Check types with mypy + uv run mypy $(SOURCES) + +.PHONY: lint-pyright +lint-pyright: ## Check types with pyright + uv run pyright + +.PHONY: lint-ruff +lint-ruff: ## Lint with ruff + ruff format --diff $(SOURCES) + ruff check $(SOURCES) + +.PHONY: lint-shellcheck +lint-shellcheck: + sh -c 'git ls-files | file --mime-type -Nnf- | grep shellscript | cut -f1 -d: | xargs -r shellcheck' + +.PHONY: lint-yaml +lint-yaml: ## Lint YAML files with yamllint + uv run yamllint . + +.PHONY: test-unit +test-unit: ## Run unit tests + uv run pytest --cov=$(PROJECT) --cov-config=pyproject.toml --cov-report=xml:.coverage.unit.xml --junit-xml=.results.unit.xml tests/unit + +.PHONY: test-integration +test-integration: ## Run integration tests + uv run pytest --cov=$(PROJECT) --cov-config=pyproject.toml --cov-report=xml:.coverage.integration.xml --junit-xml=.results.integration.xml tests/integration diff --git a/pyproject.toml b/pyproject.toml index 7c50e13..0267f1f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,21 @@ docs = [ "sphinx-lint==1.0.0", ] +[tool.uv] +dev-dependencies = [ + "build", + "coverage[toml]~=7.4", + "pytest~=8.0", + "pytest-cov~=5.0", + "pytest-mock~=3.12", + "yamllint~=1.34", + "mypy[reports]~=1.11.0", + "pyright==1.1.375", + "types-Pygments", + "types-colorama", + "types-setuptools", +] + [build-system] requires = [ "setuptools>=69.0", @@ -118,7 +133,6 @@ exclude = [ python_version = "3.10" exclude = [ "build", - "tests", "results", ] warn_unused_configs = true From cbba4d7cc60f81731e43d31c25b23fb30803cf3e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 19 Sep 2024 17:52:41 -0400 Subject: [PATCH 147/147] build: add a Makefile that uses uv Also adjusts the tox file and the github workflows --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/workflows/docs.yaml | 22 +- .github/workflows/tests.yaml | 127 +- Makefile | 48 +- pyproject.toml | 37 +- tox.ini | 71 +- uv.lock | 1922 ++++++++++++++++++++++++++++++ 7 files changed, 2064 insertions(+), 165 deletions(-) create mode 100644 uv.lock diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index da2c973..8379de5 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,5 @@ - [ ] Have you followed the guidelines for contributing? - [ ] Have you signed the [CLA](http://www.ubuntu.com/legal/contributors/)? -- [ ] Have you successfully run `tox`? +- [ ] Have you successfully run `make lint && make test`? ----- diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index c2b688c..5ad3a2d 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -16,20 +16,22 @@ jobs: sphinx: runs-on: ubuntu-latest steps: + - name: Start UV install + run: | + sudo snap install --classic astral-uv --no-wait - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install Tox - run: pip install tox - - name: Lint documentation - run: tox run --colored yes -e lint-docs - - name: Build documentation - run: tox run --colored yes -e build-docs + - name: Finish UV install + run: | + sudo snap watch --last=install + - name: Lint docs + run: | + make lint-docs + - name: Build docs + run: | + make docs - name: Upload documentation uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 4cf530d..419baf6 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -17,105 +17,126 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Install tools + run: | + make setup + - name: Run Linters + run: | + make -k lint - name: conventional commits uses: webiny/action-conventional-commits@v1.3.0 with: allowed-commit-types: "build,chore,ci,docs,feat,fix,perf,refactor,style,test" - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - cache: 'pip' - - name: Configure environment - run: | - echo "::group::Begin snap install" - echo "Installing snaps in the background while running apt and pip..." - sudo snap install --no-wait --classic pyright - sudo snap install --no-wait codespell shellcheck ruff - echo "::endgroup::" - echo "::group::pip install" - python -m pip install tox - echo "::endgroup::" - echo "::group::Create virtual environments for linting processes." - tox run --colored yes -m lint --notest - echo "::endgroup::" - echo "::group::Wait for snap to complete" - snap watch --last=install - echo "::endgroup::" - - name: Run Linters - run: tox run --skip-pkg-install --no-list-dependencies --colored yes -m lint unit: strategy: matrix: platform: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest] + resolution: [highest] + include: + - platform: ubuntu-latest + resolution: lowest runs-on: ${{ matrix.platform }} + env: + UV_CACHE_DIR: ${{ github.workspace }}/.cache/uv steps: + - uses: actions/cache@v4 + id: cache-uv + with: + path: ${{ env.UV_CACHE_DIR }} + key: ${{ matrix.platform }}-uv-${{ matrix.resolution }} - uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Install tools + shell: bash + run: | + make setup - name: Set up Python + id: setup-python uses: actions/setup-python@v5 with: python-version: | 3.10 + 3.11 3.12 3.13-dev - cache: 'pip' - - name: Configure environment + - name: Configure venv and test + shell: bash run: | - echo "::group::pip install" - python -m pip install tox - echo "::endgroup::" - mkdir -p results - - name: Setup Tox environments - run: tox run --colored yes -m tests --notest - - name: Test with tox - run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json --colored yes -m unit-tests + for python_version in 3.10 3.11 3.12 3.13; do + echo "::group::Python $python_version (install)" + uv sync --python=$python_version --reinstall --resolution=${{ matrix.resolution }} + echo "::endgroup::" + echo "::group::Python $python_version (test)" + make test-unit + echo "::endgroup::" + done env: PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload code coverage uses: codecov/codecov-action@v4 with: - directory: ./results/ - files: coverage*.xml + name: coverage-unit-${{ matrix.python-version }}-${{ matrix.platform }} + files: .coverage*.xml - name: Upload test results if: success() || failure() uses: actions/upload-artifact@v4 with: - name: unit-test-results-${{ matrix.platform }} - path: results/ + name: results-unit-${{ matrix.python-version }}-${{ matrix.platform }}-${{ matrix.resolution }} + path: | + ./.results.*.xml + ./.coverage.*.xml integration: strategy: matrix: - platform: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest] + platform: [ubuntu-latest, windows-latest, macos-latest] + resolution: [highest] + include: + - platform: ubuntu-latest + resolution: lowest runs-on: ${{ matrix.platform }} + env: + UV_CACHE_DIR: ${{ github.workspace }}/.cache/uv steps: + - uses: actions/cache@v4 + id: cache-uv + with: + path: ${{ env.UV_CACHE_DIR }} + key: ${{ matrix.platform }}-uv-${{ matrix.resolution }} - uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Install tools + shell: bash + run: | + make setup - name: Set up Python + if: ${{ runner.os != 'Linux' }} + id: setup-python uses: actions/setup-python@v5 with: - python-version: | - 3.10 - 3.12 - 3.13-dev - cache: 'pip' - - name: Configure environment + python-version: "3.10" + - name: Configure venv and test + shell: bash run: | - echo "::group::pip install" - python -m pip install tox + echo "::group::Sync" + uv sync --reinstall --resolution=${{ matrix.resolution }} + echo "::endgroup::" + echo "::group::Test" + make test-integration echo "::endgroup::" - mkdir -p results - - name: Setup Tox environments - run: tox run --colored yes -m tests --notest - - name: Test with tox - run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json --colored yes -m integration-tests env: PYTEST_ADDOPTS: "--no-header -vv -rN" + - name: Upload code coverage + uses: codecov/codecov-action@v4 + with: + name: coverage-integration-${{ matrix.python-version }}-${{ matrix.platform }} + files: .coverage*.xml - name: Upload test results if: success() || failure() uses: actions/upload-artifact@v4 with: - name: integration-test-results-${{ matrix.platform }} - path: results/ + name: results-integration-${{ matrix.python-version }}-${{ matrix.platform }}-${{ matrix.resolution }} + path: | + ./.results.*.xml + ./.coverage.*.xml diff --git a/Makefile b/Makefile index 6dcafe4..5828b87 100644 --- a/Makefile +++ b/Makefile @@ -16,9 +16,8 @@ help: ## Show this help. setup: ## Set up a development environment ifeq ($(OS),Linux) sudo snap install codespell ruff shellcheck - sudo snap install --classic --beta astral-uv - sudo snap alias astral-uv.uv uv - sudo snap alias astral-uv.uvx uvx + sudo snap install --classic astral-uv + sudo apt-get --yes install libxml2-dev libxslt-dev else ifeq ($(OS),Windows_NT) pipx install uv choco install shellcheck @@ -27,41 +26,36 @@ else ifeq ($(OS),Darwin) brew install shellcheck endif ifneq ($(OS),Linux) - uv tool install codespell - uv tool install ruff - uv tool update-shell + uv tool install --upgrade codespell + uv tool install --upgrade ruff endif + uv tool install --upgrade yamllint + uv tool update-shell -.PHONY: setup-pre-commit +.PHONY: setup-precommit setup-precommit: ## Set up pre-commit hooks in this repository. -ifeq (, $(shell which pre-commit)) - uv tool install pre-commit -endif - pre-commit install + uvx pre-commit install .PHONY: autoformat autoformat: format-ruff format-codespell ## Run all automatic formatters .PHONY: lint -lint: lint-ruff lint-codespell lint-mypy lint-pyright lint-shellcheck lint-yaml lint-docs ## Run all linters +lint: lint-ruff lint-codespell lint-mypy lint-pyright lint-yaml ## Run all linters .PHONY: test -test: test-unit test-integration ## Run all tests +test: test-unit test-integration ## Run all tests with the default python .PHONY: docs docs: ## Build documentation - uv run --extra docs sphinx-build -b html -W docs docs/_build + uv run --frozen --extra docs sphinx-build -b html -W docs docs/_build .PHONY: docs-auto docs-auto: ## Build and host docs with sphinx-autobuild - uv run --extra docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W docs docs/_build - -# Helpful in `help` to split the main targets from things that build ----------------- : ## ---------------- + uv run --frozen --extra docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W docs docs/_build .PHONY: format-codespell format-codespell: ## Fix spelling issues with codespell - uv run codespell --toml pyproject.toml --write-changes $(SOURCES) + codespell --toml pyproject.toml --write-changes $(SOURCES) .PHONY: format-ruff format-ruff: ## Automatically format with ruff @@ -70,19 +64,19 @@ format-ruff: ## Automatically format with ruff .PHONY: lint-codespell lint-codespell: ## Check spelling with codespell - uv run codespell --toml pyproject.toml $(SOURCES) + codespell --toml pyproject.toml $(SOURCES) .PHONY: lint-docs lint-docs: ## Lint the documentation - uv run --extra docs sphinx-lint --max-line-length 80 --enable all $(DOCS) + uv run --frozen --extra docs sphinx-lint --enable all $(DOCS) .PHONY: lint-mypy lint-mypy: ## Check types with mypy - uv run mypy $(SOURCES) + uv run mypy $(PROJECT) .PHONY: lint-pyright lint-pyright: ## Check types with pyright - uv run pyright + uv run pyright $(SOURCES) .PHONY: lint-ruff lint-ruff: ## Lint with ruff @@ -91,16 +85,16 @@ lint-ruff: ## Lint with ruff .PHONY: lint-shellcheck lint-shellcheck: - sh -c 'git ls-files | file --mime-type -Nnf- | grep shellscript | cut -f1 -d: | xargs -r shellcheck' + sh -c 'git ls-files | file --mime-type -Nnf- | grep shellscript | rev | cut -d: -f2- | rev | xargs -r shellcheck' .PHONY: lint-yaml lint-yaml: ## Lint YAML files with yamllint - uv run yamllint . + yamllint . .PHONY: test-unit test-unit: ## Run unit tests - uv run pytest --cov=$(PROJECT) --cov-config=pyproject.toml --cov-report=xml:.coverage.unit.xml --junit-xml=.results.unit.xml tests/unit + uv run --frozen pytest --cov=$(PACKAGE) --cov-config=pyproject.toml --cov-report=xml:.coverage.unit.xml --junit-xml=.results.unit.xml tests/unit .PHONY: test-integration test-integration: ## Run integration tests - uv run pytest --cov=$(PROJECT) --cov-config=pyproject.toml --cov-report=xml:.coverage.integration.xml --junit-xml=.results.integration.xml tests/integration + uv run --frozen pytest --cov=$(PACKAGE) --cov-config=pyproject.toml --cov-report=xml:.coverage.integration.xml --junit-xml=.results.integration.xml tests/integration diff --git a/pyproject.toml b/pyproject.toml index 0267f1f..740c705 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,20 +17,6 @@ requires-python = ">=3.10" starcraft-hello = "starcraft:hello" [project.optional-dependencies] -dev = [ - "build", - "coverage[toml]~=7.4", - "pytest~=8.0", - "pytest-cov~=5.0", - "pytest-mock~=3.12", -] -lint = [ - "yamllint~=1.34", -] -types = [ - "mypy[reports]~=1.11.0", - "pyright==1.1.380", -] docs = [ "canonical-sphinx~=0.1", "sphinx-autobuild~=2024.2", @@ -40,15 +26,30 @@ docs = [ ] [tool.uv] +constraint-dependencies = [ + # The constraints below are because older versions won't install with uv + "build>=0.1.0", + "iniconfig>=1.1.0", + "lxml>=5.0", + "pyparsing>=3.0.0", + "pyproject-hooks>=1.0.0", + "pyyaml>=5.0", + "markdown>=3.0", + "markupsafe>=2.0", + "regex>=2021.11.10", + "sphinx-basic-ng>=1.0.0b1", + "tornado>=4.0", + "webencodings>=0.4.0", +] dev-dependencies = [ - "build", + "build>=1.2.1", "coverage[toml]~=7.4", "pytest~=8.0", "pytest-cov~=5.0", "pytest-mock~=3.12", "yamllint~=1.34", "mypy[reports]~=1.11.0", - "pyright==1.1.375", + "pyright==1.1.380", "types-Pygments", "types-colorama", "types-setuptools", @@ -85,9 +86,6 @@ git_describe_command = "git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9] include = ["*craft*"] namespaces = false -[tool.black] -target-version = ["py310"] - [tool.codespell] ignore-words-list = "buildd,crate,keyserver,comandos,ro,dedent,dedented" skip = ".tox,.git,build,.*_cache,__pycache__,*.tar,*.snap,*.png,./node_modules,./docs/_build,.direnv,.venv,venv,.vscode" @@ -296,6 +294,7 @@ classmethod-decorators = ["pydantic.validator", "pydantic.root_validator"] "PLR2004", # Allow magic values in tests "SLF", # Allow accessing private members from tests. ] + "__init__.py" = [ "I001", # isort leaves init files alone by default, this makes ruff ignore them too. "F401", # Allows unused imports in __init__ files. diff --git a/tox.ini b/tox.ini index f951b6e..977d121 100644 --- a/tox.ini +++ b/tox.ini @@ -36,6 +36,8 @@ pass_env = CI CRAFT_* PYTEST_ADDOPTS +allowlist_externals = + make [test] # Base configuration for unit and integration tests package = editable @@ -55,57 +57,33 @@ labels = change_dir = unit: tests/unit integration: tests/integration -commands = pytest {tty:--color=yes} --cov={tox_root}/starcraft --cov-config={tox_root}/pyproject.toml --cov-report=xml:{tox_root}/results/coverage-{env_name}.xml --junit-xml={tox_root}/results/test-results-{env_name}.xml {posargs} - -[lint] # Standard linting configuration -package = editable -extras = lint -env_dir = {work_dir}/linting -runner = ignore_env_name_mismatch -allowlist_externals = - codespell: codespell - shellcheck: bash, xargs - ruff: ruff - -[shellcheck] -find = git ls-files -filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: +commands = pytest {tty:--color=yes} --cov={tox_root}/craft_platforms --cov-config={tox_root}/pyproject.toml --cov-report=xml:{tox_root}/results/coverage-{env_name}.xml --junit-xml={tox_root}/results/test-results-{env_name}.xml {posargs} [testenv:lint-{ruff,shellcheck,codespell,yaml}] description = Lint the source code -base = testenv, lint +base = testenv labels = lint -commands_pre = - shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' commands = - ruff: ruff format --check --diff --respect-gitignore {posargs:.} - ruff: ruff check --respect-gitignore {posargs:.} - shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck - codespell: codespell --toml {tox_root}/pyproject.toml {posargs} - yaml: yamllint {posargs} . + ruff: make lint-ruff + shellcheck: make lint-shellcheck + codespell: make lint-codespell + yaml: make lint-yaml [testenv:lint-{mypy,pyright}] description = Static type checking -base = testenv, lint -env_dir = {work_dir}/typing -extras = dev, types +base = testenv labels = lint, type -allowlist_externals = - mypy: mkdir -commands_pre = - mypy: mkdir -p {tox_root}/.mypy_cache commands = - pyright: pyright {posargs} - mypy: mypy --install-types --non-interactive {posargs:.} + pyright: make lint-pyright + mypy: make lint-mypy [testenv:format-{ruff,codespell}] description = Automatically format source code base = testenv, lint labels = format commands = - ruff: ruff format --respect-gitignore {posargs:.} - ruff: ruff check --fix --respect-gitignore {posargs} . - codespell: codespell --toml {tox_root}/pyproject.toml --write-changes {posargs} + ruff: make format-ruff + codespell: make format-codespell [testenv:pre-commit] base = @@ -117,34 +95,17 @@ runner = ignore_env_name_mismatch description = Run pre-commit on staged files or arbitrary pre-commit commands (tox run -e pre-commit -- [args]) commands = pre-commit {posargs:run} -[docs] # Sphinx documentation configuration -extras = docs -package = editable -no_package = true -env_dir = {work_dir}/docs -runner = ignore_env_name_mismatch -source_dir = {tox_root}/{project_name} - [testenv:build-docs] description = Build sphinx documentation -base = docs allowlist_externals = bash -commands_pre = bash -c 'if [[ ! -e docs ]];then echo "No docs directory. Run `tox run -e sphinx-quickstart` to create one.;";return 1;fi' -# "-W" is to treat warnings as errors -commands = sphinx-build {posargs:-b html} -W {tox_root}/docs {tox_root}/docs/_build +commands = make docs [testenv:autobuild-docs] description = Build documentation with an autoupdating server base = docs -commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} -W --watch {source_dir} {tox_root}/docs {tox_root}/docs/_build - -[lint-docs] -find = git ls-files +commands = make docs-auto [testenv:lint-docs] description = Lint the documentation with sphinx-lint -base = docs labels = lint -allowlist_externals = bash, xargs -commands_pre = bash -c '{[lint-docs]find} > {env_tmp_dir}/lint_docs_files' -commands = xargs --no-run-if-empty --arg-file {env_tmp_dir}/lint_docs_files sphinx-lint --max-line-length 88 --enable all {posargs} +commands = make lint-docs diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..0a9562c --- /dev/null +++ b/uv.lock @@ -0,0 +1,1922 @@ +version = 1 +requires-python = ">=3.10" +resolution-markers = [ + "python_full_version < '3.13'", + "python_full_version >= '3.13'", +] + +[manifest] +constraints = [ + { name = "build", specifier = ">=0.1.0" }, + { name = "iniconfig", specifier = ">=1.1.0" }, + { name = "lxml", specifier = ">=5.0" }, + { name = "markdown", specifier = ">=3.0" }, + { name = "markupsafe", specifier = ">=2.0" }, + { name = "pyparsing", specifier = ">=3.0.0" }, + { name = "pyproject-hooks", specifier = ">=1.0.0" }, + { name = "pyyaml", specifier = ">=5.0" }, + { name = "regex", specifier = ">=2021.11.10" }, + { name = "sphinx-basic-ng", specifier = ">=1.0.0b1" }, + { name = "tornado", specifier = ">=4.0" }, + { name = "webencodings", specifier = ">=0.4.0" }, +] + +[[package]] +name = "alabaster" +version = "0.7.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511 }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, +] + +[[package]] +name = "anyio" +version = "4.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "idna" }, + { name = "sniffio" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a0/44/66874c5256e9fbc30103b31927fd9341c8da6ccafd4721b2b3e81e6ef176/anyio-4.5.0.tar.gz", hash = "sha256:c5a275fe5ca0afd788001f58fca1e69e29ce706d746e317d660e21f70c530ef9", size = 169376 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/68/f9e9bf6324c46e6b8396610aef90ad423ec3e18c9079547ceafea3dce0ec/anyio-4.5.0-py3-none-any.whl", hash = "sha256:fdeb095b7cc5a5563175eedd926ec4ae55413bb4be5770c424af0ba46ccb4a78", size = 89250 }, +] + +[[package]] +name = "apeye" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "apeye-core" }, + { name = "domdf-python-tools" }, + { name = "platformdirs" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4f/6b/cc65e31843d7bfda8313a9dc0c77a21e8580b782adca53c7cb3e511fe023/apeye-1.4.1.tar.gz", hash = "sha256:14ea542fad689e3bfdbda2189a354a4908e90aee4bf84c15ab75d68453d76a36", size = 99219 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/7b/2d63664777b3e831ac1b1d8df5bbf0b7c8bee48e57115896080890527b1b/apeye-1.4.1-py3-none-any.whl", hash = "sha256:44e58a9104ec189bf42e76b3a7fe91e2b2879d96d48e9a77e5e32ff699c9204e", size = 107989 }, +] + +[[package]] +name = "apeye-core" +version = "1.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "domdf-python-tools" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e5/4c/4f108cfd06923bd897bf992a6ecb6fb122646ee7af94d7f9a64abd071d4c/apeye_core-1.1.5.tar.gz", hash = "sha256:5de72ed3d00cc9b20fea55e54b7ab8f5ef8500eb33a5368bc162a5585e238a55", size = 96511 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/9f/fa9971d2a0c6fef64c87ba362a493a4f230eff4ea8dfb9f4c7cbdf71892e/apeye_core-1.1.5-py3-none-any.whl", hash = "sha256:dc27a93f8c9e246b3b238c5ea51edf6115ab2618ef029b9f2d9a190ec8228fbf", size = 99286 }, +] + +[[package]] +name = "autodocsumm" +version = "0.2.13" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/19/2cefb1103bef41ef33393f0de37b72920a099f9a56aa5434570e7dcdf0f4/autodocsumm-0.2.13.tar.gz", hash = "sha256:ac5f0cf1adbe957acb136fe0d9e16c38fb74fcaefb45c148204aba26dbb12ee2", size = 45426 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/fb/59e528d9f5b1aadf4e4fb29e93b1d85570a0f089ebde7b43c574109f8373/autodocsumm-0.2.13-py3-none-any.whl", hash = "sha256:bf4d82ea7acb3e7d9a3ad8c135e097eca1d3f0bd00800d7804127e848e66741d", size = 14257 }, +] + +[[package]] +name = "babel" +version = "2.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, +] + +[[package]] +name = "bracex" +version = "2.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ac/f1/ac657fd234f4ee61da9d90f2bae7d6078074de2f97cb911743faa8d10a91/bracex-2.5.tar.gz", hash = "sha256:0725da5045e8d37ea9592ab3614d8b561e22c3c5fde3964699be672e072ab611", size = 26622 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/4f/54d324c35221c027ca77e9aae418f525003bd0cc2613eea162a1246b5a92/bracex-2.5-py3-none-any.whl", hash = "sha256:d2fcf4b606a82ac325471affe1706dd9bbaa3536c91ef86a31f6b766f3dad1d0", size = 11509 }, +] + +[[package]] +name = "build" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "os_name == 'nt'" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10.2'" }, + { name = "packaging" }, + { name = "pyproject-hooks" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/dd/bb/4a1b7e3a7520e310cf7bfece43788071604e1ccf693a7f0c4638c59068d6/build-1.2.2.tar.gz", hash = "sha256:119b2fb462adef986483438377a13b2f42064a2a3a4161f24a0cca698a07ac8c", size = 46516 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/fd/e4bda6228637ecae5732162b5ac2a5a822e2ba8e546eb4997cde51b231a3/build-1.2.2-py3-none-any.whl", hash = "sha256:277ccc71619d98afdd841a0e96ac9fe1593b823af481d3b0cea748e8894e0613", size = 22823 }, +] + +[[package]] +name = "cachecontrol" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "msgpack" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/55/edea9d90ee57ca54d34707607d15c20f72576b96cb9f3e7fc266cb06b426/cachecontrol-0.14.0.tar.gz", hash = "sha256:7db1195b41c81f8274a7bbd97c956f44e8348265a1bc7641c37dfebc39f0c938", size = 28899 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/a9/7d331fec593a4b2953338df33e954aac6ff79eb5a073bca2783766bc7722/cachecontrol-0.14.0-py3-none-any.whl", hash = "sha256:f5bf3f0620c38db2e5122c0726bdebb0d16869de966ea6a2befe92470b740ea0", size = 22064 }, +] + +[package.optional-dependencies] +filecache = [ + { name = "filelock" }, +] + +[[package]] +name = "canonical-sphinx" +version = "0.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "canonical-sphinx-extensions" }, + { name = "furo" }, + { name = "linkify-it-py" }, + { name = "myst-parser" }, + { name = "pyspelling" }, + { name = "sphinx" }, + { name = "sphinx-copybutton" }, + { name = "sphinx-design" }, + { name = "sphinx-notfound-page" }, + { name = "sphinx-reredirects" }, + { name = "sphinx-tabs" }, + { name = "sphinxcontrib-jquery" }, + { name = "sphinxext-opengraph" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f1/7e/1e85db040fb0a2f3b2b59ccd6c878e41f81192bc1ffd02f721151d5c2685/canonical-sphinx-0.1.0.tar.gz", hash = "sha256:0464eda448f5791dd2c1b956e2a7abf2fccf132f8032cd61f0f3739c9c91e450", size = 55922 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/6f/09128fb209e841367b717da5c54621fa687140cf068531dc1ae656b96aed/canonical_sphinx-0.1.0-py3-none-any.whl", hash = "sha256:e1dcea35dafaa74ae7729af848a1ff3ab63444df1cadbeab01953df2ca92de59", size = 30406 }, +] + +[[package]] +name = "canonical-sphinx-extensions" +version = "0.0.23" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "docutils" }, + { name = "gitpython" }, + { name = "requests" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b6/49/2e64462241adfe97615dd646ad3042e1a3e7bb77f14ed15e1aa0e543c3ff/canonical_sphinx_extensions-0.0.23.tar.gz", hash = "sha256:5178c97e8c515dcff42b1976a81a68e74e70ca77a8fb0b68af3dc097705a49eb", size = 20653 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/dd/e9079ddd7fee8f34bece4e69d9a33338f1f88630757a6a963ca0aac0e01f/canonical_sphinx_extensions-0.0.23-py3-none-any.whl", hash = "sha256:05113c93e37fe9c9be1a5f1ba6491c1dbb7492cdecd9b5202ed165e671973c31", size = 38023 }, +] + +[[package]] +name = "certifi" +version = "2024.8.30" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", size = 104809 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2b/61/095a0aa1a84d1481998b534177c8566fdc50bb1233ea9a0478cd3cc075bd/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", size = 194219 }, + { url = "https://files.pythonhosted.org/packages/cc/94/f7cf5e5134175de79ad2059edf2adce18e0685ebdb9227ff0139975d0e93/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", size = 122521 }, + { url = "https://files.pythonhosted.org/packages/46/6a/d5c26c41c49b546860cc1acabdddf48b0b3fb2685f4f5617ac59261b44ae/charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", size = 120383 }, + { url = "https://files.pythonhosted.org/packages/b8/60/e2f67915a51be59d4539ed189eb0a2b0d292bf79270410746becb32bc2c3/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", size = 138223 }, + { url = "https://files.pythonhosted.org/packages/05/8c/eb854996d5fef5e4f33ad56927ad053d04dc820e4a3d39023f35cad72617/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", size = 148101 }, + { url = "https://files.pythonhosted.org/packages/f6/93/bb6cbeec3bf9da9b2eba458c15966658d1daa8b982c642f81c93ad9b40e1/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", size = 140699 }, + { url = "https://files.pythonhosted.org/packages/da/f1/3702ba2a7470666a62fd81c58a4c40be00670e5006a67f4d626e57f013ae/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", size = 142065 }, + { url = "https://files.pythonhosted.org/packages/3f/ba/3f5e7be00b215fa10e13d64b1f6237eb6ebea66676a41b2bcdd09fe74323/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", size = 144505 }, + { url = "https://files.pythonhosted.org/packages/33/c3/3b96a435c5109dd5b6adc8a59ba1d678b302a97938f032e3770cc84cd354/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", size = 139425 }, + { url = "https://files.pythonhosted.org/packages/43/05/3bf613e719efe68fb3a77f9c536a389f35b95d75424b96b426a47a45ef1d/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", size = 145287 }, + { url = "https://files.pythonhosted.org/packages/58/78/a0bc646900994df12e07b4ae5c713f2b3e5998f58b9d3720cce2aa45652f/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", size = 149929 }, + { url = "https://files.pythonhosted.org/packages/eb/5c/97d97248af4920bc68687d9c3b3c0f47c910e21a8ff80af4565a576bd2f0/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", size = 141605 }, + { url = "https://files.pythonhosted.org/packages/a8/31/47d018ef89f95b8aded95c589a77c072c55e94b50a41aa99c0a2008a45a4/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", size = 142646 }, + { url = "https://files.pythonhosted.org/packages/ae/d5/4fecf1d58bedb1340a50f165ba1c7ddc0400252d6832ff619c4568b36cc0/charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", size = 92846 }, + { url = "https://files.pythonhosted.org/packages/a2/a0/4af29e22cb5942488cf45630cbdd7cefd908768e69bdd90280842e4e8529/charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", size = 100343 }, + { url = "https://files.pythonhosted.org/packages/68/77/02839016f6fbbf808e8b38601df6e0e66c17bbab76dff4613f7511413597/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", size = 191647 }, + { url = "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", size = 121434 }, + { url = "https://files.pythonhosted.org/packages/dd/51/68b61b90b24ca35495956b718f35a9756ef7d3dd4b3c1508056fa98d1a1b/charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", size = 118979 }, + { url = "https://files.pythonhosted.org/packages/e4/a6/7ee57823d46331ddc37dd00749c95b0edec2c79b15fc0d6e6efb532e89ac/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", size = 136582 }, + { url = "https://files.pythonhosted.org/packages/74/f1/0d9fe69ac441467b737ba7f48c68241487df2f4522dd7246d9426e7c690e/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", size = 146645 }, + { url = "https://files.pythonhosted.org/packages/05/31/e1f51c76db7be1d4aef220d29fbfa5dbb4a99165d9833dcbf166753b6dc0/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", size = 139398 }, + { url = "https://files.pythonhosted.org/packages/40/26/f35951c45070edc957ba40a5b1db3cf60a9dbb1b350c2d5bef03e01e61de/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", size = 140273 }, + { url = "https://files.pythonhosted.org/packages/07/07/7e554f2bbce3295e191f7e653ff15d55309a9ca40d0362fcdab36f01063c/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", size = 142577 }, + { url = "https://files.pythonhosted.org/packages/d8/b5/eb705c313100defa57da79277d9207dc8d8e45931035862fa64b625bfead/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", size = 137747 }, + { url = "https://files.pythonhosted.org/packages/19/28/573147271fd041d351b438a5665be8223f1dd92f273713cb882ddafe214c/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", size = 143375 }, + { url = "https://files.pythonhosted.org/packages/cf/7c/f3b682fa053cc21373c9a839e6beba7705857075686a05c72e0f8c4980ca/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", size = 148474 }, + { url = "https://files.pythonhosted.org/packages/1e/49/7ab74d4ac537ece3bc3334ee08645e231f39f7d6df6347b29a74b0537103/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", size = 140232 }, + { url = "https://files.pythonhosted.org/packages/2d/dc/9dacba68c9ac0ae781d40e1a0c0058e26302ea0660e574ddf6797a0347f7/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", size = 140859 }, + { url = "https://files.pythonhosted.org/packages/6c/c2/4a583f800c0708dd22096298e49f887b49d9746d0e78bfc1d7e29816614c/charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", size = 92509 }, + { url = "https://files.pythonhosted.org/packages/57/ec/80c8d48ac8b1741d5b963797b7c0c869335619e13d4744ca2f67fc11c6fc/charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", size = 99870 }, + { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892 }, + { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213 }, + { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404 }, + { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275 }, + { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518 }, + { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182 }, + { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869 }, + { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042 }, + { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275 }, + { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819 }, + { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415 }, + { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212 }, + { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167 }, + { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041 }, + { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397 }, + { url = "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", size = 48543 }, +] + +[[package]] +name = "click" +version = "8.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "platform_system == 'Windows'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "coverage" +version = "7.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/08/7e37f82e4d1aead42a7443ff06a1e406aabf7302c4f00a546e4b320b994c/coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d", size = 798791 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/61/eb7ce5ed62bacf21beca4937a90fe32545c91a3c8a42a30c6616d48fc70d/coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16", size = 206690 }, + { url = "https://files.pythonhosted.org/packages/7d/73/041928e434442bd3afde5584bdc3f932fb4562b1597629f537387cec6f3d/coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36", size = 207127 }, + { url = "https://files.pythonhosted.org/packages/c7/c8/6ca52b5147828e45ad0242388477fdb90df2c6cbb9a441701a12b3c71bc8/coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02", size = 235654 }, + { url = "https://files.pythonhosted.org/packages/d5/da/9ac2b62557f4340270942011d6efeab9833648380109e897d48ab7c1035d/coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc", size = 233598 }, + { url = "https://files.pythonhosted.org/packages/53/23/9e2c114d0178abc42b6d8d5281f651a8e6519abfa0ef460a00a91f80879d/coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23", size = 234732 }, + { url = "https://files.pythonhosted.org/packages/0f/7e/a0230756fb133343a52716e8b855045f13342b70e48e8ad41d8a0d60ab98/coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34", size = 233816 }, + { url = "https://files.pythonhosted.org/packages/28/7c/3753c8b40d232b1e5eeaed798c875537cf3cb183fb5041017c1fdb7ec14e/coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c", size = 232325 }, + { url = "https://files.pythonhosted.org/packages/57/e3/818a2b2af5b7573b4b82cf3e9f137ab158c90ea750a8f053716a32f20f06/coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959", size = 233418 }, + { url = "https://files.pythonhosted.org/packages/c8/fb/4532b0b0cefb3f06d201648715e03b0feb822907edab3935112b61b885e2/coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232", size = 209343 }, + { url = "https://files.pythonhosted.org/packages/5a/25/af337cc7421eca1c187cc9c315f0a755d48e755d2853715bfe8c418a45fa/coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0", size = 210136 }, + { url = "https://files.pythonhosted.org/packages/ad/5f/67af7d60d7e8ce61a4e2ddcd1bd5fb787180c8d0ae0fbd073f903b3dd95d/coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93", size = 206796 }, + { url = "https://files.pythonhosted.org/packages/e1/0e/e52332389e057daa2e03be1fbfef25bb4d626b37d12ed42ae6281d0a274c/coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3", size = 207244 }, + { url = "https://files.pythonhosted.org/packages/aa/cd/766b45fb6e090f20f8927d9c7cb34237d41c73a939358bc881883fd3a40d/coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff", size = 239279 }, + { url = "https://files.pythonhosted.org/packages/70/6c/a9ccd6fe50ddaf13442a1e2dd519ca805cbe0f1fcd377fba6d8339b98ccb/coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d", size = 236859 }, + { url = "https://files.pythonhosted.org/packages/14/6f/8351b465febb4dbc1ca9929505202db909c5a635c6fdf33e089bbc3d7d85/coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6", size = 238549 }, + { url = "https://files.pythonhosted.org/packages/68/3c/289b81fa18ad72138e6d78c4c11a82b5378a312c0e467e2f6b495c260907/coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56", size = 237477 }, + { url = "https://files.pythonhosted.org/packages/ed/1c/aa1efa6459d822bd72c4abc0b9418cf268de3f60eeccd65dc4988553bd8d/coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234", size = 236134 }, + { url = "https://files.pythonhosted.org/packages/fb/c8/521c698f2d2796565fe9c789c2ee1ccdae610b3aa20b9b2ef980cc253640/coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133", size = 236910 }, + { url = "https://files.pythonhosted.org/packages/7d/30/033e663399ff17dca90d793ee8a2ea2890e7fdf085da58d82468b4220bf7/coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c", size = 209348 }, + { url = "https://files.pythonhosted.org/packages/20/05/0d1ccbb52727ccdadaa3ff37e4d2dc1cd4d47f0c3df9eb58d9ec8508ca88/coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6", size = 210230 }, + { url = "https://files.pythonhosted.org/packages/7e/d4/300fc921dff243cd518c7db3a4c614b7e4b2431b0d1145c1e274fd99bd70/coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778", size = 206983 }, + { url = "https://files.pythonhosted.org/packages/e1/ab/6bf00de5327ecb8db205f9ae596885417a31535eeda6e7b99463108782e1/coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391", size = 207221 }, + { url = "https://files.pythonhosted.org/packages/92/8f/2ead05e735022d1a7f3a0a683ac7f737de14850395a826192f0288703472/coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8", size = 240342 }, + { url = "https://files.pythonhosted.org/packages/0f/ef/94043e478201ffa85b8ae2d2c79b4081e5a1b73438aafafccf3e9bafb6b5/coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d", size = 237371 }, + { url = "https://files.pythonhosted.org/packages/1f/0f/c890339dd605f3ebc269543247bdd43b703cce6825b5ed42ff5f2d6122c7/coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca", size = 239455 }, + { url = "https://files.pythonhosted.org/packages/d1/04/7fd7b39ec7372a04efb0f70c70e35857a99b6a9188b5205efb4c77d6a57a/coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163", size = 238924 }, + { url = "https://files.pythonhosted.org/packages/ed/bf/73ce346a9d32a09cf369f14d2a06651329c984e106f5992c89579d25b27e/coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a", size = 237252 }, + { url = "https://files.pythonhosted.org/packages/86/74/1dc7a20969725e917b1e07fe71a955eb34bc606b938316bcc799f228374b/coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d", size = 238897 }, + { url = "https://files.pythonhosted.org/packages/b6/e9/d9cc3deceb361c491b81005c668578b0dfa51eed02cd081620e9a62f24ec/coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5", size = 209606 }, + { url = "https://files.pythonhosted.org/packages/47/c8/5a2e41922ea6740f77d555c4d47544acd7dc3f251fe14199c09c0f5958d3/coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb", size = 210373 }, + { url = "https://files.pythonhosted.org/packages/8c/f9/9aa4dfb751cb01c949c990d136a0f92027fbcc5781c6e921df1cb1563f20/coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106", size = 207007 }, + { url = "https://files.pythonhosted.org/packages/b9/67/e1413d5a8591622a46dd04ff80873b04c849268831ed5c304c16433e7e30/coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9", size = 207269 }, + { url = "https://files.pythonhosted.org/packages/14/5b/9dec847b305e44a5634d0fb8498d135ab1d88330482b74065fcec0622224/coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c", size = 239886 }, + { url = "https://files.pythonhosted.org/packages/7b/b7/35760a67c168e29f454928f51f970342d23cf75a2bb0323e0f07334c85f3/coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a", size = 237037 }, + { url = "https://files.pythonhosted.org/packages/f7/95/d2fd31f1d638df806cae59d7daea5abf2b15b5234016a5ebb502c2f3f7ee/coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060", size = 239038 }, + { url = "https://files.pythonhosted.org/packages/6e/bd/110689ff5752b67924efd5e2aedf5190cbbe245fc81b8dec1abaffba619d/coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862", size = 238690 }, + { url = "https://files.pythonhosted.org/packages/d3/a8/08d7b38e6ff8df52331c83130d0ab92d9c9a8b5462f9e99c9f051a4ae206/coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388", size = 236765 }, + { url = "https://files.pythonhosted.org/packages/d6/6a/9cf96839d3147d55ae713eb2d877f4d777e7dc5ba2bce227167d0118dfe8/coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155", size = 238611 }, + { url = "https://files.pythonhosted.org/packages/74/e4/7ff20d6a0b59eeaab40b3140a71e38cf52547ba21dbcf1d79c5a32bba61b/coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a", size = 209671 }, + { url = "https://files.pythonhosted.org/packages/35/59/1812f08a85b57c9fdb6d0b383d779e47b6f643bc278ed682859512517e83/coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129", size = 210368 }, + { url = "https://files.pythonhosted.org/packages/9c/15/08913be1c59d7562a3e39fce20661a98c0a3f59d5754312899acc6cb8a2d/coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e", size = 207758 }, + { url = "https://files.pythonhosted.org/packages/c4/ae/b5d58dff26cade02ada6ca612a76447acd69dccdbb3a478e9e088eb3d4b9/coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962", size = 208035 }, + { url = "https://files.pythonhosted.org/packages/b8/d7/62095e355ec0613b08dfb19206ce3033a0eedb6f4a67af5ed267a8800642/coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb", size = 250839 }, + { url = "https://files.pythonhosted.org/packages/7c/1e/c2967cb7991b112ba3766df0d9c21de46b476d103e32bb401b1b2adf3380/coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704", size = 246569 }, + { url = "https://files.pythonhosted.org/packages/8b/61/a7a6a55dd266007ed3b1df7a3386a0d760d014542d72f7c2c6938483b7bd/coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b", size = 248927 }, + { url = "https://files.pythonhosted.org/packages/c8/fa/13a6f56d72b429f56ef612eb3bc5ce1b75b7ee12864b3bd12526ab794847/coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f", size = 248401 }, + { url = "https://files.pythonhosted.org/packages/75/06/0429c652aa0fb761fc60e8c6b291338c9173c6aa0f4e40e1902345b42830/coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223", size = 246301 }, + { url = "https://files.pythonhosted.org/packages/52/76/1766bb8b803a88f93c3a2d07e30ffa359467810e5cbc68e375ebe6906efb/coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3", size = 247598 }, + { url = "https://files.pythonhosted.org/packages/66/8b/f54f8db2ae17188be9566e8166ac6df105c1c611e25da755738025708d54/coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f", size = 210307 }, + { url = "https://files.pythonhosted.org/packages/9f/b0/e0dca6da9170aefc07515cce067b97178cefafb512d00a87a1c717d2efd5/coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657", size = 211453 }, + { url = "https://files.pythonhosted.org/packages/a5/2b/0354ed096bca64dc8e32a7cbcae28b34cb5ad0b1fe2125d6d99583313ac0/coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df", size = 198926 }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "cssutils" +version = "2.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "more-itertools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/9f/329d26121fe165be44b1dfff21aa0dc348f04633931f1d20ed6cf448a236/cssutils-2.11.1.tar.gz", hash = "sha256:0563a76513b6af6eebbe788c3bf3d01c920e46b3f90c8416738c5cfc773ff8e2", size = 711657 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/ec/bb273b7208c606890dc36540fe667d06ce840a6f62f9fae7e658fcdc90fb/cssutils-2.11.1-py3-none-any.whl", hash = "sha256:a67bfdfdff4f3867fab43698ec4897c1a828eca5973f4073321b3bccaf1199b1", size = 385747 }, +] + +[[package]] +name = "dict2css" +version = "0.3.0.post1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cssutils" }, + { name = "domdf-python-tools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/24/eb/776eef1f1aa0188c0fc165c3a60b71027539f71f2eedc43ad21b060e9c39/dict2css-0.3.0.post1.tar.gz", hash = "sha256:89c544c21c4ca7472c3fffb9d37d3d926f606329afdb751dc1de67a411b70719", size = 7845 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/47/290daabcf91628f4fc0e17c75a1690b354ba067066cd14407712600e609f/dict2css-0.3.0.post1-py3-none-any.whl", hash = "sha256:f006a6b774c3e31869015122ae82c491fd25e7de4a75607a62aa3e798f837e0d", size = 25647 }, +] + +[[package]] +name = "docutils" +version = "0.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408 }, +] + +[[package]] +name = "domdf-python-tools" +version = "3.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "natsort" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6b/78/974e10c583ba9d2302e748c9585313a7f2c7ba00e4f600324f432e38fe68/domdf_python_tools-3.9.0.tar.gz", hash = "sha256:1f8a96971178333a55e083e35610d7688cd7620ad2b99790164e1fc1a3614c18", size = 103792 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/e9/7447a88b217650a74927d3444a89507986479a69b83741900eddd34167fe/domdf_python_tools-3.9.0-py3-none-any.whl", hash = "sha256:4e1ef365cbc24627d6d1e90cf7d46d8ab8df967e1237f4a26885f6986c78872e", size = 127106 }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, +] + +[[package]] +name = "filelock" +version = "3.16.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 }, +] + +[[package]] +name = "furo" +version = "2024.8.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "pygments" }, + { name = "sphinx" }, + { name = "sphinx-basic-ng" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a0/e2/d351d69a9a9e4badb4a5be062c2d0e87bd9e6c23b5e57337fef14bef34c8/furo-2024.8.6.tar.gz", hash = "sha256:b63e4cee8abfc3136d3bc03a3d45a76a850bada4d6374d24c1716b0e01394a01", size = 1661506 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/48/e791a7ed487dbb9729ef32bb5d1af16693d8925f4366befef54119b2e576/furo-2024.8.6-py3-none-any.whl", hash = "sha256:6cd97c58b47813d3619e63e9081169880fbe331f0ca883c871ff1f3f11814f5c", size = 341333 }, +] + +[[package]] +name = "gitdb" +version = "4.0.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "smmap" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/0d/bbb5b5ee188dec84647a4664f3e11b06ade2bde568dbd489d9d64adef8ed/gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b", size = 394469 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/5b/8f0c4a5bb9fd491c277c21eff7ccae71b47d43c4446c9d0c6cff2fe8c2c4/gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4", size = 62721 }, +] + +[[package]] +name = "gitpython" +version = "3.1.43" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gitdb" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b6/a1/106fd9fa2dd989b6fb36e5893961f82992cf676381707253e0bf93eb1662/GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c", size = 214149 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/bd/cc3a402a6439c15c3d4294333e13042b915bbeab54edc457c723931fed3f/GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff", size = 207337 }, +] + +[[package]] +name = "h11" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, +] + +[[package]] +name = "html5lib" +version = "1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/b6/b55c3f49042f1df3dcd422b7f224f939892ee94f22abcf503a9b7339eaf2/html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f", size = 272215 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d", size = 112173 }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769 }, +] + +[[package]] +name = "importlib-metadata" +version = "8.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", size = 55304 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/d9/a1e041c5e7caa9a05c925f4bdbdfb7f006d1f74996af53467bc394c97be7/importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", size = 26514 }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "jinja2" +version = "3.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 }, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595 }, +] + +[[package]] +name = "linkify-it-py" +version = "2.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "uc-micro-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/ae/bb56c6828e4797ba5a4821eec7c43b8bf40f69cda4d4f5f8c8a2810ec96a/linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048", size = 27946 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/1e/b832de447dee8b582cac175871d2f6c3d5077cc56d5575cadba1fd1cccfa/linkify_it_py-2.0.3-py3-none-any.whl", hash = "sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79", size = 19820 }, +] + +[[package]] +name = "lxml" +version = "5.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/6b/20c3a4b24751377aaa6307eb230b66701024012c29dd374999cc92983269/lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f", size = 3679318 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/ce/2789e39eddf2b13fac29878bfa465f0910eb6b0096e29090e5176bc8cf43/lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656", size = 8124570 }, + { url = "https://files.pythonhosted.org/packages/24/a8/f4010166a25d41715527129af2675981a50d3bbf7df09c5d9ab8ca24fbf9/lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d", size = 4413042 }, + { url = "https://files.pythonhosted.org/packages/41/a4/7e45756cecdd7577ddf67a68b69c1db0f5ddbf0c9f65021ee769165ffc5a/lxml-5.3.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:501d0d7e26b4d261fca8132854d845e4988097611ba2531408ec91cf3fd9d20a", size = 5139213 }, + { url = "https://files.pythonhosted.org/packages/02/e2/ecf845b12323c92748077e1818b64e8b4dba509a4cb12920b3762ebe7552/lxml-5.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb66442c2546446944437df74379e9cf9e9db353e61301d1a0e26482f43f0dd8", size = 4838814 }, + { url = "https://files.pythonhosted.org/packages/12/91/619f9fb72cf75e9ceb8700706f7276f23995f6ad757e6d400fbe35ca4990/lxml-5.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e41506fec7a7f9405b14aa2d5c8abbb4dbbd09d88f9496958b6d00cb4d45330", size = 5425084 }, + { url = "https://files.pythonhosted.org/packages/25/3b/162a85a8f0fd2a3032ec3f936636911c6e9523a8e263fffcfd581ce98b54/lxml-5.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f7d4a670107d75dfe5ad080bed6c341d18c4442f9378c9f58e5851e86eb79965", size = 4875993 }, + { url = "https://files.pythonhosted.org/packages/43/af/dd3f58cc7d946da6ae42909629a2b1d5dd2d1b583334d4af9396697d6863/lxml-5.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41ce1f1e2c7755abfc7e759dc34d7d05fd221723ff822947132dc934d122fe22", size = 5012462 }, + { url = "https://files.pythonhosted.org/packages/69/c1/5ea46b2d4c98f5bf5c83fffab8a0ad293c9bc74df9ecfbafef10f77f7201/lxml-5.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:44264ecae91b30e5633013fb66f6ddd05c006d3e0e884f75ce0b4755b3e3847b", size = 4815288 }, + { url = "https://files.pythonhosted.org/packages/1d/51/a0acca077ad35da458f4d3f729ef98effd2b90f003440d35fc36323f8ae6/lxml-5.3.0-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:3c174dc350d3ec52deb77f2faf05c439331d6ed5e702fc247ccb4e6b62d884b7", size = 5472435 }, + { url = "https://files.pythonhosted.org/packages/4d/6b/0989c9368986961a6b0f55b46c80404c4b758417acdb6d87bfc3bd5f4967/lxml-5.3.0-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:2dfab5fa6a28a0b60a20638dc48e6343c02ea9933e3279ccb132f555a62323d8", size = 4976354 }, + { url = "https://files.pythonhosted.org/packages/05/9e/87492d03ff604fbf656ed2bf3e2e8d28f5d58ea1f00ff27ac27b06509079/lxml-5.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b1c8c20847b9f34e98080da785bb2336ea982e7f913eed5809e5a3c872900f32", size = 5029973 }, + { url = "https://files.pythonhosted.org/packages/f9/cc/9ae1baf5472af88e19e2c454b3710c1be9ecafb20eb474eeabcd88a055d2/lxml-5.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2c86bf781b12ba417f64f3422cfc302523ac9cd1d8ae8c0f92a1c66e56ef2e86", size = 4888837 }, + { url = "https://files.pythonhosted.org/packages/d2/10/5594ffaec8c120d75b17e3ad23439b740a51549a9b5fd7484b2179adfe8f/lxml-5.3.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c162b216070f280fa7da844531169be0baf9ccb17263cf5a8bf876fcd3117fa5", size = 5530555 }, + { url = "https://files.pythonhosted.org/packages/ea/9b/de17f05377c8833343b629905571fb06cff2028f15a6f58ae2267662e341/lxml-5.3.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:36aef61a1678cb778097b4a6eeae96a69875d51d1e8f4d4b491ab3cfb54b5a03", size = 5405314 }, + { url = "https://files.pythonhosted.org/packages/8a/b4/227be0f1f3cca8255925985164c3838b8b36e441ff0cc10c1d3c6bdba031/lxml-5.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f65e5120863c2b266dbcc927b306c5b78e502c71edf3295dfcb9501ec96e5fc7", size = 5079303 }, + { url = "https://files.pythonhosted.org/packages/5c/ee/19abcebb7fc40319bb71cd6adefa1ad94d09b5660228715854d6cc420713/lxml-5.3.0-cp310-cp310-win32.whl", hash = "sha256:ef0c1fe22171dd7c7c27147f2e9c3e86f8bdf473fed75f16b0c2e84a5030ce80", size = 3475126 }, + { url = "https://files.pythonhosted.org/packages/a1/35/183d32551447e280032b2331738cd850da435a42f850b71ebeaab42c1313/lxml-5.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:052d99051e77a4f3e8482c65014cf6372e61b0a6f4fe9edb98503bb5364cfee3", size = 3805065 }, + { url = "https://files.pythonhosted.org/packages/5c/a8/449faa2a3cbe6a99f8d38dcd51a3ee8844c17862841a6f769ea7c2a9cd0f/lxml-5.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74bcb423462233bc5d6066e4e98b0264e7c1bed7541fff2f4e34fe6b21563c8b", size = 8141056 }, + { url = "https://files.pythonhosted.org/packages/ac/8a/ae6325e994e2052de92f894363b038351c50ee38749d30cc6b6d96aaf90f/lxml-5.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a3d819eb6f9b8677f57f9664265d0a10dd6551d227afb4af2b9cd7bdc2ccbf18", size = 4425238 }, + { url = "https://files.pythonhosted.org/packages/f8/fb/128dddb7f9086236bce0eeae2bfb316d138b49b159f50bc681d56c1bdd19/lxml-5.3.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b8f5db71b28b8c404956ddf79575ea77aa8b1538e8b2ef9ec877945b3f46442", size = 5095197 }, + { url = "https://files.pythonhosted.org/packages/b4/f9/a181a8ef106e41e3086629c8bdb2d21a942f14c84a0e77452c22d6b22091/lxml-5.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3406b63232fc7e9b8783ab0b765d7c59e7c59ff96759d8ef9632fca27c7ee4", size = 4809809 }, + { url = "https://files.pythonhosted.org/packages/25/2f/b20565e808f7f6868aacea48ddcdd7e9e9fb4c799287f21f1a6c7c2e8b71/lxml-5.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ecdd78ab768f844c7a1d4a03595038c166b609f6395e25af9b0f3f26ae1230f", size = 5407593 }, + { url = "https://files.pythonhosted.org/packages/23/0e/caac672ec246d3189a16c4d364ed4f7d6bf856c080215382c06764058c08/lxml-5.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168f2dfcfdedf611eb285efac1516c8454c8c99caf271dccda8943576b67552e", size = 4866657 }, + { url = "https://files.pythonhosted.org/packages/67/a4/1f5fbd3f58d4069000522196b0b776a014f3feec1796da03e495cf23532d/lxml-5.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa617107a410245b8660028a7483b68e7914304a6d4882b5ff3d2d3eb5948d8c", size = 4967017 }, + { url = "https://files.pythonhosted.org/packages/ee/73/623ecea6ca3c530dd0a4ed0d00d9702e0e85cd5624e2d5b93b005fe00abd/lxml-5.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:69959bd3167b993e6e710b99051265654133a98f20cec1d9b493b931942e9c16", size = 4810730 }, + { url = "https://files.pythonhosted.org/packages/1d/ce/fb84fb8e3c298f3a245ae3ea6221c2426f1bbaa82d10a88787412a498145/lxml-5.3.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:bd96517ef76c8654446fc3db9242d019a1bb5fe8b751ba414765d59f99210b79", size = 5455154 }, + { url = "https://files.pythonhosted.org/packages/b1/72/4d1ad363748a72c7c0411c28be2b0dc7150d91e823eadad3b91a4514cbea/lxml-5.3.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:ab6dd83b970dc97c2d10bc71aa925b84788c7c05de30241b9e96f9b6d9ea3080", size = 4969416 }, + { url = "https://files.pythonhosted.org/packages/42/07/b29571a58a3a80681722ea8ed0ba569211d9bb8531ad49b5cacf6d409185/lxml-5.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eec1bb8cdbba2925bedc887bc0609a80e599c75b12d87ae42ac23fd199445654", size = 5013672 }, + { url = "https://files.pythonhosted.org/packages/b9/93/bde740d5a58cf04cbd38e3dd93ad1e36c2f95553bbf7d57807bc6815d926/lxml-5.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a7095eeec6f89111d03dabfe5883a1fd54da319c94e0fb104ee8f23616b572d", size = 4878644 }, + { url = "https://files.pythonhosted.org/packages/56/b5/645c8c02721d49927c93181de4017164ec0e141413577687c3df8ff0800f/lxml-5.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6f651ebd0b21ec65dfca93aa629610a0dbc13dbc13554f19b0113da2e61a4763", size = 5511531 }, + { url = "https://files.pythonhosted.org/packages/85/3f/6a99a12d9438316f4fc86ef88c5d4c8fb674247b17f3173ecadd8346b671/lxml-5.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f422a209d2455c56849442ae42f25dbaaba1c6c3f501d58761c619c7836642ec", size = 5402065 }, + { url = "https://files.pythonhosted.org/packages/80/8a/df47bff6ad5ac57335bf552babfb2408f9eb680c074ec1ba412a1a6af2c5/lxml-5.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62f7fdb0d1ed2065451f086519865b4c90aa19aed51081979ecd05a21eb4d1be", size = 5069775 }, + { url = "https://files.pythonhosted.org/packages/08/ae/e7ad0f0fbe4b6368c5ee1e3ef0c3365098d806d42379c46c1ba2802a52f7/lxml-5.3.0-cp311-cp311-win32.whl", hash = "sha256:c6379f35350b655fd817cd0d6cbeef7f265f3ae5fedb1caae2eb442bbeae9ab9", size = 3474226 }, + { url = "https://files.pythonhosted.org/packages/c3/b5/91c2249bfac02ee514ab135e9304b89d55967be7e53e94a879b74eec7a5c/lxml-5.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c52100e2c2dbb0649b90467935c4b0de5528833c76a35ea1a2691ec9f1ee7a1", size = 3814971 }, + { url = "https://files.pythonhosted.org/packages/eb/6d/d1f1c5e40c64bf62afd7a3f9b34ce18a586a1cccbf71e783cd0a6d8e8971/lxml-5.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859", size = 8171753 }, + { url = "https://files.pythonhosted.org/packages/bd/83/26b1864921869784355459f374896dcf8b44d4af3b15d7697e9156cb2de9/lxml-5.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e", size = 4441955 }, + { url = "https://files.pythonhosted.org/packages/e0/d2/e9bff9fb359226c25cda3538f664f54f2804f4b37b0d7c944639e1a51f69/lxml-5.3.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f", size = 5050778 }, + { url = "https://files.pythonhosted.org/packages/88/69/6972bfafa8cd3ddc8562b126dd607011e218e17be313a8b1b9cc5a0ee876/lxml-5.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e", size = 4748628 }, + { url = "https://files.pythonhosted.org/packages/5d/ea/a6523c7c7f6dc755a6eed3d2f6d6646617cad4d3d6d8ce4ed71bfd2362c8/lxml-5.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179", size = 5322215 }, + { url = "https://files.pythonhosted.org/packages/99/37/396fbd24a70f62b31d988e4500f2068c7f3fd399d2fd45257d13eab51a6f/lxml-5.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a", size = 4813963 }, + { url = "https://files.pythonhosted.org/packages/09/91/e6136f17459a11ce1757df864b213efbeab7adcb2efa63efb1b846ab6723/lxml-5.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3", size = 4923353 }, + { url = "https://files.pythonhosted.org/packages/1d/7c/2eeecf87c9a1fca4f84f991067c693e67340f2b7127fc3eca8fa29d75ee3/lxml-5.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1", size = 4740541 }, + { url = "https://files.pythonhosted.org/packages/3b/ed/4c38ba58defca84f5f0d0ac2480fdcd99fc7ae4b28fc417c93640a6949ae/lxml-5.3.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d", size = 5346504 }, + { url = "https://files.pythonhosted.org/packages/a5/22/bbd3995437e5745cb4c2b5d89088d70ab19d4feabf8a27a24cecb9745464/lxml-5.3.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c", size = 4898077 }, + { url = "https://files.pythonhosted.org/packages/0a/6e/94537acfb5b8f18235d13186d247bca478fea5e87d224644e0fe907df976/lxml-5.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99", size = 4946543 }, + { url = "https://files.pythonhosted.org/packages/8d/e8/4b15df533fe8e8d53363b23a41df9be907330e1fa28c7ca36893fad338ee/lxml-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff", size = 4816841 }, + { url = "https://files.pythonhosted.org/packages/1a/e7/03f390ea37d1acda50bc538feb5b2bda6745b25731e4e76ab48fae7106bf/lxml-5.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a", size = 5417341 }, + { url = "https://files.pythonhosted.org/packages/ea/99/d1133ab4c250da85a883c3b60249d3d3e7c64f24faff494cf0fd23f91e80/lxml-5.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8", size = 5327539 }, + { url = "https://files.pythonhosted.org/packages/7d/ed/e6276c8d9668028213df01f598f385b05b55a4e1b4662ee12ef05dab35aa/lxml-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d", size = 5012542 }, + { url = "https://files.pythonhosted.org/packages/36/88/684d4e800f5aa28df2a991a6a622783fb73cf0e46235cfa690f9776f032e/lxml-5.3.0-cp312-cp312-win32.whl", hash = "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30", size = 3486454 }, + { url = "https://files.pythonhosted.org/packages/fc/82/ace5a5676051e60355bd8fb945df7b1ba4f4fb8447f2010fb816bfd57724/lxml-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f", size = 3816857 }, + { url = "https://files.pythonhosted.org/packages/94/6a/42141e4d373903bfea6f8e94b2f554d05506dfda522ada5343c651410dc8/lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a", size = 8156284 }, + { url = "https://files.pythonhosted.org/packages/91/5e/fa097f0f7d8b3d113fb7312c6308af702f2667f22644441715be961f2c7e/lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd", size = 4432407 }, + { url = "https://files.pythonhosted.org/packages/2d/a1/b901988aa6d4ff937f2e5cfc114e4ec561901ff00660c3e56713642728da/lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51", size = 5048331 }, + { url = "https://files.pythonhosted.org/packages/30/0f/b2a54f48e52de578b71bbe2a2f8160672a8a5e103df3a78da53907e8c7ed/lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b", size = 4744835 }, + { url = "https://files.pythonhosted.org/packages/82/9d/b000c15538b60934589e83826ecbc437a1586488d7c13f8ee5ff1f79a9b8/lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002", size = 5316649 }, + { url = "https://files.pythonhosted.org/packages/e3/ee/ffbb9eaff5e541922611d2c56b175c45893d1c0b8b11e5a497708a6a3b3b/lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4", size = 4812046 }, + { url = "https://files.pythonhosted.org/packages/15/ff/7ff89d567485c7b943cdac316087f16b2399a8b997007ed352a1248397e5/lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492", size = 4918597 }, + { url = "https://files.pythonhosted.org/packages/c6/a3/535b6ed8c048412ff51268bdf4bf1cf052a37aa7e31d2e6518038a883b29/lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3", size = 4738071 }, + { url = "https://files.pythonhosted.org/packages/7a/8f/cbbfa59cb4d4fd677fe183725a76d8c956495d7a3c7f111ab8f5e13d2e83/lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4", size = 5342213 }, + { url = "https://files.pythonhosted.org/packages/5c/fb/db4c10dd9958d4b52e34d1d1f7c1f434422aeaf6ae2bbaaff2264351d944/lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367", size = 4893749 }, + { url = "https://files.pythonhosted.org/packages/f2/38/bb4581c143957c47740de18a3281a0cab7722390a77cc6e610e8ebf2d736/lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832", size = 4945901 }, + { url = "https://files.pythonhosted.org/packages/fc/d5/18b7de4960c731e98037bd48fa9f8e6e8f2558e6fbca4303d9b14d21ef3b/lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff", size = 4815447 }, + { url = "https://files.pythonhosted.org/packages/97/a8/cd51ceaad6eb849246559a8ef60ae55065a3df550fc5fcd27014361c1bab/lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd", size = 5411186 }, + { url = "https://files.pythonhosted.org/packages/89/c3/1e3dabab519481ed7b1fdcba21dcfb8832f57000733ef0e71cf6d09a5e03/lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb", size = 5324481 }, + { url = "https://files.pythonhosted.org/packages/b6/17/71e9984cf0570cd202ac0a1c9ed5c1b8889b0fc8dc736f5ef0ffb181c284/lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b", size = 5011053 }, + { url = "https://files.pythonhosted.org/packages/69/68/9f7e6d3312a91e30829368c2b3217e750adef12a6f8eb10498249f4e8d72/lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957", size = 3485634 }, + { url = "https://files.pythonhosted.org/packages/7d/db/214290d58ad68c587bd5d6af3d34e56830438733d0d0856c0275fde43652/lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d", size = 3814417 }, + { url = "https://files.pythonhosted.org/packages/99/f7/b73a431c8500565aa500e99e60b448d305eaf7c0b4c893c7c5a8a69cc595/lxml-5.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7b1cd427cb0d5f7393c31b7496419da594fe600e6fdc4b105a54f82405e6626c", size = 3925431 }, + { url = "https://files.pythonhosted.org/packages/db/48/4a206623c0d093d0e3b15f415ffb4345b0bdf661a3d0b15a112948c033c7/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51806cfe0279e06ed8500ce19479d757db42a30fd509940b1701be9c86a5ff9a", size = 4216683 }, + { url = "https://files.pythonhosted.org/packages/54/47/577820c45dd954523ae8453b632d91e76da94ca6d9ee40d8c98dd86f916b/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee70d08fd60c9565ba8190f41a46a54096afa0eeb8f76bd66f2c25d3b1b83005", size = 4326732 }, + { url = "https://files.pythonhosted.org/packages/68/de/96cb6d3269bc994b4f5ede8ca7bf0840f5de0a278bc6e50cb317ff71cafa/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:8dc2c0395bea8254d8daebc76dcf8eb3a95ec2a46fa6fae5eaccee366bfe02ce", size = 4218377 }, + { url = "https://files.pythonhosted.org/packages/a5/43/19b1ef6cbffa4244a217f95cc5f41a6cb4720fed33510a49670b03c5f1a0/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6ba0d3dcac281aad8a0e5b14c7ed6f9fa89c8612b47939fc94f80b16e2e9bc83", size = 4351237 }, + { url = "https://files.pythonhosted.org/packages/ba/b2/6a22fb5c0885da3b00e116aee81f0b829ec9ac8f736cd414b4a09413fc7d/lxml-5.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6e91cf736959057f7aac7adfc83481e03615a8e8dd5758aa1d95ea69e8931dba", size = 3487557 }, +] + +[[package]] +name = "markdown" +version = "3.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/28/3af612670f82f4c056911fbbbb42760255801b3068c48de792d354ff4472/markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2", size = 357086 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/08/83871f3c50fc983b88547c196d11cf8c3340e37c32d2e9d6152abe2c61f7/Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803", size = 106349 }, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, +] + +[[package]] +name = "markupsafe" +version = "2.1.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/54/ad5eb37bf9d51800010a74e4665425831a9db4e7c4e0fde4352e391e808e/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", size = 18206 }, + { url = "https://files.pythonhosted.org/packages/6a/4a/a4d49415e600bacae038c67f9fecc1d5433b9d3c71a4de6f33537b89654c/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", size = 14079 }, + { url = "https://files.pythonhosted.org/packages/0a/7b/85681ae3c33c385b10ac0f8dd025c30af83c78cec1c37a6aa3b55e67f5ec/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", size = 26620 }, + { url = "https://files.pythonhosted.org/packages/7c/52/2b1b570f6b8b803cef5ac28fdf78c0da318916c7d2fe9402a84d591b394c/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", size = 25818 }, + { url = "https://files.pythonhosted.org/packages/29/fe/a36ba8c7ca55621620b2d7c585313efd10729e63ef81e4e61f52330da781/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", size = 25493 }, + { url = "https://files.pythonhosted.org/packages/60/ae/9c60231cdfda003434e8bd27282b1f4e197ad5a710c14bee8bea8a9ca4f0/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", size = 30630 }, + { url = "https://files.pythonhosted.org/packages/65/dc/1510be4d179869f5dafe071aecb3f1f41b45d37c02329dfba01ff59e5ac5/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", size = 29745 }, + { url = "https://files.pythonhosted.org/packages/30/39/8d845dd7d0b0613d86e0ef89549bfb5f61ed781f59af45fc96496e897f3a/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", size = 30021 }, + { url = "https://files.pythonhosted.org/packages/c7/5c/356a6f62e4f3c5fbf2602b4771376af22a3b16efa74eb8716fb4e328e01e/MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", size = 16659 }, + { url = "https://files.pythonhosted.org/packages/69/48/acbf292615c65f0604a0c6fc402ce6d8c991276e16c80c46a8f758fbd30c/MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", size = 17213 }, + { url = "https://files.pythonhosted.org/packages/11/e7/291e55127bb2ae67c64d66cef01432b5933859dfb7d6949daa721b89d0b3/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", size = 18219 }, + { url = "https://files.pythonhosted.org/packages/6b/cb/aed7a284c00dfa7c0682d14df85ad4955a350a21d2e3b06d8240497359bf/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", size = 14098 }, + { url = "https://files.pythonhosted.org/packages/1c/cf/35fe557e53709e93feb65575c93927942087e9b97213eabc3fe9d5b25a55/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", size = 29014 }, + { url = "https://files.pythonhosted.org/packages/97/18/c30da5e7a0e7f4603abfc6780574131221d9148f323752c2755d48abad30/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", size = 28220 }, + { url = "https://files.pythonhosted.org/packages/0c/40/2e73e7d532d030b1e41180807a80d564eda53babaf04d65e15c1cf897e40/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", size = 27756 }, + { url = "https://files.pythonhosted.org/packages/18/46/5dca760547e8c59c5311b332f70605d24c99d1303dd9a6e1fc3ed0d73561/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", size = 33988 }, + { url = "https://files.pythonhosted.org/packages/6d/c5/27febe918ac36397919cd4a67d5579cbbfa8da027fa1238af6285bb368ea/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", size = 32718 }, + { url = "https://files.pythonhosted.org/packages/f8/81/56e567126a2c2bc2684d6391332e357589a96a76cb9f8e5052d85cb0ead8/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", size = 33317 }, + { url = "https://files.pythonhosted.org/packages/00/0b/23f4b2470accb53285c613a3ab9ec19dc944eaf53592cb6d9e2af8aa24cc/MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", size = 16670 }, + { url = "https://files.pythonhosted.org/packages/b7/a2/c78a06a9ec6d04b3445a949615c4c7ed86a0b2eb68e44e7541b9d57067cc/MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", size = 17224 }, + { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215 }, + { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069 }, + { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452 }, + { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462 }, + { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869 }, + { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906 }, + { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296 }, + { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038 }, + { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572 }, + { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127 }, +] + +[[package]] +name = "mdit-py-plugins" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/03/a2ecab526543b152300717cf232bb4bb8605b6edb946c845016fa9c9c9fd/mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5", size = 43542 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636", size = 55316 }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, +] + +[[package]] +name = "more-itertools" +version = "10.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/78/65922308c4248e0eb08ebcbe67c95d48615cc6f27854b6f2e57143e9178f/more-itertools-10.5.0.tar.gz", hash = "sha256:5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6", size = 121020 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/7e/3a64597054a70f7c86eb0a7d4fc315b8c1ab932f64883a297bdffeb5f967/more_itertools-10.5.0-py3-none-any.whl", hash = "sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef", size = 60952 }, +] + +[[package]] +name = "msgpack" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/d0/7555686ae7ff5731205df1012ede15dd9d927f6227ea151e901c7406af4f/msgpack-1.1.0.tar.gz", hash = "sha256:dd432ccc2c72b914e4cb77afce64aab761c1137cc698be3984eee260bcb2896e", size = 167260 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/f9/a892a6038c861fa849b11a2bb0502c07bc698ab6ea53359e5771397d883b/msgpack-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ad442d527a7e358a469faf43fda45aaf4ac3249c8310a82f0ccff9164e5dccd", size = 150428 }, + { url = "https://files.pythonhosted.org/packages/df/7a/d174cc6a3b6bb85556e6a046d3193294a92f9a8e583cdbd46dc8a1d7e7f4/msgpack-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:74bed8f63f8f14d75eec75cf3d04ad581da6b914001b474a5d3cd3372c8cc27d", size = 84131 }, + { url = "https://files.pythonhosted.org/packages/08/52/bf4fbf72f897a23a56b822997a72c16de07d8d56d7bf273242f884055682/msgpack-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:914571a2a5b4e7606997e169f64ce53a8b1e06f2cf2c3a7273aa106236d43dd5", size = 81215 }, + { url = "https://files.pythonhosted.org/packages/02/95/dc0044b439b518236aaf012da4677c1b8183ce388411ad1b1e63c32d8979/msgpack-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c921af52214dcbb75e6bdf6a661b23c3e6417f00c603dd2070bccb5c3ef499f5", size = 371229 }, + { url = "https://files.pythonhosted.org/packages/ff/75/09081792db60470bef19d9c2be89f024d366b1e1973c197bb59e6aabc647/msgpack-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8ce0b22b890be5d252de90d0e0d119f363012027cf256185fc3d474c44b1b9e", size = 378034 }, + { url = "https://files.pythonhosted.org/packages/32/d3/c152e0c55fead87dd948d4b29879b0f14feeeec92ef1fd2ec21b107c3f49/msgpack-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:73322a6cc57fcee3c0c57c4463d828e9428275fb85a27aa2aa1a92fdc42afd7b", size = 363070 }, + { url = "https://files.pythonhosted.org/packages/d9/2c/82e73506dd55f9e43ac8aa007c9dd088c6f0de2aa19e8f7330e6a65879fc/msgpack-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e1f3c3d21f7cf67bcf2da8e494d30a75e4cf60041d98b3f79875afb5b96f3a3f", size = 359863 }, + { url = "https://files.pythonhosted.org/packages/cb/a0/3d093b248837094220e1edc9ec4337de3443b1cfeeb6e0896af8ccc4cc7a/msgpack-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64fc9068d701233effd61b19efb1485587560b66fe57b3e50d29c5d78e7fef68", size = 368166 }, + { url = "https://files.pythonhosted.org/packages/e4/13/7646f14f06838b406cf5a6ddbb7e8dc78b4996d891ab3b93c33d1ccc8678/msgpack-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:42f754515e0f683f9c79210a5d1cad631ec3d06cea5172214d2176a42e67e19b", size = 370105 }, + { url = "https://files.pythonhosted.org/packages/67/fa/dbbd2443e4578e165192dabbc6a22c0812cda2649261b1264ff515f19f15/msgpack-1.1.0-cp310-cp310-win32.whl", hash = "sha256:3df7e6b05571b3814361e8464f9304c42d2196808e0119f55d0d3e62cd5ea044", size = 68513 }, + { url = "https://files.pythonhosted.org/packages/24/ce/c2c8fbf0ded750cb63cbcbb61bc1f2dfd69e16dca30a8af8ba80ec182dcd/msgpack-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:685ec345eefc757a7c8af44a3032734a739f8c45d1b0ac45efc5d8977aa4720f", size = 74687 }, + { url = "https://files.pythonhosted.org/packages/b7/5e/a4c7154ba65d93be91f2f1e55f90e76c5f91ccadc7efc4341e6f04c8647f/msgpack-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3d364a55082fb2a7416f6c63ae383fbd903adb5a6cf78c5b96cc6316dc1cedc7", size = 150803 }, + { url = "https://files.pythonhosted.org/packages/60/c2/687684164698f1d51c41778c838d854965dd284a4b9d3a44beba9265c931/msgpack-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79ec007767b9b56860e0372085f8504db5d06bd6a327a335449508bbee9648fa", size = 84343 }, + { url = "https://files.pythonhosted.org/packages/42/ae/d3adea9bb4a1342763556078b5765e666f8fdf242e00f3f6657380920972/msgpack-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6ad622bf7756d5a497d5b6836e7fc3752e2dd6f4c648e24b1803f6048596f701", size = 81408 }, + { url = "https://files.pythonhosted.org/packages/dc/17/6313325a6ff40ce9c3207293aee3ba50104aed6c2c1559d20d09e5c1ff54/msgpack-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e59bca908d9ca0de3dc8684f21ebf9a690fe47b6be93236eb40b99af28b6ea6", size = 396096 }, + { url = "https://files.pythonhosted.org/packages/a8/a1/ad7b84b91ab5a324e707f4c9761633e357820b011a01e34ce658c1dda7cc/msgpack-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e1da8f11a3dd397f0a32c76165cf0c4eb95b31013a94f6ecc0b280c05c91b59", size = 403671 }, + { url = "https://files.pythonhosted.org/packages/bb/0b/fd5b7c0b308bbf1831df0ca04ec76fe2f5bf6319833646b0a4bd5e9dc76d/msgpack-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:452aff037287acb1d70a804ffd022b21fa2bb7c46bee884dbc864cc9024128a0", size = 387414 }, + { url = "https://files.pythonhosted.org/packages/f0/03/ff8233b7c6e9929a1f5da3c7860eccd847e2523ca2de0d8ef4878d354cfa/msgpack-1.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8da4bf6d54ceed70e8861f833f83ce0814a2b72102e890cbdfe4b34764cdd66e", size = 383759 }, + { url = "https://files.pythonhosted.org/packages/1f/1b/eb82e1fed5a16dddd9bc75f0854b6e2fe86c0259c4353666d7fab37d39f4/msgpack-1.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:41c991beebf175faf352fb940bf2af9ad1fb77fd25f38d9142053914947cdbf6", size = 394405 }, + { url = "https://files.pythonhosted.org/packages/90/2e/962c6004e373d54ecf33d695fb1402f99b51832631e37c49273cc564ffc5/msgpack-1.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a52a1f3a5af7ba1c9ace055b659189f6c669cf3657095b50f9602af3a3ba0fe5", size = 396041 }, + { url = "https://files.pythonhosted.org/packages/f8/20/6e03342f629474414860c48aeffcc2f7f50ddaf351d95f20c3f1c67399a8/msgpack-1.1.0-cp311-cp311-win32.whl", hash = "sha256:58638690ebd0a06427c5fe1a227bb6b8b9fdc2bd07701bec13c2335c82131a88", size = 68538 }, + { url = "https://files.pythonhosted.org/packages/aa/c4/5a582fc9a87991a3e6f6800e9bb2f3c82972912235eb9539954f3e9997c7/msgpack-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fd2906780f25c8ed5d7b323379f6138524ba793428db5d0e9d226d3fa6aa1788", size = 74871 }, + { url = "https://files.pythonhosted.org/packages/e1/d6/716b7ca1dbde63290d2973d22bbef1b5032ca634c3ff4384a958ec3f093a/msgpack-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d46cf9e3705ea9485687aa4001a76e44748b609d260af21c4ceea7f2212a501d", size = 152421 }, + { url = "https://files.pythonhosted.org/packages/70/da/5312b067f6773429cec2f8f08b021c06af416bba340c912c2ec778539ed6/msgpack-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5dbad74103df937e1325cc4bfeaf57713be0b4f15e1c2da43ccdd836393e2ea2", size = 85277 }, + { url = "https://files.pythonhosted.org/packages/28/51/da7f3ae4462e8bb98af0d5bdf2707f1b8c65a0d4f496e46b6afb06cbc286/msgpack-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:58dfc47f8b102da61e8949708b3eafc3504509a5728f8b4ddef84bd9e16ad420", size = 82222 }, + { url = "https://files.pythonhosted.org/packages/33/af/dc95c4b2a49cff17ce47611ca9ba218198806cad7796c0b01d1e332c86bb/msgpack-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676e5be1b472909b2ee6356ff425ebedf5142427842aa06b4dfd5117d1ca8a2", size = 392971 }, + { url = "https://files.pythonhosted.org/packages/f1/54/65af8de681fa8255402c80eda2a501ba467921d5a7a028c9c22a2c2eedb5/msgpack-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17fb65dd0bec285907f68b15734a993ad3fc94332b5bb21b0435846228de1f39", size = 401403 }, + { url = "https://files.pythonhosted.org/packages/97/8c/e333690777bd33919ab7024269dc3c41c76ef5137b211d776fbb404bfead/msgpack-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a51abd48c6d8ac89e0cfd4fe177c61481aca2d5e7ba42044fd218cfd8ea9899f", size = 385356 }, + { url = "https://files.pythonhosted.org/packages/57/52/406795ba478dc1c890559dd4e89280fa86506608a28ccf3a72fbf45df9f5/msgpack-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2137773500afa5494a61b1208619e3871f75f27b03bcfca7b3a7023284140247", size = 383028 }, + { url = "https://files.pythonhosted.org/packages/e7/69/053b6549bf90a3acadcd8232eae03e2fefc87f066a5b9fbb37e2e608859f/msgpack-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:398b713459fea610861c8a7b62a6fec1882759f308ae0795b5413ff6a160cf3c", size = 391100 }, + { url = "https://files.pythonhosted.org/packages/23/f0/d4101d4da054f04274995ddc4086c2715d9b93111eb9ed49686c0f7ccc8a/msgpack-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:06f5fd2f6bb2a7914922d935d3b8bb4a7fff3a9a91cfce6d06c13bc42bec975b", size = 394254 }, + { url = "https://files.pythonhosted.org/packages/1c/12/cf07458f35d0d775ff3a2dc5559fa2e1fcd06c46f1ef510e594ebefdca01/msgpack-1.1.0-cp312-cp312-win32.whl", hash = "sha256:ad33e8400e4ec17ba782f7b9cf868977d867ed784a1f5f2ab46e7ba53b6e1e1b", size = 69085 }, + { url = "https://files.pythonhosted.org/packages/73/80/2708a4641f7d553a63bc934a3eb7214806b5b39d200133ca7f7afb0a53e8/msgpack-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:115a7af8ee9e8cddc10f87636767857e7e3717b7a2e97379dc2054712693e90f", size = 75347 }, + { url = "https://files.pythonhosted.org/packages/c8/b0/380f5f639543a4ac413e969109978feb1f3c66e931068f91ab6ab0f8be00/msgpack-1.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:071603e2f0771c45ad9bc65719291c568d4edf120b44eb36324dcb02a13bfddf", size = 151142 }, + { url = "https://files.pythonhosted.org/packages/c8/ee/be57e9702400a6cb2606883d55b05784fada898dfc7fd12608ab1fdb054e/msgpack-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0f92a83b84e7c0749e3f12821949d79485971f087604178026085f60ce109330", size = 84523 }, + { url = "https://files.pythonhosted.org/packages/7e/3a/2919f63acca3c119565449681ad08a2f84b2171ddfcff1dba6959db2cceb/msgpack-1.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1964df7b81285d00a84da4e70cb1383f2e665e0f1f2a7027e683956d04b734", size = 81556 }, + { url = "https://files.pythonhosted.org/packages/7c/43/a11113d9e5c1498c145a8925768ea2d5fce7cbab15c99cda655aa09947ed/msgpack-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59caf6a4ed0d164055ccff8fe31eddc0ebc07cf7326a2aaa0dbf7a4001cd823e", size = 392105 }, + { url = "https://files.pythonhosted.org/packages/2d/7b/2c1d74ca6c94f70a1add74a8393a0138172207dc5de6fc6269483519d048/msgpack-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0907e1a7119b337971a689153665764adc34e89175f9a34793307d9def08e6ca", size = 399979 }, + { url = "https://files.pythonhosted.org/packages/82/8c/cf64ae518c7b8efc763ca1f1348a96f0e37150061e777a8ea5430b413a74/msgpack-1.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65553c9b6da8166e819a6aa90ad15288599b340f91d18f60b2061f402b9a4915", size = 383816 }, + { url = "https://files.pythonhosted.org/packages/69/86/a847ef7a0f5ef3fa94ae20f52a4cacf596a4e4a010197fbcc27744eb9a83/msgpack-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7a946a8992941fea80ed4beae6bff74ffd7ee129a90b4dd5cf9c476a30e9708d", size = 380973 }, + { url = "https://files.pythonhosted.org/packages/aa/90/c74cf6e1126faa93185d3b830ee97246ecc4fe12cf9d2d31318ee4246994/msgpack-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4b51405e36e075193bc051315dbf29168d6141ae2500ba8cd80a522964e31434", size = 387435 }, + { url = "https://files.pythonhosted.org/packages/7a/40/631c238f1f338eb09f4acb0f34ab5862c4e9d7eda11c1b685471a4c5ea37/msgpack-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4c01941fd2ff87c2a934ee6055bda4ed353a7846b8d4f341c428109e9fcde8c", size = 399082 }, + { url = "https://files.pythonhosted.org/packages/e9/1b/fa8a952be252a1555ed39f97c06778e3aeb9123aa4cccc0fd2acd0b4e315/msgpack-1.1.0-cp313-cp313-win32.whl", hash = "sha256:7c9a35ce2c2573bada929e0b7b3576de647b0defbd25f5139dcdaba0ae35a4cc", size = 69037 }, + { url = "https://files.pythonhosted.org/packages/b6/bc/8bd826dd03e022153bfa1766dcdec4976d6c818865ed54223d71f07862b3/msgpack-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:bce7d9e614a04d0883af0b3d4d501171fbfca038f12c77fa838d9f198147a23f", size = 75140 }, +] + +[[package]] +name = "mypy" +version = "1.11.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5c/86/5d7cbc4974fd564550b80fbb8103c05501ea11aa7835edf3351d90095896/mypy-1.11.2.tar.gz", hash = "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79", size = 3078806 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/cd/815368cd83c3a31873e5e55b317551500b12f2d1d7549720632f32630333/mypy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a", size = 10939401 }, + { url = "https://files.pythonhosted.org/packages/f1/27/e18c93a195d2fad75eb96e1f1cbc431842c332e8eba2e2b77eaf7313c6b7/mypy-1.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef", size = 10111697 }, + { url = "https://files.pythonhosted.org/packages/dc/08/cdc1fc6d0d5a67d354741344cc4aa7d53f7128902ebcbe699ddd4f15a61c/mypy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383", size = 12500508 }, + { url = "https://files.pythonhosted.org/packages/64/12/aad3af008c92c2d5d0720ea3b6674ba94a98cdb86888d389acdb5f218c30/mypy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8", size = 13020712 }, + { url = "https://files.pythonhosted.org/packages/03/e6/a7d97cc124a565be5e9b7d5c2a6ebf082379ffba99646e4863ed5bbcb3c3/mypy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7", size = 9567319 }, + { url = "https://files.pythonhosted.org/packages/e2/aa/cc56fb53ebe14c64f1fe91d32d838d6f4db948b9494e200d2f61b820b85d/mypy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385", size = 10859630 }, + { url = "https://files.pythonhosted.org/packages/04/c8/b19a760fab491c22c51975cf74e3d253b8c8ce2be7afaa2490fbf95a8c59/mypy-1.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca", size = 10037973 }, + { url = "https://files.pythonhosted.org/packages/88/57/7e7e39f2619c8f74a22efb9a4c4eff32b09d3798335625a124436d121d89/mypy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104", size = 12416659 }, + { url = "https://files.pythonhosted.org/packages/fc/a6/37f7544666b63a27e46c48f49caeee388bf3ce95f9c570eb5cfba5234405/mypy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4", size = 12897010 }, + { url = "https://files.pythonhosted.org/packages/84/8b/459a513badc4d34acb31c736a0101c22d2bd0697b969796ad93294165cfb/mypy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6", size = 9562873 }, + { url = "https://files.pythonhosted.org/packages/35/3a/ed7b12ecc3f6db2f664ccf85cb2e004d3e90bec928e9d7be6aa2f16b7cdf/mypy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318", size = 10990335 }, + { url = "https://files.pythonhosted.org/packages/04/e4/1a9051e2ef10296d206519f1df13d2cc896aea39e8683302f89bf5792a59/mypy-1.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36", size = 10007119 }, + { url = "https://files.pythonhosted.org/packages/f3/3c/350a9da895f8a7e87ade0028b962be0252d152e0c2fbaafa6f0658b4d0d4/mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987", size = 12506856 }, + { url = "https://files.pythonhosted.org/packages/b6/49/ee5adf6a49ff13f4202d949544d3d08abb0ea1f3e7f2a6d5b4c10ba0360a/mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca", size = 12952066 }, + { url = "https://files.pythonhosted.org/packages/27/c0/b19d709a42b24004d720db37446a42abadf844d5c46a2c442e2a074d70d9/mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70", size = 9664000 }, + { url = "https://files.pythonhosted.org/packages/42/3a/bdf730640ac523229dd6578e8a581795720a9321399de494374afc437ec5/mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12", size = 2619625 }, +] + +[package.optional-dependencies] +reports = [ + { name = "lxml" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, +] + +[[package]] +name = "myst-parser" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "jinja2" }, + { name = "markdown-it-py" }, + { name = "mdit-py-plugins" }, + { name = "pyyaml" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/55/6d1741a1780e5e65038b74bce6689da15f620261c490c3511eb4c12bac4b/myst_parser-4.0.0.tar.gz", hash = "sha256:851c9dfb44e36e56d15d05e72f02b80da21a9e0d07cba96baf5e2d476bb91531", size = 93858 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/b4/b036f8fdb667587bb37df29dc6644681dd78b7a2a6321a34684b79412b28/myst_parser-4.0.0-py3-none-any.whl", hash = "sha256:b9317997552424448c6096c2558872fdb6f81d3ecb3a40ce84a7518798f3f28d", size = 84563 }, +] + +[[package]] +name = "natsort" +version = "8.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/a9/a0c57aee75f77794adaf35322f8b6404cbd0f89ad45c87197a937764b7d0/natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581", size = 76575 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c", size = 38268 }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + +[[package]] +name = "packaging" +version = "24.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "polib" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/10/9a/79b1067d27e38ddf84fe7da6ec516f1743f31f752c6122193e7bce38bdbf/polib-1.2.0.tar.gz", hash = "sha256:f3ef94aefed6e183e342a8a269ae1fc4742ba193186ad76f175938621dbfc26b", size = 161658 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/99/45bb1f9926efe370c6dbe324741c749658e44cb060124f28dad201202274/polib-1.2.0-py2.py3-none-any.whl", hash = "sha256:1c77ee1b81feb31df9bca258cbc58db1bbb32d10214b173882452c73af06d62d", size = 20634 }, +] + +[[package]] +name = "pydantic" +version = "2.9.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/b7/d9e3f12af310e1120c21603644a1cd86f59060e040ec5c3a80b8f05fae30/pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", size = 769917 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/e4/ba44652d562cbf0bf320e0f3810206149c8a4e99cdbf66da82e97ab53a15/pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12", size = 434928 }, +] + +[[package]] +name = "pydantic-core" +version = "2.23.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e2/aa/6b6a9b9f8537b872f552ddd46dd3da230367754b6f707b8e1e963f515ea3/pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", size = 402156 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/8b/d3ae387f66277bd8104096d6ec0a145f4baa2966ebb2cad746c0920c9526/pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b", size = 1867835 }, + { url = "https://files.pythonhosted.org/packages/46/76/f68272e4c3a7df8777798282c5e47d508274917f29992d84e1898f8908c7/pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166", size = 1776689 }, + { url = "https://files.pythonhosted.org/packages/cc/69/5f945b4416f42ea3f3bc9d2aaec66c76084a6ff4ff27555bf9415ab43189/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb", size = 1800748 }, + { url = "https://files.pythonhosted.org/packages/50/ab/891a7b0054bcc297fb02d44d05c50e68154e31788f2d9d41d0b72c89fdf7/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916", size = 1806469 }, + { url = "https://files.pythonhosted.org/packages/31/7c/6e3fa122075d78f277a8431c4c608f061881b76c2b7faca01d317ee39b5d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07", size = 2002246 }, + { url = "https://files.pythonhosted.org/packages/ad/6f/22d5692b7ab63fc4acbc74de6ff61d185804a83160adba5e6cc6068e1128/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232", size = 2659404 }, + { url = "https://files.pythonhosted.org/packages/11/ac/1e647dc1121c028b691028fa61a4e7477e6aeb5132628fde41dd34c1671f/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2", size = 2053940 }, + { url = "https://files.pythonhosted.org/packages/91/75/984740c17f12c3ce18b5a2fcc4bdceb785cce7df1511a4ce89bca17c7e2d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f", size = 1921437 }, + { url = "https://files.pythonhosted.org/packages/a0/74/13c5f606b64d93f0721e7768cd3e8b2102164866c207b8cd6f90bb15d24f/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3", size = 1966129 }, + { url = "https://files.pythonhosted.org/packages/18/03/9c4aa5919457c7b57a016c1ab513b1a926ed9b2bb7915bf8e506bf65c34b/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071", size = 2110908 }, + { url = "https://files.pythonhosted.org/packages/92/2c/053d33f029c5dc65e5cf44ff03ceeefb7cce908f8f3cca9265e7f9b540c8/pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119", size = 1735278 }, + { url = "https://files.pythonhosted.org/packages/de/81/7dfe464eca78d76d31dd661b04b5f2036ec72ea8848dd87ab7375e185c23/pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f", size = 1917453 }, + { url = "https://files.pythonhosted.org/packages/5d/30/890a583cd3f2be27ecf32b479d5d615710bb926d92da03e3f7838ff3e58b/pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8", size = 1865160 }, + { url = "https://files.pythonhosted.org/packages/1d/9a/b634442e1253bc6889c87afe8bb59447f106ee042140bd57680b3b113ec7/pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d", size = 1776777 }, + { url = "https://files.pythonhosted.org/packages/75/9a/7816295124a6b08c24c96f9ce73085032d8bcbaf7e5a781cd41aa910c891/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e", size = 1799244 }, + { url = "https://files.pythonhosted.org/packages/a9/8f/89c1405176903e567c5f99ec53387449e62f1121894aa9fc2c4fdc51a59b/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607", size = 1805307 }, + { url = "https://files.pythonhosted.org/packages/d5/a5/1a194447d0da1ef492e3470680c66048fef56fc1f1a25cafbea4bc1d1c48/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd", size = 2000663 }, + { url = "https://files.pythonhosted.org/packages/13/a5/1df8541651de4455e7d587cf556201b4f7997191e110bca3b589218745a5/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea", size = 2655941 }, + { url = "https://files.pythonhosted.org/packages/44/31/a3899b5ce02c4316865e390107f145089876dff7e1dfc770a231d836aed8/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e", size = 2052105 }, + { url = "https://files.pythonhosted.org/packages/1b/aa/98e190f8745d5ec831f6d5449344c48c0627ac5fed4e5340a44b74878f8e/pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b", size = 1919967 }, + { url = "https://files.pythonhosted.org/packages/ae/35/b6e00b6abb2acfee3e8f85558c02a0822e9a8b2f2d812ea8b9079b118ba0/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0", size = 1964291 }, + { url = "https://files.pythonhosted.org/packages/13/46/7bee6d32b69191cd649bbbd2361af79c472d72cb29bb2024f0b6e350ba06/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64", size = 2109666 }, + { url = "https://files.pythonhosted.org/packages/39/ef/7b34f1b122a81b68ed0a7d0e564da9ccdc9a2924c8d6c6b5b11fa3a56970/pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f", size = 1732940 }, + { url = "https://files.pythonhosted.org/packages/2f/76/37b7e76c645843ff46c1d73e046207311ef298d3f7b2f7d8f6ac60113071/pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3", size = 1916804 }, + { url = "https://files.pythonhosted.org/packages/74/7b/8e315f80666194b354966ec84b7d567da77ad927ed6323db4006cf915f3f/pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231", size = 1856459 }, + { url = "https://files.pythonhosted.org/packages/14/de/866bdce10ed808323d437612aca1ec9971b981e1c52e5e42ad9b8e17a6f6/pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee", size = 1770007 }, + { url = "https://files.pythonhosted.org/packages/dc/69/8edd5c3cd48bb833a3f7ef9b81d7666ccddd3c9a635225214e044b6e8281/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87", size = 1790245 }, + { url = "https://files.pythonhosted.org/packages/80/33/9c24334e3af796ce80d2274940aae38dd4e5676298b4398eff103a79e02d/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8", size = 1801260 }, + { url = "https://files.pythonhosted.org/packages/a5/6f/e9567fd90104b79b101ca9d120219644d3314962caa7948dd8b965e9f83e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327", size = 1996872 }, + { url = "https://files.pythonhosted.org/packages/2d/ad/b5f0fe9e6cfee915dd144edbd10b6e9c9c9c9d7a56b69256d124b8ac682e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2", size = 2661617 }, + { url = "https://files.pythonhosted.org/packages/06/c8/7d4b708f8d05a5cbfda3243aad468052c6e99de7d0937c9146c24d9f12e9/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36", size = 2071831 }, + { url = "https://files.pythonhosted.org/packages/89/4d/3079d00c47f22c9a9a8220db088b309ad6e600a73d7a69473e3a8e5e3ea3/pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126", size = 1917453 }, + { url = "https://files.pythonhosted.org/packages/e9/88/9df5b7ce880a4703fcc2d76c8c2d8eb9f861f79d0c56f4b8f5f2607ccec8/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e", size = 1968793 }, + { url = "https://files.pythonhosted.org/packages/e3/b9/41f7efe80f6ce2ed3ee3c2dcfe10ab7adc1172f778cc9659509a79518c43/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", size = 2116872 }, + { url = "https://files.pythonhosted.org/packages/63/08/b59b7a92e03dd25554b0436554bf23e7c29abae7cce4b1c459cd92746811/pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", size = 1738535 }, + { url = "https://files.pythonhosted.org/packages/88/8d/479293e4d39ab409747926eec4329de5b7129beaedc3786eca070605d07f/pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", size = 1917992 }, + { url = "https://files.pythonhosted.org/packages/ad/ef/16ee2df472bf0e419b6bc68c05bf0145c49247a1095e85cee1463c6a44a1/pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", size = 1856143 }, + { url = "https://files.pythonhosted.org/packages/da/fa/bc3dbb83605669a34a93308e297ab22be82dfb9dcf88c6cf4b4f264e0a42/pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", size = 1770063 }, + { url = "https://files.pythonhosted.org/packages/4e/48/e813f3bbd257a712303ebdf55c8dc46f9589ec74b384c9f652597df3288d/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", size = 1790013 }, + { url = "https://files.pythonhosted.org/packages/b4/e0/56eda3a37929a1d297fcab1966db8c339023bcca0b64c5a84896db3fcc5c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", size = 1801077 }, + { url = "https://files.pythonhosted.org/packages/04/be/5e49376769bfbf82486da6c5c1683b891809365c20d7c7e52792ce4c71f3/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", size = 1996782 }, + { url = "https://files.pythonhosted.org/packages/bc/24/e3ee6c04f1d58cc15f37bcc62f32c7478ff55142b7b3e6d42ea374ea427c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", size = 2661375 }, + { url = "https://files.pythonhosted.org/packages/c1/f8/11a9006de4e89d016b8de74ebb1db727dc100608bb1e6bbe9d56a3cbbcce/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", size = 2071635 }, + { url = "https://files.pythonhosted.org/packages/7c/45/bdce5779b59f468bdf262a5bc9eecbae87f271c51aef628d8c073b4b4b4c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", size = 1916994 }, + { url = "https://files.pythonhosted.org/packages/d8/fa/c648308fe711ee1f88192cad6026ab4f925396d1293e8356de7e55be89b5/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", size = 1968877 }, + { url = "https://files.pythonhosted.org/packages/16/16/b805c74b35607d24d37103007f899abc4880923b04929547ae68d478b7f4/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", size = 2116814 }, + { url = "https://files.pythonhosted.org/packages/d1/58/5305e723d9fcdf1c5a655e6a4cc2a07128bf644ff4b1d98daf7a9dbf57da/pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", size = 1738360 }, + { url = "https://files.pythonhosted.org/packages/a5/ae/e14b0ff8b3f48e02394d8acd911376b7b66e164535687ef7dc24ea03072f/pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", size = 1919411 }, + { url = "https://files.pythonhosted.org/packages/13/a9/5d582eb3204464284611f636b55c0a7410d748ff338756323cb1ce721b96/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", size = 1857135 }, + { url = "https://files.pythonhosted.org/packages/2c/57/faf36290933fe16717f97829eabfb1868182ac495f99cf0eda9f59687c9d/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", size = 1740583 }, + { url = "https://files.pythonhosted.org/packages/91/7c/d99e3513dc191c4fec363aef1bf4c8af9125d8fa53af7cb97e8babef4e40/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", size = 1793637 }, + { url = "https://files.pythonhosted.org/packages/29/18/812222b6d18c2d13eebbb0f7cdc170a408d9ced65794fdb86147c77e1982/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068", size = 1941963 }, + { url = "https://files.pythonhosted.org/packages/0f/36/c1f3642ac3f05e6bb4aec3ffc399fa3f84895d259cf5f0ce3054b7735c29/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801", size = 1915332 }, + { url = "https://files.pythonhosted.org/packages/f7/ca/9c0854829311fb446020ebb540ee22509731abad886d2859c855dd29b904/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728", size = 1957926 }, + { url = "https://files.pythonhosted.org/packages/c0/1c/7836b67c42d0cd4441fcd9fafbf6a027ad4b79b6559f80cf11f89fd83648/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433", size = 2100342 }, + { url = "https://files.pythonhosted.org/packages/a9/f9/b6bcaf874f410564a78908739c80861a171788ef4d4f76f5009656672dfe/pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", size = 1920344 }, +] + +[[package]] +name = "pygments" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, +] + +[[package]] +name = "pyproject-hooks" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/07/6f63dda440d4abb191b91dc383b472dae3dd9f37e4c1e4a5c3db150531c6/pyproject_hooks-1.1.0.tar.gz", hash = "sha256:4b37730834edbd6bd37f26ece6b44802fb1c1ee2ece0e54ddff8bfc06db86965", size = 7838 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", hash = "sha256:7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", size = 9184 }, +] + +[[package]] +name = "pyright" +version = "1.1.380" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/bc/3bb71d02125dae6730d64bb32571c0eda5e5d86483b198b7f6dd82c49c6f/pyright-1.1.380.tar.gz", hash = "sha256:e6ceb1a5f7e9f03106e0aa1d6fbb4d97735a5e7ffb59f3de6b2db590baf935b2", size = 17487 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c9/fc/527c58a3b66d5a16dbb124e1c40cf9f207147f5a36f224fb29eb786a0763/pyright-1.1.380-py3-none-any.whl", hash = "sha256:a6404392053d8848bacc7aebcbd9d318bb46baf1a1a000359305481920f43879", size = 18219 }, +] + +[[package]] +name = "pyspelling" +version = "2.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "html5lib" }, + { name = "lxml" }, + { name = "markdown" }, + { name = "pyyaml" }, + { name = "soupsieve" }, + { name = "wcmatch" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/12/07/168a857755a29b7e41550a28cd8f527025bc62fcb36a951d8f3f2eedcdf7/pyspelling-2.10.tar.gz", hash = "sha256:acd67133c1b7cecd410e3d4489e61f2e4b1f0b6acf1ae6c48c240fbb21729c37", size = 148239 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/16/242558b5c5cb73efd52490f1e6bfb03eae63b2585770b9cae78bd491ef0b/pyspelling-2.10-py3-none-any.whl", hash = "sha256:9b079dd238bd0616a49f9ac5df32799beb851dddc5ed7634f551e7df1aeee943", size = 45035 }, +] + +[[package]] +name = "pytest" +version = "8.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 }, +] + +[[package]] +name = "pytest-cov" +version = "5.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/67/00efc8d11b630c56f15f4ad9c7f9223f1e5ec275aaae3fa9118c6a223ad2/pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857", size = 63042 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/3a/af5b4fa5961d9a1e6237b530eb87dd04aea6eb83da09d2a4073d81b54ccf/pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", size = 21990 }, +] + +[[package]] +name = "pytest-mock" +version = "3.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863 }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, +] + +[[package]] +name = "regex" +version = "2024.9.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/38/148df33b4dbca3bd069b963acab5e0fa1a9dbd6820f8c322d0dd6faeff96/regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd", size = 399403 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/12/497bd6599ce8a239ade68678132296aec5ee25ebea45fc8ba91aa60fceec/regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408", size = 482488 }, + { url = "https://files.pythonhosted.org/packages/c1/24/595ddb9bec2a9b151cdaf9565b0c9f3da9f0cb1dca6c158bc5175332ddf8/regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d", size = 287443 }, + { url = "https://files.pythonhosted.org/packages/69/a8/b2fb45d9715b1469383a0da7968f8cacc2f83e9fbbcd6b8713752dd980a6/regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5", size = 284561 }, + { url = "https://files.pythonhosted.org/packages/88/87/1ce4a5357216b19b7055e7d3b0efc75a6e426133bf1e7d094321df514257/regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c", size = 783177 }, + { url = "https://files.pythonhosted.org/packages/3c/65/b9f002ab32f7b68e7d1dcabb67926f3f47325b8dbc22cc50b6a043e1d07c/regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8", size = 823193 }, + { url = "https://files.pythonhosted.org/packages/22/91/8339dd3abce101204d246e31bc26cdd7ec07c9f91598472459a3a902aa41/regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35", size = 809950 }, + { url = "https://files.pythonhosted.org/packages/cb/19/556638aa11c2ec9968a1da998f07f27ec0abb9bf3c647d7c7985ca0b8eea/regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71", size = 782661 }, + { url = "https://files.pythonhosted.org/packages/d1/e9/7a5bc4c6ef8d9cd2bdd83a667888fc35320da96a4cc4da5fa084330f53db/regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8", size = 772348 }, + { url = "https://files.pythonhosted.org/packages/f1/0b/29f2105bfac3ed08e704914c38e93b07c784a6655f8a015297ee7173e95b/regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a", size = 697460 }, + { url = "https://files.pythonhosted.org/packages/71/3a/52ff61054d15a4722605f5872ad03962b319a04c1ebaebe570b8b9b7dde1/regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d", size = 769151 }, + { url = "https://files.pythonhosted.org/packages/97/07/37e460ab5ca84be8e1e197c3b526c5c86993dcc9e13cbc805c35fc2463c1/regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137", size = 777478 }, + { url = "https://files.pythonhosted.org/packages/65/7b/953075723dd5ab00780043ac2f9de667306ff9e2a85332975e9f19279174/regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6", size = 845373 }, + { url = "https://files.pythonhosted.org/packages/40/b8/3e9484c6230b8b6e8f816ab7c9a080e631124991a4ae2c27a81631777db0/regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca", size = 845369 }, + { url = "https://files.pythonhosted.org/packages/b7/99/38434984d912edbd2e1969d116257e869578f67461bd7462b894c45ed874/regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a", size = 773935 }, + { url = "https://files.pythonhosted.org/packages/ab/67/43174d2b46fa947b7b9dfe56b6c8a8a76d44223f35b1d64645a732fd1d6f/regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0", size = 261624 }, + { url = "https://files.pythonhosted.org/packages/c4/2a/4f9c47d9395b6aff24874c761d8d620c0232f97c43ef3cf668c8b355e7a7/regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623", size = 274020 }, + { url = "https://files.pythonhosted.org/packages/86/a1/d526b7b6095a0019aa360948c143aacfeb029919c898701ce7763bbe4c15/regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df", size = 482483 }, + { url = "https://files.pythonhosted.org/packages/32/d9/bfdd153179867c275719e381e1e8e84a97bd186740456a0dcb3e7125c205/regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268", size = 287442 }, + { url = "https://files.pythonhosted.org/packages/33/c4/60f3370735135e3a8d673ddcdb2507a8560d0e759e1398d366e43d000253/regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad", size = 284561 }, + { url = "https://files.pythonhosted.org/packages/b1/51/91a5ebdff17f9ec4973cb0aa9d37635efec1c6868654bbc25d1543aca4ec/regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679", size = 791779 }, + { url = "https://files.pythonhosted.org/packages/07/4a/022c5e6f0891a90cd7eb3d664d6c58ce2aba48bff107b00013f3d6167069/regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4", size = 832605 }, + { url = "https://files.pythonhosted.org/packages/ac/1c/3793990c8c83ca04e018151ddda83b83ecc41d89964f0f17749f027fc44d/regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664", size = 818556 }, + { url = "https://files.pythonhosted.org/packages/e9/5c/8b385afbfacb853730682c57be56225f9fe275c5bf02ac1fc88edbff316d/regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50", size = 792808 }, + { url = "https://files.pythonhosted.org/packages/9b/8b/a4723a838b53c771e9240951adde6af58c829fb6a6a28f554e8131f53839/regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199", size = 781115 }, + { url = "https://files.pythonhosted.org/packages/83/5f/031a04b6017033d65b261259c09043c06f4ef2d4eac841d0649d76d69541/regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4", size = 778155 }, + { url = "https://files.pythonhosted.org/packages/fd/cd/4660756070b03ce4a66663a43f6c6e7ebc2266cc6b4c586c167917185eb4/regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd", size = 784614 }, + { url = "https://files.pythonhosted.org/packages/93/8d/65b9bea7df120a7be8337c415b6d256ba786cbc9107cebba3bf8ff09da99/regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f", size = 853744 }, + { url = "https://files.pythonhosted.org/packages/96/a7/fba1eae75eb53a704475baf11bd44b3e6ccb95b316955027eb7748f24ef8/regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96", size = 855890 }, + { url = "https://files.pythonhosted.org/packages/45/14/d864b2db80a1a3358534392373e8a281d95b28c29c87d8548aed58813910/regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1", size = 781887 }, + { url = "https://files.pythonhosted.org/packages/4d/a9/bfb29b3de3eb11dc9b412603437023b8e6c02fb4e11311863d9bf62c403a/regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9", size = 261644 }, + { url = "https://files.pythonhosted.org/packages/c7/ab/1ad2511cf6a208fde57fafe49829cab8ca018128ab0d0b48973d8218634a/regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf", size = 274033 }, + { url = "https://files.pythonhosted.org/packages/6e/92/407531450762bed778eedbde04407f68cbd75d13cee96c6f8d6903d9c6c1/regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7", size = 483590 }, + { url = "https://files.pythonhosted.org/packages/8e/a2/048acbc5ae1f615adc6cba36cc45734e679b5f1e4e58c3c77f0ed611d4e2/regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231", size = 288175 }, + { url = "https://files.pythonhosted.org/packages/8a/ea/909d8620329ab710dfaf7b4adee41242ab7c9b95ea8d838e9bfe76244259/regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d", size = 284749 }, + { url = "https://files.pythonhosted.org/packages/ca/fa/521eb683b916389b4975337873e66954e0f6d8f91bd5774164a57b503185/regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64", size = 795181 }, + { url = "https://files.pythonhosted.org/packages/28/db/63047feddc3280cc242f9c74f7aeddc6ee662b1835f00046f57d5630c827/regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42", size = 835842 }, + { url = "https://files.pythonhosted.org/packages/e3/94/86adc259ff8ec26edf35fcca7e334566c1805c7493b192cb09679f9c3dee/regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766", size = 823533 }, + { url = "https://files.pythonhosted.org/packages/29/52/84662b6636061277cb857f658518aa7db6672bc6d1a3f503ccd5aefc581e/regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a", size = 797037 }, + { url = "https://files.pythonhosted.org/packages/c3/2a/cd4675dd987e4a7505f0364a958bc41f3b84942de9efaad0ef9a2646681c/regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9", size = 784106 }, + { url = "https://files.pythonhosted.org/packages/6f/75/3ea7ec29de0bbf42f21f812f48781d41e627d57a634f3f23947c9a46e303/regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d", size = 782468 }, + { url = "https://files.pythonhosted.org/packages/d3/67/15519d69b52c252b270e679cb578e22e0c02b8dd4e361f2b04efcc7f2335/regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822", size = 790324 }, + { url = "https://files.pythonhosted.org/packages/9c/71/eff77d3fe7ba08ab0672920059ec30d63fa7e41aa0fb61c562726e9bd721/regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0", size = 860214 }, + { url = "https://files.pythonhosted.org/packages/81/11/e1bdf84a72372e56f1ea4b833dd583b822a23138a616ace7ab57a0e11556/regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a", size = 859420 }, + { url = "https://files.pythonhosted.org/packages/ea/75/9753e9dcebfa7c3645563ef5c8a58f3a47e799c872165f37c55737dadd3e/regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a", size = 787333 }, + { url = "https://files.pythonhosted.org/packages/bc/4e/ba1cbca93141f7416624b3ae63573e785d4bc1834c8be44a8f0747919eca/regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776", size = 262058 }, + { url = "https://files.pythonhosted.org/packages/6e/16/efc5f194778bf43e5888209e5cec4b258005d37c613b67ae137df3b89c53/regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009", size = 273526 }, + { url = "https://files.pythonhosted.org/packages/93/0a/d1c6b9af1ff1e36832fe38d74d5c5bab913f2bdcbbd6bc0e7f3ce8b2f577/regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784", size = 483376 }, + { url = "https://files.pythonhosted.org/packages/a4/42/5910a050c105d7f750a72dcb49c30220c3ae4e2654e54aaaa0e9bc0584cb/regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36", size = 288112 }, + { url = "https://files.pythonhosted.org/packages/8d/56/0c262aff0e9224fa7ffce47b5458d373f4d3e3ff84e99b5ff0cb15e0b5b2/regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92", size = 284608 }, + { url = "https://files.pythonhosted.org/packages/b9/54/9fe8f9aec5007bbbbce28ba3d2e3eaca425f95387b7d1e84f0d137d25237/regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86", size = 795337 }, + { url = "https://files.pythonhosted.org/packages/b2/e7/6b2f642c3cded271c4f16cc4daa7231be544d30fe2b168e0223724b49a61/regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85", size = 835848 }, + { url = "https://files.pythonhosted.org/packages/cd/9e/187363bdf5d8c0e4662117b92aa32bf52f8f09620ae93abc7537d96d3311/regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963", size = 823503 }, + { url = "https://files.pythonhosted.org/packages/f8/10/601303b8ee93589f879664b0cfd3127949ff32b17f9b6c490fb201106c4d/regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6", size = 797049 }, + { url = "https://files.pythonhosted.org/packages/ef/1c/ea200f61ce9f341763f2717ab4daebe4422d83e9fd4ac5e33435fd3a148d/regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802", size = 784144 }, + { url = "https://files.pythonhosted.org/packages/d8/5c/d2429be49ef3292def7688401d3deb11702c13dcaecdc71d2b407421275b/regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29", size = 782483 }, + { url = "https://files.pythonhosted.org/packages/12/d9/cbc30f2ff7164f3b26a7760f87c54bf8b2faed286f60efd80350a51c5b99/regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8", size = 790320 }, + { url = "https://files.pythonhosted.org/packages/19/1d/43ed03a236313639da5a45e61bc553c8d41e925bcf29b0f8ecff0c2c3f25/regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84", size = 860435 }, + { url = "https://files.pythonhosted.org/packages/34/4f/5d04da61c7c56e785058a46349f7285ae3ebc0726c6ea7c5c70600a52233/regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554", size = 859571 }, + { url = "https://files.pythonhosted.org/packages/12/7f/8398c8155a3c70703a8e91c29532558186558e1aea44144b382faa2a6f7a/regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8", size = 787398 }, + { url = "https://files.pythonhosted.org/packages/58/3a/f5903977647a9a7e46d5535e9e96c194304aeeca7501240509bde2f9e17f/regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8", size = 262035 }, + { url = "https://files.pythonhosted.org/packages/ff/80/51ba3a4b7482f6011095b3a036e07374f64de180b7d870b704ed22509002/regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f", size = 273510 }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, +] + +[[package]] +name = "ruamel-yaml" +version = "0.18.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ruamel-yaml-clib", marker = "python_full_version < '3.13' and platform_python_implementation == 'CPython'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/29/81/4dfc17eb6ebb1aac314a3eb863c1325b907863a1b8b1382cdffcb6ac0ed9/ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b", size = 143362 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/67/8ece580cc363331d9a53055130f86b096bf16e38156e33b1d3014fffda6b/ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636", size = 117761 }, +] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/46/ab/bab9eb1566cd16f060b54055dd39cf6a34bfa0240c53a7218c43e974295b/ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512", size = 213824 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/01/37ac131614f71b98e9b148b2d7790662dcee92217d2fb4bac1aa377def33/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d", size = 148236 }, + { url = "https://files.pythonhosted.org/packages/61/ee/4874c9fc96010fce85abefdcbe770650c5324288e988d7a48b527a423815/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462", size = 133996 }, + { url = "https://files.pythonhosted.org/packages/d3/62/c60b034d9a008bbd566eeecf53a5a4c73d191c8de261290db6761802b72d/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412", size = 526680 }, + { url = "https://files.pythonhosted.org/packages/90/8c/6cdb44f548b29eb6328b9e7e175696336bc856de2ff82e5776f860f03822/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f", size = 605853 }, + { url = "https://files.pythonhosted.org/packages/88/30/fc45b45d5eaf2ff36cffd215a2f85e9b90ac04e70b97fd4097017abfb567/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334", size = 655206 }, + { url = "https://files.pythonhosted.org/packages/af/dc/133547f90f744a0c827bac5411d84d4e81da640deb3af1459e38c5f3b6a0/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d", size = 689649 }, + { url = "https://files.pythonhosted.org/packages/23/1d/589139191b187a3c750ae8d983c42fd799246d5f0dd84451a0575c9bdbe9/ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d", size = 100044 }, + { url = "https://files.pythonhosted.org/packages/4f/5b/744df20285a75ac4c606452ce9a0fcc42087d122f42294518ded1017697c/ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31", size = 117825 }, + { url = "https://files.pythonhosted.org/packages/b1/15/971b385c098e8d0d170893f5ba558452bb7b776a0c90658b8f4dd0e3382b/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069", size = 148870 }, + { url = "https://files.pythonhosted.org/packages/01/b0/4ddef56e9f703d7909febc3a421d709a3482cda25826816ec595b73e3847/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248", size = 134475 }, + { url = "https://files.pythonhosted.org/packages/a4/f7/22d6b620ed895a05d40802d8281eff924dc6190f682d933d4efff60db3b5/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b", size = 544020 }, + { url = "https://files.pythonhosted.org/packages/7c/e4/0d19d65e340f93df1c47f323d95fa4b256bb28320290f5fddef90837853a/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe", size = 642643 }, + { url = "https://files.pythonhosted.org/packages/c9/ff/f781eb5e2ae011e586d5426e2086a011cf1e0f59704a6cad1387975c5a62/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899", size = 695832 }, + { url = "https://files.pythonhosted.org/packages/e3/41/f62e67ac651358b8f0d60cfb12ab2daf99b1b69eeaa188d0cec809d943a6/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9", size = 730923 }, + { url = "https://files.pythonhosted.org/packages/9f/f0/19ab8acbf983cd1b37f47d27ceb8b10a738d60d36316a54bad57e0d73fbb/ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7", size = 99999 }, + { url = "https://files.pythonhosted.org/packages/ec/54/d8a795997921d87224c65d44499ca595a833093fb215b133f920c1062956/ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb", size = 118008 }, + { url = "https://files.pythonhosted.org/packages/7a/a2/eb5e9d088cb9d15c24d956944c09dca0a89108ad6e2e913c099ef36e3f0d/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1", size = 144636 }, + { url = "https://files.pythonhosted.org/packages/66/98/8de4f22bbfd9135deb3422e96d450c4bc0a57d38c25976119307d2efe0aa/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2", size = 135684 }, + { url = "https://files.pythonhosted.org/packages/30/d3/5fe978cd01a61c12efd24d65fa68c6f28f28c8073a06cf11db3a854390ca/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92", size = 734571 }, + { url = "https://files.pythonhosted.org/packages/55/b3/e2531a050758b717c969cbf76c103b75d8a01e11af931b94ba656117fbe9/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62", size = 643946 }, + { url = "https://files.pythonhosted.org/packages/0d/aa/06db7ca0995b513538402e11280282c615b5ae5f09eb820460d35fb69715/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9", size = 692169 }, + { url = "https://files.pythonhosted.org/packages/27/38/4cf4d482b84ecdf51efae6635cc5483a83cf5ca9d9c13e205a750e251696/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d", size = 740325 }, + { url = "https://files.pythonhosted.org/packages/6f/67/c62c6eea53a4feb042727a3d6c18f50dc99683c2b199c06bd2a9e3db8e22/ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa", size = 98639 }, + { url = "https://files.pythonhosted.org/packages/10/d2/52a3d810d0b5b3720725c0504a27b3fced7b6f310fe928f7019d79387bc1/ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b", size = 115305 }, +] + +[[package]] +name = "six" +version = "1.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, +] + +[[package]] +name = "smmap" +version = "5.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/88/04/b5bf6d21dc4041000ccba7eb17dd3055feb237e7ffc2c20d3fae3af62baa/smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", size = 22291 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/a5/10f97f73544edcdef54409f1d839f6049a0d79df68adbc1ceb24d1aaca42/smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da", size = 24282 }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, +] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/7b/af302bebf22c749c56c9c3e8ae13190b5b5db37a33d9068652e8f73b7089/snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", size = 86699 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a", size = 93002 }, +] + +[[package]] +name = "soupsieve" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, +] + +[[package]] +name = "sphinx" +version = "7.4.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/be/50e50cb4f2eff47df05673d361095cafd95521d2a22521b920c67a372dcb/sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe", size = 8067911 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239", size = 3401624 }, +] + +[[package]] +name = "sphinx-autobuild" +version = "2024.9.19" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama" }, + { name = "sphinx" }, + { name = "starlette" }, + { name = "uvicorn" }, + { name = "watchfiles" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ad/5b/2adf7fb2451ba9a098c00d40fad0c6ca2cfa967ce0b6c6fa4c36cbc7c70c/sphinx_autobuild-2024.9.19.tar.gz", hash = "sha256:2dd4863d174e533c1cd075eb5dfc90ad9a21734af7efd25569bf228b405e08ef", size = 13712 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/7f/fa4387bbe792bc4592f7e793bc56f7822746d5f26bef0cfc88a262884ec3/sphinx_autobuild-2024.9.19-py3-none-any.whl", hash = "sha256:57d974eebfc6461ff0fd136e78bf7a9c057d543d5166d318a45599898019b82c", size = 11519 }, +] + +[[package]] +name = "sphinx-autodoc-typehints" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/cd/03e7b917230dc057922130a79ba0240df1693bfd76727ea33fae84b39138/sphinx_autodoc_typehints-2.3.0.tar.gz", hash = "sha256:535c78ed2d6a1bad393ba9f3dfa2602cf424e2631ee207263e07874c38fde084", size = 40709 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/f3/e0a4ce49da4b6f4e4ce84b3c39a0677831884cb9d8a87ccbf1e9e56e53ac/sphinx_autodoc_typehints-2.3.0-py3-none-any.whl", hash = "sha256:3098e2c6d0ba99eacd013eb06861acc9b51c6e595be86ab05c08ee5506ac0c67", size = 19836 }, +] + +[[package]] +name = "sphinx-basic-ng" +version = "1.0.0b2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/0b/a866924ded68efec7a1759587a4e478aec7559d8165fac8b2ad1c0e774d6/sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9", size = 20736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/dd/018ce05c532a22007ac58d4f45232514cd9d6dd0ee1dc374e309db830983/sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b", size = 22496 }, +] + +[[package]] +name = "sphinx-copybutton" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e", size = 13343 }, +] + +[[package]] +name = "sphinx-design" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2b/69/b34e0cb5336f09c6866d53b4a19d76c227cdec1bbc7ac4de63ca7d58c9c7/sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632", size = 2193689 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/43/65c0acbd8cc6f50195a3a1fc195c404988b15c67090e73c7a41a9f57d6bd/sphinx_design-0.6.1-py3-none-any.whl", hash = "sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c", size = 2215338 }, +] + +[[package]] +name = "sphinx-jinja2-compat" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "markupsafe" }, + { name = "standard-imghdr", marker = "python_full_version >= '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/26/df/27282da6f8c549f765beca9de1a5fc56f9651ed87711a5cac1e914137753/sphinx_jinja2_compat-0.3.0.tar.gz", hash = "sha256:f3c1590b275f42e7a654e081db5e3e5fb97f515608422bde94015ddf795dfe7c", size = 4998 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/42/2fd09d672eaaa937d6893d8b747d07943f97a6e5e30653aee6ebd339b704/sphinx_jinja2_compat-0.3.0-py3-none-any.whl", hash = "sha256:b1e4006d8e1ea31013fa9946d1b075b0c8d2a42c6e3425e63542c1e9f8be9084", size = 7883 }, +] + +[[package]] +name = "sphinx-jsonschema" +version = "1.19.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "jsonpointer" }, + { name = "pyyaml" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9c/3f/559d054f977596c5535edfeeab1f3a278f3bbb81bada2a1cb3cadbf7bb67/sphinx-jsonschema-1.19.1.tar.gz", hash = "sha256:b2385fe1c7acf2e759152aefed0cb17c920645b2a75c9934000c9c528e7d53c1", size = 18599 } + +[[package]] +name = "sphinx-lint" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "polib" }, + { name = "regex" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cf/46/f2dad36a4076e9ce88498b25b3f0de82eb7d341ea0ef715cd6c48005bcef/sphinx_lint-1.0.0.tar.gz", hash = "sha256:6eafdb44172ce526f405bf36c713eb246f1340ec2d667e7298e2487ed76decd2", size = 33574 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/31/d2/a130ffba531af7cbbb0e7ad24c7d577d3de0b797437f61d3a7234ed6d836/sphinx_lint-1.0.0-py3-none-any.whl", hash = "sha256:6117a0f340b2dc73eadfc57db7531d4477e0929f92a0c1a2f61e6edbc272f0bc", size = 20163 }, +] + +[[package]] +name = "sphinx-notfound-page" +version = "1.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/73/7d/c545883c714319380325a52c9f80d093c97e718d812fd8090e42b1a08508/sphinx_notfound_page-1.0.4.tar.gz", hash = "sha256:2a52f49cd367b5c4e64072de1591cc367714098500abf4ecb9a3ecb4fec25aae", size = 519228 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/c4/877a5beffb8dcaf35e919c4c3cad56732c76370d106126394f4ca211ad7f/sphinx_notfound_page-1.0.4-py3-none-any.whl", hash = "sha256:f7c26ae0df3cf3d6f38f56b068762e6203d0ebb7e1c804de1059598d7dd8b9d8", size = 8170 }, +] + +[[package]] +name = "sphinx-prompt" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "pygments" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/fb/7a07b8df1ca2418147a6b13e3f6b445071f2565198b45efa631d0d6ef0cd/sphinx_prompt-1.8.0.tar.gz", hash = "sha256:47482f86fcec29662fdfd23e7c04ef03582714195d01f5d565403320084372ed", size = 5121 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/49/f890a2668b7cbf375f5528b549c8d36dd2e801b0fbb7b2b5ef65663ecb6c/sphinx_prompt-1.8.0-py3-none-any.whl", hash = "sha256:369ecc633f0711886f9b3a078c83264245be1adf46abeeb9b88b5519e4b51007", size = 7298 }, +] + +[[package]] +name = "sphinx-pydantic" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "sphinx-jsonschema" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/58/e7a518876db551cf3bd6621eecc6675d003b9bd8413382c10298e2113f7e/sphinx-pydantic-0.1.1.tar.gz", hash = "sha256:a830e4f07fe88fbdfe3edecc2f52ef133cde2def7cb882a3f22780f34963b0fb", size = 3394 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/87/e397aba1d53aea3bccb8df07e1086e00855404afd92d118b07854d746947/sphinx_pydantic-0.1.1-py3-none-any.whl", hash = "sha256:371487ad81250d8bc5b944a2936b33c10ff88af7188d5be0ee6c4b46bb70254a", size = 2888 }, +] + +[[package]] +name = "sphinx-reredirects" +version = "0.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/1d/b1229d825a418738ce1a03930629a7b873cd6a0ff05953493604de35a3d5/sphinx_reredirects-0.1.5.tar.gz", hash = "sha256:cfa753b441020a22708ce8eb17d4fd553a28fc87a609330092917ada2a6da0d8", size = 7095 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/97/1f8143f87330f4c9ccc2c08ae9cd3cb1ce2944c51e98dd7ff141154fbcc7/sphinx_reredirects-0.1.5-py3-none-any.whl", hash = "sha256:444ae1438fba4418242ca76d6a6de3eaee82aaf0d8f2b0cac71a15d32ce6eba2", size = 5673 }, +] + +[[package]] +name = "sphinx-tabs" +version = "3.4.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "pygments" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/27/32/ab475e252dc2b704e82a91141fa404cdd8901a5cf34958fd22afacebfccd/sphinx-tabs-3.4.5.tar.gz", hash = "sha256:ba9d0c1e3e37aaadd4b5678449eb08176770e0fc227e769b6ce747df3ceea531", size = 16070 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/9f/4ac7dbb9f23a2ff5a10903a4f9e9f43e0ff051f63a313e989c962526e305/sphinx_tabs-3.4.5-py3-none-any.whl", hash = "sha256:92cc9473e2ecf1828ca3f6617d0efc0aa8acb06b08c56ba29d1413f2f0f6cf09", size = 9904 }, +] + +[[package]] +name = "sphinx-toolbox" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "apeye" }, + { name = "autodocsumm" }, + { name = "beautifulsoup4" }, + { name = "cachecontrol", extra = ["filecache"] }, + { name = "dict2css" }, + { name = "docutils" }, + { name = "domdf-python-tools" }, + { name = "filelock" }, + { name = "html5lib" }, + { name = "ruamel-yaml" }, + { name = "sphinx" }, + { name = "sphinx-autodoc-typehints" }, + { name = "sphinx-jinja2-compat" }, + { name = "sphinx-prompt" }, + { name = "sphinx-tabs" }, + { name = "tabulate" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/a8/da2b37fe247a7d67232d8be99ae9e598bff4ab2f84065122534dae2e1770/sphinx_toolbox-3.8.0.tar.gz", hash = "sha256:f6b62c7800dc2a2e2cbaf7b13ee7c5f06cbf3e1a5ad2c4b2f0744851a05afaee", size = 112107 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/b2/375be339c7d6d1a96dc82440a53320dfded18503b7362038dd39d83da0b7/sphinx_toolbox-3.8.0-py3-none-any.whl", hash = "sha256:36f484c540569c0fb62b4197187d166443fe0708134b98c88f6ba5418d06b95e", size = 194622 }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300 }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530 }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705 }, +] + +[[package]] +name = "sphinxcontrib-jquery" +version = "4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/f3/aa67467e051df70a6330fe7770894b3e4f09436dea6881ae0b4f3d87cad8/sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a", size = 122331 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/85/749bd22d1a68db7291c89e2ebca53f4306c3f205853cf31e9de279034c3c/sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae", size = 121104 }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071 }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743 }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072 }, +] + +[[package]] +name = "sphinxext-opengraph" +version = "0.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/5b/4302fe33c88dbfb572e2c1cad26735164c23f16fb8dba94ddb1867d0ef06/sphinxext-opengraph-0.9.1.tar.gz", hash = "sha256:dd2868a1e7c9497977fbbf44cc0844a42af39ca65fe1bb0272518af225d06fc5", size = 1034511 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/0a/970b80b4fa1feeb6deb6f2e22d4cb14e388b27b315a1afdb9db930ff91a4/sphinxext_opengraph-0.9.1-py3-none-any.whl", hash = "sha256:b3b230cc6a5b5189139df937f0d9c7b23c7c204493b22646273687969dcb760e", size = 1005241 }, +] + +[[package]] +name = "standard-imghdr" +version = "3.10.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/d2/2eb5521072c9598886035c65c023f39f7384bcb73eed70794f469e34efac/standard_imghdr-3.10.14.tar.gz", hash = "sha256:2598fe2e7c540dbda34b233295e10957ab8dc8ac6f3bd9eaa8d38be167232e52", size = 5474 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/d0/9852f70eb01f814843530c053542b72d30e9fbf74da7abb0107e71938389/standard_imghdr-3.10.14-py3-none-any.whl", hash = "sha256:cdf6883163349624dee9a81d2853a20260337c4cd41c04e99c082e01833a08e2", size = 5598 }, +] + +[[package]] +name = "starcraft" +version = "0.0.post232+g5d06b94" +source = { editable = "." } + +[package.optional-dependencies] +docs = [ + { name = "canonical-sphinx" }, + { name = "sphinx-autobuild" }, + { name = "sphinx-lint" }, + { name = "sphinx-pydantic" }, + { name = "sphinx-toolbox" }, +] + +[package.dev-dependencies] +dev = [ + { name = "build" }, + { name = "coverage", extra = ["toml"] }, + { name = "mypy", extra = ["reports"] }, + { name = "pyright" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "pytest-mock" }, + { name = "types-colorama" }, + { name = "types-pygments" }, + { name = "types-setuptools" }, + { name = "yamllint" }, +] + +[package.metadata] +requires-dist = [ + { name = "canonical-sphinx", marker = "extra == 'docs'", specifier = "~=0.1" }, + { name = "sphinx-autobuild", marker = "extra == 'docs'", specifier = "~=2024.2" }, + { name = "sphinx-lint", marker = "extra == 'docs'", specifier = "==1.0.0" }, + { name = "sphinx-pydantic", marker = "extra == 'docs'", specifier = "==0.1.1" }, + { name = "sphinx-toolbox", marker = "extra == 'docs'", specifier = "~=3.5" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "build", specifier = ">=1.2.1" }, + { name = "coverage", extras = ["toml"], specifier = "~=7.4" }, + { name = "mypy", extras = ["reports"], specifier = "~=1.11.0" }, + { name = "pyright", specifier = "==1.1.380" }, + { name = "pytest", specifier = "~=8.0" }, + { name = "pytest-cov", specifier = "~=5.0" }, + { name = "pytest-mock", specifier = "~=3.12" }, + { name = "types-colorama" }, + { name = "types-pygments" }, + { name = "types-setuptools" }, + { name = "yamllint", specifier = "~=1.34" }, +] + +[[package]] +name = "starlette" +version = "0.38.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/13/aa/57975da16ca0c368bbb5687daa6ad79561c2328a44667a1d6802e94df3e5/starlette-0.38.5.tar.gz", hash = "sha256:04a92830a9b6eb1442c766199d62260c3d4dc9c4f9188360626b1e0273cb7077", size = 2569511 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/1a/8853ba4cea1ec99535ac9be5795a50ca92cddd04d57bbaa56e866cb7548c/starlette-0.38.5-py3-none-any.whl", hash = "sha256:632f420a9d13e3ee2a6f18f437b0a9f1faecb0bc42e1942aa2ea0e379a4c4206", size = 71447 }, +] + +[[package]] +name = "tabulate" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252 }, +] + +[[package]] +name = "tomli" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757 }, +] + +[[package]] +name = "types-colorama" +version = "0.4.15.20240311" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/59/73/0fb0b9fe4964b45b2a06ed41b60c352752626db46aa0fb70a49a9e283a75/types-colorama-0.4.15.20240311.tar.gz", hash = "sha256:a28e7f98d17d2b14fb9565d32388e419f4108f557a7d939a66319969b2b99c7a", size = 5608 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/83/6944b4fa01efb2e63ac62b791a8ddf0fee358f93be9f64b8f152648ad9d3/types_colorama-0.4.15.20240311-py3-none-any.whl", hash = "sha256:6391de60ddc0db3f147e31ecb230006a6823e81e380862ffca1e4695c13a0b8e", size = 5840 }, +] + +[[package]] +name = "types-docutils" +version = "0.21.0.20240907" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/d1/29a516f8f42540a65dfa18df0dbf05e669554f09fa002bf9e07c896db9a2/types-docutils-0.21.0.20240907.tar.gz", hash = "sha256:5dd2aa5e2e06fcfa090020bc4115479b4dd28da3329ab708563ee29894bd3c0d", size = 20273 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/ba/f9ad4e16e77774c3a8f1799572b61cd74360185f992f6ac09f641314f2d5/types_docutils-0.21.0.20240907-py3-none-any.whl", hash = "sha256:9c8ed6d90583944af00f6b5fa3aecc2101e20672f6b1a4a299c6bf7d1e47084d", size = 28034 }, +] + +[[package]] +name = "types-pygments" +version = "2.18.0.20240506" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "types-docutils" }, + { name = "types-setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f0/ed/0a70203637650ecaa74731faf441d128edb908ed6ca184013bfc498283ba/types-Pygments-2.18.0.20240506.tar.gz", hash = "sha256:4b4c37812c87bbde687dbf27adf5bac593745a321e57f678dbc311571ba2ac9d", size = 13516 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/52/1a740a823dcfbe7fe7c44c2ff83528df2c2b5b6e93c299e8db7bf4205c1b/types_Pygments-2.18.0.20240506-py3-none-any.whl", hash = "sha256:11c90bc1737c9af55e5569558b88df7c2233e12325cb516215f722271444e91d", size = 20775 }, +] + +[[package]] +name = "types-setuptools" +version = "75.1.0.20240917" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/48/91/c1168caa2a5ba14c01b146b516fab2d8646887cb5db7e78e13b9c6da88d2/types-setuptools-75.1.0.20240917.tar.gz", hash = "sha256:12f12a165e7ed383f31def705e5c0fa1c26215dd466b0af34bd042f7d5331f55", size = 42585 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/4c/a4c87d86ba18ff00773ab8591c79c23a6938293ab3e2cec2b2eb4ca5b644/types_setuptools-75.1.0.20240917-py3-none-any.whl", hash = "sha256:06f78307e68d1bbde6938072c57b81cf8a99bc84bd6dc7e4c5014730b097dc0c", size = 65516 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] + +[[package]] +name = "uc-micro-py" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/7a/146a99696aee0609e3712f2b44c6274566bc368dfe8375191278045186b8/uc-micro-py-1.0.3.tar.gz", hash = "sha256:d321b92cff673ec58027c04015fcaa8bb1e005478643ff4a500882eaab88c48a", size = 6043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/87/1f677586e8ac487e29672e4b17455758fce261de06a0d086167bb760361a/uc_micro_py-1.0.3-py3-none-any.whl", hash = "sha256:db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5", size = 6229 }, +] + +[[package]] +name = "urllib3" +version = "2.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, +] + +[[package]] +name = "uvicorn" +version = "0.30.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/01/5e637e7aa9dd031be5376b9fb749ec20b86f5a5b6a49b87fabd374d5fa9f/uvicorn-0.30.6.tar.gz", hash = "sha256:4b15decdda1e72be08209e860a1e10e92439ad5b97cf44cc945fcbee66fc5788", size = 42825 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f5/8e/cdc7d6263db313030e4c257dd5ba3909ebc4e4fb53ad62d5f09b1a2f5458/uvicorn-0.30.6-py3-none-any.whl", hash = "sha256:65fd46fe3fda5bdc1b03b94eb634923ff18cd35b2f084813ea79d1f103f711b5", size = 62835 }, +] + +[[package]] +name = "watchfiles" +version = "0.24.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c8/27/2ba23c8cc85796e2d41976439b08d52f691655fdb9401362099502d1f0cf/watchfiles-0.24.0.tar.gz", hash = "sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1", size = 37870 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/a1/631c12626378b9f1538664aa221feb5c60dfafbd7f60b451f8d0bdbcdedd/watchfiles-0.24.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0", size = 375096 }, + { url = "https://files.pythonhosted.org/packages/f7/5c/f27c979c8a10aaa2822286c1bffdce3db731cd1aa4224b9f86623e94bbfe/watchfiles-0.24.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c", size = 367425 }, + { url = "https://files.pythonhosted.org/packages/74/0d/1889e5649885484d29f6c792ef274454d0a26b20d6ed5fdba5409335ccb6/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361", size = 437705 }, + { url = "https://files.pythonhosted.org/packages/85/8a/01d9a22e839f0d1d547af11b1fcac6ba6f889513f1b2e6f221d9d60d9585/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3", size = 433636 }, + { url = "https://files.pythonhosted.org/packages/62/32/a93db78d340c7ef86cde469deb20e36c6b2a873edee81f610e94bbba4e06/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571", size = 451069 }, + { url = "https://files.pythonhosted.org/packages/99/c2/e9e2754fae3c2721c9a7736f92dab73723f1968ed72535fff29e70776008/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd", size = 469306 }, + { url = "https://files.pythonhosted.org/packages/4c/45/f317d9e3affb06c3c27c478de99f7110143e87f0f001f0f72e18d0e1ddce/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a", size = 476187 }, + { url = "https://files.pythonhosted.org/packages/ac/d3/f1f37248abe0114916921e638f71c7d21fe77e3f2f61750e8057d0b68ef2/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e", size = 425743 }, + { url = "https://files.pythonhosted.org/packages/2b/e8/c7037ea38d838fd81a59cd25761f106ee3ef2cfd3261787bee0c68908171/watchfiles-0.24.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c", size = 612327 }, + { url = "https://files.pythonhosted.org/packages/a0/c5/0e6e228aafe01a7995fbfd2a4edb221bb11a2744803b65a5663fb85e5063/watchfiles-0.24.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188", size = 595096 }, + { url = "https://files.pythonhosted.org/packages/63/d5/4780e8bf3de3b4b46e7428a29654f7dc041cad6b19fd86d083e4b6f64bbe/watchfiles-0.24.0-cp310-none-win32.whl", hash = "sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735", size = 264149 }, + { url = "https://files.pythonhosted.org/packages/fe/1b/5148898ba55fc9c111a2a4a5fb67ad3fa7eb2b3d7f0618241ed88749313d/watchfiles-0.24.0-cp310-none-win_amd64.whl", hash = "sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04", size = 277542 }, + { url = "https://files.pythonhosted.org/packages/85/02/366ae902cd81ca5befcd1854b5c7477b378f68861597cef854bd6dc69fbe/watchfiles-0.24.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:bdcd5538e27f188dd3c804b4a8d5f52a7fc7f87e7fd6b374b8e36a4ca03db428", size = 375579 }, + { url = "https://files.pythonhosted.org/packages/bc/67/d8c9d256791fe312fea118a8a051411337c948101a24586e2df237507976/watchfiles-0.24.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2dadf8a8014fde6addfd3c379e6ed1a981c8f0a48292d662e27cabfe4239c83c", size = 367726 }, + { url = "https://files.pythonhosted.org/packages/b1/dc/a8427b21ef46386adf824a9fec4be9d16a475b850616cfd98cf09a97a2ef/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6509ed3f467b79d95fc62a98229f79b1a60d1b93f101e1c61d10c95a46a84f43", size = 437735 }, + { url = "https://files.pythonhosted.org/packages/3a/21/0b20bef581a9fbfef290a822c8be645432ceb05fb0741bf3c032e0d90d9a/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8360f7314a070c30e4c976b183d1d8d1585a4a50c5cb603f431cebcbb4f66327", size = 433644 }, + { url = "https://files.pythonhosted.org/packages/1c/e8/d5e5f71cc443c85a72e70b24269a30e529227986096abe091040d6358ea9/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:316449aefacf40147a9efaf3bd7c9bdd35aaba9ac5d708bd1eb5763c9a02bef5", size = 450928 }, + { url = "https://files.pythonhosted.org/packages/61/ee/bf17f5a370c2fcff49e1fec987a6a43fd798d8427ea754ce45b38f9e117a/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73bde715f940bea845a95247ea3e5eb17769ba1010efdc938ffcb967c634fa61", size = 469072 }, + { url = "https://files.pythonhosted.org/packages/a3/34/03b66d425986de3fc6077e74a74c78da298f8cb598887f664a4485e55543/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3770e260b18e7f4e576edca4c0a639f704088602e0bc921c5c2e721e3acb8d15", size = 475517 }, + { url = "https://files.pythonhosted.org/packages/70/eb/82f089c4f44b3171ad87a1b433abb4696f18eb67292909630d886e073abe/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa0fd7248cf533c259e59dc593a60973a73e881162b1a2f73360547132742823", size = 425480 }, + { url = "https://files.pythonhosted.org/packages/53/20/20509c8f5291e14e8a13104b1808cd7cf5c44acd5feaecb427a49d387774/watchfiles-0.24.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d7a2e3b7f5703ffbd500dabdefcbc9eafeff4b9444bbdd5d83d79eedf8428fab", size = 612322 }, + { url = "https://files.pythonhosted.org/packages/df/2b/5f65014a8cecc0a120f5587722068a975a692cadbe9fe4ea56b3d8e43f14/watchfiles-0.24.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d831ee0a50946d24a53821819b2327d5751b0c938b12c0653ea5be7dea9c82ec", size = 595094 }, + { url = "https://files.pythonhosted.org/packages/18/98/006d8043a82c0a09d282d669c88e587b3a05cabdd7f4900e402250a249ac/watchfiles-0.24.0-cp311-none-win32.whl", hash = "sha256:49d617df841a63b4445790a254013aea2120357ccacbed00253f9c2b5dc24e2d", size = 264191 }, + { url = "https://files.pythonhosted.org/packages/8a/8b/badd9247d6ec25f5f634a9b3d0d92e39c045824ec7e8afcedca8ee52c1e2/watchfiles-0.24.0-cp311-none-win_amd64.whl", hash = "sha256:d3dcb774e3568477275cc76554b5a565024b8ba3a0322f77c246bc7111c5bb9c", size = 277527 }, + { url = "https://files.pythonhosted.org/packages/af/19/35c957c84ee69d904299a38bae3614f7cede45f07f174f6d5a2f4dbd6033/watchfiles-0.24.0-cp311-none-win_arm64.whl", hash = "sha256:9301c689051a4857d5b10777da23fafb8e8e921bcf3abe6448a058d27fb67633", size = 266253 }, + { url = "https://files.pythonhosted.org/packages/35/82/92a7bb6dc82d183e304a5f84ae5437b59ee72d48cee805a9adda2488b237/watchfiles-0.24.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7211b463695d1e995ca3feb38b69227e46dbd03947172585ecb0588f19b0d87a", size = 374137 }, + { url = "https://files.pythonhosted.org/packages/87/91/49e9a497ddaf4da5e3802d51ed67ff33024597c28f652b8ab1e7c0f5718b/watchfiles-0.24.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b8693502d1967b00f2fb82fc1e744df128ba22f530e15b763c8d82baee15370", size = 367733 }, + { url = "https://files.pythonhosted.org/packages/0d/d8/90eb950ab4998effea2df4cf3a705dc594f6bc501c5a353073aa990be965/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdab9555053399318b953a1fe1f586e945bc8d635ce9d05e617fd9fe3a4687d6", size = 437322 }, + { url = "https://files.pythonhosted.org/packages/6c/a2/300b22e7bc2a222dd91fce121cefa7b49aa0d26a627b2777e7bdfcf1110b/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:34e19e56d68b0dad5cff62273107cf5d9fbaf9d75c46277aa5d803b3ef8a9e9b", size = 433409 }, + { url = "https://files.pythonhosted.org/packages/99/44/27d7708a43538ed6c26708bcccdde757da8b7efb93f4871d4cc39cffa1cc/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:41face41f036fee09eba33a5b53a73e9a43d5cb2c53dad8e61fa6c9f91b5a51e", size = 452142 }, + { url = "https://files.pythonhosted.org/packages/b0/ec/c4e04f755be003129a2c5f3520d2c47026f00da5ecb9ef1e4f9449637571/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5148c2f1ea043db13ce9b0c28456e18ecc8f14f41325aa624314095b6aa2e9ea", size = 469414 }, + { url = "https://files.pythonhosted.org/packages/c5/4e/cdd7de3e7ac6432b0abf282ec4c1a1a2ec62dfe423cf269b86861667752d/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e4bd963a935aaf40b625c2499f3f4f6bbd0c3776f6d3bc7c853d04824ff1c9f", size = 472962 }, + { url = "https://files.pythonhosted.org/packages/27/69/e1da9d34da7fc59db358424f5d89a56aaafe09f6961b64e36457a80a7194/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c79d7719d027b7a42817c5d96461a99b6a49979c143839fc37aa5748c322f234", size = 425705 }, + { url = "https://files.pythonhosted.org/packages/e8/c1/24d0f7357be89be4a43e0a656259676ea3d7a074901f47022f32e2957798/watchfiles-0.24.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:32aa53a9a63b7f01ed32e316e354e81e9da0e6267435c7243bf8ae0f10b428ef", size = 612851 }, + { url = "https://files.pythonhosted.org/packages/c7/af/175ba9b268dec56f821639c9893b506c69fd999fe6a2e2c51de420eb2f01/watchfiles-0.24.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ce72dba6a20e39a0c628258b5c308779b8697f7676c254a845715e2a1039b968", size = 594868 }, + { url = "https://files.pythonhosted.org/packages/44/81/1f701323a9f70805bc81c74c990137123344a80ea23ab9504a99492907f8/watchfiles-0.24.0-cp312-none-win32.whl", hash = "sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444", size = 264109 }, + { url = "https://files.pythonhosted.org/packages/b4/0b/32cde5bc2ebd9f351be326837c61bdeb05ad652b793f25c91cac0b48a60b/watchfiles-0.24.0-cp312-none-win_amd64.whl", hash = "sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896", size = 277055 }, + { url = "https://files.pythonhosted.org/packages/4b/81/daade76ce33d21dbec7a15afd7479de8db786e5f7b7d249263b4ea174e08/watchfiles-0.24.0-cp312-none-win_arm64.whl", hash = "sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418", size = 266169 }, + { url = "https://files.pythonhosted.org/packages/30/dc/6e9f5447ae14f645532468a84323a942996d74d5e817837a5c8ce9d16c69/watchfiles-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48", size = 373764 }, + { url = "https://files.pythonhosted.org/packages/79/c0/c3a9929c372816c7fc87d8149bd722608ea58dc0986d3ef7564c79ad7112/watchfiles-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90", size = 367873 }, + { url = "https://files.pythonhosted.org/packages/2e/11/ff9a4445a7cfc1c98caf99042df38964af12eed47d496dd5d0d90417349f/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94", size = 438381 }, + { url = "https://files.pythonhosted.org/packages/48/a3/763ba18c98211d7bb6c0f417b2d7946d346cdc359d585cc28a17b48e964b/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e", size = 432809 }, + { url = "https://files.pythonhosted.org/packages/30/4c/616c111b9d40eea2547489abaf4ffc84511e86888a166d3a4522c2ba44b5/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827", size = 451801 }, + { url = "https://files.pythonhosted.org/packages/b6/be/d7da83307863a422abbfeb12903a76e43200c90ebe5d6afd6a59d158edea/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df", size = 468886 }, + { url = "https://files.pythonhosted.org/packages/1d/d3/3dfe131ee59d5e90b932cf56aba5c996309d94dafe3d02d204364c23461c/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab", size = 472973 }, + { url = "https://files.pythonhosted.org/packages/42/6c/279288cc5653a289290d183b60a6d80e05f439d5bfdfaf2d113738d0f932/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f", size = 425282 }, + { url = "https://files.pythonhosted.org/packages/d6/d7/58afe5e85217e845edf26d8780c2d2d2ae77675eeb8d1b8b8121d799ce52/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b", size = 612540 }, + { url = "https://files.pythonhosted.org/packages/6d/d5/b96eeb9fe3fda137200dd2f31553670cbc731b1e13164fd69b49870b76ec/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18", size = 593625 }, + { url = "https://files.pythonhosted.org/packages/c1/e5/c326fe52ee0054107267608d8cea275e80be4455b6079491dfd9da29f46f/watchfiles-0.24.0-cp313-none-win32.whl", hash = "sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07", size = 263899 }, + { url = "https://files.pythonhosted.org/packages/a6/8b/8a7755c5e7221bb35fe4af2dc44db9174f90ebf0344fd5e9b1e8b42d381e/watchfiles-0.24.0-cp313-none-win_amd64.whl", hash = "sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366", size = 276622 }, + { url = "https://files.pythonhosted.org/packages/df/94/1ad200e937ec91b2a9d6b39ae1cf9c2b1a9cc88d5ceb43aa5c6962eb3c11/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f", size = 376986 }, + { url = "https://files.pythonhosted.org/packages/ee/fd/d9e020d687ccf90fe95efc513fbb39a8049cf5a3ff51f53c59fcf4c47a5d/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b", size = 369445 }, + { url = "https://files.pythonhosted.org/packages/43/cb/c0279b35053555d10ef03559c5aebfcb0c703d9c70a7b4e532df74b9b0e8/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4", size = 439383 }, + { url = "https://files.pythonhosted.org/packages/8b/c4/08b3c2cda45db5169148a981c2100c744a4a222fa7ae7644937c0c002069/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a", size = 426804 }, +] + +[[package]] +name = "wcmatch" +version = "9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "bracex" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/90/a29d5b359c128c48e32a2dc161464d6aab822df82d3bf1c1286231eda3c2/wcmatch-9.0.tar.gz", hash = "sha256:567d66b11ad74384954c8af86f607857c3bdf93682349ad32066231abd556c92", size = 113625 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ea/da/0633223f30f5db6e52236567e09c28e37ff455b3dfbe0843029206e609e6/wcmatch-9.0-py3-none-any.whl", hash = "sha256:af25922e2b6dbd1550fa37a4c8de7dd558d6c1bb330c641de9b907b9776cb3c4", size = 39139 }, +] + +[[package]] +name = "webencodings" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774 }, +] + +[[package]] +name = "websockets" +version = "13.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8f/1c/78687e0267b09412409ac134f10fd14d14ac6475da892a8b09a02d0f6ae2/websockets-13.0.1.tar.gz", hash = "sha256:4d6ece65099411cfd9a48d13701d7438d9c34f479046b34c50ff60bb8834e43e", size = 149769 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/bd/224fd6c4c0d60645444bb77cabf3633a6c14a47e2d03cdbc2136486c51f7/websockets-13.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1841c9082a3ba4a05ea824cf6d99570a6a2d8849ef0db16e9c826acb28089e8f", size = 150946 }, + { url = "https://files.pythonhosted.org/packages/44/5b/16f06fa678432d0cdbc55477bb6f0215c42b31615948bd63a884c294e0a5/websockets-13.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c5870b4a11b77e4caa3937142b650fbbc0914a3e07a0cf3131f35c0587489c1c", size = 148600 }, + { url = "https://files.pythonhosted.org/packages/5a/33/c57b4ecdd26510ffcda37d30073097f1e9015b316fe21b513360bf2d8ee2/websockets-13.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f1d3d1f2eb79fe7b0fb02e599b2bf76a7619c79300fc55f0b5e2d382881d4f7f", size = 148853 }, + { url = "https://files.pythonhosted.org/packages/71/a3/6a8a0e86c44fc39fab83fc6b946f9f7d53e5be6824916450dac637937086/websockets-13.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15c7d62ee071fa94a2fc52c2b472fed4af258d43f9030479d9c4a2de885fd543", size = 157935 }, + { url = "https://files.pythonhosted.org/packages/a0/58/ba14373234d2b7cce48031f7bd05ab2d23a11ffa0d35c3348d5729fa0527/websockets-13.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6724b554b70d6195ba19650fef5759ef11346f946c07dbbe390e039bcaa7cc3d", size = 156949 }, + { url = "https://files.pythonhosted.org/packages/7d/8a/8e2319207bae70156d0505bf91e192de015ee91ccc5b1afb406bb7db3819/websockets-13.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56a952fa2ae57a42ba7951e6b2605e08a24801a4931b5644dfc68939e041bc7f", size = 157260 }, + { url = "https://files.pythonhosted.org/packages/03/cd/31ff415c4b0dc3c185bd87c412affdc5fab42c700b04d02b380bfb789310/websockets-13.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:17118647c0ea14796364299e942c330d72acc4b248e07e639d34b75067b3cdd8", size = 157661 }, + { url = "https://files.pythonhosted.org/packages/e8/58/a95d1dc6f589cbbfca0918d160ff27c920ab2e94637b750591c6f226cf27/websockets-13.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64a11aae1de4c178fa653b07d90f2fb1a2ed31919a5ea2361a38760192e1858b", size = 157078 }, + { url = "https://files.pythonhosted.org/packages/ce/02/207f49e1c22c8fad9e6353815de698e778d365609801dc2387e01e0f94a2/websockets-13.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0617fd0b1d14309c7eab6ba5deae8a7179959861846cbc5cb528a7531c249448", size = 157027 }, + { url = "https://files.pythonhosted.org/packages/3b/aa/e59d994712635e9e6bc883471e12cc493e3a704e4e22e9d4a59ff1491161/websockets-13.0.1-cp310-cp310-win32.whl", hash = "sha256:11f9976ecbc530248cf162e359a92f37b7b282de88d1d194f2167b5e7ad80ce3", size = 151776 }, + { url = "https://files.pythonhosted.org/packages/7b/f9/83bc78788d6ce5492fa44133708584a885080aa7c790be2532f326948115/websockets-13.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:c3c493d0e5141ec055a7d6809a28ac2b88d5b878bb22df8c621ebe79a61123d0", size = 152206 }, + { url = "https://files.pythonhosted.org/packages/20/95/e002ec55688b751d3c9cc131c1960af7e440d95e1954c441535b9da2bf36/websockets-13.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:699ba9dd6a926f82a277063603fc8d586b89f4cb128efc353b749b641fcddda7", size = 150948 }, + { url = "https://files.pythonhosted.org/packages/62/6b/85fb8c13b278db7d45e27ff6ee0db3009b0fadef7c37c85e6cb4a0fbf08e/websockets-13.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cf2fae6d85e5dc384bf846f8243ddaa9197f3a1a70044f59399af001fd1f51d4", size = 148599 }, + { url = "https://files.pythonhosted.org/packages/e8/2e/c80cafbab86f8c399ba8323efff298b7062055724146391443d266e9c49b/websockets-13.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:52aed6ef21a0f1a2a5e310fb5c42d7555e9c5855476bbd7173c3aa3d8a0302f2", size = 148851 }, + { url = "https://files.pythonhosted.org/packages/2e/67/631d4b1f28fef6f12730c0cbe982203a9d6814768c2ab1e0a352d9a07a97/websockets-13.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8eb2b9a318542153674c6e377eb8cb9ca0fc011c04475110d3477862f15d29f0", size = 158509 }, + { url = "https://files.pythonhosted.org/packages/9b/e8/ba740eab2a9c5b903ea94d9a2a448db63f0a296265aee976d17abf734758/websockets-13.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5df891c86fe68b2c38da55b7aea7095beca105933c697d719f3f45f4220a5e0e", size = 157507 }, + { url = "https://files.pythonhosted.org/packages/f8/4e/ffa2f1aad2da67e483fb7bad6c69f80c786f4e85d1942a39d7b275b084ed/websockets-13.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac2d146ff30d9dd2fcf917e5d147db037a5c573f0446c564f16f1f94cf87462", size = 157881 }, + { url = "https://files.pythonhosted.org/packages/c0/85/0cbfe7b0e0dd3d885cd87b0523c6690ae7369feaf3aab5a23e95bdb4fefa/websockets-13.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b8ac5b46fd798bbbf2ac6620e0437c36a202b08e1f827832c4bf050da081b501", size = 158187 }, + { url = "https://files.pythonhosted.org/packages/39/29/d9df0a1daedebefaeea88fb8071539604df09fd0f1bfb73bf58333aa3eb6/websockets-13.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:46af561eba6f9b0848b2c9d2427086cabadf14e0abdd9fde9d72d447df268418", size = 157626 }, + { url = "https://files.pythonhosted.org/packages/7d/9a/f88e186059f6b89f8bb08461d9fda7a26940b7b8897c7d7f02aead40b7e4/websockets-13.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b5a06d7f60bc2fc378a333978470dfc4e1415ee52f5f0fce4f7853eb10c1e9df", size = 157575 }, + { url = "https://files.pythonhosted.org/packages/cf/e4/ecdb8352ebab2e44c10b9d6f50008f95e30bb0a7ef0e6b66cb475d539d74/websockets-13.0.1-cp311-cp311-win32.whl", hash = "sha256:556e70e4f69be1082e6ef26dcb70efcd08d1850f5d6c5f4f2bcb4e397e68f01f", size = 151779 }, + { url = "https://files.pythonhosted.org/packages/12/40/46967d00640e6c3231b73d310617927a11c91bcc044dd5a0860a3c457c33/websockets-13.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:67494e95d6565bf395476e9d040037ff69c8b3fa356a886b21d8422ad86ae075", size = 152206 }, + { url = "https://files.pythonhosted.org/packages/4e/51/23ed2d239f1c3087c1431d41cfd159865df0bc35bb0c89973e3b6a0fff9b/websockets-13.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f9c9e258e3d5efe199ec23903f5da0eeaad58cf6fccb3547b74fd4750e5ac47a", size = 150953 }, + { url = "https://files.pythonhosted.org/packages/57/8d/814a7ef62b916b0f39108ad2e4d9b4cb0f8c640f8c30202fb63041598ada/websockets-13.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6b41a1b3b561f1cba8321fb32987552a024a8f67f0d05f06fcf29f0090a1b956", size = 148610 }, + { url = "https://files.pythonhosted.org/packages/ad/8b/a378d21124011737e0e490a8a6ef778914b03e50c8d938de2f2170a20dbd/websockets-13.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f73e676a46b0fe9426612ce8caeca54c9073191a77c3e9d5c94697aef99296af", size = 148849 }, + { url = "https://files.pythonhosted.org/packages/46/d2/814a61226af313c1bc289cfe3a10f87bf426b6f2d9df0f927c47afab7612/websockets-13.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f613289f4a94142f914aafad6c6c87903de78eae1e140fa769a7385fb232fdf", size = 158772 }, + { url = "https://files.pythonhosted.org/packages/a1/7e/5987299eb7e131216c9027b05a65f149cbc2bde7c582e694d9eed6ec3d40/websockets-13.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f52504023b1480d458adf496dc1c9e9811df4ba4752f0bc1f89ae92f4f07d0c", size = 157724 }, + { url = "https://files.pythonhosted.org/packages/94/6e/eaf95894042ba8a05a125fe8bcf9ee3572fef6edbcbf49478f4991c027cc/websockets-13.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:139add0f98206cb74109faf3611b7783ceafc928529c62b389917a037d4cfdf4", size = 158152 }, + { url = "https://files.pythonhosted.org/packages/ce/ba/a1315d569cc2dadaafda74a9cea16ab5d68142525937f1994442d969b306/websockets-13.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:47236c13be337ef36546004ce8c5580f4b1150d9538b27bf8a5ad8edf23ccfab", size = 158442 }, + { url = "https://files.pythonhosted.org/packages/90/9b/59866695cfd05e785c90932fef3dae4682eb4e06e7076b7c53478f25faad/websockets-13.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c44ca9ade59b2e376612df34e837013e2b273e6c92d7ed6636d0556b6f4db93d", size = 157823 }, + { url = "https://files.pythonhosted.org/packages/9b/47/20af68a313b6453d2d094ccc497b7232e8475175d234e3e5bef5088521e5/websockets-13.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9bbc525f4be3e51b89b2a700f5746c2a6907d2e2ef4513a8daafc98198b92237", size = 157818 }, + { url = "https://files.pythonhosted.org/packages/f8/bb/60aaedc80e388e978617dda1ff38788780c6b0f6e462b85368cb934131a5/websockets-13.0.1-cp312-cp312-win32.whl", hash = "sha256:3624fd8664f2577cf8de996db3250662e259bfbc870dd8ebdcf5d7c6ac0b5185", size = 151785 }, + { url = "https://files.pythonhosted.org/packages/16/2e/e47692f569e1be2e66c1dbc5e85ea4d2cc93b80027fbafa28ae8b0dee52c/websockets-13.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0513c727fb8adffa6d9bf4a4463b2bade0186cbd8c3604ae5540fae18a90cb99", size = 152214 }, + { url = "https://files.pythonhosted.org/packages/46/37/d8ef4b68684d1fa368a5c64be466db07fc58b68163bc2496db2d4cc208ff/websockets-13.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1ee4cc030a4bdab482a37462dbf3ffb7e09334d01dd37d1063be1136a0d825fa", size = 150962 }, + { url = "https://files.pythonhosted.org/packages/95/49/78aeb3af08ec9887a9065e85cef9d7e199d6c6261fcd39eec087f3a62328/websockets-13.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dbb0b697cc0655719522406c059eae233abaa3243821cfdfab1215d02ac10231", size = 148621 }, + { url = "https://files.pythonhosted.org/packages/31/0d/dc9b7cec8deaee452092a631ccda894bd7098859f71dd7639b4b5b9c615c/websockets-13.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:acbebec8cb3d4df6e2488fbf34702cbc37fc39ac7abf9449392cefb3305562e9", size = 148853 }, + { url = "https://files.pythonhosted.org/packages/16/bf/734cbd815d7bc94cffe35c934f4e08b619bf3b47df1c6c7af21c1d35bcfe/websockets-13.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63848cdb6fcc0bf09d4a155464c46c64ffdb5807ede4fb251da2c2692559ce75", size = 158741 }, + { url = "https://files.pythonhosted.org/packages/af/9b/756f89b12fee8931785531a314e6f087b21774a7f8c60878e597c684f91b/websockets-13.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:872afa52a9f4c414d6955c365b6588bc4401272c629ff8321a55f44e3f62b553", size = 157690 }, + { url = "https://files.pythonhosted.org/packages/d3/37/31f97132d2262e666b797e250879ca833eab55115f88043b3952a2840eb8/websockets-13.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05e70fec7c54aad4d71eae8e8cab50525e899791fc389ec6f77b95312e4e9920", size = 158132 }, + { url = "https://files.pythonhosted.org/packages/41/ce/59c8d44e148c002fec506a9527504fb4281676e2e75c2ee5a58180f1b99a/websockets-13.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e82db3756ccb66266504f5a3de05ac6b32f287faacff72462612120074103329", size = 158490 }, + { url = "https://files.pythonhosted.org/packages/1a/74/5b31ce0f318b902c0d70c031f8e1228ba1a4d95a46b2a24a2a5ac17f9cf0/websockets-13.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4e85f46ce287f5c52438bb3703d86162263afccf034a5ef13dbe4318e98d86e7", size = 157879 }, + { url = "https://files.pythonhosted.org/packages/0d/a7/6eac4f04177644bbc98deb98d11770cc7fbc216f6f67ab187c150540fd52/websockets-13.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f3fea72e4e6edb983908f0db373ae0732b275628901d909c382aae3b592589f2", size = 157873 }, + { url = "https://files.pythonhosted.org/packages/72/f6/b8b30a3b134dfdb4ccd1694befa48fddd43783957c988a1dab175732af33/websockets-13.0.1-cp313-cp313-win32.whl", hash = "sha256:254ecf35572fca01a9f789a1d0f543898e222f7b69ecd7d5381d8d8047627bdb", size = 151782 }, + { url = "https://files.pythonhosted.org/packages/3e/88/d94ccc006c69583168aa9dd73b3f1885c8931f2c676f4bdd8cbfae91c7b6/websockets-13.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:ca48914cdd9f2ccd94deab5bcb5ac98025a5ddce98881e5cce762854a5de330b", size = 152212 }, + { url = "https://files.pythonhosted.org/packages/ae/d8/9d0e5c836f89147aa769b72e2d82217ae1c17ffd5f375de8d785e1e16870/websockets-13.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:faef9ec6354fe4f9a2c0bbb52fb1ff852effc897e2a4501e25eb3a47cb0a4f89", size = 148629 }, + { url = "https://files.pythonhosted.org/packages/9c/ff/005a440db101d298b42cc7565579ed55a7e12ccc0c6ea0491e53bb073930/websockets-13.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:03d3f9ba172e0a53e37fa4e636b86cc60c3ab2cfee4935e66ed1d7acaa4625ad", size = 148863 }, + { url = "https://files.pythonhosted.org/packages/9f/06/44d7c7d48e0beaecbacaf0020eafccd490741e496622da6b2a5626fe6689/websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d450f5a7a35662a9b91a64aefa852f0c0308ee256122f5218a42f1d13577d71e", size = 150226 }, + { url = "https://files.pythonhosted.org/packages/48/6f/861ba99aa3c5cb54412c3870d5549e466d82d2f7c440b435e23ca6496865/websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f55b36d17ac50aa8a171b771e15fbe1561217510c8768af3d546f56c7576cdc", size = 149833 }, + { url = "https://files.pythonhosted.org/packages/8d/a0/9fb50648f69ed341e30096356a815c89c4f9daef24a32e9754dbdc3de8a8/websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14b9c006cac63772b31abbcd3e3abb6228233eec966bf062e89e7fa7ae0b7333", size = 149778 }, + { url = "https://files.pythonhosted.org/packages/f1/ba/48b5b8343e6f62a8a809ffe987d4d7c911cedcb1b8353f3da615f2609893/websockets-13.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b79915a1179a91f6c5f04ece1e592e2e8a6bd245a0e45d12fd56b2b59e559a32", size = 152259 }, + { url = "https://files.pythonhosted.org/packages/fd/bd/d34c4b7918453506d2149208b175368738148ffc4ba256d7fd8708956732/websockets-13.0.1-py3-none-any.whl", hash = "sha256:b80f0c51681c517604152eb6a572f5a9378f877763231fddb883ba2f968e8817", size = 145262 }, +] + +[[package]] +name = "yamllint" +version = "1.35.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pathspec" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/06/d8cee5c3dfd550cc0a466ead8b321138198485d1034130ac1393cc49d63e/yamllint-1.35.1.tar.gz", hash = "sha256:7a003809f88324fd2c877734f2d575ee7881dd9043360657cc8049c809eba6cd", size = 134583 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/28/2abf1ec14df2d584b9e7ce3b0be458838741e6aaff7a540374ba9af83916/yamllint-1.35.1-py3-none-any.whl", hash = "sha256:2e16e504bb129ff515b37823b472750b36b6de07963bd74b307341ef5ad8bdc3", size = 66738 }, +] + +[[package]] +name = "zipp" +version = "3.20.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/bf/5c0000c44ebc80123ecbdddba1f5dcd94a5ada602a9c225d84b5aaa55e86/zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29", size = 24199 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/8b/5ba542fa83c90e09eac972fc9baca7a88e7e7ca4b221a89251954019308b/zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", size = 9200 }, +]