From f05e4aaf92e5a41264168ef6a3b087480fab39fb Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Mon, 2 Sep 2024 09:34:28 +0200 Subject: [PATCH 01/19] ci: add uv based workflows --- .github/DOCS.md | 32 +++ .github/actions/setup-python-env/action.yml | 50 +++++ .github/codecov.yml | 21 ++ .github/dependabot.yml | 25 +++ .github/workflows/check.yml | 170 +++++++++++++++ .github/workflows/release.yml | 158 ++++++++++++++ .github/workflows/scheduled.yml | 102 +++++++++ .github/workflows/test.yml | 224 ++++++++++++++++++++ 8 files changed, 782 insertions(+) create mode 100644 .github/DOCS.md create mode 100644 .github/actions/setup-python-env/action.yml create mode 100644 .github/codecov.yml create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/check.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/scheduled.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/DOCS.md b/.github/DOCS.md new file mode 100644 index 0000000..1350254 --- /dev/null +++ b/.github/DOCS.md @@ -0,0 +1,32 @@ +# Github config and workflows + +In this folder there is configuration for codecoverage, dependabot and ci workflows. + +This folder can be merged using a `--allow-unrelated-histories` merge strategy from which provides a reasonably sensible base for writing your own ci on. By using this strategy the history of the CI repo is included in your repo, and future updates to the CI can be merged later. + +The workflows in this folder requires a root Makefile with a couple of targets defined. +As base can the Makefile in be used. + +## Publish + +The `publish`-step in [release.yml](./workflows/release.yml) is configured to use the GitHub environment `release`, create that or change to your preferred environment. +To publish to PyPI you must also configure your Pypi-project settings to use Trusted Publisher Management, by setting repo, workflow and environment on PyPI. + +To perform this merge run: + +```shell +git remote add ci git@github.com:spraakbanken/python-uv-ci-conf.git +git fetch ci +git merge --allow-unrelated-histories ci/main +``` + +or add the remote as `git remote add ci https://github.com/spraakbanken/python-uv-ci-conf.git` + +To later merge updates to this repo, just run: + +```shell +git fetch ci +get merge ci/main +``` + +This setup is inspired by . diff --git a/.github/actions/setup-python-env/action.yml b/.github/actions/setup-python-env/action.yml new file mode 100644 index 0000000..2329507 --- /dev/null +++ b/.github/actions/setup-python-env/action.yml @@ -0,0 +1,50 @@ +name: "setup-python-env" +description: "Composite action to setup the Python and rye environment." + +inputs: + cache-extra-key: + required: false + description: "Extra cache key to use" + default: "" + python-version: + required: false + description: "The python version to use" + default: "3.11" +outputs: + python-version: + description: "Python version used" + value: ${{ steps.set-python-version.outputs.python-version }} + +runs: + using: "composite" + steps: + - name: Setup Python + id: setup-python + uses: actions/setup-python@v5 + with: + python-version: ${{ inputs.python-version }} + + - name: Output python version + id: set-python-version + run: echo "python-version=${{ steps.setup-python.outputs.python-version }}" >> $GITHUB_OUTPUT + shell: bash + + - name: Load cached venv + id: cached-poetry-dependencies + uses: actions/cache@v3 + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.set-python-version.outputs.python-version }}-${{ inputs.cache-extra-key }}-${{ hashFiles('**/pyproject.toml') }} + + - name: Install dependencies + if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' + run: | + test -d .venv || python -m venv .venv + pip install wheel + pip install -r tests/requirements-testing.txt + pip install -e . + shell: bash + + - name: list .venv + run: ls -R .venv + shell: bash diff --git a/.github/codecov.yml b/.github/codecov.yml new file mode 100644 index 0000000..cd5ce8f --- /dev/null +++ b/.github/codecov.yml @@ -0,0 +1,21 @@ +# ref: https://docs.codecov.com/docs/codecovyml-reference +coverage: + # Hold ourselves to a high bar + range: 85..100 + round: down + precision: 1 + status: + # ref: https://docs.codecov.com/docs/commit-status + project: + default: + # Avoid false negatives + threshold: 1% + +# Test files aren't important for coverage +ignore: + - "tests" + +# Make comments less noisy +comment: + layout: "files" + require_changes: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..aa363d3 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "pip" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "daily" + ignore: + - dependency-name: "*" + # patch and minor updates don't matter for libraries as consumers of this library build + # with their own lockfile, rather than the version specified in this library's lockfile + # remove this ignore rule if your package has binaries to ensure that the binaries are + # built with the exact set of dependencies and those are up to date. + update-types: + - "version-update:semver-patch" + - "version-update:semver-minor" diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..431881b --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,170 @@ +name: check + +on: + push: + branches: + - main + pull_request: + merge_group: + +permissions: + contents: read + +env: + MINIMUM_PYTHON_VERSION: "3.8" + UV_VERSION: "0.3.5" + UV_CACHE_DIR: /tmp/.uv-cache + +# If new code is pushed to a PR branch, then cancel in progress workflows for that PR. Ensures that +# we don't waste CI time, and returns results quicker https://github.com/jonhoo/rust-ci-conf/pull/5 +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + fmt: + runs-on: ubuntu-latest + name: ubuntu / 3.8 / fmt + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up the python ${{ env.MINIMUM_PYTHON_VERSION }} + uses: actions/setup-python@v5 + id: setup-python + with: + python-version: ${{ env.MINIMUM_PYTHON_VERSION }} + + #---------------------------------------------- + # ----- setup uv and load cache ----- + #---------------------------------------------- + - name: Set up uv + run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + + - name: Restore uv cache + uses: actions/cache@v4 + with: + path: /tmp/.uv-cache + key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + restore-keys: | + uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + uv-${{ runner.os }} + + - name: Load cached venv + id: cached-venv + uses: actions/cache@v4 + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }}-${{ hashFiles('.github/workflows/check.yml') }} + + - name: Install dependencies + if: steps.cached-venv.outputs.cache-hit != 'true' + run: make install-dev + + - name: check formatting + run: make check-fmt + + - name: Minimize uv cache + run: uv cache prune --ci + lint: + runs-on: ubuntu-latest + name: ubuntu / 3.8 / lint + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Set up the python ${{ env.MINIMUM_PYTHON_VERSION }} + uses: actions/setup-python@v5 + id: setup-python + with: + python-version: ${{ env.MINIMUM_PYTHON_VERSION }} + + #---------------------------------------------- + # ----- setup uv and load cache ----- + #---------------------------------------------- + - name: Set up uv + run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + + - name: Restore uv cache + uses: actions/cache@v4 + with: + path: /tmp/.uv-cache + key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + restore-keys: | + uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + uv-${{ runner.os }} + + - name: Load cached venv + id: cached-venv + uses: actions/cache@v4 + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }}-${{ hashFiles('.github/workflows/check.yml') }} + - name: Install dependencies + if: steps.cached-venv.outputs.cache-hit != 'true' + run: make install-dev + - name: lint code + run: make lint + + - name: Minimize uv cache + run: uv cache prune --ci + + type-check: + runs-on: ubuntu-latest + name: ubuntu / 3.8 / type-check + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Set up the python ${{ env.MINIMUM_PYTHON_VERSION }} + uses: actions/setup-python@v5 + id: setup-python + with: + python-version: ${{ env.MINIMUM_PYTHON_VERSION }} + + #---------------------------------------------- + # ----- setup uv and load cache ----- + #---------------------------------------------- + - name: Set up uv + run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + + - name: Restore uv cache + uses: actions/cache@v4 + with: + path: /tmp/.uv-cache + key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + restore-keys: | + uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + uv-${{ runner.os }} + + - name: Load cached venv + id: cached-venv + uses: actions/cache@v4 + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }}-${{ hashFiles('.github/workflows/check.yml') }} + - name: Install dependencies + if: steps.cached-venv.outputs.cache-hit != 'true' + run: make install-dev + - name: type-check code + run: make type-check + + - name: Minimize uv cache + run: uv cache prune --ci + + # https://github.com/marketplace/actions/alls-green#why used for branch protection checks + check-check: + if: always() + needs: + - fmt + - lint + - type-check + runs-on: ubuntu-latest + permissions: {} + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} + allowed-failures: upload-coverage diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..11293a5 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,158 @@ +name: release + +on: + push: + branches: + - main + tags: + - "v[0-9]+.[0-9]+.[0-9]+" + pull_request: + merge_group: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true +permissions: + contents: read + +env: + MINIMUM_PYTHON_VERSION: "3.8" + UV_VERSION: "0.3.5" + UV_CACHE_DIR: /tmp/.uv-cache + +jobs: + build: + # This action builds distribution files for upload to PyPI + + name: ubuntu / 3.8 / build + runs-on: ubuntu-latest + steps: + #---------------------------------------------- + # check-out repo and set-up python + #---------------------------------------------- + - name: Check out repository + uses: actions/checkout@v4 + with: + submodules: true + + #---------------------------------------------- + # ----- setup python ----- + #---------------------------------------------- + - name: Set up the environment + uses: actions/setup-python@v5 + id: setup-python + with: + python-version: ${{ env.MINIMUM_PYTHON_VERSION }} + + #---------------------------------------------- + # ----- setup uv and load cache ----- + #---------------------------------------------- + - name: Set up uv + run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + + - name: Restore uv cache + uses: actions/cache@v4 + with: + path: /tmp/.uv-cache + key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + restore-keys: | + uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + uv-${{ runner.os }} + + #---------------------------------------------- + # ----- build distribution ----- + #---------------------------------------------- + - name: Build distribution + run: make build + + #---------------------------------------------- + # ----- upload artifacts ----- + #---------------------------------------------- + - uses: actions/upload-artifact@v4 + with: + name: pypi_files + path: dist + + - name: Minimize uv cache + run: uv cache prune --ci + + test-build: + # This action runs the test suite on the built artifact in the `build` action. + # The default is to run this in ubuntu, macos and windows + + name: ${{ matrix.os }} / 3.8 / test built artifact + needs: [build] + + strategy: + fail-fast: false + matrix: + os: + - ubuntu + - macos + - windows + + runs-on: ${{ matrix.os }}-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: set up python + uses: actions/setup-python@v5 + with: + python-version: ${{ env.MINIMUM_PYTHON_VERSION }} + + - name: get dist artifacts + uses: actions/download-artifact@v4 + with: + name: pypi_files + path: dist + + - run: rm -r + - run: pip install typing-extensions + - run: pip install -r tests/requirements-testing.lock + - run: pip install --no-index --no-deps --find-links dist --force-reinstall + - run: pytest + + # https://github.com/marketplace/actions/alls-green#why used for branch protection checks + release-check: + if: always() + needs: + - build + - test-build + runs-on: ubuntu-latest + permissions: {} + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} + # allowed-failures: coverage + + publish: + # This action publishes the built and tested artifact to PyPI, but only on a tag + + needs: + - test-build + if: success() && startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + environment: release + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up Python ${{ env.MINIMUM_PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.MINIMUM_PYTHON_VERSION }} + - name: get dist artifacts + uses: actions/download-artifact@v4 + with: + name: pypi_files + path: dist + + - name: Publish package to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml new file mode 100644 index 0000000..669634d --- /dev/null +++ b/.github/workflows/scheduled.yml @@ -0,0 +1,102 @@ +# Run scheduled (rolling) jobs on a nightly basis, as your crate may break independently of any +# given PR. E.g., updates to rust nightly and updates to this crates dependencies. See check.yml for +# information about how the concurrency cancellation and workflow triggering works +permissions: + contents: read + +on: + push: + branches: [main] + pull_request: + schedule: + - cron: "7 7 * * *" + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +name: rolling + +env: + MINIMUM_PYTHON_VERSION: "3.8" + UV_VERSION: "0.3.5" + UV_CACHE_DIR: /tmp/.uv-cache + +jobs: + # https://twitter.com/mycoliza/status/1571295690063753218 + nightly: + runs-on: ubuntu-latest + name: ubuntu / 3.13-dev + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Set up uv + run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + - name: Install python + uses: actions/setup-python@v5 + with: + python-version: "3.13-dev" + - name: Restore uv cache + uses: actions/cache@v4 + with: + path: /tmp/.uv-cache + key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + restore-keys: | + uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + uv-${{ runner.os }} + - run: python --version + - name: uv lock + if: hashFiles('uv.lock') == '' + run: uv lock + - name: uv sync --dev + run: uv sync --dev + - name: make test + run: make test + + - name: Minimize uv cache + run: uv cache prune --ci + # https://twitter.com/alcuadrado/status/1571291687837732873 + update: + # This action checks that updating the dependencies of this crate to the latest available that + # satisfy the versions in Cargo.toml does not break this crate. This is important as consumers + # of this crate will generally use the latest available crates. This is subject to the standard + # Cargo semver rules (i.e cargo does not update to a new major version unless explicitly told + # to). + runs-on: ubuntu-latest + name: ubuntu / 3.12 / updates work + # There's no point running this if no Cargo.lock was checked in in the first place, since we'd + # just redo what happened in the regular test job. Unfortunately, hashFiles only works in if on + # steps, so we repeat it. + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Set up uv + if: hashFiles('uv.lock') != '' + run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + - name: Install 3.12 + if: hashFiles('uv.lock') != '' + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Restore uv cache + uses: actions/cache@v4 + with: + path: /tmp/.uv-cache + key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + restore-keys: | + uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + uv-${{ runner.os }} + + - name: uv sync --dev --upgrade + if: hashFiles('uv.lock') != '' + run: uv sync --dev --upgrade + - name: make test + if: hashFiles('uv.lock') != '' + run: make test + + - name: Minimize uv cache + if: hashFiles('uv.lock') != '' + run: uv cache prune --ci diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..6ca58dd --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,224 @@ +name: test + +on: + push: + branches: + - main + pull_request: + merge_group: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read + +env: + MINIMUM_PYTHON_VERSION: "3.8" + UV_VERSION: "0.3.5" + UV_CACHE_DIR: /tmp/.uv-cache + +jobs: + coverage: + # This action runs tests for coverage collection and uploads them to codecov.io. + # This requires the secret `CODECOV_TOKEN` be set as secret on GitHub, both for + # Actions and Dependabot + + name: "${{ matrix.os }} / ${{ matrix.python-version }} / coverage" + strategy: + max-parallel: 4 + fail-fast: false + matrix: + os: [ubuntu] + python-version: + # remove the unused versions + - "3.8" + - "3.9" + - "3.10" + - "3.11" + - "3.12" + + runs-on: ${{ matrix.os }}-latest + env: + OS: ${{ matrix.os }}-latest + PYTHON: ${{ matrix.python-version }} + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up uv + run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + + - name: Set up Python ${{ matrix.python-version }} + id: setup-python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Restore uv cache + uses: actions/cache@v4 + with: + path: /tmp/.uv-cache + key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + restore-keys: | + uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + uv-${{ runner.os }} + + - name: Load cached venv + id: cached-venv + uses: actions/cache@v4 + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }}-${{ hashFiles('.github/workflows/test.yml') }} + + - name: Install dependencies + if: steps.cached-venv.outputs.cache-hit != 'true' + run: uv sync --all-extras --dev + + - name: Run tests for coverage + run: make test-w-coverage cov_report=xml + + - name: Minimize uv cache + run: uv cache prune --ci + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + # directory: ./coverage + env_vars: OS,PYTHON + fail_ci_if_error: true + # files: ./coverage/coverage.xml + # flags: unittests + # name: codecov-umbrella + verbose: true + + doctests: + # This action runs doctests for coverage collection and uploads them to codecov.io. + # This requires the secret `CODECOV_TOKEN` be set as secret on GitHub, both for + # Actions and Dependabot + + name: "${{ matrix.os }} / 3.8 / doctest" + strategy: + max-parallel: 4 + fail-fast: false + matrix: + os: [ubuntu] + + runs-on: ${{ matrix.os }}-latest + env: + OS: ${{ matrix.os }}-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up uv + run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + + - name: Set up Python ${{ matrix.python-version }} + id: setup-python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Restore uv cache + uses: actions/cache@v4 + with: + path: /tmp/.uv-cache + key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + restore-keys: | + uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + uv-${{ runner.os }} + + - name: Load cached venv + id: cached-venv + uses: actions/cache@v4 + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }}-${{ hashFiles('.github/workflows/test.yml') }} + + - name: Install dependencies + if: steps.cached-venv.outputs.cache-hit != 'true' + run: uv sync --all-extras --dev + #---------------------------------------------- + # Run tests and upload coverage + #---------------------------------------------- + - name: make doc-tests + run: make doc-tests cov_report=xml + + - name: Minimize uv cache + run: uv cache prune --ci + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + # directory: ./coverage + env_vars: OS,PYTHON,TESTTYPE + fail_ci_if_error: true + # files: ./coverage/coverage.xml + # flags: unittests + # name: codecov-umbrella + verbose: true + env: + PYTHON: ${{ env.MINIMUM_PYTHON_VERSION }} + TESTTYPE: doctest + + minimal: + # This action chooses the oldest version of the dependencies permitted by Cargo.toml to ensure + # that this crate is compatible with the minimal version that this crate and its dependencies + # require. This will pickup issues where this create relies on functionality that was introduced + # later than the actual version specified (e.g., when we choose just a major version, but a + # method was added after this version). + # + + runs-on: ubuntu-latest + name: ubuntu / 3.8 / minimal-versions + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Set up uv + run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + + - name: Set up Python ${{ matrix.python-version }} + id: setup-python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Restore uv cache + uses: actions/cache@v4 + with: + path: /tmp/.uv-cache + key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + restore-keys: | + uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + uv-${{ runner.os }} + + - name: install lowest direct dependencies + run: uv sync --resolution lowest-direct --all-extras --dev + + - name: make test + run: make test + + - name: Minimize uv cache + run: uv cache prune --ci + + # https://github.com/marketplace/actions/alls-green#why used for branch protection checks + test-check: + if: always() + needs: + - coverage + - doctests + - minimal + runs-on: ubuntu-latest + permissions: {} + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} From 1704d8925838d8f07628664f3585ca3b9d25abcc Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Mon, 2 Sep 2024 09:44:18 +0200 Subject: [PATCH 02/19] ci: use env namespace --- .github/workflows/check.yml | 6 +++--- .github/workflows/release.yml | 2 +- .github/workflows/scheduled.yml | 4 ++-- .github/workflows/test.yml | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 431881b..8e6109e 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -40,7 +40,7 @@ jobs: # ----- setup uv and load cache ----- #---------------------------------------------- - name: Set up uv - run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - name: Restore uv cache uses: actions/cache@v4 @@ -84,7 +84,7 @@ jobs: # ----- setup uv and load cache ----- #---------------------------------------------- - name: Set up uv - run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - name: Restore uv cache uses: actions/cache@v4 @@ -127,7 +127,7 @@ jobs: # ----- setup uv and load cache ----- #---------------------------------------------- - name: Set up uv - run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - name: Restore uv cache uses: actions/cache@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 11293a5..6fbc15b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,7 +48,7 @@ jobs: # ----- setup uv and load cache ----- #---------------------------------------------- - name: Set up uv - run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - name: Restore uv cache uses: actions/cache@v4 diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml index 669634d..a928820 100644 --- a/.github/workflows/scheduled.yml +++ b/.github/workflows/scheduled.yml @@ -32,7 +32,7 @@ jobs: with: submodules: true - name: Set up uv - run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - name: Install python uses: actions/setup-python@v5 with: @@ -74,7 +74,7 @@ jobs: submodules: true - name: Set up uv if: hashFiles('uv.lock') != '' - run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - name: Install 3.12 if: hashFiles('uv.lock') != '' uses: actions/setup-python@v5 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6ca58dd..a07a390 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -49,7 +49,7 @@ jobs: submodules: true - name: Set up uv - run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - name: Set up Python ${{ matrix.python-version }} id: setup-python @@ -116,7 +116,7 @@ jobs: submodules: true - name: Set up uv - run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - name: Set up Python ${{ matrix.python-version }} id: setup-python @@ -182,7 +182,7 @@ jobs: with: submodules: true - name: Set up uv - run: curl -LsSf https://astral.sh/uv/${{ UV_VERSION }}/install.sh | sh + run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - name: Set up Python ${{ matrix.python-version }} id: setup-python From 6ad6e5d22eea441d00bad4bb6d75d0723554c9fd Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Mon, 2 Sep 2024 10:31:40 +0200 Subject: [PATCH 03/19] chore: add uv based Makefile --- Makefile | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d944107 --- /dev/null +++ b/Makefile @@ -0,0 +1,168 @@ + +# use this Makefile as base in your project by running +# git remote add make https://github.com/spraakbanken/python-uv-make-conf +# git fetch make +# git merge --allow-unrelated-histories make/main +# +# To later update this makefile: +# git fetch make +# git merge make/main +# +.default: help + +.PHONY: help +help: + @echo "usage:" + @echo "dev | install-dev" + @echo " setup development environment" + @echo "install" + @echo " setup production environment" + @echo "" + @echo "info" + @echo " print info about the system and project" + @echo "" + @echo "test" + @echo " run all tests" + @echo "" + @echo "test-w-coverage [cov=] [cov_report=]" + @echo " run all tests with coverage collection. (Default: cov_report='term-missing', cov='--cov=${PROJECT_SRC}')" + @echo "" + @echo "lint" + @echo " lint the code" + @echo "" + @echo "lint-fix" + @echo " lint the code and try to fix it" + @echo "" + @echo "type-check" + @echo " check types" + @echo "" + @echo "fmt" + @echo " format the code" + @echo "" + @echo "check-fmt" + @echo " check that the code is formatted" + @echo "" + @echo "bumpversion [part=]" + @echo " bumps the given part of the version of the project. (Default: part='patch')" + @echo "" + @echo "bumpversion-show" + @echo " shows the bump path that is possible" + @echo "" + @echo "publish [branch=]" + @echo " pushes the given branch including tags to origin, for CI to publish based on tags. (Default: branch='main')" + @echo " Typically used after 'make bumpversion'" + @echo "" + @echo "prepare-release" + @echo " run tasks to prepare a release" + @echo "" + +PLATFORM := `uname -o` +REPO := "" +PROJECT_SRC := "" + +ifeq (${VIRTUAL_ENV},) + VENV_NAME = .venv + INVENV = uv run +else + VENV_NAME = ${VIRTUAL_ENV} + INVENV = +endif + +default_cov := "--cov=${PROJECT_SRC}" +cov_report := "term-missing" +cov := ${default_cov} + +all_tests := tests +tests := tests + +info: + @echo "Platform: ${PLATFORM}" + @echo "INVENV: '${INVENV}'" + +dev: install-dev + +# setup development environment +install-dev: + uv sync --dev + +# setup production environment +install: + uv sync --no-dev + +lock: uv.lock + +uv.lock: pyproject.toml + uv lock + +.PHONY: test +test: + ${INVENV} pytest -vv ${tests} + +.PHONY: test-w-coverage +# run all tests with coverage collection +test-w-coverage: + ${INVENV} pytest -vv ${cov} --cov-report=${cov_report} ${all_tests} + +.PHONY: doc-tests +doc-tests: + ${INVENV} pytest ${cov} --cov-report=${cov_report} --doctest-modules ${PROJECT_SRC} + +.PHONY: type-check +# check types +type-check: + ${INVENV} mypy ${PROJECT_SRC} ${tests} + +.PHONY: lint +# lint the code +lint: + ${INVENV} ruff check ${PROJECT_SRC} ${tests} + +.PHONY: lint-fix +# lint the code (and fix if possible) +lint-fix: + ${INVENV} ruff check --fix ${PROJECT_SRC} ${tests} + +part := "patch" +bumpversion: + ${INVENV} bump-my-version bump ${part} + +bumpversion-show: + ${INVENV} bump-my-version show-bump + +# run formatter(s) +fmt: + ${INVENV} ruff format ${PROJECT_SRC} ${tests} + +.PHONY: check-fmt +# check formatting +check-fmt: + ${INVENV} ruff format --check ${PROJECT_SRC} ${tests} + +build: + uvx --from build pyproject-build --installer uv + +branch := "main" +publish: + git push -u origin ${branch} --tags + + +.PHONY: prepare-release +prepare-release: update-changelog tests/requirements-testing.lock + +# we use lock extension so that dependabot doesn't pick up changes in this file +tests/requirements-testing.lock: pyproject.toml + uv pip compile $< --output-file $@ + +.PHONY: update-changelog +update-changelog: CHANGELOG.md + +.PHONY: CHANGELOG.md +CHANGELOG.md: + git cliff --unreleased --prepend $@ + +# update snapshots for `syrupy` +.PHONY: snapshot-update +snapshot-update: + ${INVENV} pytest --snapshot-update + +### === project targets below this line === From 0a9d5c1d44c524814ca152509e872393cc6042d3 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Mon, 2 Sep 2024 16:37:26 +0200 Subject: [PATCH 04/19] ci: remove unused actions --- .github/actions/setup-python-env/action.yml | 50 --------------------- 1 file changed, 50 deletions(-) delete mode 100644 .github/actions/setup-python-env/action.yml diff --git a/.github/actions/setup-python-env/action.yml b/.github/actions/setup-python-env/action.yml deleted file mode 100644 index 2329507..0000000 --- a/.github/actions/setup-python-env/action.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: "setup-python-env" -description: "Composite action to setup the Python and rye environment." - -inputs: - cache-extra-key: - required: false - description: "Extra cache key to use" - default: "" - python-version: - required: false - description: "The python version to use" - default: "3.11" -outputs: - python-version: - description: "Python version used" - value: ${{ steps.set-python-version.outputs.python-version }} - -runs: - using: "composite" - steps: - - name: Setup Python - id: setup-python - uses: actions/setup-python@v5 - with: - python-version: ${{ inputs.python-version }} - - - name: Output python version - id: set-python-version - run: echo "python-version=${{ steps.setup-python.outputs.python-version }}" >> $GITHUB_OUTPUT - shell: bash - - - name: Load cached venv - id: cached-poetry-dependencies - uses: actions/cache@v3 - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.set-python-version.outputs.python-version }}-${{ inputs.cache-extra-key }}-${{ hashFiles('**/pyproject.toml') }} - - - name: Install dependencies - if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' - run: | - test -d .venv || python -m venv .venv - pip install wheel - pip install -r tests/requirements-testing.txt - pip install -e . - shell: bash - - - name: list .venv - run: ls -R .venv - shell: bash From 15b3c7deb955d294c3bccaf8e953cc71304ddeef Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Mon, 16 Sep 2024 11:44:09 +0200 Subject: [PATCH 05/19] ci(test): fix python-version --- .github/workflows/test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a07a390..99f673c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -118,11 +118,11 @@ jobs: - name: Set up uv run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ env.MINIMUM_PYTHON_VERSION }} id: setup-python uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} + python-version: ${{ env.MINIMUM_PYTHON_VERSION }} - name: Restore uv cache uses: actions/cache@v4 @@ -184,11 +184,11 @@ jobs: - name: Set up uv run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ env.MINIMUM_PYTHON_VERSION }} id: setup-python uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} + python-version: ${{ env.MINIMUM_PYTHON_VERSION }} - name: Restore uv cache uses: actions/cache@v4 From cb56a6c737bc87752733c51d8cac237e9bf1fd02 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Fri, 4 Oct 2024 09:46:26 +0200 Subject: [PATCH 06/19] ci: bump uv to 0.4.18 --- .github/workflows/check.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/scheduled.yml | 2 +- .github/workflows/test.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 8e6109e..4d0b613 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -12,7 +12,7 @@ permissions: env: MINIMUM_PYTHON_VERSION: "3.8" - UV_VERSION: "0.3.5" + UV_VERSION: "0.4.18" UV_CACHE_DIR: /tmp/.uv-cache # If new code is pushed to a PR branch, then cancel in progress workflows for that PR. Ensures that diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6fbc15b..4d3b95f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ permissions: env: MINIMUM_PYTHON_VERSION: "3.8" - UV_VERSION: "0.3.5" + UV_VERSION: "0.4.18" UV_CACHE_DIR: /tmp/.uv-cache jobs: diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml index a928820..369dd87 100644 --- a/.github/workflows/scheduled.yml +++ b/.github/workflows/scheduled.yml @@ -19,7 +19,7 @@ name: rolling env: MINIMUM_PYTHON_VERSION: "3.8" - UV_VERSION: "0.3.5" + UV_VERSION: "0.4.18" UV_CACHE_DIR: /tmp/.uv-cache jobs: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 99f673c..36d5c87 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ permissions: env: MINIMUM_PYTHON_VERSION: "3.8" - UV_VERSION: "0.3.5" + UV_VERSION: "0.4.18" UV_CACHE_DIR: /tmp/.uv-cache jobs: From 2b55d174486c124f502929abf4fd4dbc442c0914 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Fri, 4 Oct 2024 09:48:57 +0200 Subject: [PATCH 07/19] ci: do not use hashes from workflow file --- .github/workflows/check.yml | 6 +++--- .github/workflows/test.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 4d0b613..0e3824e 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -56,7 +56,7 @@ jobs: uses: actions/cache@v4 with: path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }}-${{ hashFiles('.github/workflows/check.yml') }} + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }} - name: Install dependencies if: steps.cached-venv.outputs.cache-hit != 'true' @@ -100,7 +100,7 @@ jobs: uses: actions/cache@v4 with: path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }}-${{ hashFiles('.github/workflows/check.yml') }} + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }} - name: Install dependencies if: steps.cached-venv.outputs.cache-hit != 'true' run: make install-dev @@ -143,7 +143,7 @@ jobs: uses: actions/cache@v4 with: path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }}-${{ hashFiles('.github/workflows/check.yml') }} + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }} - name: Install dependencies if: steps.cached-venv.outputs.cache-hit != 'true' run: make install-dev diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 36d5c87..062706b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -71,7 +71,7 @@ jobs: uses: actions/cache@v4 with: path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }}-${{ hashFiles('.github/workflows/test.yml') }} + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }} - name: Install dependencies if: steps.cached-venv.outputs.cache-hit != 'true' @@ -138,7 +138,7 @@ jobs: uses: actions/cache@v4 with: path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }}-${{ hashFiles('.github/workflows/test.yml') }} + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/uv.lock') }} - name: Install dependencies if: steps.cached-venv.outputs.cache-hit != 'true' From 479cbf3386885d7c8d69b74eb512d855dec9470f Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Wed, 16 Oct 2024 09:15:35 +0200 Subject: [PATCH 08/19] ci: set python 3.9 as minimum version --- .github/workflows/check.yml | 8 ++++---- .github/workflows/release.yml | 6 +++--- .github/workflows/scheduled.yml | 1 - .github/workflows/test.yml | 7 +++---- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 0e3824e..f6bc7c3 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -11,7 +11,7 @@ permissions: contents: read env: - MINIMUM_PYTHON_VERSION: "3.8" + MINIMUM_PYTHON_VERSION: "3.9" UV_VERSION: "0.4.18" UV_CACHE_DIR: /tmp/.uv-cache @@ -24,7 +24,7 @@ concurrency: jobs: fmt: runs-on: ubuntu-latest - name: ubuntu / 3.8 / fmt + name: ubuntu / 3.9 / fmt steps: - uses: actions/checkout@v4 with: @@ -69,7 +69,7 @@ jobs: run: uv cache prune --ci lint: runs-on: ubuntu-latest - name: ubuntu / 3.8 / lint + name: ubuntu / 3.9 / lint steps: - uses: actions/checkout@v4 with: @@ -112,7 +112,7 @@ jobs: type-check: runs-on: ubuntu-latest - name: ubuntu / 3.8 / type-check + name: ubuntu / 3.9 / type-check steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4d3b95f..19310c0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ permissions: contents: read env: - MINIMUM_PYTHON_VERSION: "3.8" + MINIMUM_PYTHON_VERSION: "3.9" UV_VERSION: "0.4.18" UV_CACHE_DIR: /tmp/.uv-cache @@ -24,7 +24,7 @@ jobs: build: # This action builds distribution files for upload to PyPI - name: ubuntu / 3.8 / build + name: ubuntu / 3.9 / build runs-on: ubuntu-latest steps: #---------------------------------------------- @@ -80,7 +80,7 @@ jobs: # This action runs the test suite on the built artifact in the `build` action. # The default is to run this in ubuntu, macos and windows - name: ${{ matrix.os }} / 3.8 / test built artifact + name: ${{ matrix.os }} / 3.9 / test built artifact needs: [build] strategy: diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml index 369dd87..4b262f4 100644 --- a/.github/workflows/scheduled.yml +++ b/.github/workflows/scheduled.yml @@ -18,7 +18,6 @@ concurrency: name: rolling env: - MINIMUM_PYTHON_VERSION: "3.8" UV_VERSION: "0.4.18" UV_CACHE_DIR: /tmp/.uv-cache diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 062706b..a5a5805 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ permissions: contents: read env: - MINIMUM_PYTHON_VERSION: "3.8" + MINIMUM_PYTHON_VERSION: "3.9" UV_VERSION: "0.4.18" UV_CACHE_DIR: /tmp/.uv-cache @@ -33,7 +33,6 @@ jobs: os: [ubuntu] python-version: # remove the unused versions - - "3.8" - "3.9" - "3.10" - "3.11" @@ -100,7 +99,7 @@ jobs: # This requires the secret `CODECOV_TOKEN` be set as secret on GitHub, both for # Actions and Dependabot - name: "${{ matrix.os }} / 3.8 / doctest" + name: "${{ matrix.os }} / 3.9 / doctest" strategy: max-parallel: 4 fail-fast: false @@ -176,7 +175,7 @@ jobs: # runs-on: ubuntu-latest - name: ubuntu / 3.8 / minimal-versions + name: ubuntu / 3.9 / minimal-versions steps: - uses: actions/checkout@v4 with: From 3cae6a5afef90da0977c4ce33bb71cedf477ea13 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Wed, 16 Oct 2024 09:16:30 +0200 Subject: [PATCH 09/19] ci: also test for python 3.13 --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a5a5805..b276d4f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,6 +37,7 @@ jobs: - "3.10" - "3.11" - "3.12" + - "3.13" runs-on: ${{ matrix.os }}-latest env: From db04c029437a8eedb401000218bc304d2ccd0ad7 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Wed, 16 Oct 2024 09:16:54 +0200 Subject: [PATCH 10/19] ci: also test for python 3.14-dev --- .github/workflows/scheduled.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml index 4b262f4..1376cb7 100644 --- a/.github/workflows/scheduled.yml +++ b/.github/workflows/scheduled.yml @@ -25,7 +25,7 @@ jobs: # https://twitter.com/mycoliza/status/1571295690063753218 nightly: runs-on: ubuntu-latest - name: ubuntu / 3.13-dev + name: ubuntu / 3.14-dev steps: - uses: actions/checkout@v4 with: @@ -35,7 +35,7 @@ jobs: - name: Install python uses: actions/setup-python@v5 with: - python-version: "3.13-dev" + python-version: "3.14-dev" - name: Restore uv cache uses: actions/cache@v4 with: From f191bf8acde2141e11dd80dbab0bdfd1ceb67d89 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Tue, 22 Oct 2024 12:50:08 +0200 Subject: [PATCH 11/19] chore: remove old makefile and CI --- .github/DOCS.md | 32 -- .github/codecov.yml | 21 - .github/dependabot.yml | 25 -- .github/workflows/check.yml | 111 ----- .github/workflows/release.yml | 138 ------- .github/workflows/scheduled.yml | 51 --- .github/workflows/test.yml | 180 -------- Makefile | 166 -------- pdm.lock | 707 -------------------------------- 9 files changed, 1431 deletions(-) delete mode 100644 .github/DOCS.md delete mode 100644 .github/codecov.yml delete mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/check.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/scheduled.yml delete mode 100644 .github/workflows/test.yml delete mode 100644 Makefile delete mode 100644 pdm.lock diff --git a/.github/DOCS.md b/.github/DOCS.md deleted file mode 100644 index c740c32..0000000 --- a/.github/DOCS.md +++ /dev/null @@ -1,32 +0,0 @@ -# Github config and workflows - -In this folder there is configuration for codecoverage, dependabot and ci workflows. - -This folder can be merged using a `--allow-unrelated-histories` merge strategy from which provides a reasonably sensible base for writing your own ci on. By using this strategy the history of the CI repo is included in your repo, and future updates to the CI can be merged later. - -The workflows in this folder requires a root Makefile with a couple of targets defined. -As base can the Makefile in be used. - -## Publish - -The `publish`-step in [test.yml](./workflows/test.yml) is configured to use the GitHub environment `release`, create that or change to your preferred environment. -To publish to PyPI you must also configure your Pypi-project settings to use Trusted Publisher Management, by setting repo, workflow and environment on PyPI. - -To perform this merge run: - -```shell -git remote add ci git@github.com:spraakbanken/python-pdm-ci-conf.git -git fetch ci -git merge --allow-unrelated-histories ci/main -``` - -or add the remote as `git remote add ci https://github.com/spraakbanken/python-pdm-ci-conf.git` - -To later merge updates to this repo, just run: - -```shell -git fetch ci -get merge ci/main -``` - -This setup is inspired by . diff --git a/.github/codecov.yml b/.github/codecov.yml deleted file mode 100644 index cd5ce8f..0000000 --- a/.github/codecov.yml +++ /dev/null @@ -1,21 +0,0 @@ -# ref: https://docs.codecov.com/docs/codecovyml-reference -coverage: - # Hold ourselves to a high bar - range: 85..100 - round: down - precision: 1 - status: - # ref: https://docs.codecov.com/docs/commit-status - project: - default: - # Avoid false negatives - threshold: 1% - -# Test files aren't important for coverage -ignore: - - "tests" - -# Make comments less noisy -comment: - layout: "files" - require_changes: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index aa363d3..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,25 +0,0 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: - # Maintain dependencies for GitHub Actions - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - - package-ecosystem: "pip" # See documentation for possible values - directory: "/" # Location of package manifests - schedule: - interval: "daily" - ignore: - - dependency-name: "*" - # patch and minor updates don't matter for libraries as consumers of this library build - # with their own lockfile, rather than the version specified in this library's lockfile - # remove this ignore rule if your package has binaries to ensure that the binaries are - # built with the exact set of dependencies and those are up to date. - update-types: - - "version-update:semver-patch" - - "version-update:semver-minor" diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml deleted file mode 100644 index e9cb537..0000000 --- a/.github/workflows/check.yml +++ /dev/null @@ -1,111 +0,0 @@ -name: check - -on: - push: - branches: - - main - pull_request: - merge_group: - -permissions: - contents: read - -env: - MINIMUM_PYTHON_VERSION: "3.8" - -# If new code is pushed to a PR branch, then cancel in progress workflows for that PR. Ensures that -# we don't waste CI time, and returns results quicker https://github.com/jonhoo/rust-ci-conf/pull/5 -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - fmt: - runs-on: ubuntu-latest - name: ubuntu / 3.8 / fmt - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - - name: Set up the python ${{ env.MINIMUM_PYTHON_VERSION }} - uses: pdm-project/setup-pdm@v4 - id: setup-python - with: - python-version: ${{ env.MINIMUM_PYTHON_VERSION }} - - - name: Load cached venv - id: cached-venv - uses: actions/cache@v4 - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/pdm.lock') }}-${{ hashFiles('.github/workflows/check.yml') }} - - - name: Install dependencies - if: steps.cached-venv.outputs.cache-hit != 'true' - run: make install-dev - - - name: check formatting - run: make check-fmt - lint: - runs-on: ubuntu-latest - name: ubuntu / 3.8 / lint - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - name: Set up the python ${{ env.MINIMUM_PYTHON_VERSION }} - uses: pdm-project/setup-pdm@v4 - id: setup-python - with: - python-version: ${{ env.MINIMUM_PYTHON_VERSION }} - - name: Load cached venv - id: cached-venv - uses: actions/cache@v4 - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/pdm.lock') }}-${{ hashFiles('.github/workflows/check.yml') }} - - name: Install dependencies - if: steps.cached-venv.outputs.cache-hit != 'true' - run: make install-dev - - name: lint code - run: make lint - type-check: - runs-on: ubuntu-latest - name: ubuntu / 3.8 / type-check - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - name: Set up the python ${{ env.MINIMUM_PYTHON_VERSION }} - uses: pdm-project/setup-pdm@v4 - id: setup-python - with: - python-version: ${{ env.MINIMUM_PYTHON_VERSION }} - - name: Load cached venv - id: cached-venv - uses: actions/cache@v4 - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/pdm.lock') }}-${{ hashFiles('.github/workflows/check.yml') }} - - name: Install dependencies - if: steps.cached-venv.outputs.cache-hit != 'true' - run: make install-dev - - name: type-check code - run: make type-check - - # https://github.com/marketplace/actions/alls-green#why used for branch protection checks - check-check: - if: always() - needs: - - fmt - - lint - - type-check - runs-on: ubuntu-latest - permissions: {} - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} - allowed-failures: upload-coverage diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index e37fb25..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,138 +0,0 @@ -name: release - -on: - push: - branches: - - main - tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - pull_request: - merge_group: - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true -permissions: - contents: read - -env: - MINIMUM_PYTHON_VERSION: "3.8" - -jobs: - build: - # This action builds distribution files for upload to PyPI - - name: ubuntu / 3.8 / build - runs-on: ubuntu-latest - steps: - #---------------------------------------------- - # check-out repo and set-up python - #---------------------------------------------- - - name: Check out repository - uses: actions/checkout@v4 - with: - submodules: true - - #---------------------------------------------- - # ----- setup python ----- - #---------------------------------------------- - - name: Set up the environment - uses: pdm-project/setup-pdm@v4 - id: setup-python - with: - python-version: ${{ env.MINIMUM_PYTHON_VERSION }} - - #---------------------------------------------- - # ----- build distribution ----- - #---------------------------------------------- - - name: Build distribution - run: make build - - #---------------------------------------------- - # ----- upload artifacts ----- - #---------------------------------------------- - - uses: actions/upload-artifact@v4 - with: - name: pypi_files - path: dist - - test-build: - # This action runs the test suite on the built artifact in the `build` action. - # The default is to run this in ubuntu, macos and windows - - name: ${{ matrix.os }} / 3.8 / test built artifact - needs: [build] - - strategy: - fail-fast: false - matrix: - os: - - ubuntu - - macos - - windows - - runs-on: ${{ matrix.os }}-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - - name: set up python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.MINIMUM_PYTHON_VERSION }} - - - name: get dist artifacts - uses: actions/download-artifact@v4 - with: - name: pypi_files - path: dist - - - run: rm -r src/parallel_corpus - - run: pip install typing-extensions - - run: pip install -r tests/requirements-testing.lock - - run: pip install parallel-corpus --no-index --no-deps --find-links dist --force-reinstall - - run: pytest - - # https://github.com/marketplace/actions/alls-green#why used for branch protection checks - release-check: - if: always() - needs: - - build - - test-build - runs-on: ubuntu-latest - permissions: {} - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} - # allowed-failures: coverage - - publish: - # This action publishes the built and tested artifact to PyPI, but only on a tag - - needs: - - test-build - if: success() && startsWith(github.ref, 'refs/tags/v') - runs-on: ubuntu-latest - environment: release - permissions: - # IMPORTANT: this permission is mandatory for trusted publishing - id-token: write - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set up Python ${{ env.MINIMUM_PYTHON_VERSION }} - uses: actions/setup-python@v5 - with: - python-version: ${{ env.MINIMUM_PYTHON_VERSION }} - - name: get dist artifacts - uses: actions/download-artifact@v4 - with: - name: pypi_files - path: dist - - - name: Publish package to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml deleted file mode 100644 index 1a1b986..0000000 --- a/.github/workflows/scheduled.yml +++ /dev/null @@ -1,51 +0,0 @@ -# Run scheduled (rolling) jobs on a nightly basis, as your crate may break independently of any -# given PR. E.g., updates to rust nightly and updates to this crates dependencies. See check.yml for -# information about how the concurrency cancellation and workflow triggering works -permissions: - contents: read - -on: - push: - branches: [main] - pull_request: - schedule: - - cron: '7 7 * * *' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -name: rolling - -jobs: - - # https://twitter.com/alcuadrado/status/1571291687837732873 - update: - # This action checks that updating the dependencies of this crate to the latest available that - # satisfy the versions in Cargo.toml does not break this crate. This is important as consumers - # of this crate will generally use the latest available crates. This is subject to the standard - # Cargo semver rules (i.e cargo does not update to a new major version unless explicitly told - # to). - runs-on: ubuntu-latest - name: ubuntu / 3.12 / updates work - # There's no point running this if no Cargo.lock was checked in in the first place, since we'd - # just redo what happened in the regular test job. Unfortunately, hashFiles only works in if on - # steps, so we repeat it. - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - name: Install 3.12 - if: hashFiles('pdm.lock') != '' - uses: pdm-project/setup-pdm@v4 - with: - python-version: "3.12" - - name: pdm update - if: hashFiles('pdm.lock') != '' - run: pdm update - - name: pdm sync --dev - if: hashFiles('pdm.lock') != '' - run: pdm sync --dev - - name: make test - if: hashFiles('pdm.lock') != '' - run: make test diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 1a9978d..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,180 +0,0 @@ -name: test - -on: - push: - branches: - - main - pull_request: - merge_group: - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -permissions: - contents: read - -env: - MINIMUM_PYTHON_VERSION: "3.8" - -jobs: - - coverage: - # This action runs tests for coverage collection and uploads them to codecov.io. - # This requires the secret `CODECOV_TOKEN` be set as secret on GitHub, both for - # Actions and Dependabot - - name: "${{ matrix.os }} / ${{ matrix.python-version }} / coverage" - strategy: - max-parallel: 4 - fail-fast: false - matrix: - os: [ubuntu] - python-version: - # remove the unused versions - - "3.8" - - "3.9" - - "3.10" - - "3.11" - - "3.12" - - runs-on: ${{ matrix.os }}-latest - env: - OS: ${{ matrix.os }}-latest - PYTHON: ${{ matrix.python-version }} - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - - name: Set up the environment - uses: pdm-project/setup-pdm@v4 - id: setup-python - with: - python-version: ${{ matrix.python-version }} - - - name: Load cached venv - id: cached-venv - uses: actions/cache@v4 - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/pdm.lock') }}-${{ hashFiles('.github/workflows/test.yml') }} - - - name: Install dependencies - if: steps.cached-venv.outputs.cache-hit != 'true' - run: make install-dev - - - name: Run tests for coverage - run: make test-w-coverage cov_report=xml - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - # directory: ./coverage - env_vars: OS,PYTHON - fail_ci_if_error: true - # files: ./coverage/coverage.xml - # flags: unittests - # name: codecov-umbrella - verbose: true - - doctests: - # This action runs doctests for coverage collection and uploads them to codecov.io. - # This requires the secret `CODECOV_TOKEN` be set as secret on GitHub, both for - # Actions and Dependabot - - name: "${{ matrix.os }} / 3.8 / doctest" - strategy: - max-parallel: 4 - fail-fast: false - matrix: - os: [ubuntu] - - runs-on: ${{ matrix.os }}-latest - env: - OS: ${{ matrix.os }}-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - - name: Set up the environment - uses: pdm-project/setup-pdm@v4 - id: setup-python - with: - python-version: ${{ env.MINIMUM_PYTHON_VERSION }} - - - name: Load cached venv - id: cached-venv - uses: actions/cache@v4 - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/pdm.lock') }}-${{ hashFiles('.github/workflows/test.yml') }} - - - name: Install dependencies - if: steps.cached-venv.outputs.cache-hit != 'true' - run: make install-dev - #---------------------------------------------- - # Run tests and upload coverage - #---------------------------------------------- - - name: make doc-tests - run: make doc-tests cov_report=xml - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - # directory: ./coverage - env_vars: OS,PYTHON,TESTTYPE - fail_ci_if_error: true - # files: ./coverage/coverage.xml - # flags: unittests - # name: codecov-umbrella - verbose: true - env: - PYTHON: ${{ env.MINIMUM_PYTHON_VERSION }} - TESTTYPE: doctest - - minimal: - # This action chooses the oldest version of the dependencies permitted by Cargo.toml to ensure - # that this crate is compatible with the minimal version that this crate and its dependencies - # require. This will pickup issues where this create relies on functionality that was introduced - # later than the actual version specified (e.g., when we choose just a major version, but a - # method was added after this version). - # - - runs-on: ubuntu-latest - name: ubuntu / 3.8 / minimal-versions - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - name: Set up the environment - uses: pdm-project/setup-pdm@v4 - id: setup-python - with: - python-version: ${{ env.MINIMUM_PYTHON_VERSION }} - - - name: pdm lock --strategy direct_minimal_versions - run: pdm lock --strategy direct_minimal_versions - - name: pdm sync --dev - run: pdm sync --dev - - name: make test - run: make test - - # https://github.com/marketplace/actions/alls-green#why used for branch protection checks - test-check: - if: always() - needs: - - coverage - - doctests - - minimal - runs-on: ubuntu-latest - permissions: {} - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} - diff --git a/Makefile b/Makefile deleted file mode 100644 index 925e691..0000000 --- a/Makefile +++ /dev/null @@ -1,166 +0,0 @@ - -# use this Makefile as base in your project by running -# git remote add make https://github.com/spraakbanken/python-pdm-make-conf -# git fetch make -# git merge --allow-unrelated-histories make/main -# -# To later update this makefile: -# git fetch make -# git merge make/main -# -.default: help - -.PHONY: help -help: - @echo "usage:" - @echo "dev | install-dev" - @echo " setup development environment" - @echo "install" - @echo " setup production environment" - @echo "" - @echo "info" - @echo " print info about the system and project" - @echo "" - @echo "test" - @echo " run all tests" - @echo "" - @echo "test-w-coverage [cov=] [cov_report=]" - @echo " run all tests with coverage collection. (Default: cov_report='term-missing', cov='--cov=${PROJECT_SRC}')" - @echo "" - @echo "lint" - @echo " lint the code" - @echo "" - @echo "lint-fix" - @echo " lint the code and try to fix it" - @echo "" - @echo "type-check" - @echo " check types" - @echo "" - @echo "fmt" - @echo " format the code" - @echo "" - @echo "check-fmt" - @echo " check that the code is formatted" - @echo "" - @echo "bumpversion [part=]" - @echo " bumps the given part of the version of the project. (Default: part='patch')" - @echo "" - @echo "bumpversion-show" - @echo " shows the bump path that is possible" - @echo "" - @echo "publish [branch=]" - @echo " pushes the given branch including tags to origin, for CI to publish based on tags. (Default: branch='main')" - @echo " Typically used after 'make bumpversion'" - @echo "" - @echo "prepare-release" - @echo " run tasks to prepare a release" - @echo "" - -PLATFORM := `uname -o` -REPO := "graph-py" -PROJECT_SRC := "src/parallel_corpus" - -ifeq (${VIRTUAL_ENV},) - VENV_NAME = .venv - INVENV = pdm run -else - VENV_NAME = ${VIRTUAL_ENV} - INVENV = -endif - -default_cov := "--cov=${PROJECT_SRC}" -cov_report := "term-missing" -cov := ${default_cov} - -all_tests := tests -tests := tests - -info: - @echo "Platform: ${PLATFORM}" - @echo "INVENV: '${INVENV}'" - -dev: install-dev - -# setup development environment -install-dev: - pdm install --dev - -# setup production environment -install: - pdm sync --prod - -lock: pdm.lock - -pdm.lock: pyproject.toml - pdm lock - -.PHONY: test -test: - ${INVENV} pytest -vv ${tests} - -.PHONY: test-w-coverage -# run all tests with coverage collection -test-w-coverage: - ${INVENV} pytest -vv ${cov} --cov-report=${cov_report} ${all_tests} - -.PHONY: doc-tests -doc-tests: - ${INVENV} pytest ${cov} --cov-report=${cov_report} --doctest-modules ${PROJECT_SRC} - -.PHONY: type-check -# check types -type-check: - ${INVENV} mypy ${PROJECT_SRC} ${tests} - -.PHONY: lint -# lint the code -lint: - ${INVENV} ruff check ${PROJECT_SRC} ${tests} - -.PHONY: lint-fix -# lint the code (and fix if possible) -lint-fix: - ${INVENV} ruff check --fix ${PROJECT_SRC} ${tests} - -part := "patch" -bumpversion: - ${INVENV} bump-my-version bump ${part} - -bumpversion-show: - ${INVENV} bump-my-version show-bump - -# run formatter(s) -fmt: - ${INVENV} ruff format ${PROJECT_SRC} ${tests} - -.PHONY: check-fmt -# check formatting -check-fmt: - ${INVENV} ruff format --check ${PROJECT_SRC} ${tests} - -build: - pdm build - -branch := "main" -publish: - git push -u origin ${branch} --tags - - -.PHONY: prepare-release -prepare-release: update-changelog tests/requirements-testing.lock - -# we use lock extension so that dependabot doesn't pick up changes in this file -tests/requirements-testing.lock: pyproject.toml pdm.lock - pdm export --dev --format requirements --output $@ - -.PHONY: update-changelog -update-changelog: CHANGELOG.md - -.PHONY: CHANGELOG.md -CHANGELOG.md: - git cliff --unreleased --prepend $@ - -# update snapshots for `syrupy` -.PHONY: snapshot-update -snapshot-update: - ${INVENV} pytest --snapshot-update \ No newline at end of file diff --git a/pdm.lock b/pdm.lock deleted file mode 100644 index de4fa46..0000000 --- a/pdm.lock +++ /dev/null @@ -1,707 +0,0 @@ -# This file is @generated by PDM. -# It is not intended for manual editing. - -[metadata] -groups = ["default", "dev"] -strategy = ["cross_platform", "inherit_metadata"] -lock_version = "4.4.1" -content_hash = "sha256:e3c3f07151017328f7b873bbafbd868ed8d5dac1e8672d635add52307d93dcde" - -[[package]] -name = "annotated-types" -version = "0.6.0" -requires_python = ">=3.8" -summary = "Reusable constraint types to use with typing.Annotated" -groups = ["dev"] -dependencies = [ - "typing-extensions>=4.0.0; python_version < \"3.9\"", -] -files = [ - {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, - {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, -] - -[[package]] -name = "bracex" -version = "2.4" -requires_python = ">=3.8" -summary = "Bash style brace expander." -groups = ["dev"] -files = [ - {file = "bracex-2.4-py3-none-any.whl", hash = "sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418"}, - {file = "bracex-2.4.tar.gz", hash = "sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb"}, -] - -[[package]] -name = "bump-my-version" -version = "0.21.0" -requires_python = ">=3.8" -summary = "Version bump your Python project" -groups = ["dev"] -dependencies = [ - "click", - "pydantic-settings", - "pydantic>=2.0.0", - "questionary", - "rich", - "rich-click", - "tomlkit", - "wcmatch>=8.5.1", -] -files = [ - {file = "bump_my_version-0.21.0-py3-none-any.whl", hash = "sha256:a614d8176b5ac0e644239c9a8a246b696d316f68406fd78b8486a9e13fc93266"}, - {file = "bump_my_version-0.21.0.tar.gz", hash = "sha256:c3f1a31e32345679b517cbba99a0875457ee45d7ba6189fcd2a74d3ddae41515"}, -] - -[[package]] -name = "click" -version = "8.1.7" -requires_python = ">=3.7" -summary = "Composable command line interface toolkit" -groups = ["dev"] -dependencies = [ - "colorama; platform_system == \"Windows\"", -] -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -summary = "Cross-platform colored terminal text." -groups = ["dev"] -marker = "sys_platform == \"win32\" or platform_system == \"Windows\"" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "colored" -version = "1.4.4" -summary = "Simple library for color and formatting to terminal" -groups = ["dev"] -files = [ - {file = "colored-1.4.4.tar.gz", hash = "sha256:04ff4d4dd514274fe3b99a21bb52fb96f2688c01e93fba7bef37221e7cb56ce0"}, -] - -[[package]] -name = "coverage" -version = "7.5.1" -requires_python = ">=3.8" -summary = "Code coverage measurement for Python" -groups = ["dev"] -files = [ - {file = "coverage-7.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e"}, - {file = "coverage-7.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146"}, - {file = "coverage-7.5.1-cp310-cp310-win32.whl", hash = "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228"}, - {file = "coverage-7.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8"}, - {file = "coverage-7.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428"}, - {file = "coverage-7.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987"}, - {file = "coverage-7.5.1-cp311-cp311-win32.whl", hash = "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136"}, - {file = "coverage-7.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd"}, - {file = "coverage-7.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206"}, - {file = "coverage-7.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7"}, - {file = "coverage-7.5.1-cp312-cp312-win32.whl", hash = "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19"}, - {file = "coverage-7.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596"}, - {file = "coverage-7.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7"}, - {file = "coverage-7.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d"}, - {file = "coverage-7.5.1-cp38-cp38-win32.whl", hash = "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41"}, - {file = "coverage-7.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de"}, - {file = "coverage-7.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1"}, - {file = "coverage-7.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668"}, - {file = "coverage-7.5.1-cp39-cp39-win32.whl", hash = "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981"}, - {file = "coverage-7.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f"}, - {file = "coverage-7.5.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312"}, - {file = "coverage-7.5.1.tar.gz", hash = "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c"}, -] - -[[package]] -name = "coverage" -version = "7.5.1" -extras = ["toml"] -requires_python = ">=3.8" -summary = "Code coverage measurement for Python" -groups = ["dev"] -dependencies = [ - "coverage==7.5.1", - "tomli; python_full_version <= \"3.11.0a6\"", -] -files = [ - {file = "coverage-7.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e"}, - {file = "coverage-7.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146"}, - {file = "coverage-7.5.1-cp310-cp310-win32.whl", hash = "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228"}, - {file = "coverage-7.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8"}, - {file = "coverage-7.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428"}, - {file = "coverage-7.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987"}, - {file = "coverage-7.5.1-cp311-cp311-win32.whl", hash = "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136"}, - {file = "coverage-7.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd"}, - {file = "coverage-7.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206"}, - {file = "coverage-7.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7"}, - {file = "coverage-7.5.1-cp312-cp312-win32.whl", hash = "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19"}, - {file = "coverage-7.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596"}, - {file = "coverage-7.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7"}, - {file = "coverage-7.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d"}, - {file = "coverage-7.5.1-cp38-cp38-win32.whl", hash = "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41"}, - {file = "coverage-7.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de"}, - {file = "coverage-7.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1"}, - {file = "coverage-7.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668"}, - {file = "coverage-7.5.1-cp39-cp39-win32.whl", hash = "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981"}, - {file = "coverage-7.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f"}, - {file = "coverage-7.5.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312"}, - {file = "coverage-7.5.1.tar.gz", hash = "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c"}, -] - -[[package]] -name = "diff-match-patch" -version = "20230430" -requires_python = ">=3.7" -summary = "Diff Match and Patch" -groups = ["default"] -files = [ - {file = "diff-match-patch-20230430.tar.gz", hash = "sha256:953019cdb9c9d2c9e47b5b12bcff3cf4746fc4598eb406076fa1fc27e6a1f15c"}, - {file = "diff_match_patch-20230430-py3-none-any.whl", hash = "sha256:dce43505fb7b1b317de7195579388df0746d90db07015ed47a85e5e44930ef93"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.1" -requires_python = ">=3.7" -summary = "Backport of PEP 654 (exception groups)" -groups = ["dev"] -marker = "python_version < \"3.11\"" -files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, -] - -[[package]] -name = "iniconfig" -version = "2.0.0" -requires_python = ">=3.7" -summary = "brain-dead simple config-ini parsing" -groups = ["dev"] -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "markdown-it-py" -version = "3.0.0" -requires_python = ">=3.8" -summary = "Python port of markdown-it. Markdown parsing, done right!" -groups = ["dev"] -dependencies = [ - "mdurl~=0.1", -] -files = [ - {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, - {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, -] - -[[package]] -name = "mdurl" -version = "0.1.2" -requires_python = ">=3.7" -summary = "Markdown URL utilities" -groups = ["dev"] -files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] - -[[package]] -name = "more-itertools" -version = "10.2.0" -requires_python = ">=3.8" -summary = "More routines for operating on iterables, beyond itertools" -groups = ["default"] -files = [ - {file = "more-itertools-10.2.0.tar.gz", hash = "sha256:8fccb480c43d3e99a00087634c06dd02b0d50fbf088b380de5a41a015ec239e1"}, - {file = "more_itertools-10.2.0-py3-none-any.whl", hash = "sha256:686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684"}, -] - -[[package]] -name = "mypy" -version = "1.10.0" -requires_python = ">=3.8" -summary = "Optional static typing for Python" -groups = ["dev"] -dependencies = [ - "mypy-extensions>=1.0.0", - "tomli>=1.1.0; python_version < \"3.11\"", - "typing-extensions>=4.1.0", -] -files = [ - {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, - {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, - {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, - {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, - {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, - {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, - {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, - {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, - {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, - {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, - {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, - {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, - {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, - {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, - {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, - {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, - {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, - {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, - {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, -] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -requires_python = ">=3.5" -summary = "Type system extensions for programs checked with the mypy type checker." -groups = ["dev"] -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "packaging" -version = "24.0" -requires_python = ">=3.7" -summary = "Core utilities for Python packages" -groups = ["dev"] -files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, -] - -[[package]] -name = "pluggy" -version = "1.5.0" -requires_python = ">=3.8" -summary = "plugin and hook calling mechanisms for python" -groups = ["dev"] -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[[package]] -name = "prompt-toolkit" -version = "3.0.36" -requires_python = ">=3.6.2" -summary = "Library for building powerful interactive command lines in Python" -groups = ["dev"] -dependencies = [ - "wcwidth", -] -files = [ - {file = "prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305"}, - {file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"}, -] - -[[package]] -name = "pydantic" -version = "2.7.1" -requires_python = ">=3.8" -summary = "Data validation using Python type hints" -groups = ["dev"] -dependencies = [ - "annotated-types>=0.4.0", - "pydantic-core==2.18.2", - "typing-extensions>=4.6.1", -] -files = [ - {file = "pydantic-2.7.1-py3-none-any.whl", hash = "sha256:e029badca45266732a9a79898a15ae2e8b14840b1eabbb25844be28f0b33f3d5"}, - {file = "pydantic-2.7.1.tar.gz", hash = "sha256:e9dbb5eada8abe4d9ae5f46b9939aead650cd2b68f249bb3a8139dbe125803cc"}, -] - -[[package]] -name = "pydantic-core" -version = "2.18.2" -requires_python = ">=3.8" -summary = "Core functionality for Pydantic validation and serialization" -groups = ["dev"] -dependencies = [ - "typing-extensions!=4.7.0,>=4.6.0", -] -files = [ - {file = "pydantic_core-2.18.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9e08e867b306f525802df7cd16c44ff5ebbe747ff0ca6cf3fde7f36c05a59a81"}, - {file = "pydantic_core-2.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f0a21cbaa69900cbe1a2e7cad2aa74ac3cf21b10c3efb0fa0b80305274c0e8a2"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0680b1f1f11fda801397de52c36ce38ef1c1dc841a0927a94f226dea29c3ae3d"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95b9d5e72481d3780ba3442eac863eae92ae43a5f3adb5b4d0a1de89d42bb250"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fcf5cd9c4b655ad666ca332b9a081112cd7a58a8b5a6ca7a3104bc950f2038"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b5155ff768083cb1d62f3e143b49a8a3432e6789a3abee8acd005c3c7af1c74"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:553ef617b6836fc7e4df130bb851e32fe357ce36336d897fd6646d6058d980af"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89ed9eb7d616ef5714e5590e6cf7f23b02d0d539767d33561e3675d6f9e3857"}, - {file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:75f7e9488238e920ab6204399ded280dc4c307d034f3924cd7f90a38b1829563"}, - {file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ef26c9e94a8c04a1b2924149a9cb081836913818e55681722d7f29af88fe7b38"}, - {file = "pydantic_core-2.18.2-cp310-none-win32.whl", hash = "sha256:182245ff6b0039e82b6bb585ed55a64d7c81c560715d1bad0cbad6dfa07b4027"}, - {file = "pydantic_core-2.18.2-cp310-none-win_amd64.whl", hash = "sha256:e23ec367a948b6d812301afc1b13f8094ab7b2c280af66ef450efc357d2ae543"}, - {file = "pydantic_core-2.18.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:219da3f096d50a157f33645a1cf31c0ad1fe829a92181dd1311022f986e5fbe3"}, - {file = "pydantic_core-2.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cc1cfd88a64e012b74e94cd00bbe0f9c6df57049c97f02bb07d39e9c852e19a4"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b7133a6e6aeb8df37d6f413f7705a37ab4031597f64ab56384c94d98fa0e90"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:224c421235f6102e8737032483f43c1a8cfb1d2f45740c44166219599358c2cd"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b14d82cdb934e99dda6d9d60dc84a24379820176cc4a0d123f88df319ae9c150"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2728b01246a3bba6de144f9e3115b532ee44bd6cf39795194fb75491824a1413"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:470b94480bb5ee929f5acba6995251ada5e059a5ef3e0dfc63cca287283ebfa6"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:997abc4df705d1295a42f95b4eec4950a37ad8ae46d913caeee117b6b198811c"}, - {file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75250dbc5290e3f1a0f4618db35e51a165186f9034eff158f3d490b3fed9f8a0"}, - {file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4456f2dca97c425231d7315737d45239b2b51a50dc2b6f0c2bb181fce6207664"}, - {file = "pydantic_core-2.18.2-cp311-none-win32.whl", hash = "sha256:269322dcc3d8bdb69f054681edff86276b2ff972447863cf34c8b860f5188e2e"}, - {file = "pydantic_core-2.18.2-cp311-none-win_amd64.whl", hash = "sha256:800d60565aec896f25bc3cfa56d2277d52d5182af08162f7954f938c06dc4ee3"}, - {file = "pydantic_core-2.18.2-cp311-none-win_arm64.whl", hash = "sha256:1404c69d6a676245199767ba4f633cce5f4ad4181f9d0ccb0577e1f66cf4c46d"}, - {file = "pydantic_core-2.18.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:fb2bd7be70c0fe4dfd32c951bc813d9fe6ebcbfdd15a07527796c8204bd36242"}, - {file = "pydantic_core-2.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6132dd3bd52838acddca05a72aafb6eab6536aa145e923bb50f45e78b7251043"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d904828195733c183d20a54230c0df0eb46ec746ea1a666730787353e87182"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c9bd70772c720142be1020eac55f8143a34ec9f82d75a8e7a07852023e46617f"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b8ed04b3582771764538f7ee7001b02e1170223cf9b75dff0bc698fadb00cf3"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6dac87ddb34aaec85f873d737e9d06a3555a1cc1a8e0c44b7f8d5daeb89d86f"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca4ae5a27ad7a4ee5170aebce1574b375de390bc01284f87b18d43a3984df72"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:886eec03591b7cf058467a70a87733b35f44707bd86cf64a615584fd72488b7c"}, - {file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ca7b0c1f1c983e064caa85f3792dd2fe3526b3505378874afa84baf662e12241"}, - {file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b4356d3538c3649337df4074e81b85f0616b79731fe22dd11b99499b2ebbdf3"}, - {file = "pydantic_core-2.18.2-cp312-none-win32.whl", hash = "sha256:8b172601454f2d7701121bbec3425dd71efcb787a027edf49724c9cefc14c038"}, - {file = "pydantic_core-2.18.2-cp312-none-win_amd64.whl", hash = "sha256:b1bd7e47b1558ea872bd16c8502c414f9e90dcf12f1395129d7bb42a09a95438"}, - {file = "pydantic_core-2.18.2-cp312-none-win_arm64.whl", hash = "sha256:98758d627ff397e752bc339272c14c98199c613f922d4a384ddc07526c86a2ec"}, - {file = "pydantic_core-2.18.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:9fdad8e35f278b2c3eb77cbdc5c0a49dada440657bf738d6905ce106dc1de439"}, - {file = "pydantic_core-2.18.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1d90c3265ae107f91a4f279f4d6f6f1d4907ac76c6868b27dc7fb33688cfb347"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:390193c770399861d8df9670fb0d1874f330c79caaca4642332df7c682bf6b91"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:82d5d4d78e4448683cb467897fe24e2b74bb7b973a541ea1dcfec1d3cbce39fb"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4774f3184d2ef3e14e8693194f661dea5a4d6ca4e3dc8e39786d33a94865cefd"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4d938ec0adf5167cb335acb25a4ee69a8107e4984f8fbd2e897021d9e4ca21b"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0e8b1be28239fc64a88a8189d1df7fad8be8c1ae47fcc33e43d4be15f99cc70"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:868649da93e5a3d5eacc2b5b3b9235c98ccdbfd443832f31e075f54419e1b96b"}, - {file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:78363590ef93d5d226ba21a90a03ea89a20738ee5b7da83d771d283fd8a56761"}, - {file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:852e966fbd035a6468fc0a3496589b45e2208ec7ca95c26470a54daed82a0788"}, - {file = "pydantic_core-2.18.2-cp38-none-win32.whl", hash = "sha256:6a46e22a707e7ad4484ac9ee9f290f9d501df45954184e23fc29408dfad61350"}, - {file = "pydantic_core-2.18.2-cp38-none-win_amd64.whl", hash = "sha256:d91cb5ea8b11607cc757675051f61b3d93f15eca3cefb3e6c704a5d6e8440f4e"}, - {file = "pydantic_core-2.18.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ae0a8a797a5e56c053610fa7be147993fe50960fa43609ff2a9552b0e07013e8"}, - {file = "pydantic_core-2.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:042473b6280246b1dbf530559246f6842b56119c2926d1e52b631bdc46075f2a"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a388a77e629b9ec814c1b1e6b3b595fe521d2cdc625fcca26fbc2d44c816804"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25add29b8f3b233ae90ccef2d902d0ae0432eb0d45370fe315d1a5cf231004b"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f459a5ce8434614dfd39bbebf1041952ae01da6bed9855008cb33b875cb024c0"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eff2de745698eb46eeb51193a9f41d67d834d50e424aef27df2fcdee1b153845"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8309f67285bdfe65c372ea3722b7a5642680f3dba538566340a9d36e920b5f0"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f93a8a2e3938ff656a7c1bc57193b1319960ac015b6e87d76c76bf14fe0244b4"}, - {file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:22057013c8c1e272eb8d0eebc796701167d8377441ec894a8fed1af64a0bf399"}, - {file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cfeecd1ac6cc1fb2692c3d5110781c965aabd4ec5d32799773ca7b1456ac636b"}, - {file = "pydantic_core-2.18.2-cp39-none-win32.whl", hash = "sha256:0d69b4c2f6bb3e130dba60d34c0845ba31b69babdd3f78f7c0c8fae5021a253e"}, - {file = "pydantic_core-2.18.2-cp39-none-win_amd64.whl", hash = "sha256:d9319e499827271b09b4e411905b24a426b8fb69464dfa1696258f53a3334641"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a1874c6dd4113308bd0eb568418e6114b252afe44319ead2b4081e9b9521fe75"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:ccdd111c03bfd3666bd2472b674c6899550e09e9f298954cfc896ab92b5b0e6d"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e18609ceaa6eed63753037fc06ebb16041d17d28199ae5aba0052c51449650a9"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e5c584d357c4e2baf0ff7baf44f4994be121e16a2c88918a5817331fc7599d7"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43f0f463cf89ace478de71a318b1b4f05ebc456a9b9300d027b4b57c1a2064fb"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e1b395e58b10b73b07b7cf740d728dd4ff9365ac46c18751bf8b3d8cca8f625a"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0098300eebb1c837271d3d1a2cd2911e7c11b396eac9661655ee524a7f10587b"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:36789b70d613fbac0a25bb07ab3d9dba4d2e38af609c020cf4d888d165ee0bf3"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f9a801e7c8f1ef8718da265bba008fa121243dfe37c1cea17840b0944dfd72c"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3a6515ebc6e69d85502b4951d89131ca4e036078ea35533bb76327f8424531ce"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20aca1e2298c56ececfd8ed159ae4dde2df0781988c97ef77d5c16ff4bd5b400"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:223ee893d77a310a0391dca6df00f70bbc2f36a71a895cecd9a0e762dc37b349"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2334ce8c673ee93a1d6a65bd90327588387ba073c17e61bf19b4fd97d688d63c"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cbca948f2d14b09d20268cda7b0367723d79063f26c4ffc523af9042cad95592"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b3ef08e20ec49e02d5c6717a91bb5af9b20f1805583cb0adfe9ba2c6b505b5ae"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6fdc8627910eed0c01aed6a390a252fe3ea6d472ee70fdde56273f198938374"}, - {file = "pydantic_core-2.18.2.tar.gz", hash = "sha256:2e29d20810dfc3043ee13ac7d9e25105799817683348823f305ab3f349b9386e"}, -] - -[[package]] -name = "pydantic-settings" -version = "2.2.1" -requires_python = ">=3.8" -summary = "Settings management using Pydantic" -groups = ["dev"] -dependencies = [ - "pydantic>=2.3.0", - "python-dotenv>=0.21.0", -] -files = [ - {file = "pydantic_settings-2.2.1-py3-none-any.whl", hash = "sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091"}, - {file = "pydantic_settings-2.2.1.tar.gz", hash = "sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed"}, -] - -[[package]] -name = "pygments" -version = "2.18.0" -requires_python = ">=3.8" -summary = "Pygments is a syntax highlighting package written in Python." -groups = ["dev"] -files = [ - {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, - {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, -] - -[[package]] -name = "pytest" -version = "7.4.4" -requires_python = ">=3.7" -summary = "pytest: simple powerful testing with Python" -groups = ["dev"] -dependencies = [ - "colorama; sys_platform == \"win32\"", - "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", - "iniconfig", - "packaging", - "pluggy<2.0,>=0.12", - "tomli>=1.0.0; python_version < \"3.11\"", -] -files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, -] - -[[package]] -name = "pytest-cov" -version = "5.0.0" -requires_python = ">=3.8" -summary = "Pytest plugin for measuring coverage." -groups = ["dev"] -dependencies = [ - "coverage[toml]>=5.2.1", - "pytest>=4.6", -] -files = [ - {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, - {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, -] - -[[package]] -name = "python-dotenv" -version = "1.0.1" -requires_python = ">=3.8" -summary = "Read key-value pairs from a .env file and set them as environment variables" -groups = ["dev"] -files = [ - {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, - {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, -] - -[[package]] -name = "questionary" -version = "2.0.1" -requires_python = ">=3.8" -summary = "Python library to build pretty command line user prompts ⭐️" -groups = ["dev"] -dependencies = [ - "prompt-toolkit<=3.0.36,>=2.0", -] -files = [ - {file = "questionary-2.0.1-py3-none-any.whl", hash = "sha256:8ab9a01d0b91b68444dff7f6652c1e754105533f083cbe27597c8110ecc230a2"}, - {file = "questionary-2.0.1.tar.gz", hash = "sha256:bcce898bf3dbb446ff62830c86c5c6fb9a22a54146f0f5597d3da43b10d8fc8b"}, -] - -[[package]] -name = "rich" -version = "13.7.1" -requires_python = ">=3.7.0" -summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -groups = ["dev"] -dependencies = [ - "markdown-it-py>=2.2.0", - "pygments<3.0.0,>=2.13.0", - "typing-extensions<5.0,>=4.0.0; python_version < \"3.9\"", -] -files = [ - {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, - {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, -] - -[[package]] -name = "rich-click" -version = "1.8.1" -requires_python = ">=3.7" -summary = "Format click help output nicely with rich" -groups = ["dev"] -dependencies = [ - "click>=7", - "rich>=10.7", - "typing-extensions", -] -files = [ - {file = "rich_click-1.8.1-py3-none-any.whl", hash = "sha256:0cf0bf84404e78379bd2722db88cb07ffd0535440e20a05943d5b02249d90f8a"}, - {file = "rich_click-1.8.1.tar.gz", hash = "sha256:73c2ec88a66d7bf6b8c32783539d1c9c92c7c75847f14186092d27f83b206e8a"}, -] - -[[package]] -name = "ruff" -version = "0.4.3" -requires_python = ">=3.7" -summary = "An extremely fast Python linter and code formatter, written in Rust." -groups = ["dev"] -files = [ - {file = "ruff-0.4.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b70800c290f14ae6fcbb41bbe201cf62dfca024d124a1f373e76371a007454ce"}, - {file = "ruff-0.4.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08a0d6a22918ab2552ace96adeaca308833873a4d7d1d587bb1d37bae8728eb3"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba1f14df3c758dd7de5b55fbae7e1c8af238597961e5fb628f3de446c3c40c5"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:819fb06d535cc76dfddbfe8d3068ff602ddeb40e3eacbc90e0d1272bb8d97113"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfc9e955e6dc6359eb6f82ea150c4f4e82b660e5b58d9a20a0e42ec3bb6342b"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:510a67d232d2ebe983fddea324dbf9d69b71c4d2dfeb8a862f4a127536dd4cfb"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc9ff11cd9a092ee7680a56d21f302bdda14327772cd870d806610a3503d001f"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29efff25bf9ee685c2c8390563a5b5c006a3fee5230d28ea39f4f75f9d0b6f2f"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b00e0bcccf0fc8d7186ed21e311dffd19761cb632241a6e4fe4477cc80ef6e"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262f5635e2c74d80b7507fbc2fac28fe0d4fef26373bbc62039526f7722bca1b"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7363691198719c26459e08cc17c6a3dac6f592e9ea3d2fa772f4e561b5fe82a3"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eeb039f8428fcb6725bb63cbae92ad67b0559e68b5d80f840f11914afd8ddf7f"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:927b11c1e4d0727ce1a729eace61cee88a334623ec424c0b1c8fe3e5f9d3c865"}, - {file = "ruff-0.4.3-py3-none-win32.whl", hash = "sha256:25cacda2155778beb0d064e0ec5a3944dcca9c12715f7c4634fd9d93ac33fd30"}, - {file = "ruff-0.4.3-py3-none-win_amd64.whl", hash = "sha256:7a1c3a450bc6539ef00da6c819fb1b76b6b065dec585f91456e7c0d6a0bbc725"}, - {file = "ruff-0.4.3-py3-none-win_arm64.whl", hash = "sha256:71ca5f8ccf1121b95a59649482470c5601c60a416bf189d553955b0338e34614"}, - {file = "ruff-0.4.3.tar.gz", hash = "sha256:ff0a3ef2e3c4b6d133fbedcf9586abfbe38d076041f2dc18ffb2c7e0485d5a07"}, -] - -[[package]] -name = "strenum" -version = "0.4.15" -summary = "An Enum that inherits from str." -groups = ["default"] -files = [ - {file = "StrEnum-0.4.15-py3-none-any.whl", hash = "sha256:a30cda4af7cc6b5bf52c8055bc4bf4b2b6b14a93b574626da33df53cf7740659"}, - {file = "StrEnum-0.4.15.tar.gz", hash = "sha256:878fb5ab705442070e4dd1929bb5e2249511c0bcf2b0eeacf3bcd80875c82eff"}, -] - -[[package]] -name = "syrupy" -version = "3.0.6" -requires_python = ">=3.7,<4" -summary = "Pytest Snapshot Test Utility" -groups = ["dev"] -dependencies = [ - "colored<2.0.0,>=1.3.92", - "pytest<8.0.0,>=5.1.0", -] -files = [ - {file = "syrupy-3.0.6-py3-none-any.whl", hash = "sha256:9c18e22264026b34239bcc87ab7cc8d893eb17236ea7dae634217ea4f22a848d"}, - {file = "syrupy-3.0.6.tar.gz", hash = "sha256:583aa5ca691305c27902c3e29a1ce9da50ff9ab5f184c54b1dc124a16e4a6cf4"}, -] - -[[package]] -name = "tomli" -version = "2.0.1" -requires_python = ">=3.7" -summary = "A lil' TOML parser" -groups = ["dev"] -marker = "python_version < \"3.11\"" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - -[[package]] -name = "tomlkit" -version = "0.12.4" -requires_python = ">=3.7" -summary = "Style preserving TOML library" -groups = ["dev"] -files = [ - {file = "tomlkit-0.12.4-py3-none-any.whl", hash = "sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b"}, - {file = "tomlkit-0.12.4.tar.gz", hash = "sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3"}, -] - -[[package]] -name = "typing-extensions" -version = "4.11.0" -requires_python = ">=3.8" -summary = "Backported and Experimental Type Hints for Python 3.8+" -groups = ["default", "dev"] -files = [ - {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, - {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, -] - -[[package]] -name = "wcmatch" -version = "8.5.1" -requires_python = ">=3.8" -summary = "Wildcard/glob file name matcher." -groups = ["dev"] -dependencies = [ - "bracex>=2.1.1", -] -files = [ - {file = "wcmatch-8.5.1-py3-none-any.whl", hash = "sha256:24c19cedc92bc9c9e27f39db4e1824d72f95bd2cea32b254a47a45b1a1b227ed"}, - {file = "wcmatch-8.5.1.tar.gz", hash = "sha256:c0088c7f6426cf6bf27e530e2b7b734031905f7e490475fd83c7c5008ab581b3"}, -] - -[[package]] -name = "wcwidth" -version = "0.2.13" -summary = "Measures the displayed width of unicode strings in a terminal" -groups = ["dev"] -files = [ - {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, - {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, -] From 46caccab6ed463a033e2aae661efd57d657d68da Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Tue, 22 Oct 2024 13:03:26 +0200 Subject: [PATCH 12/19] chore: adapt Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d944107..1c36e77 100644 --- a/Makefile +++ b/Makefile @@ -57,8 +57,8 @@ help: @echo "" PLATFORM := `uname -o` -REPO := "" -PROJECT_SRC := "" +REPO := parallel-corpus-py +PROJECT_SRC := src ifeq (${VIRTUAL_ENV},) VENV_NAME = .venv From 390a7718d222b2e6f9d4bbdf577f2e52459a514a Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Tue, 22 Oct 2024 13:11:19 +0200 Subject: [PATCH 13/19] ci: adapt workflows --- .github/workflows/release.yml | 4 ++-- .github/workflows/scheduled.yml | 33 --------------------------------- 2 files changed, 2 insertions(+), 35 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 19310c0..db3ad6b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -108,10 +108,10 @@ jobs: name: pypi_files path: dist - - run: rm -r + - run: rm -r src/parallel_corpus - run: pip install typing-extensions - run: pip install -r tests/requirements-testing.lock - - run: pip install --no-index --no-deps --find-links dist --force-reinstall + - run: pip install parallel-corpus --no-index --no-deps --find-links dist --force-reinstall - run: pytest # https://github.com/marketplace/actions/alls-green#why used for branch protection checks diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml index 1376cb7..d4f3ec2 100644 --- a/.github/workflows/scheduled.yml +++ b/.github/workflows/scheduled.yml @@ -22,39 +22,6 @@ env: UV_CACHE_DIR: /tmp/.uv-cache jobs: - # https://twitter.com/mycoliza/status/1571295690063753218 - nightly: - runs-on: ubuntu-latest - name: ubuntu / 3.14-dev - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - name: Set up uv - run: curl -LsSf https://astral.sh/uv/${{ env.UV_VERSION }}/install.sh | sh - - name: Install python - uses: actions/setup-python@v5 - with: - python-version: "3.14-dev" - - name: Restore uv cache - uses: actions/cache@v4 - with: - path: /tmp/.uv-cache - key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} - restore-keys: | - uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} - uv-${{ runner.os }} - - run: python --version - - name: uv lock - if: hashFiles('uv.lock') == '' - run: uv lock - - name: uv sync --dev - run: uv sync --dev - - name: make test - run: make test - - - name: Minimize uv cache - run: uv cache prune --ci # https://twitter.com/alcuadrado/status/1571291687837732873 update: # This action checks that updating the dependencies of this crate to the latest available that From f6501025153b14ce6860d0ea101074c9b11e8a8c Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Tue, 22 Oct 2024 13:12:11 +0200 Subject: [PATCH 14/19] chore: use uv instead of pdm --- .gitignore | 1 + .pre-commit-config.yaml | 2 +- Makefile | 2 +- pyproject.toml | 26 +- tests/requirements-testing.in | 2 + tests/requirements-testing.lock | 291 +-------------- uv.lock | 608 ++++++++++++++++++++++++++++++++ 7 files changed, 638 insertions(+), 294 deletions(-) create mode 100644 tests/requirements-testing.in create mode 100644 uv.lock diff --git a/.gitignore b/.gitignore index 04f1bf2..653ea67 100644 --- a/.gitignore +++ b/.gitignore @@ -159,3 +159,4 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ .pdm-python +.python-version diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 23fc147..d58c332 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,7 +21,7 @@ repos: stages: [commit] - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.3.2 + rev: v0.7.0 hooks: # Run the linter. - id: ruff diff --git a/Makefile b/Makefile index 1c36e77..f86a6d1 100644 --- a/Makefile +++ b/Makefile @@ -150,7 +150,7 @@ publish: prepare-release: update-changelog tests/requirements-testing.lock # we use lock extension so that dependabot doesn't pick up changes in this file -tests/requirements-testing.lock: pyproject.toml +tests/requirements-testing.lock: tests/requirements-testing.in uv pip compile $< --output-file $@ .PHONY: update-changelog diff --git a/pyproject.toml b/pyproject.toml index ab1dbe4..e05f86f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "typing-extensions>=4.11.0", "strenum>=0.4.15", # For StrEnum i Python < 3.10 ] -requires-python = ">=3.8" +requires-python = ">=3.9" readme = "README.md" license = { text = "MIT" } classifiers = [ @@ -25,11 +25,11 @@ classifiers = [ "Operating System :: POSIX", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS :: MacOS X", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", # "uncomment if you test on these interpreters:", # "Programming Language :: Python :: Implementation :: IronPython", @@ -39,19 +39,15 @@ classifiers = [ ] [build-system] -requires = ["pdm-backend"] -build-backend = "pdm.backend" +requires = ["hatchling"] +build-backend = "hatchling.build" - -[tool.pdm] -distribution = true - -[tool.pdm.dev-dependencies] -dev = [ - "syrupy>=3.0.6", - "pytest>=7.4.4", - "ruff>=0.4.1", - "mypy>=1.9.0", +[tool.uv] +dev-dependencies = [ + "bump-my-version>=0.28.0", + "mypy>=1.12.1", "pytest-cov>=5.0.0", - "bump-my-version>=0.21.0", + "pytest>=8.3.3", + "ruff>=0.7.0", + "syrupy>=4.7.2", ] diff --git a/tests/requirements-testing.in b/tests/requirements-testing.in new file mode 100644 index 0000000..af4a43e --- /dev/null +++ b/tests/requirements-testing.in @@ -0,0 +1,2 @@ +pytest +syrupy diff --git a/tests/requirements-testing.lock b/tests/requirements-testing.lock index 586d56a..84b8098 100644 --- a/tests/requirements-testing.lock +++ b/tests/requirements-testing.lock @@ -1,277 +1,14 @@ -# This file is @generated by PDM. -# Please do not edit it manually. - -annotated-types==0.6.0 \ - --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ - --hash=sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d -bracex==2.4 \ - --hash=sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb \ - --hash=sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418 -bump-my-version==0.21.0 \ - --hash=sha256:a614d8176b5ac0e644239c9a8a246b696d316f68406fd78b8486a9e13fc93266 \ - --hash=sha256:c3f1a31e32345679b517cbba99a0875457ee45d7ba6189fcd2a74d3ddae41515 -click==8.1.7 \ - --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ - --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de -colorama==0.4.6; sys_platform == "win32" or platform_system == "Windows" \ - --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ - --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 -colored==1.4.4 \ - --hash=sha256:04ff4d4dd514274fe3b99a21bb52fb96f2688c01e93fba7bef37221e7cb56ce0 -coverage==7.5.1 \ - --hash=sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de \ - --hash=sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661 \ - --hash=sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26 \ - --hash=sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41 \ - --hash=sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d \ - --hash=sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981 \ - --hash=sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2 \ - --hash=sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34 \ - --hash=sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f \ - --hash=sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a \ - --hash=sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35 \ - --hash=sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223 \ - --hash=sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1 \ - --hash=sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746 \ - --hash=sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90 \ - --hash=sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c \ - --hash=sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca \ - --hash=sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8 \ - --hash=sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596 \ - --hash=sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e \ - --hash=sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd \ - --hash=sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e \ - --hash=sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3 \ - --hash=sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e \ - --hash=sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312 \ - --hash=sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7 \ - --hash=sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572 \ - --hash=sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428 \ - --hash=sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f \ - --hash=sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07 \ - --hash=sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e \ - --hash=sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4 \ - --hash=sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136 \ - --hash=sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5 \ - --hash=sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8 \ - --hash=sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d \ - --hash=sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228 \ - --hash=sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206 \ - --hash=sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa \ - --hash=sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e \ - --hash=sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be \ - --hash=sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5 \ - --hash=sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668 \ - --hash=sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601 \ - --hash=sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057 \ - --hash=sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146 \ - --hash=sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f \ - --hash=sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8 \ - --hash=sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7 \ - --hash=sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987 \ - --hash=sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19 \ - --hash=sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece -diff-match-patch==20230430 \ - --hash=sha256:953019cdb9c9d2c9e47b5b12bcff3cf4746fc4598eb406076fa1fc27e6a1f15c \ - --hash=sha256:dce43505fb7b1b317de7195579388df0746d90db07015ed47a85e5e44930ef93 -exceptiongroup==1.2.1; python_version < "3.11" \ - --hash=sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad \ - --hash=sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16 -iniconfig==2.0.0 \ - --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \ - --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 -markdown-it-py==3.0.0 \ - --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \ - --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb -mdurl==0.1.2 \ - --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ - --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba -more-itertools==10.2.0 \ - --hash=sha256:686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684 \ - --hash=sha256:8fccb480c43d3e99a00087634c06dd02b0d50fbf088b380de5a41a015ec239e1 -mypy==1.10.0 \ - --hash=sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061 \ - --hash=sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99 \ - --hash=sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de \ - --hash=sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a \ - --hash=sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9 \ - --hash=sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec \ - --hash=sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1 \ - --hash=sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131 \ - --hash=sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f \ - --hash=sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821 \ - --hash=sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5 \ - --hash=sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee \ - --hash=sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e \ - --hash=sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746 \ - --hash=sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2 \ - --hash=sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0 \ - --hash=sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b \ - --hash=sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53 \ - --hash=sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30 \ - --hash=sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda \ - --hash=sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051 \ - --hash=sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2 \ - --hash=sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7 \ - --hash=sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee \ - --hash=sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727 \ - --hash=sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976 \ - --hash=sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4 -mypy-extensions==1.0.0 \ - --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ - --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782 -packaging==24.0 \ - --hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \ - --hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9 -pluggy==1.5.0 \ - --hash=sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1 \ - --hash=sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 -prompt-toolkit==3.0.36 \ - --hash=sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63 \ - --hash=sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305 -pydantic==2.7.1 \ - --hash=sha256:e029badca45266732a9a79898a15ae2e8b14840b1eabbb25844be28f0b33f3d5 \ - --hash=sha256:e9dbb5eada8abe4d9ae5f46b9939aead650cd2b68f249bb3a8139dbe125803cc -pydantic-core==2.18.2 \ - --hash=sha256:0098300eebb1c837271d3d1a2cd2911e7c11b396eac9661655ee524a7f10587b \ - --hash=sha256:042473b6280246b1dbf530559246f6842b56119c2926d1e52b631bdc46075f2a \ - --hash=sha256:05b7133a6e6aeb8df37d6f413f7705a37ab4031597f64ab56384c94d98fa0e90 \ - --hash=sha256:0680b1f1f11fda801397de52c36ce38ef1c1dc841a0927a94f226dea29c3ae3d \ - --hash=sha256:0d69b4c2f6bb3e130dba60d34c0845ba31b69babdd3f78f7c0c8fae5021a253e \ - --hash=sha256:1404c69d6a676245199767ba4f633cce5f4ad4181f9d0ccb0577e1f66cf4c46d \ - --hash=sha256:182245ff6b0039e82b6bb585ed55a64d7c81c560715d1bad0cbad6dfa07b4027 \ - --hash=sha256:1a388a77e629b9ec814c1b1e6b3b595fe521d2cdc625fcca26fbc2d44c816804 \ - --hash=sha256:1d90c3265ae107f91a4f279f4d6f6f1d4907ac76c6868b27dc7fb33688cfb347 \ - --hash=sha256:20aca1e2298c56ececfd8ed159ae4dde2df0781988c97ef77d5c16ff4bd5b400 \ - --hash=sha256:219da3f096d50a157f33645a1cf31c0ad1fe829a92181dd1311022f986e5fbe3 \ - --hash=sha256:22057013c8c1e272eb8d0eebc796701167d8377441ec894a8fed1af64a0bf399 \ - --hash=sha256:223ee893d77a310a0391dca6df00f70bbc2f36a71a895cecd9a0e762dc37b349 \ - --hash=sha256:224c421235f6102e8737032483f43c1a8cfb1d2f45740c44166219599358c2cd \ - --hash=sha256:2334ce8c673ee93a1d6a65bd90327588387ba073c17e61bf19b4fd97d688d63c \ - --hash=sha256:269322dcc3d8bdb69f054681edff86276b2ff972447863cf34c8b860f5188e2e \ - --hash=sha256:2728b01246a3bba6de144f9e3115b532ee44bd6cf39795194fb75491824a1413 \ - --hash=sha256:2b8ed04b3582771764538f7ee7001b02e1170223cf9b75dff0bc698fadb00cf3 \ - --hash=sha256:2e29d20810dfc3043ee13ac7d9e25105799817683348823f305ab3f349b9386e \ - --hash=sha256:36789b70d613fbac0a25bb07ab3d9dba4d2e38af609c020cf4d888d165ee0bf3 \ - --hash=sha256:390193c770399861d8df9670fb0d1874f330c79caaca4642332df7c682bf6b91 \ - --hash=sha256:3a6515ebc6e69d85502b4951d89131ca4e036078ea35533bb76327f8424531ce \ - --hash=sha256:3f9a801e7c8f1ef8718da265bba008fa121243dfe37c1cea17840b0944dfd72c \ - --hash=sha256:43f0f463cf89ace478de71a318b1b4f05ebc456a9b9300d027b4b57c1a2064fb \ - --hash=sha256:4456f2dca97c425231d7315737d45239b2b51a50dc2b6f0c2bb181fce6207664 \ - --hash=sha256:470b94480bb5ee929f5acba6995251ada5e059a5ef3e0dfc63cca287283ebfa6 \ - --hash=sha256:4774f3184d2ef3e14e8693194f661dea5a4d6ca4e3dc8e39786d33a94865cefd \ - --hash=sha256:4b4356d3538c3649337df4074e81b85f0616b79731fe22dd11b99499b2ebbdf3 \ - --hash=sha256:553ef617b6836fc7e4df130bb851e32fe357ce36336d897fd6646d6058d980af \ - --hash=sha256:6132dd3bd52838acddca05a72aafb6eab6536aa145e923bb50f45e78b7251043 \ - --hash=sha256:6a46e22a707e7ad4484ac9ee9f290f9d501df45954184e23fc29408dfad61350 \ - --hash=sha256:6e5c584d357c4e2baf0ff7baf44f4994be121e16a2c88918a5817331fc7599d7 \ - --hash=sha256:75250dbc5290e3f1a0f4618db35e51a165186f9034eff158f3d490b3fed9f8a0 \ - --hash=sha256:75f7e9488238e920ab6204399ded280dc4c307d034f3924cd7f90a38b1829563 \ - --hash=sha256:78363590ef93d5d226ba21a90a03ea89a20738ee5b7da83d771d283fd8a56761 \ - --hash=sha256:7ca4ae5a27ad7a4ee5170aebce1574b375de390bc01284f87b18d43a3984df72 \ - --hash=sha256:800d60565aec896f25bc3cfa56d2277d52d5182af08162f7954f938c06dc4ee3 \ - --hash=sha256:82d5d4d78e4448683cb467897fe24e2b74bb7b973a541ea1dcfec1d3cbce39fb \ - --hash=sha256:852e966fbd035a6468fc0a3496589b45e2208ec7ca95c26470a54daed82a0788 \ - --hash=sha256:868649da93e5a3d5eacc2b5b3b9235c98ccdbfd443832f31e075f54419e1b96b \ - --hash=sha256:886eec03591b7cf058467a70a87733b35f44707bd86cf64a615584fd72488b7c \ - --hash=sha256:8b172601454f2d7701121bbec3425dd71efcb787a027edf49724c9cefc14c038 \ - --hash=sha256:95b9d5e72481d3780ba3442eac863eae92ae43a5f3adb5b4d0a1de89d42bb250 \ - --hash=sha256:98758d627ff397e752bc339272c14c98199c613f922d4a384ddc07526c86a2ec \ - --hash=sha256:997abc4df705d1295a42f95b4eec4950a37ad8ae46d913caeee117b6b198811c \ - --hash=sha256:9b5155ff768083cb1d62f3e143b49a8a3432e6789a3abee8acd005c3c7af1c74 \ - --hash=sha256:9e08e867b306f525802df7cd16c44ff5ebbe747ff0ca6cf3fde7f36c05a59a81 \ - --hash=sha256:9fdad8e35f278b2c3eb77cbdc5c0a49dada440657bf738d6905ce106dc1de439 \ - --hash=sha256:a1874c6dd4113308bd0eb568418e6114b252afe44319ead2b4081e9b9521fe75 \ - --hash=sha256:a8309f67285bdfe65c372ea3722b7a5642680f3dba538566340a9d36e920b5f0 \ - --hash=sha256:ae0a8a797a5e56c053610fa7be147993fe50960fa43609ff2a9552b0e07013e8 \ - --hash=sha256:b14d82cdb934e99dda6d9d60dc84a24379820176cc4a0d123f88df319ae9c150 \ - --hash=sha256:b1bd7e47b1558ea872bd16c8502c414f9e90dcf12f1395129d7bb42a09a95438 \ - --hash=sha256:b3ef08e20ec49e02d5c6717a91bb5af9b20f1805583cb0adfe9ba2c6b505b5ae \ - --hash=sha256:b89ed9eb7d616ef5714e5590e6cf7f23b02d0d539767d33561e3675d6f9e3857 \ - --hash=sha256:c4fcf5cd9c4b655ad666ca332b9a081112cd7a58a8b5a6ca7a3104bc950f2038 \ - --hash=sha256:c6fdc8627910eed0c01aed6a390a252fe3ea6d472ee70fdde56273f198938374 \ - --hash=sha256:c9bd70772c720142be1020eac55f8143a34ec9f82d75a8e7a07852023e46617f \ - --hash=sha256:ca7b0c1f1c983e064caa85f3792dd2fe3526b3505378874afa84baf662e12241 \ - --hash=sha256:cbca948f2d14b09d20268cda7b0367723d79063f26c4ffc523af9042cad95592 \ - --hash=sha256:cc1cfd88a64e012b74e94cd00bbe0f9c6df57049c97f02bb07d39e9c852e19a4 \ - --hash=sha256:ccdd111c03bfd3666bd2472b674c6899550e09e9f298954cfc896ab92b5b0e6d \ - --hash=sha256:cfeecd1ac6cc1fb2692c3d5110781c965aabd4ec5d32799773ca7b1456ac636b \ - --hash=sha256:d4d938ec0adf5167cb335acb25a4ee69a8107e4984f8fbd2e897021d9e4ca21b \ - --hash=sha256:d7d904828195733c183d20a54230c0df0eb46ec746ea1a666730787353e87182 \ - --hash=sha256:d91cb5ea8b11607cc757675051f61b3d93f15eca3cefb3e6c704a5d6e8440f4e \ - --hash=sha256:d9319e499827271b09b4e411905b24a426b8fb69464dfa1696258f53a3334641 \ - --hash=sha256:e0e8b1be28239fc64a88a8189d1df7fad8be8c1ae47fcc33e43d4be15f99cc70 \ - --hash=sha256:e18609ceaa6eed63753037fc06ebb16041d17d28199ae5aba0052c51449650a9 \ - --hash=sha256:e1b395e58b10b73b07b7cf740d728dd4ff9365ac46c18751bf8b3d8cca8f625a \ - --hash=sha256:e23ec367a948b6d812301afc1b13f8094ab7b2c280af66ef450efc357d2ae543 \ - --hash=sha256:e25add29b8f3b233ae90ccef2d902d0ae0432eb0d45370fe315d1a5cf231004b \ - --hash=sha256:e6dac87ddb34aaec85f873d737e9d06a3555a1cc1a8e0c44b7f8d5daeb89d86f \ - --hash=sha256:ef26c9e94a8c04a1b2924149a9cb081836913818e55681722d7f29af88fe7b38 \ - --hash=sha256:eff2de745698eb46eeb51193a9f41d67d834d50e424aef27df2fcdee1b153845 \ - --hash=sha256:f0a21cbaa69900cbe1a2e7cad2aa74ac3cf21b10c3efb0fa0b80305274c0e8a2 \ - --hash=sha256:f459a5ce8434614dfd39bbebf1041952ae01da6bed9855008cb33b875cb024c0 \ - --hash=sha256:f93a8a2e3938ff656a7c1bc57193b1319960ac015b6e87d76c76bf14fe0244b4 \ - --hash=sha256:fb2bd7be70c0fe4dfd32c951bc813d9fe6ebcbfdd15a07527796c8204bd36242 -pydantic-settings==2.2.1 \ - --hash=sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed \ - --hash=sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091 -pygments==2.18.0 \ - --hash=sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199 \ - --hash=sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a -pytest==7.4.4 \ - --hash=sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280 \ - --hash=sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8 -pytest-cov==5.0.0 \ - --hash=sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652 \ - --hash=sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857 -python-dotenv==1.0.1 \ - --hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \ - --hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a -questionary==2.0.1 \ - --hash=sha256:8ab9a01d0b91b68444dff7f6652c1e754105533f083cbe27597c8110ecc230a2 \ - --hash=sha256:bcce898bf3dbb446ff62830c86c5c6fb9a22a54146f0f5597d3da43b10d8fc8b -rich==13.7.1 \ - --hash=sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 \ - --hash=sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432 -rich-click==1.8.1 \ - --hash=sha256:0cf0bf84404e78379bd2722db88cb07ffd0535440e20a05943d5b02249d90f8a \ - --hash=sha256:73c2ec88a66d7bf6b8c32783539d1c9c92c7c75847f14186092d27f83b206e8a -ruff==0.4.3 \ - --hash=sha256:08a0d6a22918ab2552ace96adeaca308833873a4d7d1d587bb1d37bae8728eb3 \ - --hash=sha256:0bfc9e955e6dc6359eb6f82ea150c4f4e82b660e5b58d9a20a0e42ec3bb6342b \ - --hash=sha256:18b00e0bcccf0fc8d7186ed21e311dffd19761cb632241a6e4fe4477cc80ef6e \ - --hash=sha256:25cacda2155778beb0d064e0ec5a3944dcca9c12715f7c4634fd9d93ac33fd30 \ - --hash=sha256:262f5635e2c74d80b7507fbc2fac28fe0d4fef26373bbc62039526f7722bca1b \ - --hash=sha256:29efff25bf9ee685c2c8390563a5b5c006a3fee5230d28ea39f4f75f9d0b6f2f \ - --hash=sha256:510a67d232d2ebe983fddea324dbf9d69b71c4d2dfeb8a862f4a127536dd4cfb \ - --hash=sha256:71ca5f8ccf1121b95a59649482470c5601c60a416bf189d553955b0338e34614 \ - --hash=sha256:7363691198719c26459e08cc17c6a3dac6f592e9ea3d2fa772f4e561b5fe82a3 \ - --hash=sha256:7a1c3a450bc6539ef00da6c819fb1b76b6b065dec585f91456e7c0d6a0bbc725 \ - --hash=sha256:819fb06d535cc76dfddbfe8d3068ff602ddeb40e3eacbc90e0d1272bb8d97113 \ - --hash=sha256:927b11c1e4d0727ce1a729eace61cee88a334623ec424c0b1c8fe3e5f9d3c865 \ - --hash=sha256:b70800c290f14ae6fcbb41bbe201cf62dfca024d124a1f373e76371a007454ce \ - --hash=sha256:dc9ff11cd9a092ee7680a56d21f302bdda14327772cd870d806610a3503d001f \ - --hash=sha256:eba1f14df3c758dd7de5b55fbae7e1c8af238597961e5fb628f3de446c3c40c5 \ - --hash=sha256:eeb039f8428fcb6725bb63cbae92ad67b0559e68b5d80f840f11914afd8ddf7f \ - --hash=sha256:ff0a3ef2e3c4b6d133fbedcf9586abfbe38d076041f2dc18ffb2c7e0485d5a07 -strenum==0.4.15 \ - --hash=sha256:878fb5ab705442070e4dd1929bb5e2249511c0bcf2b0eeacf3bcd80875c82eff \ - --hash=sha256:a30cda4af7cc6b5bf52c8055bc4bf4b2b6b14a93b574626da33df53cf7740659 -syrupy==3.0.6 \ - --hash=sha256:583aa5ca691305c27902c3e29a1ce9da50ff9ab5f184c54b1dc124a16e4a6cf4 \ - --hash=sha256:9c18e22264026b34239bcc87ab7cc8d893eb17236ea7dae634217ea4f22a848d -tomli==2.0.1; python_version < "3.11" \ - --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ - --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f -tomlkit==0.12.4 \ - --hash=sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b \ - --hash=sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3 -typing-extensions==4.11.0 \ - --hash=sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0 \ - --hash=sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a -wcmatch==8.5.1 \ - --hash=sha256:24c19cedc92bc9c9e27f39db4e1824d72f95bd2cea32b254a47a45b1a1b227ed \ - --hash=sha256:c0088c7f6426cf6bf27e530e2b7b734031905f7e490475fd83c7c5008ab581b3 -wcwidth==0.2.13 \ - --hash=sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859 \ - --hash=sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5 +# This file was autogenerated by uv via the following command: +# uv pip compile tests/requirements-testing.in --output-file tests/requirements-testing.lock +iniconfig==2.0.0 + # via pytest +packaging==24.1 + # via pytest +pluggy==1.5.0 + # via pytest +pytest==8.3.3 + # via + # -r tests/requirements-testing.in + # syrupy +syrupy==4.7.2 + # via -r tests/requirements-testing.in diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..71bfcaa --- /dev/null +++ b/uv.lock @@ -0,0 +1,608 @@ +version = 1 +requires-python = ">=3.9" +resolution-markers = [ + "python_full_version < '3.13'", + "python_full_version >= '3.13'", +] + +[[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 = "bracex" +version = "2.5.post1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/6c/57418c4404cd22fe6275b8301ca2b46a8cdaa8157938017a9ae0b3edf363/bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6", size = 26641 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/02/8db98cdc1a58e0abd6716d5e63244658e6e63513c65f469f34b6f1053fd0/bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6", size = 11558 }, +] + +[[package]] +name = "bump-my-version" +version = "0.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "pydantic" }, + { name = "pydantic-settings" }, + { name = "questionary" }, + { name = "rich" }, + { name = "rich-click" }, + { name = "tomlkit" }, + { name = "wcmatch" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d4/25/9b361ff2d42733578ee2b5564cf8b7dc389a187b6b6184c2c19d090e3084/bump_my_version-0.28.0.tar.gz", hash = "sha256:ff3cb51bb15509ae8ebb8e8efa3eaa7c02209677f45457c8b007ef2f5bef7179", size = 983361 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/f8/3d46566ab1caaac211ef678160d8174cb8e88ab4bd22439cecc6351ddecd/bump_my_version-0.28.0-py3-none-any.whl", hash = "sha256:cc84ace477022a4cc8c401ef5c035f2f752df45488be90ccb764a47f7de0e395", size = 52201 }, +] + +[[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.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/12/3669b6382792783e92046730ad3327f53b2726f0603f4c311c4da4824222/coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", size = 798716 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/93/4ad92f71e28ece5c0326e5f4a6630aa4928a8846654a65cfff69b49b95b9/coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", size = 206713 }, + { url = "https://files.pythonhosted.org/packages/01/ae/747a580b1eda3f2e431d87de48f0604bd7bc92e52a1a95185a4aa585bc47/coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", size = 207149 }, + { url = "https://files.pythonhosted.org/packages/07/1a/1f573f8a6145f6d4c9130bbc120e0024daf1b24cf2a78d7393fa6eb6aba7/coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", size = 235584 }, + { url = "https://files.pythonhosted.org/packages/40/42/c8523f2e4db34aa9389caee0d3688b6ada7a84fcc782e943a868a7f302bd/coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/8d/95/565c310fffa16ede1a042e9ea1ca3962af0d8eb5543bc72df6b91dc0c3d5/coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", size = 234649 }, + { url = "https://files.pythonhosted.org/packages/d5/81/3b550674d98968ec29c92e3e8650682be6c8b1fa7581a059e7e12e74c431/coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", size = 233744 }, + { url = "https://files.pythonhosted.org/packages/0d/70/d66c7f51b3e33aabc5ea9f9624c1c9d9655472962270eb5e7b0d32707224/coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", size = 232204 }, + { url = "https://files.pythonhosted.org/packages/23/2d/2b3a2dbed7a5f40693404c8a09e779d7c1a5fbed089d3e7224c002129ec8/coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", size = 233335 }, + { url = "https://files.pythonhosted.org/packages/5a/4f/92d1d2ad720d698a4e71c176eacf531bfb8e0721d5ad560556f2c484a513/coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", size = 209435 }, + { url = "https://files.pythonhosted.org/packages/c7/b9/cdf158e7991e2287bcf9082670928badb73d310047facac203ff8dcd5ff3/coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", size = 210243 }, + { url = "https://files.pythonhosted.org/packages/87/31/9c0cf84f0dfcbe4215b7eb95c31777cdc0483c13390e69584c8150c85175/coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", size = 206819 }, + { url = "https://files.pythonhosted.org/packages/53/ed/a38401079ad320ad6e054a01ec2b61d270511aeb3c201c80e99c841229d5/coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", size = 207263 }, + { url = "https://files.pythonhosted.org/packages/20/e7/c3ad33b179ab4213f0d70da25a9c214d52464efa11caeab438592eb1d837/coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", size = 239205 }, + { url = "https://files.pythonhosted.org/packages/36/91/fc02e8d8e694f557752120487fd982f654ba1421bbaa5560debf96ddceda/coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", size = 236612 }, + { url = "https://files.pythonhosted.org/packages/cc/57/cb08f0eda0389a9a8aaa4fc1f9fec7ac361c3e2d68efd5890d7042c18aa3/coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", size = 238479 }, + { url = "https://files.pythonhosted.org/packages/d5/c9/2c7681a9b3ca6e6f43d489c2e6653a53278ed857fd6e7010490c307b0a47/coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", size = 237405 }, + { url = "https://files.pythonhosted.org/packages/b5/4e/ebfc6944b96317df8b537ae875d2e57c27b84eb98820bc0a1055f358f056/coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", size = 236038 }, + { url = "https://files.pythonhosted.org/packages/13/f2/3a0bf1841a97c0654905e2ef531170f02c89fad2555879db8fe41a097871/coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", size = 236812 }, + { url = "https://files.pythonhosted.org/packages/b9/9c/66bf59226b52ce6ed9541b02d33e80a6e816a832558fbdc1111a7bd3abd4/coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", size = 209400 }, + { url = "https://files.pythonhosted.org/packages/2a/a0/b0790934c04dfc8d658d4a62acb8f7ca0efdf3818456fcad757b11c6479d/coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", size = 210243 }, + { url = "https://files.pythonhosted.org/packages/7d/e7/9291de916d084f41adddfd4b82246e68d61d6a75747f075f7e64628998d2/coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", size = 207013 }, + { url = "https://files.pythonhosted.org/packages/27/03/932c2c5717a7fa80cd43c6a07d3177076d97b79f12f40f882f9916db0063/coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", size = 207251 }, + { url = "https://files.pythonhosted.org/packages/d5/3f/0af47dcb9327f65a45455fbca846fe96eb57c153af46c4754a3ba678938a/coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", size = 240268 }, + { url = "https://files.pythonhosted.org/packages/8a/3c/37a9d81bbd4b23bc7d46ca820e16174c613579c66342faa390a271d2e18b/coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", size = 237298 }, + { url = "https://files.pythonhosted.org/packages/c0/70/6b0627e5bd68204ee580126ed3513140b2298995c1233bd67404b4e44d0e/coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", size = 239367 }, + { url = "https://files.pythonhosted.org/packages/3c/eb/634d7dfab24ac3b790bebaf9da0f4a5352cbc125ce6a9d5c6cf4c6cae3c7/coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", size = 238853 }, + { url = "https://files.pythonhosted.org/packages/d9/0d/8e3ed00f1266ef7472a4e33458f42e39492e01a64281084fb3043553d3f1/coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", size = 237160 }, + { url = "https://files.pythonhosted.org/packages/ce/9c/4337f468ef0ab7a2e0887a9c9da0e58e2eada6fc6cbee637a4acd5dfd8a9/coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", size = 238824 }, + { url = "https://files.pythonhosted.org/packages/5e/09/3e94912b8dd37251377bb02727a33a67ee96b84bbbe092f132b401ca5dd9/coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", size = 209639 }, + { url = "https://files.pythonhosted.org/packages/01/69/d4f3a4101171f32bc5b3caec8ff94c2c60f700107a6aaef7244b2c166793/coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", size = 210428 }, + { url = "https://files.pythonhosted.org/packages/c2/4d/2dede4f7cb5a70fb0bb40a57627fddf1dbdc6b9c1db81f7c4dcdcb19e2f4/coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", size = 207039 }, + { url = "https://files.pythonhosted.org/packages/3f/f9/d86368ae8c79e28f1fb458ebc76ae9ff3e8bd8069adc24e8f2fed03c58b7/coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", size = 207298 }, + { url = "https://files.pythonhosted.org/packages/64/c5/b4cc3c3f64622c58fbfd4d8b9a7a8ce9d355f172f91fcabbba1f026852f6/coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", size = 239813 }, + { url = "https://files.pythonhosted.org/packages/8a/86/14c42e60b70a79b26099e4d289ccdfefbc68624d096f4481163085aa614c/coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", size = 236959 }, + { url = "https://files.pythonhosted.org/packages/7f/f8/4436a643631a2fbab4b44d54f515028f6099bfb1cd95b13cfbf701e7f2f2/coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", size = 238950 }, + { url = "https://files.pythonhosted.org/packages/49/50/1571810ddd01f99a0a8be464a4ac8b147f322cd1e8e296a1528984fc560b/coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", size = 238610 }, + { url = "https://files.pythonhosted.org/packages/f3/8c/6312d241fe7cbd1f0cade34a62fea6f333d1a261255d76b9a87074d8703c/coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", size = 236697 }, + { url = "https://files.pythonhosted.org/packages/ce/5f/fef33dfd05d87ee9030f614c857deb6df6556b8f6a1c51bbbb41e24ee5ac/coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", size = 238541 }, + { url = "https://files.pythonhosted.org/packages/a9/64/6a984b6e92e1ea1353b7ffa08e27f707a5e29b044622445859200f541e8c/coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", size = 209707 }, + { url = "https://files.pythonhosted.org/packages/5c/60/ce5a9e942e9543783b3db5d942e0578b391c25cdd5e7f342d854ea83d6b7/coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", size = 210439 }, + { url = "https://files.pythonhosted.org/packages/78/53/6719677e92c308207e7f10561a1b16ab8b5c00e9328efc9af7cfd6fb703e/coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", size = 207784 }, + { url = "https://files.pythonhosted.org/packages/fa/dd/7054928930671fcb39ae6a83bb71d9ab5f0afb733172543ced4b09a115ca/coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", size = 208058 }, + { url = "https://files.pythonhosted.org/packages/b5/7d/fd656ddc2b38301927b9eb3aae3fe827e7aa82e691923ed43721fd9423c9/coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", size = 250772 }, + { url = "https://files.pythonhosted.org/packages/90/d0/eb9a3cc2100b83064bb086f18aedde3afffd7de6ead28f69736c00b7f302/coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", size = 246490 }, + { url = "https://files.pythonhosted.org/packages/45/44/3f64f38f6faab8a0cfd2c6bc6eb4c6daead246b97cf5f8fc23bf3788f841/coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", size = 248848 }, + { url = "https://files.pythonhosted.org/packages/5d/11/4c465a5f98656821e499f4b4619929bd5a34639c466021740ecdca42aa30/coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", size = 248340 }, + { url = "https://files.pythonhosted.org/packages/f1/96/ebecda2d016cce9da812f404f720ca5df83c6b29f65dc80d2000d0078741/coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", size = 246229 }, + { url = "https://files.pythonhosted.org/packages/16/d9/3d820c00066ae55d69e6d0eae11d6149a5ca7546de469ba9d597f01bf2d7/coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", size = 247510 }, + { url = "https://files.pythonhosted.org/packages/8f/c3/4fa1eb412bb288ff6bfcc163c11700ff06e02c5fad8513817186e460ed43/coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", size = 210353 }, + { url = "https://files.pythonhosted.org/packages/7e/77/03fc2979d1538884d921c2013075917fc927f41cd8526909852fe4494112/coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", size = 211502 }, + { url = "https://files.pythonhosted.org/packages/fb/27/7efede2355bd1417137246246ab0980751b3ba6065102518a2d1eba6a278/coverage-7.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3", size = 206714 }, + { url = "https://files.pythonhosted.org/packages/f3/94/594af55226676d078af72b329372e2d036f9ba1eb6bcf1f81debea2453c7/coverage-7.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c", size = 207146 }, + { url = "https://files.pythonhosted.org/packages/d5/13/19de1c5315b22795dd67dbd9168281632424a344b648d23d146572e42c2b/coverage-7.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076", size = 235180 }, + { url = "https://files.pythonhosted.org/packages/db/26/8fba01ce9f376708c7efed2761cea740f50a1b4138551886213797a4cecd/coverage-7.6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376", size = 233100 }, + { url = "https://files.pythonhosted.org/packages/74/66/4db60266551b89e820b457bc3811a3c5eaad3c1324cef7730c468633387a/coverage-7.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0", size = 234231 }, + { url = "https://files.pythonhosted.org/packages/2a/9b/7b33f0892fccce50fc82ad8da76c7af1731aea48ec71279eef63a9522db7/coverage-7.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858", size = 233383 }, + { url = "https://files.pythonhosted.org/packages/91/49/6ff9c4e8a67d9014e1c434566e9169965f970350f4792a0246cd0d839442/coverage-7.6.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111", size = 231863 }, + { url = "https://files.pythonhosted.org/packages/81/f9/c9d330dec440676b91504fcceebca0814718fa71c8498cf29d4e21e9dbfc/coverage-7.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901", size = 232854 }, + { url = "https://files.pythonhosted.org/packages/ee/d9/605517a023a0ba8eb1f30d958f0a7ff3a21867b07dcb42618f862695ca0e/coverage-7.6.4-cp39-cp39-win32.whl", hash = "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09", size = 209437 }, + { url = "https://files.pythonhosted.org/packages/aa/79/2626903efa84e9f5b9c8ee6972de8338673fdb5bb8d8d2797740bf911027/coverage-7.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f", size = 210209 }, + { url = "https://files.pythonhosted.org/packages/cc/56/e1d75e8981a2a92c2a777e67c26efa96c66da59d645423146eb9ff3a851b/coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", size = 198954 }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "diff-match-patch" +version = "20241021" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0e/ad/32e1777dd57d8e85fa31e3a243af66c538245b8d64b7265bec9a61f2ca33/diff_match_patch-20241021.tar.gz", hash = "sha256:beae57a99fa48084532935ee2968b8661db861862ec82c6f21f4acdd6d835073", size = 39962 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/bb/2aa9b46a01197398b901e458974c20ed107935c26e44e37ad5b0e5511e44/diff_match_patch-20241021-py3-none-any.whl", hash = "sha256:93cea333fb8b2bc0d181b0de5e16df50dd344ce64828226bda07728818936782", size = 43252 }, +] + +[[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 = "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 = "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 = "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 = "mypy" +version = "1.12.1" +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/17/03/744330105a74dc004578f47ec27e1bf66b1dd5664ea444d18423e41343bd/mypy-1.12.1.tar.gz", hash = "sha256:f5b3936f7a6d0e8280c9bdef94c7ce4847f5cdfc258fbb2c29a8c1711e8bb96d", size = 3150767 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/90/3a83d3bcff2eb85151723f116336bd545995b5260a49d3e0d95213fcc2d7/mypy-1.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3d7d4371829184e22fda4015278fbfdef0327a4b955a483012bd2d423a788801", size = 11017908 }, + { url = "https://files.pythonhosted.org/packages/e4/5c/d6b32ddde2460fc63168ca0f7bf44f38474353547f7c0304a30023c40aa0/mypy-1.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f59f1dfbf497d473201356966e353ef09d4daec48caeacc0254db8ef633a28a5", size = 10184164 }, + { url = "https://files.pythonhosted.org/packages/42/5e/680aa37c938e6db23bd7e6dd4d38d7e609998491721e453b32ec10d31e7f/mypy-1.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b947097fae68004b8328c55161ac9db7d3566abfef72d9d41b47a021c2fba6b1", size = 12587852 }, + { url = "https://files.pythonhosted.org/packages/9e/0f/9cafea1c3aaf852cfa1d4a387f33923b6d9714b5c16eb0469da67c5c31e4/mypy-1.12.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96af62050971c5241afb4701c15189ea9507db89ad07794a4ee7b4e092dc0627", size = 13106489 }, + { url = "https://files.pythonhosted.org/packages/ea/c3/7f56d5d87a81e665de8dfa424120ab3a6954ae5854946cec0a46f78f6168/mypy-1.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:d90da248f4c2dba6c44ddcfea94bb361e491962f05f41990ff24dbd09969ce20", size = 9634753 }, + { url = "https://files.pythonhosted.org/packages/18/0a/70de7c97a86cb85535077ab5cef1cbc4e2812fd2e9cc21d78eb561a6b80f/mypy-1.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1230048fec1380faf240be6385e709c8570604d2d27ec6ca7e573e3bc09c3735", size = 10940998 }, + { url = "https://files.pythonhosted.org/packages/c0/97/9ed6d4834d7549936ab88533b302184fb568a0940c4000d2aaee6dc07112/mypy-1.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:02dcfe270c6ea13338210908f8cadc8d31af0f04cee8ca996438fe6a97b4ec66", size = 10108523 }, + { url = "https://files.pythonhosted.org/packages/48/41/1686f37d09c915dfc5b683e20cc99dabac199900b5ca6d22747b99ddcb50/mypy-1.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5a437c9102a6a252d9e3a63edc191a3aed5f2fcb786d614722ee3f4472e33f6", size = 12505553 }, + { url = "https://files.pythonhosted.org/packages/8d/2b/2dbcaa7e97b23f27ced77493256ee878f4a140ac750e198630ff1b9b60c6/mypy-1.12.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:186e0c8346efc027ee1f9acf5ca734425fc4f7dc2b60144f0fbe27cc19dc7931", size = 12988634 }, + { url = "https://files.pythonhosted.org/packages/54/55/710d082e91a2ccaea21214229b11f9215a9d22446f949491b5457655e82b/mypy-1.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:673ba1140a478b50e6d265c03391702fa11a5c5aff3f54d69a62a48da32cb811", size = 9630747 }, + { url = "https://files.pythonhosted.org/packages/8a/74/b9e0e4f06e951e277058f878302faa154d282ca11274c59fe08353f52949/mypy-1.12.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9fb83a7be97c498176fb7486cafbb81decccaef1ac339d837c377b0ce3743a7f", size = 11079902 }, + { url = "https://files.pythonhosted.org/packages/9f/62/fcad290769db3eb0de265094cef5c94d6075c70bc1e42b67eee4ca192dcc/mypy-1.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:389e307e333879c571029d5b93932cf838b811d3f5395ed1ad05086b52148fb0", size = 10072373 }, + { url = "https://files.pythonhosted.org/packages/cb/27/9ac78349c2952e4446288ec1174675ab9e0160ed18c2cb1154fa456c54e8/mypy-1.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:94b2048a95a21f7a9ebc9fbd075a4fcd310410d078aa0228dbbad7f71335e042", size = 12589779 }, + { url = "https://files.pythonhosted.org/packages/7c/4a/58cebd122cf1cba95680ac51303fbeb508392413ca64e3e711aa7d4877aa/mypy-1.12.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ee5932370ccf7ebf83f79d1c157a5929d7ea36313027b0d70a488493dc1b179", size = 13044459 }, + { url = "https://files.pythonhosted.org/packages/5b/c7/672935e2a3f9bcc07b1b870395a653f665657bef3cdaa504ad99f56eadf0/mypy-1.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:19bf51f87a295e7ab2894f1d8167622b063492d754e69c3c2fed6563268cb42a", size = 9731919 }, + { url = "https://files.pythonhosted.org/packages/bb/b0/092be5094840a401940c95224f63bb2a8f09bce9251ac1df180ec523830c/mypy-1.12.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d34167d43613ffb1d6c6cdc0cc043bb106cac0aa5d6a4171f77ab92a3c758bcc", size = 11068611 }, + { url = "https://files.pythonhosted.org/packages/9a/86/f20f53b8f062876c39602243d7a59b5cabd6b24315d8de511d607fa4de6a/mypy-1.12.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:427878aa54f2e2c5d8db31fa9010c599ed9f994b3b49e64ae9cd9990c40bd635", size = 10068036 }, + { url = "https://files.pythonhosted.org/packages/84/c7/1dbd6575785522da1d4c1ac2c419505fcf23bee74811880cac447a4a77ab/mypy-1.12.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5fcde63ea2c9f69d6be859a1e6dd35955e87fa81de95bc240143cf00de1f7f81", size = 12585671 }, + { url = "https://files.pythonhosted.org/packages/46/8a/f6ae18b446eb2bccce54c4bd94065bcfe417d6c67021dcc032bf1e720aff/mypy-1.12.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d54d840f6c052929f4a3d2aab2066af0f45a020b085fe0e40d4583db52aab4e4", size = 13036083 }, + { url = "https://files.pythonhosted.org/packages/59/e6/fc65fde3dc7156fce8d49ba21c7b1f5d866ad50467bf196ca94a7f6d2c9e/mypy-1.12.1-cp313-cp313-win_amd64.whl", hash = "sha256:20db6eb1ca3d1de8ece00033b12f793f1ea9da767334b7e8c626a4872090cf02", size = 9735467 }, + { url = "https://files.pythonhosted.org/packages/ee/dc/98c84202135943428963858bbd4d469b44f0fe0659c885f2e790fc77a9e3/mypy-1.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:de5b2a8988b4e1269a98beaf0e7cc71b510d050dce80c343b53b4955fff45f19", size = 11014712 }, + { url = "https://files.pythonhosted.org/packages/20/6a/7fd68f58f457efb6d30206c5c454ef26cd71ed6f7dbc87dc9cee68e1d805/mypy-1.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843826966f1d65925e8b50d2b483065c51fc16dc5d72647e0236aae51dc8d77e", size = 10179252 }, + { url = "https://files.pythonhosted.org/packages/bd/31/4948ea5e9331d1fec202fdeb2a3184b53752f7e914533d884500dba3233f/mypy-1.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9fe20f89da41a95e14c34b1ddb09c80262edcc295ad891f22cc4b60013e8f78d", size = 12585725 }, + { url = "https://files.pythonhosted.org/packages/6d/6d/76c52b69799a0338e9a938eee3171a9794c4b9b7eba80080aee20355eb31/mypy-1.12.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8135ffec02121a75f75dc97c81af7c14aa4ae0dda277132cfcd6abcd21551bfd", size = 13103153 }, + { url = "https://files.pythonhosted.org/packages/5c/b1/e77a79a4895e1a4009f07bc1b8639f251bb5dd3029d7110a3c07d76f021b/mypy-1.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:a7b76fa83260824300cc4834a3ab93180db19876bce59af921467fd03e692810", size = 9631585 }, + { url = "https://files.pythonhosted.org/packages/84/6b/1db9de4e0764778251fb2d64cb7455cf6db75dc99c9f72c8b7e74b6a8a17/mypy-1.12.1-py3-none-any.whl", hash = "sha256:ce561a09e3bb9863ab77edf29ae3a50e65685ad74bba1431278185b7e5d5486e", size = 2646060 }, +] + +[[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 = "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 = "parallel-corpus" +version = "0.1.2" +source = { editable = "." } +dependencies = [ + { name = "diff-match-patch" }, + { name = "more-itertools" }, + { name = "strenum" }, + { name = "typing-extensions" }, +] + +[package.dev-dependencies] +dev = [ + { name = "bump-my-version" }, + { name = "mypy" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, + { name = "syrupy" }, +] + +[package.metadata] +requires-dist = [ + { name = "diff-match-patch", specifier = ">=20230430" }, + { name = "more-itertools", specifier = ">=10.2.0" }, + { name = "strenum", specifier = ">=0.4.15" }, + { name = "typing-extensions", specifier = ">=4.11.0" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "bump-my-version", specifier = ">=0.28.0" }, + { name = "mypy", specifier = ">=1.12.1" }, + { name = "pytest", specifier = ">=8.3.3" }, + { name = "pytest-cov", specifier = ">=5.0.0" }, + { name = "ruff", specifier = ">=0.7.0" }, + { name = "syrupy", specifier = ">=4.7.2" }, +] + +[[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 = "prompt-toolkit" +version = "3.0.36" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/93/180be2342f89f16543ec4eb3f25083b5b84eba5378f68efff05409fb39a9/prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63", size = 423863 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/37/791f1a6edd13c61cac85282368aa68cb0f3f164440fdf60032f2cc6ca34e/prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305", size = 386414 }, +] + +[[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/7a/04/2580b2deaae37b3e30fc30c54298be938b973990b23612d6b61c7bdd01c7/pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a", size = 1868200 }, + { url = "https://files.pythonhosted.org/packages/39/6e/e311bd0751505350f0cdcee3077841eb1f9253c5a1ddbad048cd9fbf7c6e/pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36", size = 1749316 }, + { url = "https://files.pythonhosted.org/packages/d0/b4/95b5eb47c6dc8692508c3ca04a1f8d6f0884c9dacb34cf3357595cbe73be/pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b", size = 1800880 }, + { url = "https://files.pythonhosted.org/packages/da/79/41c4f817acd7f42d94cd1e16526c062a7b089f66faed4bd30852314d9a66/pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323", size = 1807077 }, + { url = "https://files.pythonhosted.org/packages/fb/53/d13d1eb0a97d5c06cf7a225935d471e9c241afd389a333f40c703f214973/pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3", size = 2002859 }, + { url = "https://files.pythonhosted.org/packages/53/7d/6b8a1eff453774b46cac8c849e99455b27167971a003212f668e94bc4c9c/pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df", size = 2661437 }, + { url = "https://files.pythonhosted.org/packages/6c/ea/8820f57f0b46e6148ee42d8216b15e8fe3b360944284bbc705bf34fac888/pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c", size = 2054404 }, + { url = "https://files.pythonhosted.org/packages/0f/36/d4ae869e473c3c7868e1cd1e2a1b9e13bce5cd1a7d287f6ac755a0b1575e/pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55", size = 1921680 }, + { url = "https://files.pythonhosted.org/packages/0d/f8/eed5c65b80c4ac4494117e2101973b45fc655774ef647d17dde40a70f7d2/pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040", size = 1966093 }, + { url = "https://files.pythonhosted.org/packages/e8/c8/1d42ce51d65e571ab53d466cae83434325a126811df7ce4861d9d97bee4b/pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605", size = 2111437 }, + { url = "https://files.pythonhosted.org/packages/aa/c9/7fea9d13383c2ec6865919e09cffe44ab77e911eb281b53a4deaafd4c8e8/pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6", size = 1735049 }, + { url = "https://files.pythonhosted.org/packages/98/95/dd7045c4caa2b73d0bf3b989d66b23cfbb7a0ef14ce99db15677a000a953/pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29", size = 1920180 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/32/fd/ac9cdfaaa7cf2d32590b807d900612b39acb25e5527c3c7e482f0553025b/pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21", size = 1857850 }, + { url = "https://files.pythonhosted.org/packages/08/fe/038f4b2bcae325ea643c8ad353191187a4c92a9c3b913b139289a6f2ef04/pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb", size = 1740265 }, + { url = "https://files.pythonhosted.org/packages/51/14/b215c9c3cbd1edaaea23014d4b3304260823f712d3fdee52549b19b25d62/pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59", size = 1793912 }, + { url = "https://files.pythonhosted.org/packages/62/de/2c3ad79b63ba564878cbce325be725929ba50089cd5156f89ea5155cb9b3/pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577", size = 1942870 }, + { url = "https://files.pythonhosted.org/packages/cb/55/c222af19e4644c741b3f3fe4fd8bbb6b4cdca87d8a49258b61cf7826b19e/pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744", size = 1915610 }, + { url = "https://files.pythonhosted.org/packages/c4/7a/9a8760692a6f76bb54bcd43f245ff3d8b603db695899bbc624099c00af80/pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef", size = 1958403 }, + { url = "https://files.pythonhosted.org/packages/4c/91/9b03166feb914bb5698e2f6499e07c2617e2eebf69f9374d0358d7eb2009/pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8", size = 2101154 }, + { url = "https://files.pythonhosted.org/packages/1d/d9/1d7ecb98318da4cb96986daaf0e20d66f1651d0aeb9e2d4435b916ce031d/pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e", size = 1920855 }, +] + +[[package]] +name = "pydantic-settings" +version = "2.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6c/66/5f1a9da10675bfb3b9da52f5b689c77e0a5612263fcce510cfac3e99a168/pydantic_settings-2.6.0.tar.gz", hash = "sha256:44a1804abffac9e6a30372bb45f6cafab945ef5af25e66b1c634c01dd39e0188", size = 75232 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/19/26bb6bdb9fdad5f0dfce538780814084fb667b4bc37fcb28459c14b8d3b5/pydantic_settings-2.6.0-py3-none-any.whl", hash = "sha256:4a819166f119b74d7f8c765196b165f95cc7487ce58ea27dec8a5a26be0970e0", size = 28578 }, +] + +[[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 = "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 = "python-dotenv" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, +] + +[[package]] +name = "questionary" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "prompt-toolkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/84/d0/d73525aeba800df7030ac187d09c59dc40df1c878b4fab8669bdc805535d/questionary-2.0.1.tar.gz", hash = "sha256:bcce898bf3dbb446ff62830c86c5c6fb9a22a54146f0f5597d3da43b10d8fc8b", size = 24726 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/e7/2dd8f59d1d328773505f78b85405ddb1cfe74126425d076ce72e65540b8b/questionary-2.0.1-py3-none-any.whl", hash = "sha256:8ab9a01d0b91b68444dff7f6652c1e754105533f083cbe27597c8110ecc230a2", size = 34248 }, +] + +[[package]] +name = "rich" +version = "13.9.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/aa/9e/1784d15b057b0075e5136445aaea92d23955aad2c93eaede673718a40d95/rich-13.9.2.tar.gz", hash = "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c", size = 222843 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/91/5474b84e505a6ccc295b2d322d90ff6aa0746745717839ee0c5fb4fdcceb/rich-13.9.2-py3-none-any.whl", hash = "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1", size = 242117 }, +] + +[[package]] +name = "rich-click" +version = "1.8.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/a9/a1f1af87e83832d794342fbc09c96cc7cd6798b8dfb8adfbe6ccbef8d70c/rich_click-1.8.3.tar.gz", hash = "sha256:6d75bdfa7aa9ed2c467789a0688bc6da23fbe3a143e19aa6ad3f8bac113d2ab3", size = 38209 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/ea/5a0c5a8e6532e971983d1b0fc99268eb66a10f489da35d9022ce01044191/rich_click-1.8.3-py3-none-any.whl", hash = "sha256:636d9c040d31c5eee242201b5bf4f2d358bfae4db14bb22ec1cafa717cfd02cd", size = 35032 }, +] + +[[package]] +name = "ruff" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/c7/f3367d1da5d568192968c5c9e7f3d51fb317b9ac04828493b23d8fce8ce6/ruff-0.7.0.tar.gz", hash = "sha256:47a86360cf62d9cd53ebfb0b5eb0e882193fc191c6d717e8bef4462bc3b9ea2b", size = 3146645 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/59/a0275a0913f3539498d116046dd679cd657fe3b7caf5afe1733319414932/ruff-0.7.0-py3-none-linux_armv6l.whl", hash = "sha256:0cdf20c2b6ff98e37df47b2b0bd3a34aaa155f59a11182c1303cce79be715628", size = 10434007 }, + { url = "https://files.pythonhosted.org/packages/cd/94/da0ba5f956d04c90dd899209904210600009dcda039ce840d83eb4298c7d/ruff-0.7.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:496494d350c7fdeb36ca4ef1c9f21d80d182423718782222c29b3e72b3512737", size = 10048066 }, + { url = "https://files.pythonhosted.org/packages/57/1d/e5cc149ecc46e4f203403a79ccd170fad52d316f98b87d0f63b1945567db/ruff-0.7.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:214b88498684e20b6b2b8852c01d50f0651f3cc6118dfa113b4def9f14faaf06", size = 9711389 }, + { url = "https://files.pythonhosted.org/packages/05/67/fb7ea2c869c539725a16c5bc294e9aa34f8b1b6fe702f1d173a5da517c2b/ruff-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630fce3fefe9844e91ea5bbf7ceadab4f9981f42b704fae011bb8efcaf5d84be", size = 10755174 }, + { url = "https://files.pythonhosted.org/packages/5f/f0/13703bc50536a0613ea3dce991116e5f0917a1f05528c6ab738b33c08d3f/ruff-0.7.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:211d877674e9373d4bb0f1c80f97a0201c61bcd1e9d045b6e9726adc42c156aa", size = 10196040 }, + { url = "https://files.pythonhosted.org/packages/99/c1/77b04ab20324ab03d333522ee55fb0f1c38e3ca0d326b4905f82ce6b6c70/ruff-0.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:194d6c46c98c73949a106425ed40a576f52291c12bc21399eb8f13a0f7073495", size = 11033684 }, + { url = "https://files.pythonhosted.org/packages/f2/97/f463334dc4efeea3551cd109163df15561c18a1c3ec13d51643740fd36ba/ruff-0.7.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:82c2579b82b9973a110fab281860403b397c08c403de92de19568f32f7178598", size = 11803700 }, + { url = "https://files.pythonhosted.org/packages/b4/f8/a31d40c4bb92933d376a53e7c5d0245d9b27841357e4820e96d38f54b480/ruff-0.7.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9af971fe85dcd5eaed8f585ddbc6bdbe8c217fb8fcf510ea6bca5bdfff56040e", size = 11347848 }, + { url = "https://files.pythonhosted.org/packages/83/62/0c133b35ddaf91c65c30a56718b80bdef36bfffc35684d29e3a4878e0ea3/ruff-0.7.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b641c7f16939b7d24b7bfc0be4102c56562a18281f84f635604e8a6989948914", size = 12480632 }, + { url = "https://files.pythonhosted.org/packages/46/96/464058dd1d980014fb5aa0a1254e78799efb3096fc7a4823cd66a1621276/ruff-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d71672336e46b34e0c90a790afeac8a31954fd42872c1f6adaea1dff76fd44f9", size = 10941919 }, + { url = "https://files.pythonhosted.org/packages/a0/f7/bda37ec77986a435dde44e1f59374aebf4282a5fa9cf17735315b847141f/ruff-0.7.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ab7d98c7eed355166f367597e513a6c82408df4181a937628dbec79abb2a1fe4", size = 10745519 }, + { url = "https://files.pythonhosted.org/packages/c2/33/5f77fc317027c057b61a848020a47442a1cbf12e592df0e41e21f4d0f3bd/ruff-0.7.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1eb54986f770f49edb14f71d33312d79e00e629a57387382200b1ef12d6a4ef9", size = 10284872 }, + { url = "https://files.pythonhosted.org/packages/ff/50/98aec292bc9537f640b8d031c55f3414bf15b6ed13b3e943fed75ac927b9/ruff-0.7.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:dc452ba6f2bb9cf8726a84aa877061a2462afe9ae0ea1d411c53d226661c601d", size = 10600334 }, + { url = "https://files.pythonhosted.org/packages/f2/85/12607ae3201423a179b8cfadc7cb1e57d02cd0135e45bd0445acb4cef327/ruff-0.7.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4b406c2dce5be9bad59f2de26139a86017a517e6bcd2688da515481c05a2cb11", size = 11017333 }, + { url = "https://files.pythonhosted.org/packages/d4/7f/3b85a56879e705d5f46ec14daf8a439fca05c3081720fe3dc3209100922d/ruff-0.7.0-py3-none-win32.whl", hash = "sha256:f6c968509f767776f524a8430426539587d5ec5c662f6addb6aa25bc2e8195ec", size = 8570962 }, + { url = "https://files.pythonhosted.org/packages/39/9f/c5ee2b40d377354dabcc23cff47eb299de4b4d06d345068f8f8cc1eadac8/ruff-0.7.0-py3-none-win_amd64.whl", hash = "sha256:ff4aabfbaaba880e85d394603b9e75d32b0693152e16fa659a3064a85df7fce2", size = 9365544 }, + { url = "https://files.pythonhosted.org/packages/89/8b/ee1509f60148cecba644aa718f6633216784302458340311898aaf0b1bed/ruff-0.7.0-py3-none-win_arm64.whl", hash = "sha256:10842f69c245e78d6adec7e1db0a7d9ddc2fff0621d730e61657b64fa36f207e", size = 8695763 }, +] + +[[package]] +name = "strenum" +version = "0.4.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/85/ad/430fb60d90e1d112a62ff57bdd1f286ec73a2a0331272febfddd21f330e1/StrEnum-0.4.15.tar.gz", hash = "sha256:878fb5ab705442070e4dd1929bb5e2249511c0bcf2b0eeacf3bcd80875c82eff", size = 23384 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/69/297302c5f5f59c862faa31e6cb9a4cd74721cd1e052b38e464c5b402df8b/StrEnum-0.4.15-py3-none-any.whl", hash = "sha256:a30cda4af7cc6b5bf52c8055bc4bf4b2b6b14a93b574626da33df53cf7740659", size = 8851 }, +] + +[[package]] +name = "syrupy" +version = "4.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/81/f46d234fa4ca0edcdeed973bab9acd8f8ac186537cdc850e9e84a00f61a0/syrupy-4.7.2.tar.gz", hash = "sha256:ea45e099f242de1bb53018c238f408a5bb6c82007bc687aefcbeaa0e1c2e935a", size = 49320 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/75/57b629fdd256efc58fb045618d603ce0b0f5fcc477f34b758e34423efb99/syrupy-4.7.2-py3-none-any.whl", hash = "sha256:eae7ba6be5aed190237caa93be288e97ca1eec5ca58760e4818972a10c4acc64", size = 49234 }, +] + +[[package]] +name = "tomli" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/b9/de2a5c0144d7d75a57ff355c0c24054f965b2dc3036456ae03a51ea6264b/tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed", size = 16096 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/db/ce8eda256fa131af12e0a76d481711abe4681b6923c27efb9a255c9e4594/tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", size = 13237 }, +] + +[[package]] +name = "tomlkit" +version = "0.13.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/09/a439bec5888f00a54b8b9f05fa94d7f901d6735ef4e55dcec9bc37b5d8fa/tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79", size = 192885 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/b6/a447b5e4ec71e13871be01ba81f5dfc9d0af7e473da256ff46bc0e24026f/tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", size = 37955 }, +] + +[[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 = "wcmatch" +version = "10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "bracex" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/41/ab/b3a52228538ccb983653c446c1656eddf1d5303b9cb8b9aef6a91299f862/wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a", size = 115578 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/df/4ee467ab39cc1de4b852c212c1ed3becfec2e486a51ac1ce0091f85f38d7/wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a", size = 39347 }, +] + +[[package]] +name = "wcwidth" +version = "0.2.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 }, +] From f73b2e1a1400b9450d2deaa6ef3e5b574d514994 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Tue, 22 Oct 2024 13:27:22 +0200 Subject: [PATCH 15/19] test: update snapshots --- pyproject.toml | 5 +++++ tests/__snapshots__/test_graph.ambr | 1 + tests/__snapshots__/test_token.ambr | 1 + tests/test_shared/__snapshots__/test_ranges.ambr | 1 + uv.lock | 6 ++++++ 5 files changed, 14 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index e05f86f..c0b12ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,11 @@ classifiers = [ "Topic :: Utilities", ] +[project.optional-dependencies] +dev = [ + "pytest>=8.3.3", +] + [build-system] requires = ["hatchling"] build-backend = "hatchling.build" diff --git a/tests/__snapshots__/test_graph.ambr b/tests/__snapshots__/test_graph.ambr index 1caef9b..94809cd 100644 --- a/tests/__snapshots__/test_graph.ambr +++ b/tests/__snapshots__/test_graph.ambr @@ -1,3 +1,4 @@ +# serializer version: 1 # name: test_unaligned_modify[0-0-new] list([ 'newtest ', diff --git a/tests/__snapshots__/test_token.ambr b/tests/__snapshots__/test_token.ambr index b71427c..1bd81b9 100644 --- a/tests/__snapshots__/test_token.ambr +++ b/tests/__snapshots__/test_token.ambr @@ -1,3 +1,4 @@ +# serializer version: 1 # name: test_tokenize[ -expected2] list([ ' ', diff --git a/tests/test_shared/__snapshots__/test_ranges.ambr b/tests/test_shared/__snapshots__/test_ranges.ambr index 55f2833..950975e 100644 --- a/tests/test_shared/__snapshots__/test_ranges.ambr +++ b/tests/test_shared/__snapshots__/test_ranges.ambr @@ -1,3 +1,4 @@ +# serializer version: 1 # name: test_edit_range[-01] dict({ 'from': 0, diff --git a/uv.lock b/uv.lock index 71bfcaa..55566aa 100644 --- a/uv.lock +++ b/uv.lock @@ -262,6 +262,11 @@ dependencies = [ { name = "typing-extensions" }, ] +[package.optional-dependencies] +dev = [ + { name = "pytest" }, +] + [package.dev-dependencies] dev = [ { name = "bump-my-version" }, @@ -276,6 +281,7 @@ dev = [ requires-dist = [ { name = "diff-match-patch", specifier = ">=20230430" }, { name = "more-itertools", specifier = ">=10.2.0" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.3" }, { name = "strenum", specifier = ">=0.4.15" }, { name = "typing-extensions", specifier = ">=4.11.0" }, ] From 056b7d6710a3bf59c8caf968a02363f6e377e348 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Tue, 22 Oct 2024 14:09:13 +0200 Subject: [PATCH 16/19] refactor: fix some lint errors --- ruff.toml | 90 +++++++++++++++------- src/parallel_corpus/__init__.py | 1 + src/parallel_corpus/graph.py | 71 ++++++++--------- src/parallel_corpus/shared/__init__.py | 2 + src/parallel_corpus/shared/dicts.py | 8 +- src/parallel_corpus/shared/diffs.py | 44 ++++++----- src/parallel_corpus/shared/functional.py | 4 +- src/parallel_corpus/shared/ids.py | 4 +- src/parallel_corpus/shared/lists.py | 16 ++-- src/parallel_corpus/shared/ranges.py | 9 ++- src/parallel_corpus/shared/str_map.py | 4 +- src/parallel_corpus/shared/union_find.py | 39 +++++----- src/parallel_corpus/shared/unique_check.py | 18 +++-- src/parallel_corpus/source_target.py | 10 ++- src/parallel_corpus/token.py | 19 +++-- tests/test_graph.py | 19 ++--- tests/test_shared/test_ids.py | 2 +- tests/test_shared/test_lists.py | 4 +- tests/test_shared/test_ranges.py | 23 +++--- tests/test_token.py | 3 +- 20 files changed, 232 insertions(+), 158 deletions(-) diff --git a/ruff.toml b/ruff.toml index 66c360d..4221071 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,36 +1,74 @@ line-length = 97 -target-version = "py38" - [lint] -# Enable flake8-bugbear (`B`) rules. select = [ - "A", - # "ANN", - "B", - "BLE", - "C4", - "C90", - # "D", - "E", - "F", - "FBT", - "I", - "RUF", - "S", - "YTT", + "A", # flake8-builtins + "ANN", # flake8-annotations + "ARG", # flake8-unused-arguments + "B", # flake8-bugbear + "C4", # flake8-comprehensions + "COM", # flake8-commas + "D", # pydocstyle + "D400", # pydocstyle: ends-in-period + "D401", # pydocstyle: non-imperative-mood + "E", # pycodestyle: errors + "F", # Pyflakes + "FLY", # flynt + "FURB", # refurb + "G", # flake8-logging-format + "I", # isort + "ISC", # flake8-implicit-str-concat + "N", # pep8-naming + "PERF", # Perflint + "PIE", # flake8-pie + "PL", # Pylint + "PT", # flake8-pytest-style + "PTH", # flake8-use-pathlib + "Q", # flake8-quotes + "RET", # flake8-return + "RSE", # flake8-raise + "RUF", # Ruff-specific rules + "SIM", # flake8-simplify + "T20", # flake8-print + "TID", # flake8-tidy-imports + "UP", # pyupgrade + "W", # pycodestyle: warnings +] +ignore = [ + "ANN101", # flake8-annotations: missing-type-self (deprecated) + "ANN102", # flake8-annotations: missing-type-cls (deprecated) + "ANN401", # flake8-annotations: any-type + "B008", # flake8-bugbear: function-call-in-default-argument + "COM812", # flake8-commas: missing-trailing-comma + "E741", # pycodestyle: ambiguous-variable-name + "PLR09", # Pylint: too-many-* + "PLR1702", # Pylint: too-many-nested-blocks + "SIM105", # flake8-simplify: suppressible-exception ] +preview = true -# Never enforce `E501` (line length violations). -# ignore = ["E501"] -ignore = ["ANN101", "ANN102", "D203", "D213"] +[lint.per-file-ignores] +"__init__.py" = ["F401"] +"tests/*.py" = [ + "D100", + "D101", + "D102", + "D103", + "D104", + "S101", + "ANN001", + "PLR2004", + "N806", + "T201", +] +[lint.pydocstyle] +convention = "google" -# Avoid trying to fix flake8-bugbear (`B`) violations. -unfixable = ["B"] +# # Never enforce `E501` (line length violations). +# # ignore = ["E501"] +# ignore = ["ANN101", "ANN102", "D203", "D213"] -# Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`. -[lint.per-file-ignores] -"tests/*.py" = ["D100", "D101", "D102", "D103", "D104", "S101"] -# "__init__.py" = ["E402"] +# # Avoid trying to fix flake8-bugbear (`B`) violations. +# unfixable = ["B"] diff --git a/src/parallel_corpus/__init__.py b/src/parallel_corpus/__init__.py index e69de29..ce72650 100644 --- a/src/parallel_corpus/__init__.py +++ b/src/parallel_corpus/__init__.py @@ -0,0 +1 @@ +"""Parallel corpus as a graph.""" diff --git a/src/parallel_corpus/graph.py b/src/parallel_corpus/graph.py index b29ebeb..f083907 100644 --- a/src/parallel_corpus/graph.py +++ b/src/parallel_corpus/graph.py @@ -26,7 +26,7 @@ @dataclass -class Edge: +class Edge: # noqa: D101 # a copy of the identifier used in the edges object of the graph id: str # these are ids to source and target tokens @@ -42,26 +42,26 @@ class Edge: @dataclass -class Graph(SourceTarget[List[Token]]): +class Graph(SourceTarget[List[Token]]): # noqa: D101 edges: Edges comment: Optional[str] = None - def copy_with_updated_side_and_edges( + def copy_with_updated_side_and_edges( # noqa: D102 self, side: Side, new_tokens: List[Token], edges: Edges ) -> "Graph": source = self.source if side == Side.target else new_tokens target = new_tokens if side == Side.target else self.target return Graph(source=source, target=target, edges=edges, comment=self.comment) - def copy_with_edges(self, edges: Edges) -> "Graph": + def copy_with_edges(self, edges: Edges) -> "Graph": # noqa: D102 return Graph(source=self.source, target=self.target, edges=edges, comment=self.comment) -def next_id(g: Graph) -> int: +def next_id(g: Graph) -> int: # noqa: D103 return ids.next_id(itertools.chain((t.id for t in g.target), (s.id for s in g.source))) -def edge( +def edge( # noqa: D103 ids: List[str], labels: List[str], *, @@ -79,21 +79,21 @@ def edge( ) -def edge_record(es: Iterable[Edge]) -> Dict[str, Edge]: +def edge_record(es: Iterable[Edge]) -> Dict[str, Edge]: # noqa: D103 return {e.id: e for e in es} -def init(s: str, *, manual: bool = False) -> Graph: +def init(s: str, *, manual: bool = False) -> Graph: # noqa: D103 return init_from(token.tokenize(s), manual=manual) -def init_with_source_and_target(source: str, target: str, *, manual: bool = False) -> Graph: +def init_with_source_and_target(source: str, target: str, *, manual: bool = False) -> Graph: # noqa: D103 return init_from_source_and_target( source=token.tokenize(source), target=token.tokenize(target), manual=manual ) -def init_from(tokens: List[str], *, manual: bool = False) -> Graph: +def init_from(tokens: List[str], *, manual: bool = False) -> Graph: # noqa: D103 return align( Graph( source=token.identify(tokens, "s"), @@ -105,7 +105,7 @@ def init_from(tokens: List[str], *, manual: bool = False) -> Graph: ) -def init_from_source_and_target( +def init_from_source_and_target( # noqa: D103 source: List[str], target: List[str], *, manual: bool = False ) -> Graph: source_tokens = token.identify(source, "s") @@ -124,13 +124,13 @@ def init_from_source_and_target( ) -class TextLabels(TypedDict): +class TextLabels(TypedDict): # noqa: D101 text: str labels: List[str] def from_unaligned(st: SourceTarget[List[TextLabels]]) -> Graph: - """Initialize a graph from unaligned tokens""" + """Initialize a graph from unaligned tokens.""" edges: Dict[str, Edge] = {} def proto_token_to_token(tok: TextLabels, i: int, prefix: str) -> Token: @@ -150,19 +150,19 @@ def proto_tokens_to_tokens(toks: List[TextLabels], side: Side) -> List[Token]: return align(Graph(source=g.source, target=g.target, edges=edges)) -def modify(g: Graph, from_: int, to: int, text: str, side: Side = Side.target) -> Graph: +def modify(g: Graph, from_: int, to: int, text: str, side: Side = Side.target) -> Graph: # noqa: D103 return align(unaligned_modify(g, from_, to, text, side)) -def set_source(g: Graph, text: str) -> Graph: +def set_source(g: Graph, text: str) -> Graph: # noqa: D103 return align(unaligned_set_side(g, Side.source, text)) -def set_target(g: Graph, text: str) -> Graph: +def set_target(g: Graph, text: str) -> Graph: # noqa: D103 return align(unaligned_set_side(g, Side.target, text)) -def merge_edges(*es) -> Edge: +def merge_edges(*es) -> Edge: # noqa: ANN002, D103 ids = [] labels = [] manual = False @@ -184,7 +184,7 @@ def merge_edges(*es) -> Edge: zero_edge = merge_edges() -def align(g: Graph) -> Graph: +def align(g: Graph) -> Graph: # noqa: D103 # Use a union-find to group characters into edges. uf = parallel_corpus.shared.union_find.poly_union_find(lambda u: u) em = edge_map(g) @@ -207,7 +207,7 @@ def align(g: Graph) -> Graph: proto_edges = {k: e for k, e in g.edges.items() if e.manual} first: UniqueCheck[str] = UniqueCheck() - def update_edges(tokens, _side): + def update_edges(tokens, _side) -> None: # noqa: ANN001 for tok in tokens: e_repr = em[tok.id] if not e_repr.manual: @@ -225,21 +225,21 @@ def update_edges(tokens, _side): return g.copy_with_edges(edges) -def rearrange(g: Graph, begin: int, end: int, dest: int) -> Graph: +def rearrange(g: Graph, begin: int, end: int, dest: int) -> Graph: # noqa: D103 return align(unaligned_rearrange(g, begin, end, dest)) -def target_text(g: SourceTarget[List[token.Text]]) -> str: +def target_text(g: SourceTarget[List[token.Text]]) -> str: # noqa: D103 return token.text(g.target) @dataclass -class CharIdPair: +class CharIdPair: # noqa: D101 char: str id: Optional[str] = None -def to_char_ids(token: Token) -> List[CharIdPair]: +def to_char_ids(token: Token) -> List[CharIdPair]: # noqa: D103 return parallel_corpus.shared.str_map.str_map( token.text, lambda char, _i: CharIdPair(char=char, id=None if char == " " else token.id), @@ -247,7 +247,7 @@ def to_char_ids(token: Token) -> List[CharIdPair]: def edge_map(g: Graph) -> Dict[str, Edge]: - """Map from token ids to edges + """Map from token ids to edges. Args: g (Graph): the Graph to build the edge map from. @@ -262,7 +262,7 @@ def edge_map(g: Graph) -> Dict[str, Edge]: return edges -def unaligned_set_side(g: Graph, side: Side, text: str) -> Graph: +def unaligned_set_side(g: Graph, side: Side, text: str) -> Graph: # noqa: D103 text0 = get_side_text(g, side) edits = parallel_corpus.shared.ranges.edit_range(text0, text) @@ -313,7 +313,6 @@ def unaligned_modify( Indexes are character offsets (use CodeMirror's doc.posFromIndex and doc.indexFromPos to convert) """ # noqa: E501 - tokens = get_side_texts(g, side) token_at = token.token_at(tokens, from_) from_token, from_ix = token_at["token"], token_at["offset"] @@ -326,15 +325,15 @@ def unaligned_modify( return unaligned_modify_tokens(g, from_token, to_token + 1, pre + text + post, side) -def get_side_text(g: Graph, side: Side) -> str: +def get_side_text(g: Graph, side: Side) -> str: # noqa: D103 return token.text(g.get_side(side)) -def get_side_texts(g: Graph, side: Side) -> List[str]: +def get_side_texts(g: Graph, side: Side) -> List[str]: # noqa: D103 return token.texts(g.get_side(side)) -def unaligned_modify_tokens( # noqa: C901 +def unaligned_modify_tokens( g: Graph, from_: int, to: int, text: str, side: Side = Side.target ) -> Graph: """Replace the text at some position, merging the spans it touches upon. @@ -366,7 +365,6 @@ def unaligned_modify_tokens( # noqa: C901 Indexes are token offsets """ # noqa: E501 - if ( from_ < 0 or to < 0 @@ -382,13 +380,12 @@ def unaligned_modify_tokens( # noqa: C901 return unaligned_modify_tokens( g, from_ - 1, to, g.get_side(side)[from_ - 1].text + text, side ) - elif to < len(g.get_side(side)): + if to < len(g.get_side(side)): return unaligned_modify_tokens( g, from_, to + 1, text + g.get_side(side)[to].text, side ) - else: - logger.warn("Introducing whitespace into empty graph") + logger.warning("Introducing whitespace into empty graph") if NO_WHITESPACE_AT_END.match(text[-1:]) is not None and to < len(g.get_side(side)): # if replacement text does not end with whitespace, grab the next word as well @@ -421,8 +418,7 @@ def fun(e: Edge, _id: str) -> bool: for id_ in e.ids: if id_ not in ids_removed: new_edge_ids.add(id_) - for lbl in e.labels: - new_edge_labels.add(lbl) + new_edge_labels.update(e.labels) return False return True @@ -436,11 +432,12 @@ def fun(e: Edge, _id: str) -> bool: def unaligned_rearrange(g: Graph, begin: int, end: int, dest: int) -> Graph: - """Moves a slice of the target tokens and puts it at a new destination. + """Move a slice of the target tokens and puts it at a new destination. target_text(unaligned_rearrange(init('apa bepa cepa depa'), 1, 2, 0)) // => 'bepa cepa apa depa ' - Indexes are token offsets""" # noqa: E501 + Indexes are token offsets + """ # noqa: E501 em = edge_map(g) edge_ids_to_update = {em[t.id].id for t in g.target[begin : (end + 1)]} new_edges = {} diff --git a/src/parallel_corpus/shared/__init__.py b/src/parallel_corpus/shared/__init__.py index 04e5599..196f7e7 100644 --- a/src/parallel_corpus/shared/__init__.py +++ b/src/parallel_corpus/shared/__init__.py @@ -1,3 +1,5 @@ +"""Utilities.""" + import re from typing import List, TypeVar diff --git a/src/parallel_corpus/shared/dicts.py b/src/parallel_corpus/shared/dicts.py index 3176a48..7c2c07b 100644 --- a/src/parallel_corpus/shared/dicts.py +++ b/src/parallel_corpus/shared/dicts.py @@ -1,3 +1,5 @@ +"""Dicts.""" + from typing import TYPE_CHECKING, Callable, Dict, List, TypeVar if TYPE_CHECKING: @@ -12,15 +14,15 @@ V = TypeVar("V") -def modify(x: Dict[K, V], k: K, default: V, f: Callable[[V], V]) -> V: +def modify(x: Dict[K, V], k: K, default: V, f: Callable[[V], V]) -> V: # noqa: D103 x[k] = f(x.get(k) or default) return x[k] -def traverse(x: Dict[K, A], k: Callable[[A, K], B], *, sort_keys: bool = False) -> List[B]: +def traverse(x: Dict[K, A], k: Callable[[A, K], B], *, sort_keys: bool = False) -> List[B]: # noqa: D103 ks = sorted(x.keys()) if sort_keys else x.keys() return [k(x[i], i) for i in ks] -def filter_dict(x: Dict[K, A], k: Callable[[A, K], bool]) -> Dict[K, A]: +def filter_dict(x: Dict[K, A], k: Callable[[A, K], bool]) -> Dict[K, A]: # noqa: D103 return {id_: a for id_, a in x.items() if k(a, id_)} diff --git a/src/parallel_corpus/shared/diffs.py b/src/parallel_corpus/shared/diffs.py index 56d55d0..233e29c 100644 --- a/src/parallel_corpus/shared/diffs.py +++ b/src/parallel_corpus/shared/diffs.py @@ -1,5 +1,8 @@ +"""Diffs.""" + import enum -from typing import Callable, Dict, Generic, List, Optional, Tuple, TypeVar, Union +from itertools import starmap +from typing import Any, Callable, Dict, Generator, Generic, List, Optional, Tuple, TypeVar, Union import diff_match_patch as dmp_module from typing_extensions import Self @@ -13,14 +16,14 @@ C = TypeVar("C") -class ChangeType(enum.IntEnum): +class ChangeType(enum.IntEnum): # noqa: D101 DELETED = -1 CONSTANT = 0 INSERTED = 1 -class Change(Generic[A, B]): - def __init__(self, change: ChangeType, a: Optional[A] = None, b: Optional[B] = None): +class Change(Generic[A, B]): # noqa: D101 + def __init__(self, change: ChangeType, a: Optional[A] = None, b: Optional[B] = None) -> None: # noqa: D107 if change == ChangeType.DELETED and a is None: raise ValueError("`a` must be given for DELETED") if change == ChangeType.CONSTANT and (a is None or b is None): @@ -32,18 +35,18 @@ def __init__(self, change: ChangeType, a: Optional[A] = None, b: Optional[B] = N self.b = b @classmethod - def constant(cls, a: A, b: B) -> Self: + def constant(cls, a: A, b: B) -> Self: # noqa: D102 return cls(ChangeType.CONSTANT, a=a, b=b) @classmethod - def deleted(cls, a: A) -> Self: + def deleted(cls, a: A) -> Self: # noqa: D102 return cls(ChangeType.DELETED, a=a) @classmethod - def inserted(cls, b: B) -> Self: + def inserted(cls, b: B) -> Self: # noqa: D102 return cls(ChangeType.INSERTED, b=b) - def model_dump(self) -> Dict[str, Union[int, A, B]]: + def model_dump(self) -> Dict[str, Union[int, A, B]]: # noqa: D102 out: Dict[str, Union[int, A, B]] = { "change": int(self.change), } @@ -53,20 +56,23 @@ def model_dump(self) -> Dict[str, Union[int, A, B]]: out["b"] = self.b return out - def __eq__(self, other) -> bool: + def __eq__(self, other: Any) -> bool: # noqa: D105 if not isinstance(other, Change): return NotImplemented return self.change == other.change and self.a == other.a and self.b == other.b - def __repr__(self) -> str: + def __hash__(self) -> int: # noqa: D105 + return hash((self.change, self.a, self.b)) + + def __repr__(self) -> str: # noqa: D105 return f"Change(change={self.change!r},a={self.a!r},b={self.b!r})" - def __str__(self) -> str: + def __str__(self) -> str: # noqa: D105 return f"Change(change={self.change},a={self.a},b={self.b})" -def char_stream(): - """Make a stream of all unicode characters +def char_stream() -> Generator[str, None, None]: + """Make a stream of all unicode characters. We need this because the diff-match-patch library is hard-coded to work on characters. @@ -87,7 +93,7 @@ def char_stream(): i += 1 -def hdiff( # noqa: C901 +def hdiff( # noqa: D103 xs: List[A], ys: List[B], a_cmp: Callable[[A], str] = str, @@ -111,8 +117,8 @@ def assign(c: C, c_cmp: Callable[[C], str], c_from: Dict[str, List[C]]) -> str: arr.append(c) return u - s1 = "".join((assign(a, a_cmp, a_from) for a in xs)) - s2 = "".join((assign(b, b_cmp, b_from) for b in ys)) + s1 = "".join(assign(a, a_cmp, a_from) for a in xs) + s2 = "".join(assign(b, b_cmp, b_from) for b in ys) d = dmp.diff_main(s1, s2) def str_map_change(change: int) -> Callable[[str, int], Change]: @@ -131,17 +137,17 @@ def inner(c: str, _: int) -> Change: return inner - def map_change(change: int, cs): + def map_change(change: int, cs): # noqa: ANN001, ANN202 return str_map(cs, str_map_change(change)) out = [] - for changes in (map_change(change, cs) for change, cs in d): + for changes in starmap(map_change, d): # print(f"{changes=}") out.extend(changes) return out -def token_diff(s1: str, s2: str) -> List[Tuple[int, str]]: +def token_diff(s1: str, s2: str) -> List[Tuple[int, str]]: # noqa: D103 d = dmp.diff_main(s1, s2) dmp.diff_cleanupSemantic(d) return d diff --git a/src/parallel_corpus/shared/functional.py b/src/parallel_corpus/shared/functional.py index 50a9d94..062bcbd 100644 --- a/src/parallel_corpus/shared/functional.py +++ b/src/parallel_corpus/shared/functional.py @@ -1,9 +1,11 @@ +"""Functional utilities.""" + from typing import Callable, Sequence, TypeVar A = TypeVar("A") -def take_last_while(predicate: Callable[[A], bool], xs: Sequence[A]) -> Sequence[A]: +def take_last_while(predicate: Callable[[A], bool], xs: Sequence[A]) -> Sequence[A]: # noqa: D103 start = 0 for e in reversed(xs): if not predicate(e): diff --git a/src/parallel_corpus/shared/ids.py b/src/parallel_corpus/shared/ids.py index aa0f58a..f1b2510 100644 --- a/src/parallel_corpus/shared/ids.py +++ b/src/parallel_corpus/shared/ids.py @@ -1,3 +1,5 @@ +"""Ids.""" + import re from typing import Iterable @@ -5,7 +7,7 @@ def next_id(xs: Iterable[str]) -> int: - """Calculate the next id to use from these identifiers + """Calculate the next id to use from these identifiers. next_id([]) // => 0 next_id(['t1', 't2', 't3']) // => 4 diff --git a/src/parallel_corpus/shared/lists.py b/src/parallel_corpus/shared/lists.py index ff44b20..a0e25e9 100644 --- a/src/parallel_corpus/shared/lists.py +++ b/src/parallel_corpus/shared/lists.py @@ -1,3 +1,5 @@ +"""List.""" + import copy from typing import List, Tuple, TypeVar @@ -5,13 +7,14 @@ def rearrange(xs: List[A], begin: int, end: int, dest: int) -> List[A]: - """Moves a slice of the items and puts back them at some destination. + """Move a slice of the items and puts back them at some destination. rearrange([0, 1, 2, 3], 1, 2, 0) // => [1, 2, 0, 3] rearrange([0, 1, 2, 3], 1, 2, 3) // => [0, 3, 1, 2] rearrange([0, 1, 2, 3], 1, 2, 1) // => [0, 1, 2, 3] - rearrange([0, 1, 2, 3], 1, 2, 2) // => [0, 1, 2, 3]""" + rearrange([0, 1, 2, 3], 1, 2, 2) // => [0, 1, 2, 3] + """ a, mid, z = split_at_3(xs, begin, end + 1) w = end - begin if dest > begin: @@ -20,7 +23,7 @@ def rearrange(xs: List[A], begin: int, end: int, dest: int) -> List[A]: return pre + mid + post -def splice(xs: List[A], start: int, count: int, *insert) -> Tuple[List[A], List[A]]: +def splice(xs: List[A], start: int, count: int, *insert) -> Tuple[List[A], List[A]]: # noqa: ANN002, D103 ys = copy.deepcopy(xs) zs = ys[start : (start + count)] ys[start : (start + count)] = insert @@ -28,16 +31,17 @@ def splice(xs: List[A], start: int, count: int, *insert) -> Tuple[List[A], List[ def split_at_3(xs: List[A], start: int, end: int) -> Tuple[List[A], List[A], List[A]]: - """Split an array into three pieces + """Split an array into three pieces. splitAt3('0123456'.split(''), 2, 4).map(xs => xs.join('')) // => ['01', '23', '456'] splitAt3('0123456'.split(''), 2, 2).map(xs => xs.join('')) // => ['01', '', '23456'] splitAt3('0123456'.split(''), 2, 9).map(xs => xs.join('')) // => ['01', '23456', ''] - splitAt3('0123456'.split(''), 0, 2).map(xs => xs.join('')) // => ['', '01', '23456']""" + splitAt3('0123456'.split(''), 0, 2).map(xs => xs.join('')) // => ['', '01', '23456'] + """ ab, c = split_at(xs, end) a, b = split_at(ab, start) return a, b, c -def split_at(xs: List[A], index: int) -> Tuple[List[A], List[A]]: +def split_at(xs: List[A], index: int) -> Tuple[List[A], List[A]]: # noqa: D103 return xs[:index], xs[index:] diff --git a/src/parallel_corpus/shared/ranges.py b/src/parallel_corpus/shared/ranges.py index 6945fb6..8040894 100644 --- a/src/parallel_corpus/shared/ranges.py +++ b/src/parallel_corpus/shared/ranges.py @@ -1,3 +1,5 @@ +"""Ranges.""" + import itertools from typing import TypedDict @@ -8,7 +10,8 @@ def edit_range(s0: str, s: str) -> EditRange: - """ + """Create an EditRange. + >>> edit_range('0123456789', '0189') {'from': 2, 'to': 8, 'insert': ''} @@ -39,8 +42,8 @@ def edit_range(s0: str, s: str) -> EditRange: patches = token_diff(s0, s) pre = list(itertools.takewhile(lambda i: i[0] == 0, patches)) post = take_last_while(lambda i: i[0] == 0, patches) - from_ = len("".join((i[1] for i in pre))) - postlen = len("".join((i[1] for i in post))) + from_ = len("".join(i[1] for i in pre)) + postlen = len("".join(i[1] for i in post)) to = len(s0) - postlen insert = s[from_ : (len(s) - (len(s0) - to))] return {"from": from_, "to": to, "insert": insert} diff --git a/src/parallel_corpus/shared/str_map.py b/src/parallel_corpus/shared/str_map.py index d5b68b4..784fabd 100644 --- a/src/parallel_corpus/shared/str_map.py +++ b/src/parallel_corpus/shared/str_map.py @@ -1,7 +1,9 @@ +"""str_map.""" + from typing import Callable, List, TypeVar A = TypeVar("A") -def str_map(s: str, f: Callable[[str, int], A]) -> List[A]: +def str_map(s: str, f: Callable[[str, int], A]) -> List[A]: # noqa: D103 return [f(s[i], i) for i in range(len(s))] diff --git a/src/parallel_corpus/shared/union_find.py b/src/parallel_corpus/shared/union_find.py index e201c5d..6cf01e1 100644 --- a/src/parallel_corpus/shared/union_find.py +++ b/src/parallel_corpus/shared/union_find.py @@ -1,3 +1,5 @@ +"""UnionFind.""" + import abc import functools import json @@ -10,11 +12,11 @@ class UnionFindOperations(abc.ABC, Generic[A]): - """Union-find data structure operations""" + """Union-find data structure operations.""" @abc.abstractmethod def find(self, x: A) -> A: - """What group does this belong to?""" + """Answers what group `x` belongs to.""" @abc.abstractmethod def union(self, x: A, y: A) -> A: @@ -25,11 +27,11 @@ def unions(self, xs: List[A]) -> None: """Make these belong to the same group.""" -class UnionFind(UnionFindOperations[int]): - def __init__(self, *, rev: Optional[List[int]] = None) -> None: +class UnionFind(UnionFindOperations[int]): # noqa: D101 + def __init__(self, *, rev: Optional[List[int]] = None) -> None: # noqa: D107 self._rev: List[int] = rev or [] - def find(self, x: int) -> int: + def find(self, x: int) -> int: # noqa: D102 while x >= len(self._rev): self._rev.append(None) # type: ignore [arg-type] if self._rev[x] is None: @@ -38,25 +40,25 @@ def find(self, x: int) -> int: self._rev[x] = self.find(self._rev[x]) # type: ignore [arg-type] return self._rev[x] # type: ignore [return-value] - def union(self, x: int, y: int) -> int: + def union(self, x: int, y: int) -> int: # noqa: D102 find_x = self.find(x) find_y = self.find(y) if find_x != find_y: self._rev[find_y] = find_x return find_x - def unions(self, xs: List[int]) -> None: + def unions(self, xs: List[int]) -> None: # noqa: D102 functools.reduce(self.union, xs, xs[0]) @dataclass -class Renumber(Generic[A]): +class Renumber(Generic[A]): # noqa: D101 bw: Dict[str, int] fw: Dict[int, A] i = 0 serialize: Callable[[A], str] - def num(self, a: A) -> int: + def num(self, a: A) -> int: # noqa: D102 s = self.serialize(a) if s not in self.bw: self.fw[self.i] = a @@ -64,19 +66,18 @@ def num(self, a: A) -> int: self.i += 1 return self.bw[s] - def un(self, n: int) -> Optional[A]: + def un(self, n: int) -> Optional[A]: # noqa: D102 return self.fw.get(n) @classmethod - def init(cls, serialize: Callable[[A], str] = json.dumps) -> Self: + def init(cls, serialize: Callable[[A], str] = json.dumps) -> Self: # noqa: D102 return cls(bw={}, fw={}, serialize=serialize) def renumber( serialize: Callable[[A], str] = json.dumps, ) -> Tuple[Callable[[int], Optional[A]], Callable[[A], int]]: - """ - Assign unique numbers to each distinct element + """Assign unique numbers to each distinct element. const {un, num} = Renumber() num('foo') // => 0 @@ -97,26 +98,26 @@ def renumber( @dataclass -class PolyUnionFind(Generic[A]): +class PolyUnionFind(Generic[A]): # noqa: D101 _uf: UnionFind _renum: Renumber[A] - def repr(self, x: A) -> int: + def repr(self, x: A) -> int: # noqa: D102 return self._uf.find(self._renum.num(x)) - def find(self, x: A) -> Optional[A]: + def find(self, x: A) -> Optional[A]: # noqa: D102 return self._renum.un(self._uf.find(self._renum.num(x))) - def union(self, x: A, y: A) -> Optional[A]: + def union(self, x: A, y: A) -> Optional[A]: # noqa: D102 return self._renum.un(self._uf.union(self._renum.num(x), self._renum.num(y))) - def unions(self, xs: List[A]) -> None: + def unions(self, xs: List[A]) -> None: # noqa: D102 num_xs_0 = self._renum.num(xs[0]) for x in xs[1:]: self._uf.union(num_xs_0, self._renum.num(x)) -def poly_union_find(serialize: Callable[[str], str]) -> PolyUnionFind: +def poly_union_find(serialize: Callable[[str], str]) -> PolyUnionFind[str]: # noqa: D103 renum = Renumber.init(serialize) uf = UnionFind() return PolyUnionFind(_uf=uf, _renum=renum) diff --git a/src/parallel_corpus/shared/unique_check.py b/src/parallel_corpus/shared/unique_check.py index be6b0d2..71e81e4 100644 --- a/src/parallel_corpus/shared/unique_check.py +++ b/src/parallel_corpus/shared/unique_check.py @@ -1,10 +1,13 @@ +"""UniqueCheck.""" + from typing import Dict, Generic, TypeVar S = TypeVar("S") class UniqueCheck(Generic[S]): - """ + """Check if values are unique. + >>> u = UniqueCheck() >>> u(1) True @@ -20,15 +23,16 @@ class UniqueCheck(Generic[S]): False """ - def __init__(self) -> None: + def __init__(self) -> None: # noqa: D107 self.c: Count[S] = Count() - def __call__(self, s: S) -> bool: + def __call__(self, s: S) -> bool: # noqa: D102 return self.c.inc(s) == 1 class Count(Generic[S]): - """ + """Counter that can be increased and queried. + >>> u = Count() >>> u.inc(1) 1 @@ -50,12 +54,12 @@ class Count(Generic[S]): 1 """ - def __init__(self) -> None: + def __init__(self) -> None: # noqa: D107 self.m: Dict[S, int] = {} - def get(self, s: S) -> int: + def get(self, s: S) -> int: # noqa: D102 return self.m.get(s) or 0 - def inc(self, s: S) -> int: + def inc(self, s: S) -> int: # noqa: D102 self.m[s] = self.get(s) + 1 return self.get(s) diff --git a/src/parallel_corpus/source_target.py b/src/parallel_corpus/source_target.py index f8c2dd2..c555431 100644 --- a/src/parallel_corpus/source_target.py +++ b/src/parallel_corpus/source_target.py @@ -1,3 +1,5 @@ +"""SourceTarget.""" + from dataclasses import dataclass from typing import Callable, Generic, TypeVar @@ -9,19 +11,19 @@ B = TypeVar("B") -class Side(strenum.StrEnum): +class Side(strenum.StrEnum): # noqa: D101 source = "source" target = "target" @dataclass -class SourceTarget(Generic[A]): +class SourceTarget(Generic[A]): # noqa: D101 source: A target: A - def get_side(self, side: Side) -> A: + def get_side(self, side: Side) -> A: # noqa: D102 return self.source if side == Side.source else self.target -def map_sides(g: SourceTarget[A], f: Callable[[A, Side], B]) -> SourceTarget[B]: +def map_sides(g: SourceTarget[A], f: Callable[[A, Side], B]) -> SourceTarget[B]: # noqa: D103 return SourceTarget(source=f(g.source, Side.source), target=f(g.target, Side.target)) diff --git a/src/parallel_corpus/token.py b/src/parallel_corpus/token.py index ff6e32c..9e10cb5 100644 --- a/src/parallel_corpus/token.py +++ b/src/parallel_corpus/token.py @@ -1,3 +1,5 @@ +"""Token.""" + import re from dataclasses import dataclass from typing import List, Sequence, TypedDict @@ -6,23 +8,23 @@ @dataclass -class Text: +class Text: # noqa: D101 text: str @dataclass -class Token(Text): +class Token(Text): # noqa: D101 id: str @dataclass -class Span: +class Span: # noqa: D101 begin: int end: int def text(ts: Sequence[Text]) -> str: - """The text in some tokens + """Return text from the given tokens as string. >>> text(identify(tokenize('apa bepa cepa '), '#')) 'apa bepa cepa ' @@ -32,7 +34,7 @@ def text(ts: Sequence[Text]) -> str: def texts(ts: Sequence[Text]) -> List[str]: - """The texts in some tokens + """Return text from the given tokens as list. >>> texts(identify(tokenize('apa bepa cepa '), '#')) ['apa ', 'bepa ', 'cepa '] @@ -50,17 +52,18 @@ def tokenize(s: str) -> List[str]: ) -def identify(toks: List[str], prefix: str) -> List[Token]: +def identify(toks: List[str], prefix: str) -> List[Token]: # noqa: D103 return [Token(text=text, id=f"{prefix}{i}") for i, text in enumerate(toks)] -class TokenAt(TypedDict): +class TokenAt(TypedDict): # noqa: D101 token: int offset: int def token_at(tokens: List[str], character_offset: int) -> TokenAt: - """ + """Return token at the given offset. + >>> abc = ['012', '3456', '789'] >>> token_at(abc, 0) {'token': 0, 'offset': 0} diff --git a/tests/test_graph.py b/tests/test_graph.py index 5103be0..06a8b81 100644 --- a/tests/test_graph.py +++ b/tests/test_graph.py @@ -1,6 +1,7 @@ from typing import List import pytest + from parallel_corpus import graph, token from parallel_corpus.source_target import Side, SourceTarget @@ -180,15 +181,15 @@ def show_source(g: graph.Graph) -> List[str]: def ids(g: graph.Graph) -> str: - return " ".join((t.id for t in g.target)) + return " ".join(t.id for t in g.target) def ids_source(g: graph.Graph) -> str: - return " ".join((s.id for s in g.source)) + return " ".join(s.id for s in g.source) @pytest.mark.parametrize( - "i0, i1, word", + ("i0", "i1", "word"), [ (0, 0, "new"), (0, 1, "new"), @@ -202,7 +203,7 @@ def ids_source(g: graph.Graph) -> str: (16, 16, " !"), ], ) -def test_unaligned_modify(i0: int, i1: int, word: str, snapshot): +def test_unaligned_modify(i0: int, i1: int, word: str, snapshot) -> None: g = graph.init("test graph hello") assert g is not None assert show(graph.unaligned_modify(g, i0, i1, word)) == snapshot @@ -223,13 +224,13 @@ def test_unaligned_modify_tokens() -> None: assert ids(g) == "t0 t1 t2" -@pytest.mark.parametrize("text, expected", [("this", True), ("this ", False)]) +@pytest.mark.parametrize(("text", "expected"), [("this", True), ("this ", False)]) def test_no_whitespace_at_end(text: str, *, expected: bool) -> None: assert (graph.NO_WHITESPACE_AT_END.match(text[-1:]) is not None) is expected @pytest.mark.parametrize( - "from_, to, text", + ("from_", "to", "text"), [ (0, 0, "this "), (0, 1, "this "), @@ -250,7 +251,7 @@ def test_unaligned_modify_tokens_show(from_: int, to: int, text: str, snapshot) @pytest.mark.parametrize( - "from_, to, text", + ("from_", "to", "text"), [ (0, 0, "this "), (0, 1, "this "), @@ -263,7 +264,7 @@ def test_unaligned_modify_tokens_ids(from_: int, to: int, text: str, snapshot) - @pytest.mark.parametrize( - "from_, to, text", + ("from_", "to", "text"), [ (0, 0, "this "), ], @@ -276,7 +277,7 @@ def test_unaligned_modify_tokens_show_source(from_: int, to: int, text: str, sna @pytest.mark.parametrize( - "from_, to, text", + ("from_", "to", "text"), [ (0, 0, "this "), ], diff --git a/tests/test_shared/test_ids.py b/tests/test_shared/test_ids.py index 152683e..31cade1 100644 --- a/tests/test_shared/test_ids.py +++ b/tests/test_shared/test_ids.py @@ -1,7 +1,7 @@ from parallel_corpus.shared.ids import next_id -def test_next_id(): +def test_next_id() -> None: assert next_id([]) == 0 assert next_id(["t1", "t2", "t3"]) == 4 assert next_id(["u2v5k1", "b3", "a0"]) == 6 diff --git a/tests/test_shared/test_lists.py b/tests/test_shared/test_lists.py index 010742a..797c2f4 100644 --- a/tests/test_shared/test_lists.py +++ b/tests/test_shared/test_lists.py @@ -1,14 +1,14 @@ from parallel_corpus.shared import lists -def test_splice_1(): +def test_splice_1() -> None: (*s_chars,) = "abcdef" ex, rm = lists.splice(s_chars, 3, 1, " ", "_") assert "".join(ex) == "abc _ef" assert "".join(rm) == "d" -def test_splice_2(): +def test_splice_2() -> None: (*s_chars,) = "abcdef" (ex, rm) = lists.splice(s_chars, 3, 2, " ", "_") assert "".join(ex) == "abc _f" diff --git a/tests/test_shared/test_ranges.py b/tests/test_shared/test_ranges.py index ae16bbe..16a06df 100644 --- a/tests/test_shared/test_ranges.py +++ b/tests/test_shared/test_ranges.py @@ -1,20 +1,23 @@ +import string + import pytest + from parallel_corpus.shared.ranges import edit_range @pytest.mark.parametrize( - "s0, s", + ("s0", "s"), [ - ("0123456789", "0189"), - ("0123456789", "01"), - ("0123456789", "89"), - ("0123456789", ""), - ("0123456789", "01xyz89"), - ("0123456789", "01xyz"), - ("0123456789", "xyz89"), - ("0123456789", "xyz"), + (string.digits, "0189"), + (string.digits, "01"), + (string.digits, "89"), + (string.digits, ""), + (string.digits, "01xyz89"), + (string.digits, "01xyz"), + (string.digits, "xyz89"), + (string.digits, "xyz"), ("", "01"), ], ) -def test_edit_range(s0: str, s: str, snapshot): +def test_edit_range(s0: str, s: str, snapshot) -> None: assert edit_range(s0, s) == snapshot diff --git a/tests/test_token.py b/tests/test_token.py index 0c16f5f..1d9dd72 100644 --- a/tests/test_token.py +++ b/tests/test_token.py @@ -1,6 +1,7 @@ from typing import List import pytest + from parallel_corpus.token import Token, identify, tokenize @@ -12,7 +13,7 @@ def test_can_create_token() -> None: @pytest.mark.parametrize( - "text, expected", + ("text", "expected"), [ ("", []), (" ", [" "]), From 1e2eb6e3383b9c9329d81cdf99c9b7f6460f13d7 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Tue, 22 Oct 2024 14:42:23 +0200 Subject: [PATCH 17/19] refactor: fix type errors --- src/parallel_corpus/graph.py | 34 ++++++------- src/parallel_corpus/shared/dicts.py | 2 +- .../{token.py => text_token.py} | 0 tests/test_graph.py | 50 +++++++++---------- tests/test_shared/test_lists.py | 5 +- tests/test_token.py | 2 +- 6 files changed, 47 insertions(+), 46 deletions(-) rename src/parallel_corpus/{token.py => text_token.py} (100%) diff --git a/src/parallel_corpus/graph.py b/src/parallel_corpus/graph.py index f083907..bbdd326 100644 --- a/src/parallel_corpus/graph.py +++ b/src/parallel_corpus/graph.py @@ -9,11 +9,11 @@ import parallel_corpus.shared.ranges import parallel_corpus.shared.str_map import parallel_corpus.shared.union_find -from parallel_corpus import shared, token +from parallel_corpus import shared, text_token from parallel_corpus.shared import dicts, diffs, ids, lists from parallel_corpus.shared.unique_check import UniqueCheck from parallel_corpus.source_target import Side, SourceTarget, map_sides -from parallel_corpus.token import Token +from parallel_corpus.text_token import Token A = TypeVar("A") B = TypeVar("B") @@ -84,20 +84,20 @@ def edge_record(es: Iterable[Edge]) -> Dict[str, Edge]: # noqa: D103 def init(s: str, *, manual: bool = False) -> Graph: # noqa: D103 - return init_from(token.tokenize(s), manual=manual) + return init_from(text_token.tokenize(s), manual=manual) def init_with_source_and_target(source: str, target: str, *, manual: bool = False) -> Graph: # noqa: D103 return init_from_source_and_target( - source=token.tokenize(source), target=token.tokenize(target), manual=manual + source=text_token.tokenize(source), target=text_token.tokenize(target), manual=manual ) def init_from(tokens: List[str], *, manual: bool = False) -> Graph: # noqa: D103 return align( Graph( - source=token.identify(tokens, "s"), - target=token.identify(tokens, "t"), + source=text_token.identify(tokens, "s"), + target=text_token.identify(tokens, "t"), edges=edge_record( (edge([f"s{i}", f"t{i}"], [], manual=manual) for i, _ in enumerate(tokens)) ), @@ -108,8 +108,8 @@ def init_from(tokens: List[str], *, manual: bool = False) -> Graph: # noqa: D10 def init_from_source_and_target( # noqa: D103 source: List[str], target: List[str], *, manual: bool = False ) -> Graph: - source_tokens = token.identify(source, "s") - target_tokens = token.identify(target, "t") + source_tokens = text_token.identify(source, "s") + target_tokens = text_token.identify(target, "t") return align( Graph( source=source_tokens, @@ -204,7 +204,7 @@ def align(g: Graph) -> Graph: # noqa: D103 c.a is not None and c.b is not None and c.a.id is not None and c.b.id is not None ): uf.union(c.a.id, c.b.id) - proto_edges = {k: e for k, e in g.edges.items() if e.manual} + proto_edges: Dict[str, Edge] = {k: e for k, e in g.edges.items() if e.manual} first: UniqueCheck[str] = UniqueCheck() def update_edges(tokens, _side) -> None: # noqa: ANN001 @@ -214,7 +214,7 @@ def update_edges(tokens, _side) -> None: # noqa: ANN001 labels = e_repr.labels if first(e_repr.id) else [] e_token = edge([tok.id], labels, manual=False, comment=e_repr.comment) dicts.modify( - proto_edges, + proto_edges, # type: ignore[misc] uf.find(tok.id), zero_edge, lambda e: merge_edges(e, e_token), # noqa: B023 @@ -229,8 +229,8 @@ def rearrange(g: Graph, begin: int, end: int, dest: int) -> Graph: # noqa: D103 return align(unaligned_rearrange(g, begin, end, dest)) -def target_text(g: SourceTarget[List[token.Text]]) -> str: # noqa: D103 - return token.text(g.target) +def target_text(g: SourceTarget[List[text_token.Text]]) -> str: # noqa: D103 + return text_token.text(g.target) @dataclass @@ -314,23 +314,23 @@ def unaligned_modify( Indexes are character offsets (use CodeMirror's doc.posFromIndex and doc.indexFromPos to convert) """ # noqa: E501 tokens = get_side_texts(g, side) - token_at = token.token_at(tokens, from_) + token_at = text_token.token_at(tokens, from_) from_token, from_ix = token_at["token"], token_at["offset"] pre = (tokens[from_token] if from_token < len(tokens) else "")[:from_ix] if to == len(get_side_text(g, side)): return unaligned_modify_tokens(g, from_token, len(g.get_side(side)), pre + text, side) - to_token_at = token.token_at(tokens, to) + to_token_at = text_token.token_at(tokens, to) to_token, to_ix = to_token_at["token"], to_token_at["offset"] post = (tokens[to_token] or "")[to_ix:] return unaligned_modify_tokens(g, from_token, to_token + 1, pre + text + post, side) def get_side_text(g: Graph, side: Side) -> str: # noqa: D103 - return token.text(g.get_side(side)) + return text_token.text(g.get_side(side)) def get_side_texts(g: Graph, side: Side) -> List[str]: # noqa: D103 - return token.texts(g.get_side(side)) + return text_token.texts(g.get_side(side)) def unaligned_modify_tokens( @@ -402,7 +402,7 @@ def unaligned_modify_tokens( id_offset = next_id(g) tokens = [ - Token(t, f"{side[0]}{(id_offset + i)}") for i, t in enumerate(token.tokenize(text)) + Token(t, f"{side[0]}{(id_offset + i)}") for i, t in enumerate(text_token.tokenize(text)) ] new_tokens, removed = lists.splice(g.get_side(side), from_, to - from_, *tokens) diff --git a/src/parallel_corpus/shared/dicts.py b/src/parallel_corpus/shared/dicts.py index 7c2c07b..7041264 100644 --- a/src/parallel_corpus/shared/dicts.py +++ b/src/parallel_corpus/shared/dicts.py @@ -5,7 +5,7 @@ if TYPE_CHECKING: from _typeshed import SupportsRichComparison - K = TypeVar("K", bound=SupportsRichComparison) + K = TypeVar("K", bound=SupportsRichComparison) # type: ignore [syntax] else: K = TypeVar("K") diff --git a/src/parallel_corpus/token.py b/src/parallel_corpus/text_token.py similarity index 100% rename from src/parallel_corpus/token.py rename to src/parallel_corpus/text_token.py diff --git a/tests/test_graph.py b/tests/test_graph.py index 06a8b81..900b8c0 100644 --- a/tests/test_graph.py +++ b/tests/test_graph.py @@ -2,14 +2,14 @@ import pytest -from parallel_corpus import graph, token +from parallel_corpus import graph, text_token from parallel_corpus.source_target import Side, SourceTarget def test_graph_init() -> None: g = graph.init("w1 w2") - source = [token.Token(text="w1 ", id="s0"), token.Token(text="w2 ", id="s1")] - target = [token.Token(text="w1 ", id="t0"), token.Token(text="w2 ", id="t1")] + source = [text_token.Token(text="w1 ", id="s0"), text_token.Token(text="w2 ", id="s1")] + target = [text_token.Token(text="w1 ", id="t0"), text_token.Token(text="w2 ", id="t1")] edges = graph.edge_record([graph.edge(["s0", "t0"], []), graph.edge(["s1", "t1"], [])]) assert g.source == source @@ -24,8 +24,8 @@ def test_init_from_source_and_target_1() -> None: def test_init_from_source_and_target_2() -> None: g = graph.init_with_source_and_target(source="apa bepa", target="apa") - expected_source = token.identify(token.tokenize("apa bepa"), "s") - expected_target = token.identify(token.tokenize("apa"), "t") + expected_source = text_token.identify(text_token.tokenize("apa bepa"), "s") + expected_target = text_token.identify(text_token.tokenize("apa"), "t") g_expected = graph.Graph( source=expected_source, target=expected_target, @@ -36,8 +36,8 @@ def test_init_from_source_and_target_2() -> None: def test_init_from_source_and_target_3() -> None: g = graph.init_with_source_and_target(source="apa", target="bepa apa") - expected_source = token.identify(token.tokenize("apa"), "s") - expected_target = token.identify(token.tokenize("bepa apa"), "t") + expected_source = text_token.identify(text_token.tokenize("apa"), "s") + expected_target = text_token.identify(text_token.tokenize("bepa apa"), "t") g_expected = graph.Graph( source=expected_source, target=expected_target, @@ -95,19 +95,19 @@ def test_unaligned_set_side() -> None: print("<<< test_unaligned_set_side") expected_source = [ - token.Token(id="s0", text="a "), - token.Token(id="s1", text="bc "), - token.Token(id="s2", text="d "), + text_token.Token(id="s0", text="a "), + text_token.Token(id="s1", text="bc "), + text_token.Token(id="s2", text="d "), ] expected_g0_target = [ - token.Token(id="t0", text="a "), - token.Token(id="t1", text="bc "), - token.Token(id="t2", text="d "), + text_token.Token(id="t0", text="a "), + text_token.Token(id="t1", text="bc "), + text_token.Token(id="t2", text="d "), ] expected_g_target = [ - token.Token(id="t3", text="ab "), - token.Token(id="t4", text="c "), - token.Token(id="t5", text="d "), + text_token.Token(id="t3", text="ab "), + text_token.Token(id="t4", text="c "), + text_token.Token(id="t5", text="d "), ] expected_g_edges = { "e-s0-s1-s2-t3-t4-t5": graph.Edge( @@ -131,19 +131,19 @@ def test_graph_align() -> None: g = graph.unaligned_set_side(g0, Side.target, "ab c d") expected_source = [ - token.Token(id="s0", text="a "), - token.Token(id="s1", text="bc "), - token.Token(id="s2", text="d "), + text_token.Token(id="s0", text="a "), + text_token.Token(id="s1", text="bc "), + text_token.Token(id="s2", text="d "), ] expected_g0_target = [ - token.Token(id="t0", text="a "), - token.Token(id="t1", text="bc "), - token.Token(id="t2", text="d "), + text_token.Token(id="t0", text="a "), + text_token.Token(id="t1", text="bc "), + text_token.Token(id="t2", text="d "), ] expected_g_target = [ - token.Token(id="t3", text="ab "), - token.Token(id="t4", text="c "), - token.Token(id="t5", text="d "), + text_token.Token(id="t3", text="ab "), + text_token.Token(id="t4", text="c "), + text_token.Token(id="t5", text="d "), ] expected_g_edges = { "e-s0-s1-s2-t3-t4-t5": graph.Edge( diff --git a/tests/test_shared/test_lists.py b/tests/test_shared/test_lists.py index 797c2f4..1720aa6 100644 --- a/tests/test_shared/test_lists.py +++ b/tests/test_shared/test_lists.py @@ -2,14 +2,15 @@ def test_splice_1() -> None: - (*s_chars,) = "abcdef" + s_chars = ["a", "b", "c", "d", "e", "f"] ex, rm = lists.splice(s_chars, 3, 1, " ", "_") assert "".join(ex) == "abc _ef" assert "".join(rm) == "d" def test_splice_2() -> None: - (*s_chars,) = "abcdef" + s_chars = ["a", "b", "c", "d", "e", "f"] + (ex, rm) = lists.splice(s_chars, 3, 2, " ", "_") assert "".join(ex) == "abc _f" assert "".join(rm) == "de" diff --git a/tests/test_token.py b/tests/test_token.py index 1d9dd72..2479ffa 100644 --- a/tests/test_token.py +++ b/tests/test_token.py @@ -2,7 +2,7 @@ import pytest -from parallel_corpus.token import Token, identify, tokenize +from parallel_corpus.text_token import Token, identify, tokenize def test_can_create_token() -> None: From 65b215610b164506ddf1cac768181523016e1644 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Tue, 22 Oct 2024 14:56:14 +0200 Subject: [PATCH 18/19] refactor: add some exports --- README.md | 9 ++++++- src/parallel_corpus/__init__.py | 5 ++++ src/parallel_corpus/graph.py | 44 +++++++++++++++++---------------- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 66c358e..8f7aa20 100644 --- a/README.md +++ b/README.md @@ -60,13 +60,20 @@ print(f"{gm.edges=}") This project keeps a [changelog](./CHANGELOG.md). +## Supported Python Versions + +This library thrives to support the following versions: + +- v0.2: Python 3.9 +- v0.1: Python 3.8 + ## Development This project uses [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/). Tools used: -- [pdm](https://pdm-project.org) for project management. +- [uv](https://docs.astral.sh/uv/) for project management. - [pre-commit](https://pre-commit.com/) for pre-commit checking - runs ruff linter - runs ruff formatter diff --git a/src/parallel_corpus/__init__.py b/src/parallel_corpus/__init__.py index ce72650..3fdafcb 100644 --- a/src/parallel_corpus/__init__.py +++ b/src/parallel_corpus/__init__.py @@ -1 +1,6 @@ """Parallel corpus as a graph.""" + +from parallel_corpus import graph +from parallel_corpus.graph import Graph + +__all__ = ["Graph", "graph"] diff --git a/src/parallel_corpus/graph.py b/src/parallel_corpus/graph.py index bbdd326..0ccfb2f 100644 --- a/src/parallel_corpus/graph.py +++ b/src/parallel_corpus/graph.py @@ -15,6 +15,8 @@ from parallel_corpus.source_target import Side, SourceTarget, map_sides from parallel_corpus.text_token import Token +__all__ = ["Graph", "Side"] + A = TypeVar("A") B = TypeVar("B") @@ -26,7 +28,7 @@ @dataclass -class Edge: # noqa: D101 +class Edge: # a copy of the identifier used in the edges object of the graph id: str # these are ids to source and target tokens @@ -57,11 +59,11 @@ def copy_with_edges(self, edges: Edges) -> "Graph": # noqa: D102 return Graph(source=self.source, target=self.target, edges=edges, comment=self.comment) -def next_id(g: Graph) -> int: # noqa: D103 +def next_id(g: Graph) -> int: return ids.next_id(itertools.chain((t.id for t in g.target), (s.id for s in g.source))) -def edge( # noqa: D103 +def edge( ids: List[str], labels: List[str], *, @@ -79,21 +81,21 @@ def edge( # noqa: D103 ) -def edge_record(es: Iterable[Edge]) -> Dict[str, Edge]: # noqa: D103 +def edge_record(es: Iterable[Edge]) -> Dict[str, Edge]: return {e.id: e for e in es} -def init(s: str, *, manual: bool = False) -> Graph: # noqa: D103 +def init(s: str, *, manual: bool = False) -> Graph: return init_from(text_token.tokenize(s), manual=manual) -def init_with_source_and_target(source: str, target: str, *, manual: bool = False) -> Graph: # noqa: D103 +def init_with_source_and_target(source: str, target: str, *, manual: bool = False) -> Graph: return init_from_source_and_target( source=text_token.tokenize(source), target=text_token.tokenize(target), manual=manual ) -def init_from(tokens: List[str], *, manual: bool = False) -> Graph: # noqa: D103 +def init_from(tokens: List[str], *, manual: bool = False) -> Graph: return align( Graph( source=text_token.identify(tokens, "s"), @@ -105,7 +107,7 @@ def init_from(tokens: List[str], *, manual: bool = False) -> Graph: # noqa: D10 ) -def init_from_source_and_target( # noqa: D103 +def init_from_source_and_target( source: List[str], target: List[str], *, manual: bool = False ) -> Graph: source_tokens = text_token.identify(source, "s") @@ -124,7 +126,7 @@ def init_from_source_and_target( # noqa: D103 ) -class TextLabels(TypedDict): # noqa: D101 +class TextLabels(TypedDict): text: str labels: List[str] @@ -150,19 +152,19 @@ def proto_tokens_to_tokens(toks: List[TextLabels], side: Side) -> List[Token]: return align(Graph(source=g.source, target=g.target, edges=edges)) -def modify(g: Graph, from_: int, to: int, text: str, side: Side = Side.target) -> Graph: # noqa: D103 +def modify(g: Graph, from_: int, to: int, text: str, side: Side = Side.target) -> Graph: return align(unaligned_modify(g, from_, to, text, side)) -def set_source(g: Graph, text: str) -> Graph: # noqa: D103 +def set_source(g: Graph, text: str) -> Graph: return align(unaligned_set_side(g, Side.source, text)) -def set_target(g: Graph, text: str) -> Graph: # noqa: D103 +def set_target(g: Graph, text: str) -> Graph: return align(unaligned_set_side(g, Side.target, text)) -def merge_edges(*es) -> Edge: # noqa: ANN002, D103 +def merge_edges(*es) -> Edge: # noqa: ANN002 ids = [] labels = [] manual = False @@ -184,7 +186,7 @@ def merge_edges(*es) -> Edge: # noqa: ANN002, D103 zero_edge = merge_edges() -def align(g: Graph) -> Graph: # noqa: D103 +def align(g: Graph) -> Graph: # Use a union-find to group characters into edges. uf = parallel_corpus.shared.union_find.poly_union_find(lambda u: u) em = edge_map(g) @@ -225,21 +227,21 @@ def update_edges(tokens, _side) -> None: # noqa: ANN001 return g.copy_with_edges(edges) -def rearrange(g: Graph, begin: int, end: int, dest: int) -> Graph: # noqa: D103 +def rearrange(g: Graph, begin: int, end: int, dest: int) -> Graph: return align(unaligned_rearrange(g, begin, end, dest)) -def target_text(g: SourceTarget[List[text_token.Text]]) -> str: # noqa: D103 +def target_text(g: SourceTarget[List[text_token.Text]]) -> str: return text_token.text(g.target) @dataclass -class CharIdPair: # noqa: D101 +class CharIdPair: char: str id: Optional[str] = None -def to_char_ids(token: Token) -> List[CharIdPair]: # noqa: D103 +def to_char_ids(token: Token) -> List[CharIdPair]: return parallel_corpus.shared.str_map.str_map( token.text, lambda char, _i: CharIdPair(char=char, id=None if char == " " else token.id), @@ -262,7 +264,7 @@ def edge_map(g: Graph) -> Dict[str, Edge]: return edges -def unaligned_set_side(g: Graph, side: Side, text: str) -> Graph: # noqa: D103 +def unaligned_set_side(g: Graph, side: Side, text: str) -> Graph: text0 = get_side_text(g, side) edits = parallel_corpus.shared.ranges.edit_range(text0, text) @@ -325,11 +327,11 @@ def unaligned_modify( return unaligned_modify_tokens(g, from_token, to_token + 1, pre + text + post, side) -def get_side_text(g: Graph, side: Side) -> str: # noqa: D103 +def get_side_text(g: Graph, side: Side) -> str: return text_token.text(g.get_side(side)) -def get_side_texts(g: Graph, side: Side) -> List[str]: # noqa: D103 +def get_side_texts(g: Graph, side: Side) -> List[str]: return text_token.texts(g.get_side(side)) From e5b05c14b3143e838d6f547a489ba907de665379 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersson Date: Tue, 22 Oct 2024 16:32:03 +0200 Subject: [PATCH 19/19] chore: create test lockfile from pyproject and tests/requirements-testing.in --- Makefile | 4 ++-- tests/requirements-testing.lock | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index f86a6d1..dec88b1 100644 --- a/Makefile +++ b/Makefile @@ -150,8 +150,8 @@ publish: prepare-release: update-changelog tests/requirements-testing.lock # we use lock extension so that dependabot doesn't pick up changes in this file -tests/requirements-testing.lock: tests/requirements-testing.in - uv pip compile $< --output-file $@ +tests/requirements-testing.lock: pyproject.toml tests/requirements-testing.in + uv pip compile $^ --output-file $@ .PHONY: update-changelog update-changelog: CHANGELOG.md diff --git a/tests/requirements-testing.lock b/tests/requirements-testing.lock index 84b8098..8ae81dd 100644 --- a/tests/requirements-testing.lock +++ b/tests/requirements-testing.lock @@ -1,7 +1,11 @@ # This file was autogenerated by uv via the following command: -# uv pip compile tests/requirements-testing.in --output-file tests/requirements-testing.lock +# uv pip compile pyproject.toml tests/requirements-testing.in --output-file tests/requirements-testing.lock +diff-match-patch==20241021 + # via parallel-corpus (pyproject.toml) iniconfig==2.0.0 # via pytest +more-itertools==10.5.0 + # via parallel-corpus (pyproject.toml) packaging==24.1 # via pytest pluggy==1.5.0 @@ -10,5 +14,9 @@ pytest==8.3.3 # via # -r tests/requirements-testing.in # syrupy +strenum==0.4.15 + # via parallel-corpus (pyproject.toml) syrupy==4.7.2 # via -r tests/requirements-testing.in +typing-extensions==4.12.2 + # via parallel-corpus (pyproject.toml)