From 161875b0463c2835adc6f9e94f135a45a7f7dddf Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Mon, 1 Sep 2025 21:38:47 +0000 Subject: [PATCH 01/22] debt: pytest pyproject.toml configuration --- python/pyproject.toml | 3 +++ python/pytest.ini | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 python/pytest.ini diff --git a/python/pyproject.toml b/python/pyproject.toml index 4a45a7a4..bcdfe3d9 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -130,3 +130,6 @@ python = pypy-3.9: pypy39 pypy-3.10: pypy310 """ + +[tool.pytest.ini_options] +testpaths = ["tests"] diff --git a/python/pytest.ini b/python/pytest.ini deleted file mode 100644 index 5ee64771..00000000 --- a/python/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -testpaths = tests From 6db43701decfc619276bfd48136592ba8e80f589 Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Mon, 1 Sep 2025 21:46:21 +0000 Subject: [PATCH 02/22] debt: Lint pyupgrade via ruff --- .pre-commit-config.yaml | 10 +++++----- python/pyproject.toml | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 19190587..b40670d8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,6 +4,11 @@ files: ^python/ exclude: .*python/src/cucumber_messages/_messages\.py repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: 73b0f6d59bbfcb75e17a4653d581c9dfaca13969 # frozen: v0.12.5 + hooks: + - id: ruff-check + files: "^python/" - repo: https://github.com/psf/black rev: 24.10.0 hooks: @@ -26,11 +31,6 @@ repos: hooks: - id: pretty-format-toml args: [--autofix] - - repo: https://github.com/asottile/pyupgrade - rev: v3.19.1 - hooks: - - id: pyupgrade - args: ["--py39-plus"] - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.13.0 hooks: diff --git a/python/pyproject.toml b/python/pyproject.toml index bcdfe3d9..dd29d75d 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -131,5 +131,10 @@ python = pypy-3.10: pypy310 """ +[tool.ruff.lint] +select = [ + "UP", +] + [tool.pytest.ini_options] testpaths = ["tests"] From 1f69e75cd74281617c92494c2506fe3961f88f94 Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Mon, 1 Sep 2025 21:51:39 +0000 Subject: [PATCH 03/22] debt: Run isort through ruff --- .pre-commit-config.yaml | 5 +---- python/pyproject.toml | 28 +++++++++++++++------------- python/tests/test_json_converter.py | 6 +++++- python/tests/test_messages.py | 7 ++++++- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b40670d8..25016c31 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,6 +9,7 @@ repos: hooks: - id: ruff-check files: "^python/" + args: [--fix] - repo: https://github.com/psf/black rev: 24.10.0 hooks: @@ -16,10 +17,6 @@ repos: args: - "python/src" - "python/tests" - - repo: https://github.com/pycqa/isort - rev: 5.13.2 - hooks: - - id: isort - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: diff --git a/python/pyproject.toml b/python/pyproject.toml index dd29d75d..8be0d9bf 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -57,11 +57,6 @@ line-length = 120 target-version = ["py39", "py310", "py311", "py312", "py313"] verbose = true -[tool.isort] -line_length = 120 -multi_line_output = 3 -profile = "black" - [tool.mypy] files = "src/**/*.py" install_types = true @@ -76,6 +71,21 @@ ignore_missing_imports = true module = [ ] +# Redundant. Automatically introduced by `pretty-format-toml` pre-commit job +[tool.pytest] + +[tool.pytest.ini_options] +testpaths = ["tests"] + +# Redundant. Automatically introduced by `pretty-format-toml` pre-commit job +[tool.ruff] + +[tool.ruff.lint] +select = [ + "I", + "UP" +] + # Once https://github.com/tox-dev/tox/issues/999 is released and available, migrate to the new tox approach [tool.tox] # language=INI @@ -130,11 +140,3 @@ python = pypy-3.9: pypy39 pypy-3.10: pypy310 """ - -[tool.ruff.lint] -select = [ - "UP", -] - -[tool.pytest.ini_options] -testpaths = ["tests"] diff --git a/python/tests/test_json_converter.py b/python/tests/test_json_converter.py index 24d6af0a..582158a8 100644 --- a/python/tests/test_json_converter.py +++ b/python/tests/test_json_converter.py @@ -7,7 +7,11 @@ import pytest -from cucumber_messages.json_converter import JsonDataclassConverter, camel_to_snake, snake_to_camel +from cucumber_messages.json_converter import ( + JsonDataclassConverter, + camel_to_snake, + snake_to_camel, +) class SimpleEnum(Enum): diff --git a/python/tests/test_messages.py b/python/tests/test_messages.py index 63190b7f..7e1fbc1c 100644 --- a/python/tests/test_messages.py +++ b/python/tests/test_messages.py @@ -1,6 +1,11 @@ import pytest -from cucumber_messages import Attachment, AttachmentContentEncoding, Envelope, SourceMediaType +from cucumber_messages import ( + Attachment, + AttachmentContentEncoding, + Envelope, + SourceMediaType, +) from cucumber_messages import TestStepResultStatus as TTestStepResultStatus from cucumber_messages import message_converter as default_converter From 4c9e69b3db8cfb70b42fb857debb0179e07436f9 Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Mon, 1 Sep 2025 21:56:10 +0000 Subject: [PATCH 04/22] Enable ruff default rules --- python/pyproject.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/python/pyproject.toml b/python/pyproject.toml index 8be0d9bf..2dec58f0 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -81,11 +81,15 @@ testpaths = ["tests"] [tool.ruff] [tool.ruff.lint] -select = [ +extend-select = [ "I", "UP" ] +[tool.ruff.lint.extend-per-file-ignores] +# TODO: Evaluate whether to use wildcard (removing need for updates) or explicit imports +"src/cucumber_messages/__init__.py" = ["F403"] + # Once https://github.com/tox-dev/tox/issues/999 is released and available, migrate to the new tox approach [tool.tox] # language=INI From 7af2d3946f4452ec0a45f4aa52e161bd97a53688 Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Mon, 1 Sep 2025 22:00:59 +0000 Subject: [PATCH 05/22] debt: Format Python through ruff --- .pre-commit-config.yaml | 9 ++------- python/pyproject.toml | 13 +++++-------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 25016c31..16032e3e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,13 +10,8 @@ repos: - id: ruff-check files: "^python/" args: [--fix] - - repo: https://github.com/psf/black - rev: 24.10.0 - hooks: - - id: black - args: - - "python/src" - - "python/tests" + - id: ruff-format + files: "^python/" - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: diff --git a/python/pyproject.toml b/python/pyproject.toml index 2dec58f0..a7db49b3 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -50,13 +50,6 @@ test-coverage = [ "pytest" ] -[tool.black] -# Don't include autogenerated file -force-exclude = ".*\\/src\\/cucumber_messages\\/_messages\\.py" -line-length = 120 -target-version = ["py39", "py310", "py311", "py312", "py313"] -verbose = true - [tool.mypy] files = "src/**/*.py" install_types = true @@ -77,8 +70,12 @@ module = [ [tool.pytest.ini_options] testpaths = ["tests"] -# Redundant. Automatically introduced by `pretty-format-toml` pre-commit job [tool.ruff] +line-length = 120 + +[tool.ruff.format] +# Ignore generated module +exclude = ["src/cucumber_messages/_messages.py"] [tool.ruff.lint] extend-select = [ From 7c9cd4e908ed80ad9baae3c01d9ac98d5f017468 Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Mon, 1 Sep 2025 22:20:37 +0000 Subject: [PATCH 06/22] debt: Build Python package with uv build backend - Removes `setup.cfg` and `tests` directory from distribution - Added missing `.gitignore` entry for `mypy` --- .github/workflows/test-python.yml | 1 - .pre-commit-config.yaml | 2 +- python/.gitignore | 3 +++ python/pyproject.toml | 12 ++++++++---- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 9d4f1b1c..978c2c0b 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -41,7 +41,6 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -U setuptools pip install tox tox-gh-actions codecov - name: Test with tox working-directory: ./python diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 16032e3e..803e3d6e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,4 +27,4 @@ repos: rev: v1.13.0 hooks: - id: mypy - additional_dependencies: [types-setuptools, types-certifi] + additional_dependencies: [types-certifi] diff --git a/python/.gitignore b/python/.gitignore index 563dcc08..2082024f 100644 --- a/python/.gitignore +++ b/python/.gitignore @@ -53,3 +53,6 @@ nosetests.xml /include /share /local + +.mypy_cache/ +.ruff_cache/ diff --git a/python/pyproject.toml b/python/pyproject.toml index a7db49b3..c5c67886 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -1,6 +1,6 @@ [build-system] -build-backend = "setuptools.build_meta" -requires = ["setuptools>=61.0", "wheel"] +requires = ["uv_build>=0.8.4,<0.9.0"] +build-backend = "uv_build" [project] authors = [ @@ -24,12 +24,16 @@ classifiers = [ ] dependencies = [] description = "Cucumber Messages is a message protocol for representing results and other information from Cucumber. " -license = {text = "MIT"} +keywords = ["gherkin", "cucumber", "bdd"] +license = "MIT" +license-files = [ + "LICENSE", +] maintainers = [ {name = "Konstantin Goloveshko", email = "kostya.goloveshko@gmail.com"} ] name = "cucumber-messages" -readme = {file = "README.md", content-type = "text/markdown"} +readme = "README.md" requires-python = ">=3.9" urls = {Repository = "https://github.com/cucumber/messages"} version = "28.1.0" From e74f9ca57582d07e869fadd7ec655af4e66e3f1d Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Mon, 1 Sep 2025 22:23:57 +0000 Subject: [PATCH 07/22] debt: redundant pytest configuration --- python/pyproject.toml | 13 +++---------- python/tests/conftest.py | 0 2 files changed, 3 insertions(+), 10 deletions(-) delete mode 100644 python/tests/conftest.py diff --git a/python/pyproject.toml b/python/pyproject.toml index c5c67886..d40bf957 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -1,6 +1,6 @@ [build-system] -requires = ["uv_build>=0.8.4,<0.9.0"] build-backend = "uv_build" +requires = ["uv_build>=0.8.4,<0.9.0"] [project] authors = [ @@ -27,7 +27,7 @@ description = "Cucumber Messages is a message protocol for representing results keywords = ["gherkin", "cucumber", "bdd"] license = "MIT" license-files = [ - "LICENSE", + "LICENSE" ] maintainers = [ {name = "Konstantin Goloveshko", email = "kostya.goloveshko@gmail.com"} @@ -65,14 +65,7 @@ warn_unused_configs = true [[tool.mypy.overrides]] ignore_missing_imports = true -module = [ -] - -# Redundant. Automatically introduced by `pretty-format-toml` pre-commit job -[tool.pytest] - -[tool.pytest.ini_options] -testpaths = ["tests"] +module = [] [tool.ruff] line-length = 120 diff --git a/python/tests/conftest.py b/python/tests/conftest.py deleted file mode 100644 index e69de29b..00000000 From 70b0907500ee38065f09b472f8b2af0598d7cb19 Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Fri, 12 Sep 2025 20:36:59 +0000 Subject: [PATCH 08/22] refactor: Python package build and deploy with uv - Matches gherkin repository implementation --- .github/workflows/release-pypi.yml | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/.github/workflows/release-pypi.yml b/.github/workflows/release-pypi.yml index 4477d8c2..031ccabd 100644 --- a/.github/workflows/release-pypi.yml +++ b/.github/workflows/release-pypi.yml @@ -15,24 +15,17 @@ jobs: run: working-directory: python steps: - - name: Checkout code - uses: actions/checkout@v5 + - uses: actions/checkout@v5 - - name: Set up Python 3.13 - uses: actions/setup-python@v5 + - name: Install uv and set the python version + uses: astral-sh/setup-uv@v6 with: + enable-cache: true python-version: "3.13" - - - name: Show Python version - run: python --version + version: "0.8.17" - name: Build package - run: | - python -m pip install build twine - python -m build - twine check --strict dist/* + run: uv build - - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - packages-dir: python/dist + - name: Publish package + run: uv publish From 25e843c274dcd5ac9e87baaf1f020d3c11c45074 Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Fri, 12 Sep 2025 22:29:26 +0000 Subject: [PATCH 09/22] refactor: only run mypy through pre-commit - Explicit trusted publishing for uv - Run pre-commit through uv backend --- .github/workflows/release-pypi.yml | 2 +- .pre-commit-config.yaml | 3 +-- python/.gitignore | 1 + python/pyproject.toml | 31 ++++++++++++------------------ 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/.github/workflows/release-pypi.yml b/.github/workflows/release-pypi.yml index 031ccabd..dfba63c9 100644 --- a/.github/workflows/release-pypi.yml +++ b/.github/workflows/release-pypi.yml @@ -28,4 +28,4 @@ jobs: run: uv build - name: Publish package - run: uv publish + run: uv publish --trusted-publishing=always diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 803e3d6e..68226753 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,6 @@ repos: - id: pretty-format-toml args: [--autofix] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.13.0 + rev: v1.18.1 hooks: - id: mypy - additional_dependencies: [types-certifi] diff --git a/python/.gitignore b/python/.gitignore index 2082024f..67a4ba97 100644 --- a/python/.gitignore +++ b/python/.gitignore @@ -53,6 +53,7 @@ nosetests.xml /include /share /local +.venv/ .mypy_cache/ .ruff_cache/ diff --git a/python/pyproject.toml b/python/pyproject.toml index 4b4a4c3e..4344f6d8 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -35,7 +35,6 @@ maintainers = [ name = "cucumber-messages" readme = "README.md" requires-python = ">=3.9" -urls = {Repository = "https://github.com/cucumber/messages"} version = "29.0.1" [project.optional-dependencies] @@ -43,8 +42,6 @@ test = [ # local "cucumber-messages[test-coverage]", # external; Must be in sync with [tool.tox] - "mypy", - "pre-commit", "tox>=4.2" ] test-coverage = [ @@ -54,6 +51,13 @@ test-coverage = [ "pytest" ] +[project.urls] +Changelog = "https://github.com/cucumber/messages/releases" +Download = "https://pypi.org/project/cucumber-messages" +Homepage = "https://github.com/cucumber/messages" +Issues = "https://github.com/cucumber/messages/issues" +Repository = "https://github.com/cucumber/messages.git" + [tool.mypy] files = "src/**/*.py" install_types = true @@ -92,8 +96,7 @@ legacy_tox_ini = """ requires = tox>=4.2 env_list = - py313-pre-commit-lin - py{313, 312, 311, 310, 39}-mypy-lin + py{313, 312, 311, 310, 39}-lint-lin py{py310, py39, 313, 312, 311, 310, 39}-pytest-coverage-lin py313-pytest-coverage-{win, mac} distshare = {homedir}/.tox/distshare @@ -104,23 +107,13 @@ platform = mac: darwin win: win32 -[testenv:py313-pre-commit-lin] +[testenv:py{313, 312, 311, 310, 39}-lint-lin] skip_install = true +description = run code formatter and linter (auto-fix) deps = - pre-commit -commands = - pre-commit run - -[testenv:py{313, 312, 311, 310, 39}-mypy-lin] -deps = - mypy -allowlist_externals = - mkdir - chmod + pre-commit-uv>=4.1.1 commands = - mkdir .mypy_cache - chmod 755 .mypy_cache - python -m mypy --cache-dir .mypy_cache + pre-commit run --all-files --show-diff-on-failure [testenv:py{py310, py39, 313, 312, 311, 310, 39}-pytest-coverage-{lin, win, mac}] deps = From 570d4da8b2c1eee9c6e1ce2f2825035e0332df1c Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sat, 13 Sep 2025 15:18:02 +0000 Subject: [PATCH 10/22] refactor: Trim tox configuration - Run mypy through pre-commit - Run Python test workflow through uv - Use Python dependency groups standard --- .github/workflows/test-python.yml | 33 +-- python/pyproject.toml | 74 ++---- python/uv.lock | 375 ++++++++++++++++++++++++++++++ 3 files changed, 412 insertions(+), 70 deletions(-) create mode 100644 python/uv.lock diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 862ac46c..b4490477 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -21,32 +21,33 @@ on: jobs: build: - runs-on: ${{ matrix.os }} strategy: matrix: include: - # Test latest python on Windows / macOS + # Test latest python on Windows and macOS - { os: 'windows-latest', python-version: '3.13' } - { os: 'macos-latest', python-version: '3.13' } os: ['ubuntu-latest'] python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', 'pypy3.9', 'pypy3.10'] - + defaults: + run: + working-directory: python steps: - uses: actions/checkout@v5 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6 + + - name: Install uv and set the python version + uses: astral-sh/setup-uv@v6 with: + enable-cache: true python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install tox tox-gh-actions codecov - - name: Test with tox - working-directory: ./python - run: | - tox + version: "0.8.17" + + - name: Linting and testing + run: uv run tox -e="lint,${{ matrix.python-version }}" + - name: Gather codecov report - working-directory: ./python - run: | - codecov + run: uvx codecov + + - name: Build package + run: uv build diff --git a/python/pyproject.toml b/python/pyproject.toml index 4344f6d8..8c970c9d 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -2,6 +2,15 @@ build-backend = "uv_build" requires = ["uv_build>=0.8.4,<0.9.0"] +[dependency-groups] +dev = [ + "coverage>=7.2", + "pytest>=6.1", + "GitPython", + "packaging", + "tox>=4.22" +] + [project] authors = [ {name = "Cucumber Limited", email = "cukes@googlegroups.com"} @@ -37,20 +46,6 @@ readme = "README.md" requires-python = ">=3.9" version = "29.0.1" -[project.optional-dependencies] -test = [ - # local - "cucumber-messages[test-coverage]", - # external; Must be in sync with [tool.tox] - "tox>=4.2" -] -test-coverage = [ - "coverage", - "GitPython", - "packaging", - "pytest" -] - [project.urls] Changelog = "https://github.com/cucumber/messages/releases" Download = "https://pypi.org/project/cucumber-messages" @@ -88,46 +83,17 @@ extend-select = [ # TODO: Evaluate whether to use wildcard (removing need for updates) or explicit imports "src/cucumber_messages/__init__.py" = ["F403"] -# Once https://github.com/tox-dev/tox/issues/999 is released and available, migrate to the new tox approach [tool.tox] -# language=INI -legacy_tox_ini = """ -[tox] -requires = - tox>=4.2 -env_list = - py{313, 312, 311, 310, 39}-lint-lin - py{py310, py39, 313, 312, 311, 310, 39}-pytest-coverage-lin - py313-pytest-coverage-{win, mac} -distshare = {homedir}/.tox/distshare +env_list = ["lint", "3.13", "3.12", "3.11", "3.10", "3.9", "pypy310", "pypy39"] +requires = ["tox>=4.22"] -[testenv] -platform = - lin: linux - mac: darwin - win: win32 +[tool.tox.env.lint] +commands = [["pre-commit", "run", "--all-files", "--show-diff-on-failure"]] +deps = ["pre-commit-uv>=4.1.1"] +description = "Run linting and formatting checks (and auto-fixes)" -[testenv:py{313, 312, 311, 310, 39}-lint-lin] -skip_install = true -description = run code formatter and linter (auto-fix) -deps = - pre-commit-uv>=4.1.1 -commands = - pre-commit run --all-files --show-diff-on-failure - -[testenv:py{py310, py39, 313, 312, 311, 310, 39}-pytest-coverage-{lin, win, mac}] -deps = - .[test-coverage] -commands = - coverage run --append -m pytest -vvl - -[gh-actions] -python = - 3.9: py39 - 3.10: py310 - 3.11: py311 - 3.12: py312 - 3.13: py313 - pypy-3.9: pypy39 - pypy-3.10: pypy310 -""" +[tool.tox.env_run_base] +commands = [["coverage", "run", "--append", "-m", "pytest", "-vvl"]] +dependency_groups = [ + "dev" +] diff --git a/python/uv.lock b/python/uv.lock new file mode 100644 index 00000000..d6d96bc6 --- /dev/null +++ b/python/uv.lock @@ -0,0 +1,375 @@ +version = 1 +revision = 3 +requires-python = ">=3.9" + +[[package]] +name = "cachetools" +version = "6.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/61/e4fad8155db4a04bfb4734c7c8ff0882f078f24294d42798b3568eb63bff/cachetools-6.2.0.tar.gz", hash = "sha256:38b328c0889450f05f5e120f56ab68c8abaf424e1275522b138ffc93253f7e32", size = 30988, upload-time = "2025-08-25T18:57:30.924Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/56/3124f61d37a7a4e7cc96afc5492c78ba0cb551151e530b54669ddd1436ef/cachetools-6.2.0-py3-none-any.whl", hash = "sha256:1c76a8960c0041fcc21097e357f882197c79da0dbff766e7317890a65d7d8ba6", size = 11276, upload-time = "2025-08-25T18:57:29.684Z" }, +] + +[[package]] +name = "chardet" +version = "5.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/f7b6ab21ec75897ed80c17d79b15951a719226b9fababf1e40ea74d69079/chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", size = 2069618, upload-time = "2023-08-01T19:23:02.662Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970", size = 199385, upload-time = "2023-08-01T19:23:00.661Z" }, +] + +[[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, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "coverage" +version = "7.10.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/14/70/025b179c993f019105b79575ac6edb5e084fb0f0e63f15cdebef4e454fb5/coverage-7.10.6.tar.gz", hash = "sha256:f644a3ae5933a552a29dbb9aa2f90c677a875f80ebea028e5a52a4f429044b90", size = 823736, upload-time = "2025-08-29T15:35:16.668Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/1d/2e64b43d978b5bd184e0756a41415597dfef30fcbd90b747474bd749d45f/coverage-7.10.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:70e7bfbd57126b5554aa482691145f798d7df77489a177a6bef80de78860a356", size = 217025, upload-time = "2025-08-29T15:32:57.169Z" }, + { url = "https://files.pythonhosted.org/packages/23/62/b1e0f513417c02cc10ef735c3ee5186df55f190f70498b3702d516aad06f/coverage-7.10.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e41be6f0f19da64af13403e52f2dec38bbc2937af54df8ecef10850ff8d35301", size = 217419, upload-time = "2025-08-29T15:32:59.908Z" }, + { url = "https://files.pythonhosted.org/packages/e7/16/b800640b7a43e7c538429e4d7223e0a94fd72453a1a048f70bf766f12e96/coverage-7.10.6-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c61fc91ab80b23f5fddbee342d19662f3d3328173229caded831aa0bd7595460", size = 244180, upload-time = "2025-08-29T15:33:01.608Z" }, + { url = "https://files.pythonhosted.org/packages/fb/6f/5e03631c3305cad187eaf76af0b559fff88af9a0b0c180d006fb02413d7a/coverage-7.10.6-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10356fdd33a7cc06e8051413140bbdc6f972137508a3572e3f59f805cd2832fd", size = 245992, upload-time = "2025-08-29T15:33:03.239Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a1/f30ea0fb400b080730125b490771ec62b3375789f90af0bb68bfb8a921d7/coverage-7.10.6-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:80b1695cf7c5ebe7b44bf2521221b9bb8cdf69b1f24231149a7e3eb1ae5fa2fb", size = 247851, upload-time = "2025-08-29T15:33:04.603Z" }, + { url = "https://files.pythonhosted.org/packages/02/8e/cfa8fee8e8ef9a6bb76c7bef039f3302f44e615d2194161a21d3d83ac2e9/coverage-7.10.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2e4c33e6378b9d52d3454bd08847a8651f4ed23ddbb4a0520227bd346382bbc6", size = 245891, upload-time = "2025-08-29T15:33:06.176Z" }, + { url = "https://files.pythonhosted.org/packages/93/a9/51be09b75c55c4f6c16d8d73a6a1d46ad764acca0eab48fa2ffaef5958fe/coverage-7.10.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c8a3ec16e34ef980a46f60dc6ad86ec60f763c3f2fa0db6d261e6e754f72e945", size = 243909, upload-time = "2025-08-29T15:33:07.74Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a6/ba188b376529ce36483b2d585ca7bdac64aacbe5aa10da5978029a9c94db/coverage-7.10.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7d79dabc0a56f5af990cc6da9ad1e40766e82773c075f09cc571e2076fef882e", size = 244786, upload-time = "2025-08-29T15:33:08.965Z" }, + { url = "https://files.pythonhosted.org/packages/d0/4c/37ed872374a21813e0d3215256180c9a382c3f5ced6f2e5da0102fc2fd3e/coverage-7.10.6-cp310-cp310-win32.whl", hash = "sha256:86b9b59f2b16e981906e9d6383eb6446d5b46c278460ae2c36487667717eccf1", size = 219521, upload-time = "2025-08-29T15:33:10.599Z" }, + { url = "https://files.pythonhosted.org/packages/8e/36/9311352fdc551dec5b973b61f4e453227ce482985a9368305880af4f85dd/coverage-7.10.6-cp310-cp310-win_amd64.whl", hash = "sha256:e132b9152749bd33534e5bd8565c7576f135f157b4029b975e15ee184325f528", size = 220417, upload-time = "2025-08-29T15:33:11.907Z" }, + { url = "https://files.pythonhosted.org/packages/d4/16/2bea27e212c4980753d6d563a0803c150edeaaddb0771a50d2afc410a261/coverage-7.10.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c706db3cabb7ceef779de68270150665e710b46d56372455cd741184f3868d8f", size = 217129, upload-time = "2025-08-29T15:33:13.575Z" }, + { url = "https://files.pythonhosted.org/packages/2a/51/e7159e068831ab37e31aac0969d47b8c5ee25b7d307b51e310ec34869315/coverage-7.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e0c38dc289e0508ef68ec95834cb5d2e96fdbe792eaccaa1bccac3966bbadcc", size = 217532, upload-time = "2025-08-29T15:33:14.872Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c0/246ccbea53d6099325d25cd208df94ea435cd55f0db38099dd721efc7a1f/coverage-7.10.6-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:752a3005a1ded28f2f3a6e8787e24f28d6abe176ca64677bcd8d53d6fe2ec08a", size = 247931, upload-time = "2025-08-29T15:33:16.142Z" }, + { url = "https://files.pythonhosted.org/packages/7d/fb/7435ef8ab9b2594a6e3f58505cc30e98ae8b33265d844007737946c59389/coverage-7.10.6-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:689920ecfd60f992cafca4f5477d55720466ad2c7fa29bb56ac8d44a1ac2b47a", size = 249864, upload-time = "2025-08-29T15:33:17.434Z" }, + { url = "https://files.pythonhosted.org/packages/51/f8/d9d64e8da7bcddb094d511154824038833c81e3a039020a9d6539bf303e9/coverage-7.10.6-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec98435796d2624d6905820a42f82149ee9fc4f2d45c2c5bc5a44481cc50db62", size = 251969, upload-time = "2025-08-29T15:33:18.822Z" }, + { url = "https://files.pythonhosted.org/packages/43/28/c43ba0ef19f446d6463c751315140d8f2a521e04c3e79e5c5fe211bfa430/coverage-7.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b37201ce4a458c7a758ecc4efa92fa8ed783c66e0fa3c42ae19fc454a0792153", size = 249659, upload-time = "2025-08-29T15:33:20.407Z" }, + { url = "https://files.pythonhosted.org/packages/79/3e/53635bd0b72beaacf265784508a0b386defc9ab7fad99ff95f79ce9db555/coverage-7.10.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2904271c80898663c810a6b067920a61dd8d38341244a3605bd31ab55250dad5", size = 247714, upload-time = "2025-08-29T15:33:21.751Z" }, + { url = "https://files.pythonhosted.org/packages/4c/55/0964aa87126624e8c159e32b0bc4e84edef78c89a1a4b924d28dd8265625/coverage-7.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5aea98383463d6e1fa4e95416d8de66f2d0cb588774ee20ae1b28df826bcb619", size = 248351, upload-time = "2025-08-29T15:33:23.105Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ab/6cfa9dc518c6c8e14a691c54e53a9433ba67336c760607e299bfcf520cb1/coverage-7.10.6-cp311-cp311-win32.whl", hash = "sha256:e3fb1fa01d3598002777dd259c0c2e6d9d5e10e7222976fc8e03992f972a2cba", size = 219562, upload-time = "2025-08-29T15:33:24.717Z" }, + { url = "https://files.pythonhosted.org/packages/5b/18/99b25346690cbc55922e7cfef06d755d4abee803ef335baff0014268eff4/coverage-7.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:f35ed9d945bece26553d5b4c8630453169672bea0050a564456eb88bdffd927e", size = 220453, upload-time = "2025-08-29T15:33:26.482Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ed/81d86648a07ccb124a5cf1f1a7788712b8d7216b593562683cd5c9b0d2c1/coverage-7.10.6-cp311-cp311-win_arm64.whl", hash = "sha256:99e1a305c7765631d74b98bf7dbf54eeea931f975e80f115437d23848ee8c27c", size = 219127, upload-time = "2025-08-29T15:33:27.777Z" }, + { url = "https://files.pythonhosted.org/packages/26/06/263f3305c97ad78aab066d116b52250dd316e74fcc20c197b61e07eb391a/coverage-7.10.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5b2dd6059938063a2c9fee1af729d4f2af28fd1a545e9b7652861f0d752ebcea", size = 217324, upload-time = "2025-08-29T15:33:29.06Z" }, + { url = "https://files.pythonhosted.org/packages/e9/60/1e1ded9a4fe80d843d7d53b3e395c1db3ff32d6c301e501f393b2e6c1c1f/coverage-7.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:388d80e56191bf846c485c14ae2bc8898aa3124d9d35903fef7d907780477634", size = 217560, upload-time = "2025-08-29T15:33:30.748Z" }, + { url = "https://files.pythonhosted.org/packages/b8/25/52136173c14e26dfed8b106ed725811bb53c30b896d04d28d74cb64318b3/coverage-7.10.6-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:90cb5b1a4670662719591aa92d0095bb41714970c0b065b02a2610172dbf0af6", size = 249053, upload-time = "2025-08-29T15:33:32.041Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1d/ae25a7dc58fcce8b172d42ffe5313fc267afe61c97fa872b80ee72d9515a/coverage-7.10.6-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:961834e2f2b863a0e14260a9a273aff07ff7818ab6e66d2addf5628590c628f9", size = 251802, upload-time = "2025-08-29T15:33:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7a/1f561d47743710fe996957ed7c124b421320f150f1d38523d8d9102d3e2a/coverage-7.10.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf9a19f5012dab774628491659646335b1928cfc931bf8d97b0d5918dd58033c", size = 252935, upload-time = "2025-08-29T15:33:34.909Z" }, + { url = "https://files.pythonhosted.org/packages/6c/ad/8b97cd5d28aecdfde792dcbf646bac141167a5cacae2cd775998b45fabb5/coverage-7.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:99c4283e2a0e147b9c9cc6bc9c96124de9419d6044837e9799763a0e29a7321a", size = 250855, upload-time = "2025-08-29T15:33:36.922Z" }, + { url = "https://files.pythonhosted.org/packages/33/6a/95c32b558d9a61858ff9d79580d3877df3eb5bc9eed0941b1f187c89e143/coverage-7.10.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:282b1b20f45df57cc508c1e033403f02283adfb67d4c9c35a90281d81e5c52c5", size = 248974, upload-time = "2025-08-29T15:33:38.175Z" }, + { url = "https://files.pythonhosted.org/packages/0d/9c/8ce95dee640a38e760d5b747c10913e7a06554704d60b41e73fdea6a1ffd/coverage-7.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cdbe264f11afd69841bd8c0d83ca10b5b32853263ee62e6ac6a0ab63895f972", size = 250409, upload-time = "2025-08-29T15:33:39.447Z" }, + { url = "https://files.pythonhosted.org/packages/04/12/7a55b0bdde78a98e2eb2356771fd2dcddb96579e8342bb52aa5bc52e96f0/coverage-7.10.6-cp312-cp312-win32.whl", hash = "sha256:a517feaf3a0a3eca1ee985d8373135cfdedfbba3882a5eab4362bda7c7cf518d", size = 219724, upload-time = "2025-08-29T15:33:41.172Z" }, + { url = "https://files.pythonhosted.org/packages/36/4a/32b185b8b8e327802c9efce3d3108d2fe2d9d31f153a0f7ecfd59c773705/coverage-7.10.6-cp312-cp312-win_amd64.whl", hash = "sha256:856986eadf41f52b214176d894a7de05331117f6035a28ac0016c0f63d887629", size = 220536, upload-time = "2025-08-29T15:33:42.524Z" }, + { url = "https://files.pythonhosted.org/packages/08/3a/d5d8dc703e4998038c3099eaf77adddb00536a3cec08c8dcd556a36a3eb4/coverage-7.10.6-cp312-cp312-win_arm64.whl", hash = "sha256:acf36b8268785aad739443fa2780c16260ee3fa09d12b3a70f772ef100939d80", size = 219171, upload-time = "2025-08-29T15:33:43.974Z" }, + { url = "https://files.pythonhosted.org/packages/bd/e7/917e5953ea29a28c1057729c1d5af9084ab6d9c66217523fd0e10f14d8f6/coverage-7.10.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ffea0575345e9ee0144dfe5701aa17f3ba546f8c3bb48db62ae101afb740e7d6", size = 217351, upload-time = "2025-08-29T15:33:45.438Z" }, + { url = "https://files.pythonhosted.org/packages/eb/86/2e161b93a4f11d0ea93f9bebb6a53f113d5d6e416d7561ca41bb0a29996b/coverage-7.10.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:95d91d7317cde40a1c249d6b7382750b7e6d86fad9d8eaf4fa3f8f44cf171e80", size = 217600, upload-time = "2025-08-29T15:33:47.269Z" }, + { url = "https://files.pythonhosted.org/packages/0e/66/d03348fdd8df262b3a7fb4ee5727e6e4936e39e2f3a842e803196946f200/coverage-7.10.6-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e23dd5408fe71a356b41baa82892772a4cefcf758f2ca3383d2aa39e1b7a003", size = 248600, upload-time = "2025-08-29T15:33:48.953Z" }, + { url = "https://files.pythonhosted.org/packages/73/dd/508420fb47d09d904d962f123221bc249f64b5e56aa93d5f5f7603be475f/coverage-7.10.6-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0f3f56e4cb573755e96a16501a98bf211f100463d70275759e73f3cbc00d4f27", size = 251206, upload-time = "2025-08-29T15:33:50.697Z" }, + { url = "https://files.pythonhosted.org/packages/e9/1f/9020135734184f439da85c70ea78194c2730e56c2d18aee6e8ff1719d50d/coverage-7.10.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db4a1d897bbbe7339946ffa2fe60c10cc81c43fab8b062d3fcb84188688174a4", size = 252478, upload-time = "2025-08-29T15:33:52.303Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a4/3d228f3942bb5a2051fde28c136eea23a761177dc4ff4ef54533164ce255/coverage-7.10.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fd7879082953c156d5b13c74aa6cca37f6a6f4747b39538504c3f9c63d043d", size = 250637, upload-time = "2025-08-29T15:33:53.67Z" }, + { url = "https://files.pythonhosted.org/packages/36/e3/293dce8cdb9a83de971637afc59b7190faad60603b40e32635cbd15fbf61/coverage-7.10.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:28395ca3f71cd103b8c116333fa9db867f3a3e1ad6a084aa3725ae002b6583bc", size = 248529, upload-time = "2025-08-29T15:33:55.022Z" }, + { url = "https://files.pythonhosted.org/packages/90/26/64eecfa214e80dd1d101e420cab2901827de0e49631d666543d0e53cf597/coverage-7.10.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:61c950fc33d29c91b9e18540e1aed7d9f6787cc870a3e4032493bbbe641d12fc", size = 250143, upload-time = "2025-08-29T15:33:56.386Z" }, + { url = "https://files.pythonhosted.org/packages/3e/70/bd80588338f65ea5b0d97e424b820fb4068b9cfb9597fbd91963086e004b/coverage-7.10.6-cp313-cp313-win32.whl", hash = "sha256:160c00a5e6b6bdf4e5984b0ef21fc860bc94416c41b7df4d63f536d17c38902e", size = 219770, upload-time = "2025-08-29T15:33:58.063Z" }, + { url = "https://files.pythonhosted.org/packages/a7/14/0b831122305abcc1060c008f6c97bbdc0a913ab47d65070a01dc50293c2b/coverage-7.10.6-cp313-cp313-win_amd64.whl", hash = "sha256:628055297f3e2aa181464c3808402887643405573eb3d9de060d81531fa79d32", size = 220566, upload-time = "2025-08-29T15:33:59.766Z" }, + { url = "https://files.pythonhosted.org/packages/83/c6/81a83778c1f83f1a4a168ed6673eeedc205afb562d8500175292ca64b94e/coverage-7.10.6-cp313-cp313-win_arm64.whl", hash = "sha256:df4ec1f8540b0bcbe26ca7dd0f541847cc8a108b35596f9f91f59f0c060bfdd2", size = 219195, upload-time = "2025-08-29T15:34:01.191Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1c/ccccf4bf116f9517275fa85047495515add43e41dfe8e0bef6e333c6b344/coverage-7.10.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c9a8b7a34a4de3ed987f636f71881cd3b8339f61118b1aa311fbda12741bff0b", size = 218059, upload-time = "2025-08-29T15:34:02.91Z" }, + { url = "https://files.pythonhosted.org/packages/92/97/8a3ceff833d27c7492af4f39d5da6761e9ff624831db9e9f25b3886ddbca/coverage-7.10.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8dd5af36092430c2b075cee966719898f2ae87b636cefb85a653f1d0ba5d5393", size = 218287, upload-time = "2025-08-29T15:34:05.106Z" }, + { url = "https://files.pythonhosted.org/packages/92/d8/50b4a32580cf41ff0423777a2791aaf3269ab60c840b62009aec12d3970d/coverage-7.10.6-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b0353b0f0850d49ada66fdd7d0c7cdb0f86b900bb9e367024fd14a60cecc1e27", size = 259625, upload-time = "2025-08-29T15:34:06.575Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7e/6a7df5a6fb440a0179d94a348eb6616ed4745e7df26bf2a02bc4db72c421/coverage-7.10.6-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d6b9ae13d5d3e8aeca9ca94198aa7b3ebbc5acfada557d724f2a1f03d2c0b0df", size = 261801, upload-time = "2025-08-29T15:34:08.006Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4c/a270a414f4ed5d196b9d3d67922968e768cd971d1b251e1b4f75e9362f75/coverage-7.10.6-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:675824a363cc05781b1527b39dc2587b8984965834a748177ee3c37b64ffeafb", size = 264027, upload-time = "2025-08-29T15:34:09.806Z" }, + { url = "https://files.pythonhosted.org/packages/9c/8b/3210d663d594926c12f373c5370bf1e7c5c3a427519a8afa65b561b9a55c/coverage-7.10.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:692d70ea725f471a547c305f0d0fc6a73480c62fb0da726370c088ab21aed282", size = 261576, upload-time = "2025-08-29T15:34:11.585Z" }, + { url = "https://files.pythonhosted.org/packages/72/d0/e1961eff67e9e1dba3fc5eb7a4caf726b35a5b03776892da8d79ec895775/coverage-7.10.6-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:851430a9a361c7a8484a36126d1d0ff8d529d97385eacc8dfdc9bfc8c2d2cbe4", size = 259341, upload-time = "2025-08-29T15:34:13.159Z" }, + { url = "https://files.pythonhosted.org/packages/3a/06/d6478d152cd189b33eac691cba27a40704990ba95de49771285f34a5861e/coverage-7.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d9369a23186d189b2fc95cc08b8160ba242057e887d766864f7adf3c46b2df21", size = 260468, upload-time = "2025-08-29T15:34:14.571Z" }, + { url = "https://files.pythonhosted.org/packages/ed/73/737440247c914a332f0b47f7598535b29965bf305e19bbc22d4c39615d2b/coverage-7.10.6-cp313-cp313t-win32.whl", hash = "sha256:92be86fcb125e9bda0da7806afd29a3fd33fdf58fba5d60318399adf40bf37d0", size = 220429, upload-time = "2025-08-29T15:34:16.394Z" }, + { url = "https://files.pythonhosted.org/packages/bd/76/b92d3214740f2357ef4a27c75a526eb6c28f79c402e9f20a922c295c05e2/coverage-7.10.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6b3039e2ca459a70c79523d39347d83b73f2f06af5624905eba7ec34d64d80b5", size = 221493, upload-time = "2025-08-29T15:34:17.835Z" }, + { url = "https://files.pythonhosted.org/packages/fc/8e/6dcb29c599c8a1f654ec6cb68d76644fe635513af16e932d2d4ad1e5ac6e/coverage-7.10.6-cp313-cp313t-win_arm64.whl", hash = "sha256:3fb99d0786fe17b228eab663d16bee2288e8724d26a199c29325aac4b0319b9b", size = 219757, upload-time = "2025-08-29T15:34:19.248Z" }, + { url = "https://files.pythonhosted.org/packages/d3/aa/76cf0b5ec00619ef208da4689281d48b57f2c7fde883d14bf9441b74d59f/coverage-7.10.6-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6008a021907be8c4c02f37cdc3ffb258493bdebfeaf9a839f9e71dfdc47b018e", size = 217331, upload-time = "2025-08-29T15:34:20.846Z" }, + { url = "https://files.pythonhosted.org/packages/65/91/8e41b8c7c505d398d7730206f3cbb4a875a35ca1041efc518051bfce0f6b/coverage-7.10.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5e75e37f23eb144e78940b40395b42f2321951206a4f50e23cfd6e8a198d3ceb", size = 217607, upload-time = "2025-08-29T15:34:22.433Z" }, + { url = "https://files.pythonhosted.org/packages/87/7f/f718e732a423d442e6616580a951b8d1ec3575ea48bcd0e2228386805e79/coverage-7.10.6-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0f7cb359a448e043c576f0da00aa8bfd796a01b06aa610ca453d4dde09cc1034", size = 248663, upload-time = "2025-08-29T15:34:24.425Z" }, + { url = "https://files.pythonhosted.org/packages/e6/52/c1106120e6d801ac03e12b5285e971e758e925b6f82ee9b86db3aa10045d/coverage-7.10.6-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c68018e4fc4e14b5668f1353b41ccf4bc83ba355f0e1b3836861c6f042d89ac1", size = 251197, upload-time = "2025-08-29T15:34:25.906Z" }, + { url = "https://files.pythonhosted.org/packages/3d/ec/3a8645b1bb40e36acde9c0609f08942852a4af91a937fe2c129a38f2d3f5/coverage-7.10.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cd4b2b0707fc55afa160cd5fc33b27ccbf75ca11d81f4ec9863d5793fc6df56a", size = 252551, upload-time = "2025-08-29T15:34:27.337Z" }, + { url = "https://files.pythonhosted.org/packages/a1/70/09ecb68eeb1155b28a1d16525fd3a9b65fbe75337311a99830df935d62b6/coverage-7.10.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4cec13817a651f8804a86e4f79d815b3b28472c910e099e4d5a0e8a3b6a1d4cb", size = 250553, upload-time = "2025-08-29T15:34:29.065Z" }, + { url = "https://files.pythonhosted.org/packages/c6/80/47df374b893fa812e953b5bc93dcb1427a7b3d7a1a7d2db33043d17f74b9/coverage-7.10.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f2a6a8e06bbda06f78739f40bfb56c45d14eb8249d0f0ea6d4b3d48e1f7c695d", size = 248486, upload-time = "2025-08-29T15:34:30.897Z" }, + { url = "https://files.pythonhosted.org/packages/4a/65/9f98640979ecee1b0d1a7164b589de720ddf8100d1747d9bbdb84be0c0fb/coverage-7.10.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:081b98395ced0d9bcf60ada7661a0b75f36b78b9d7e39ea0790bb4ed8da14747", size = 249981, upload-time = "2025-08-29T15:34:32.365Z" }, + { url = "https://files.pythonhosted.org/packages/1f/55/eeb6603371e6629037f47bd25bef300387257ed53a3c5fdb159b7ac8c651/coverage-7.10.6-cp314-cp314-win32.whl", hash = "sha256:6937347c5d7d069ee776b2bf4e1212f912a9f1f141a429c475e6089462fcecc5", size = 220054, upload-time = "2025-08-29T15:34:34.124Z" }, + { url = "https://files.pythonhosted.org/packages/15/d1/a0912b7611bc35412e919a2cd59ae98e7ea3b475e562668040a43fb27897/coverage-7.10.6-cp314-cp314-win_amd64.whl", hash = "sha256:adec1d980fa07e60b6ef865f9e5410ba760e4e1d26f60f7e5772c73b9a5b0713", size = 220851, upload-time = "2025-08-29T15:34:35.651Z" }, + { url = "https://files.pythonhosted.org/packages/ef/2d/11880bb8ef80a45338e0b3e0725e4c2d73ffbb4822c29d987078224fd6a5/coverage-7.10.6-cp314-cp314-win_arm64.whl", hash = "sha256:a80f7aef9535442bdcf562e5a0d5a5538ce8abe6bb209cfbf170c462ac2c2a32", size = 219429, upload-time = "2025-08-29T15:34:37.16Z" }, + { url = "https://files.pythonhosted.org/packages/83/c0/1f00caad775c03a700146f55536ecd097a881ff08d310a58b353a1421be0/coverage-7.10.6-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:0de434f4fbbe5af4fa7989521c655c8c779afb61c53ab561b64dcee6149e4c65", size = 218080, upload-time = "2025-08-29T15:34:38.919Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c4/b1c5d2bd7cc412cbeb035e257fd06ed4e3e139ac871d16a07434e145d18d/coverage-7.10.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6e31b8155150c57e5ac43ccd289d079eb3f825187d7c66e755a055d2c85794c6", size = 218293, upload-time = "2025-08-29T15:34:40.425Z" }, + { url = "https://files.pythonhosted.org/packages/3f/07/4468d37c94724bf6ec354e4ec2f205fda194343e3e85fd2e59cec57e6a54/coverage-7.10.6-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:98cede73eb83c31e2118ae8d379c12e3e42736903a8afcca92a7218e1f2903b0", size = 259800, upload-time = "2025-08-29T15:34:41.996Z" }, + { url = "https://files.pythonhosted.org/packages/82/d8/f8fb351be5fee31690cd8da768fd62f1cfab33c31d9f7baba6cd8960f6b8/coverage-7.10.6-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f863c08f4ff6b64fa8045b1e3da480f5374779ef187f07b82e0538c68cb4ff8e", size = 261965, upload-time = "2025-08-29T15:34:43.61Z" }, + { url = "https://files.pythonhosted.org/packages/e8/70/65d4d7cfc75c5c6eb2fed3ee5cdf420fd8ae09c4808723a89a81d5b1b9c3/coverage-7.10.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b38261034fda87be356f2c3f42221fdb4171c3ce7658066ae449241485390d5", size = 264220, upload-time = "2025-08-29T15:34:45.387Z" }, + { url = "https://files.pythonhosted.org/packages/98/3c/069df106d19024324cde10e4ec379fe2fb978017d25e97ebee23002fbadf/coverage-7.10.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e93b1476b79eae849dc3872faeb0bf7948fd9ea34869590bc16a2a00b9c82a7", size = 261660, upload-time = "2025-08-29T15:34:47.288Z" }, + { url = "https://files.pythonhosted.org/packages/fc/8a/2974d53904080c5dc91af798b3a54a4ccb99a45595cc0dcec6eb9616a57d/coverage-7.10.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ff8a991f70f4c0cf53088abf1e3886edcc87d53004c7bb94e78650b4d3dac3b5", size = 259417, upload-time = "2025-08-29T15:34:48.779Z" }, + { url = "https://files.pythonhosted.org/packages/30/38/9616a6b49c686394b318974d7f6e08f38b8af2270ce7488e879888d1e5db/coverage-7.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ac765b026c9f33044419cbba1da913cfb82cca1b60598ac1c7a5ed6aac4621a0", size = 260567, upload-time = "2025-08-29T15:34:50.718Z" }, + { url = "https://files.pythonhosted.org/packages/76/16/3ed2d6312b371a8cf804abf4e14895b70e4c3491c6e53536d63fd0958a8d/coverage-7.10.6-cp314-cp314t-win32.whl", hash = "sha256:441c357d55f4936875636ef2cfb3bee36e466dcf50df9afbd398ce79dba1ebb7", size = 220831, upload-time = "2025-08-29T15:34:52.653Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e5/d38d0cb830abede2adb8b147770d2a3d0e7fecc7228245b9b1ae6c24930a/coverage-7.10.6-cp314-cp314t-win_amd64.whl", hash = "sha256:073711de3181b2e204e4870ac83a7c4853115b42e9cd4d145f2231e12d670930", size = 221950, upload-time = "2025-08-29T15:34:54.212Z" }, + { url = "https://files.pythonhosted.org/packages/f4/51/e48e550f6279349895b0ffcd6d2a690e3131ba3a7f4eafccc141966d4dea/coverage-7.10.6-cp314-cp314t-win_arm64.whl", hash = "sha256:137921f2bac5559334ba66122b753db6dc5d1cf01eb7b64eb412bb0d064ef35b", size = 219969, upload-time = "2025-08-29T15:34:55.83Z" }, + { url = "https://files.pythonhosted.org/packages/91/70/f73ad83b1d2fd2d5825ac58c8f551193433a7deaf9b0d00a8b69ef61cd9a/coverage-7.10.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:90558c35af64971d65fbd935c32010f9a2f52776103a259f1dee865fe8259352", size = 217009, upload-time = "2025-08-29T15:34:57.381Z" }, + { url = "https://files.pythonhosted.org/packages/01/e8/099b55cd48922abbd4b01ddd9ffa352408614413ebfc965501e981aced6b/coverage-7.10.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8953746d371e5695405806c46d705a3cd170b9cc2b9f93953ad838f6c1e58612", size = 217400, upload-time = "2025-08-29T15:34:58.985Z" }, + { url = "https://files.pythonhosted.org/packages/ee/d1/c6bac7c9e1003110a318636fef3b5c039df57ab44abcc41d43262a163c28/coverage-7.10.6-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c83f6afb480eae0313114297d29d7c295670a41c11b274e6bca0c64540c1ce7b", size = 243835, upload-time = "2025-08-29T15:35:00.541Z" }, + { url = "https://files.pythonhosted.org/packages/01/f9/82c6c061838afbd2172e773156c0aa84a901d59211b4975a4e93accf5c89/coverage-7.10.6-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7eb68d356ba0cc158ca535ce1381dbf2037fa8cb5b1ae5ddfc302e7317d04144", size = 245658, upload-time = "2025-08-29T15:35:02.135Z" }, + { url = "https://files.pythonhosted.org/packages/81/6a/35674445b1d38161148558a3ff51b0aa7f0b54b1def3abe3fbd34efe05bc/coverage-7.10.6-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5b15a87265e96307482746d86995f4bff282f14b027db75469c446da6127433b", size = 247433, upload-time = "2025-08-29T15:35:03.777Z" }, + { url = "https://files.pythonhosted.org/packages/18/27/98c99e7cafb288730a93535092eb433b5503d529869791681c4f2e2012a8/coverage-7.10.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fc53ba868875bfbb66ee447d64d6413c2db91fddcfca57025a0e7ab5b07d5862", size = 245315, upload-time = "2025-08-29T15:35:05.629Z" }, + { url = "https://files.pythonhosted.org/packages/09/05/123e0dba812408c719c319dea05782433246f7aa7b67e60402d90e847545/coverage-7.10.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:efeda443000aa23f276f4df973cb82beca682fd800bb119d19e80504ffe53ec2", size = 243385, upload-time = "2025-08-29T15:35:07.494Z" }, + { url = "https://files.pythonhosted.org/packages/67/52/d57a42502aef05c6325f28e2e81216c2d9b489040132c18725b7a04d1448/coverage-7.10.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9702b59d582ff1e184945d8b501ffdd08d2cee38d93a2206aa5f1365ce0b8d78", size = 244343, upload-time = "2025-08-29T15:35:09.55Z" }, + { url = "https://files.pythonhosted.org/packages/6b/22/7f6fad7dbb37cf99b542c5e157d463bd96b797078b1ec506691bc836f476/coverage-7.10.6-cp39-cp39-win32.whl", hash = "sha256:2195f8e16ba1a44651ca684db2ea2b2d4b5345da12f07d9c22a395202a05b23c", size = 219530, upload-time = "2025-08-29T15:35:11.167Z" }, + { url = "https://files.pythonhosted.org/packages/62/30/e2fda29bfe335026027e11e6a5e57a764c9df13127b5cf42af4c3e99b937/coverage-7.10.6-cp39-cp39-win_amd64.whl", hash = "sha256:f32ff80e7ef6a5b5b606ea69a36e97b219cd9dc799bcf2963018a4d8f788cfbf", size = 220432, upload-time = "2025-08-29T15:35:12.902Z" }, + { url = "https://files.pythonhosted.org/packages/44/0c/50db5379b615854b5cf89146f8f5bd1d5a9693d7f3a987e269693521c404/coverage-7.10.6-py3-none-any.whl", hash = "sha256:92c4ecf6bf11b2e85fd4d8204814dc26e6a19f0c9d938c207c5cb0eadfcabbe3", size = 208986, upload-time = "2025-08-29T15:35:14.506Z" }, +] + +[[package]] +name = "cucumber-messages" +version = "28.1.0" +source = { editable = "." } + +[package.dev-dependencies] +dev = [ + { name = "coverage" }, + { name = "gitpython" }, + { name = "packaging" }, + { name = "pytest" }, + { name = "tox" }, +] + +[package.metadata] + +[package.metadata.requires-dev] +dev = [ + { name = "coverage", specifier = ">=7.2" }, + { name = "gitpython" }, + { name = "packaging" }, + { name = "pytest", specifier = ">=6.1" }, + { name = "tox", specifier = ">=4.22" }, +] + +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, +] + +[[package]] +name = "filelock" +version = "3.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/40/bb/0ab3e58d22305b6f5440629d20683af28959bf793d98d11950e305c1c326/filelock-3.19.1.tar.gz", hash = "sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58", size = 17687, upload-time = "2025-08-14T16:56:03.016Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size = 15988, upload-time = "2025-08-14T16:56:01.633Z" }, +] + +[[package]] +name = "gitdb" +version = "4.0.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "smmap" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" }, +] + +[[package]] +name = "gitpython" +version = "3.1.45" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gitdb" }, + { name = "typing-extensions", marker = "python_full_version < '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/c8/dd58967d119baab745caec2f9d853297cec1989ec1d63f677d3880632b88/gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c", size = 215076, upload-time = "2025-07-24T03:45:54.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/61/d4b89fec821f72385526e1b9d9a3a0385dda4a72b206d28049e2c7cd39b8/gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77", size = 208168, upload-time = "2025-07-24T03:45:52.517Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size = 21634, upload-time = "2025-08-26T14:32:04.268Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size = 18654, upload-time = "2025-08-26T14:32:02.735Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pyproject-api" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/fd/437901c891f58a7b9096511750247535e891d2d5a5a6eefbc9386a2b41d5/pyproject_api-1.9.1.tar.gz", hash = "sha256:43c9918f49daab37e302038fc1aed54a8c7a91a9fa935d00b9a485f37e0f5335", size = 22710, upload-time = "2025-05-12T14:41:58.025Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/e6/c293c06695d4a3ab0260ef124a74ebadba5f4c511ce3a4259e976902c00b/pyproject_api-1.9.1-py3-none-any.whl", hash = "sha256:7d6238d92f8962773dd75b5f0c4a6a27cce092a14b623b811dba656f3b628948", size = 13158, upload-time = "2025-05-12T14:41:56.217Z" }, +] + +[[package]] +name = "pytest" +version = "8.4.2" +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 = "pygments" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, +] + +[[package]] +name = "smmap" +version = "5.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329, upload-time = "2025-01-02T07:14:40.909Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303, upload-time = "2025-01-02T07:14:38.724Z" }, +] + +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, +] + +[[package]] +name = "tox" +version = "4.30.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cachetools" }, + { name = "chardet" }, + { name = "colorama" }, + { name = "filelock" }, + { name = "packaging" }, + { name = "platformdirs" }, + { name = "pluggy" }, + { name = "pyproject-api" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/b7/ba4e391cd112c18338aef270abcda2a25783f90509fa6806c8f2a1ea842e/tox-4.30.2.tar.gz", hash = "sha256:772925ad6c57fe35c7ed5ac3e958ac5ced21dff597e76fc40c1f5bf3cd1b6a2e", size = 202622, upload-time = "2025-09-04T16:24:49.602Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/28/8212e633612f959e9b61f3f1e3103e651e33d808a097623495590a42f1a4/tox-4.30.2-py3-none-any.whl", hash = "sha256:efd261a42e8c82a59f9026320a80a067f27f44cad2e72a6712010c311d31176b", size = 175527, upload-time = "2025-09-04T16:24:47.694Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "virtualenv" +version = "20.34.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/14/37fcdba2808a6c615681cd216fecae00413c9dab44fb2e57805ecf3eaee3/virtualenv-20.34.0.tar.gz", hash = "sha256:44815b2c9dee7ed86e387b842a84f20b93f7f417f95886ca1996a72a4138eb1a", size = 6003808, upload-time = "2025-08-13T14:24:07.464Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/06/04c8e804f813cf972e3262f3f8584c232de64f0cde9f703b46cf53a45090/virtualenv-20.34.0-py3-none-any.whl", hash = "sha256:341f5afa7eee943e4984a9207c025feedd768baff6753cd660c857ceb3e36026", size = 5983279, upload-time = "2025-08-13T14:24:05.111Z" }, +] From 9487b3a21b7b15ed0f6cb354b1a2005e2c773efb Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sat, 13 Sep 2025 17:26:43 +0000 Subject: [PATCH 11/22] debt: Redundant mypy overrides configuration --- python/pyproject.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/python/pyproject.toml b/python/pyproject.toml index 8c970c9d..26d08ef9 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -62,10 +62,6 @@ show_error_codes = true warn_return_any = true warn_unused_configs = true -[[tool.mypy.overrides]] -ignore_missing_imports = true -module = [] - [tool.ruff] line-length = 120 From e4da46b79eabfa8d4b7423de56eb4c9dfebe51f8 Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sat, 13 Sep 2025 17:46:12 +0000 Subject: [PATCH 12/22] refactor: Language agnostic coverage action --- .github/workflows/test-python.yml | 8 +++++--- python/.gitignore | 1 + python/pyproject.toml | 5 ++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index b4490477..cf5a815c 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -25,7 +25,6 @@ jobs: strategy: matrix: include: - # Test latest python on Windows and macOS - { os: 'windows-latest', python-version: '3.13' } - { os: 'macos-latest', python-version: '3.13' } os: ['ubuntu-latest'] @@ -46,8 +45,11 @@ jobs: - name: Linting and testing run: uv run tox -e="lint,${{ matrix.python-version }}" - - name: Gather codecov report - run: uvx codecov + - name: Upload test results to Codecov + uses: codecov/test-results-action@v1 + with: + files: python/coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} - name: Build package run: uv build diff --git a/python/.gitignore b/python/.gitignore index 67a4ba97..52eb0b3e 100644 --- a/python/.gitignore +++ b/python/.gitignore @@ -28,6 +28,7 @@ pip-log.txt # Unit test / coverage reports .coverage +coverage.xml .tox nosetests.xml diff --git a/python/pyproject.toml b/python/pyproject.toml index 26d08ef9..35795551 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -89,7 +89,10 @@ deps = ["pre-commit-uv>=4.1.1"] description = "Run linting and formatting checks (and auto-fixes)" [tool.tox.env_run_base] -commands = [["coverage", "run", "--append", "-m", "pytest", "-vvl"]] +commands = [ + ["coverage", "run", "--append", "-m", "pytest", "-vvl"], + ["coverage", "xml"] +] dependency_groups = [ "dev" ] From 578f166eed630d72e2c9b57b9972edb08cbb296a Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sat, 13 Sep 2025 18:47:59 +0000 Subject: [PATCH 13/22] refactor: Install tox dependencies with uv --- .github/workflows/test-python.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index cf5a815c..64825738 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -43,7 +43,9 @@ jobs: version: "0.8.17" - name: Linting and testing - run: uv run tox -e="lint,${{ matrix.python-version }}" + run: | + uv tool install tox --with tox-uv + tox -e="lint,${{ matrix.python-version }}" - name: Upload test results to Codecov uses: codecov/test-results-action@v1 From 80869936046d38db1fbffaddfcd2cd3c847bbb87 Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sat, 13 Sep 2025 19:08:29 +0000 Subject: [PATCH 14/22] chore: Bump to latest codecov action --- .github/workflows/test-python.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 64825738..55b72c8d 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -47,8 +47,8 @@ jobs: uv tool install tox --with tox-uv tox -e="lint,${{ matrix.python-version }}" - - name: Upload test results to Codecov - uses: codecov/test-results-action@v1 + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v5 with: files: python/coverage.xml token: ${{ secrets.CODECOV_TOKEN }} From 316f46412589d3f990ac7fc51e2c906f163b26dc Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sat, 13 Sep 2025 21:21:42 +0000 Subject: [PATCH 15/22] debt: Freeze pre-commit dependencies - Drop redundant ruff pre-commit files specification --- .pre-commit-config.yaml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 68226753..00d490db 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,26 +4,24 @@ files: ^python/ exclude: .*python/src/cucumber_messages/_messages\.py repos: - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 73b0f6d59bbfcb75e17a4653d581c9dfaca13969 # frozen: v0.12.5 - hooks: - - id: ruff-check - files: "^python/" - args: [--fix] - - id: ruff-format - files: "^python/" - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-added-large-files - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks - rev: v2.14.0 + rev: 19b28a9f0a0102b30776f054bea4176e7af50dbe # frozen: v2.15.0 hooks: - id: pretty-format-toml args: [--autofix] + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: 13a6bda8ea7612b3aec844ded16569d424b9a1ab # frozen: v0.13.0 + hooks: + - id: ruff-check + args: [--fix] + - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.18.1 + rev: 30f435a17e4833cfc546d0c2bff4ec75d815f739 # frozen: v1.18.1 hooks: - id: mypy From f3908538a517f8addbce6f592e75e5837bdbea5e Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sat, 13 Sep 2025 21:40:27 +0000 Subject: [PATCH 16/22] debt: test pypy311 and drop pypy39 --- .github/workflows/test-python.yml | 2 +- python/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 55b72c8d..c4007e27 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -28,7 +28,7 @@ jobs: - { os: 'windows-latest', python-version: '3.13' } - { os: 'macos-latest', python-version: '3.13' } os: ['ubuntu-latest'] - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', 'pypy3.9', 'pypy3.10'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', 'pypy3.10', 'pypy3.11'] defaults: run: working-directory: python diff --git a/python/pyproject.toml b/python/pyproject.toml index 35795551..edd121ef 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -80,7 +80,7 @@ extend-select = [ "src/cucumber_messages/__init__.py" = ["F403"] [tool.tox] -env_list = ["lint", "3.13", "3.12", "3.11", "3.10", "3.9", "pypy310", "pypy39"] +env_list = ["lint", "3.13", "3.12", "3.11", "3.10", "3.9", "pypy311", "pypy310"] requires = ["tox>=4.22"] [tool.tox.env.lint] From 8ee4e32565557dc60e5348b2189943c10c92f16d Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sat, 13 Sep 2025 22:34:14 +0000 Subject: [PATCH 17/22] refactor: Leverage tox py alias --- .github/workflows/test-python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index c4007e27..133efef5 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -45,7 +45,7 @@ jobs: - name: Linting and testing run: | uv tool install tox --with tox-uv - tox -e="lint,${{ matrix.python-version }}" + tox -e="lint,py" - name: Upload coverage to Codecov uses: codecov/codecov-action@v5 From 81568c3f82fdab1e1c13e52517c56bde7a306afa Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sat, 13 Sep 2025 22:43:17 +0000 Subject: [PATCH 18/22] debt: Run linting through latest Python only --- .github/workflows/test-python.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 133efef5..2f821086 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -25,10 +25,13 @@ jobs: strategy: matrix: include: - - { os: 'windows-latest', python-version: '3.13' } - - { os: 'macos-latest', python-version: '3.13' } + - { os: 'windows-latest', python-version: '3.13', toxenv: 'py' } + - { os: 'macos-latest', python-version: '3.13', toxenv: 'py' } + # Running linting through latest Python + - { os: 'ubuntu-latest', python-version: '3.13', toxenv: 'lint' } os: ['ubuntu-latest'] python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', 'pypy3.10', 'pypy3.11'] + toxenv: ['py'] defaults: run: working-directory: python @@ -45,7 +48,7 @@ jobs: - name: Linting and testing run: | uv tool install tox --with tox-uv - tox -e="lint,py" + tox -e ${{ matrix.toxenv }} - name: Upload coverage to Codecov uses: codecov/codecov-action@v5 From 88f89f0c8cd0ae1b3da87dd753f27a38fd9b5e71 Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sun, 14 Sep 2025 12:02:43 +0000 Subject: [PATCH 19/22] refactor: Serialise Python 3.13 lint and test jobs - No affect on workflow duration as job will remain faster than Windows --- .github/workflows/test-python.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 2f821086..3fc903b2 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -28,9 +28,9 @@ jobs: - { os: 'windows-latest', python-version: '3.13', toxenv: 'py' } - { os: 'macos-latest', python-version: '3.13', toxenv: 'py' } # Running linting through latest Python - - { os: 'ubuntu-latest', python-version: '3.13', toxenv: 'lint' } + - { os: 'ubuntu-latest', python-version: '3.13', toxenv: 'lint,py' } os: ['ubuntu-latest'] - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', 'pypy3.10', 'pypy3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12', 'pypy3.10', 'pypy3.11'] toxenv: ['py'] defaults: run: From aa297d09a13ee441a6b9c4efd99ccaff5838e49c Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sun, 14 Sep 2025 15:01:24 +0000 Subject: [PATCH 20/22] refactor: Extend Python linting rules Parity with gherkin repository https://github.com/cucumber/gherkin/blob/06fc2deaeda590b8dcd1c23562471dfd3c714816/python/pyproject.toml#L82-L93 --- python/pyproject.toml | 10 +++++++++ .../src/cucumber_messages/json_converter.py | 5 ++--- python/tests/test_json_converter.py | 4 ++-- python/tests/test_messages.py | 14 ++++++------ python/tests/test_model_load.py | 22 +++++-------------- 5 files changed, 27 insertions(+), 28 deletions(-) diff --git a/python/pyproject.toml b/python/pyproject.toml index edd121ef..ff304747 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -71,7 +71,17 @@ exclude = ["src/cucumber_messages/_messages.py"] [tool.ruff.lint] extend-select = [ + "B", + "C4", + "COM", + "FURB", "I", + "ISC", + "N", + "PERF", + "PIE", + "RET", + "TID", "UP" ] diff --git a/python/src/cucumber_messages/json_converter.py b/python/src/cucumber_messages/json_converter.py index 5158e729..5ebe57ef 100644 --- a/python/src/cucumber_messages/json_converter.py +++ b/python/src/cucumber_messages/json_converter.py @@ -179,7 +179,7 @@ def _convert_value(self, value: Any, target_type: Any, field_name: Optional[str] if value is None: return None - converted = ( + return ( self._convert_optional(value, target_type, field_name) or self._convert_datetime(value, target_type) or self._convert_enum(value, target_type) @@ -188,7 +188,6 @@ def _convert_value(self, value: Any, target_type: Any, field_name: Optional[str] or self._convert_dataclass(value, target_type) or value ) - return converted def from_dict(self, data: Any, target_class: type[Any]) -> Any: """Convert a dictionary to a dataclass instance.""" @@ -215,7 +214,7 @@ def from_dict(self, data: Any, target_class: type[Any]) -> Any: try: init_kwargs[field_name] = self._convert_value(value, field_type, field_name) except Exception as e: - raise TypeError(f"Error converting field {key}: {str(e)}") + raise TypeError(f"Error converting field {key}: {str(e)}") from e missing_required = [ name diff --git a/python/tests/test_json_converter.py b/python/tests/test_json_converter.py index 582158a8..6cc45def 100644 --- a/python/tests/test_json_converter.py +++ b/python/tests/test_json_converter.py @@ -107,7 +107,7 @@ def test_collections_with_optional_field_types(serializer): "floatField": 3.14, "boolField": True, "enumField": "value1", - } + }, ], "dictField": { "key": { @@ -116,7 +116,7 @@ def test_collections_with_optional_field_types(serializer): "floatField": 6.28, "boolField": False, "enumField": "value2", - } + }, }, "optionalSequence": ["x", "y", "z"], } diff --git a/python/tests/test_messages.py b/python/tests/test_messages.py index 7e1fbc1c..f2efa1cb 100644 --- a/python/tests/test_messages.py +++ b/python/tests/test_messages.py @@ -40,7 +40,7 @@ def test_envelope_with_attachment(converter): "body": "some body", "contentEncoding": "BASE64", "mediaType": "text/x.cucumber.gherkin+plain", - } + }, } envelope = converter.from_dict(data, Envelope) @@ -60,7 +60,7 @@ def test_envelope_with_source(converter): "data": "Feature: Sample\nScenario: Test\n", "mediaType": "text/x.cucumber.gherkin+plain", "uri": "features/sample.feature", - } + }, } envelope = converter.from_dict(data, Envelope) @@ -79,7 +79,7 @@ def test_test_run_finished_with_optional_fields(converter): "success": True, "timestamp": {"seconds": 1700000000, "nanos": 123456789}, # exception and message are omitted, should be None after deserialization - } + }, } envelope = converter.from_dict(data, Envelope) @@ -101,7 +101,7 @@ def test_test_case_finished(converter): "testCaseStartedId": "some_test_case_started_id", "timestamp": {"seconds": 1600000000, "nanos": 500}, "willBeRetried": False, - } + }, } envelope = converter.from_dict(data, Envelope) @@ -125,7 +125,7 @@ def test_exception_serialization(converter): "message": "Expected 'X' but got 'Y'", "stackTrace": "Traceback (most recent call last): ...", }, - } + }, } envelope = converter.from_dict(data, Envelope) @@ -151,7 +151,7 @@ def test_test_step_result(converter): "message": "Step executed successfully", }, "timestamp": {"seconds": 1700000020, "nanos": 0}, - } + }, } envelope = converter.from_dict(data, Envelope) @@ -173,7 +173,7 @@ def test_missing_optional_fields(converter): "body": "no optional fields", "contentEncoding": "IDENTITY", "mediaType": "text/plain", - } + }, } envelope = converter.from_dict(data, Envelope) diff --git a/python/tests/test_model_load.py b/python/tests/test_model_load.py index 5a801e02..7a066873 100644 --- a/python/tests/test_model_load.py +++ b/python/tests/test_model_load.py @@ -17,25 +17,15 @@ def compatibility_kit_repo(tmpdir): str(repo_path), branch="main", ) - repo_tags = list( - filter( - lambda tag: tag is not None, - map(lambda tag: getattr(tag.tag, "tag", None), repo.tags), - ) - ) + repo_tags = [getattr(tag.tag, "tag", None) for tag in repo.tags if getattr(tag.tag, "tag", None) is not None] version_pattern = re.compile(r"((.*/)?)v(\d+\.\d+\.\d+)") last_version = sorted( - map( - version.parse, - map( - lambda match: match.groups()[-1], - filter( - lambda match: match is not None, - map(lambda tag: re.match(version_pattern, tag), repo_tags), - ), - ), - ) + [ + version.parse(match.groups()[-1]) + for tag in repo_tags + if (match := re.match(version_pattern, tag)) is not None + ], )[-1] last_version_tag = next(filter(lambda tag: re.search(re.escape(str(last_version)), tag), repo_tags)) From e35af2431baf1227a5bc1aa5cd34e42b3c124bbd Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sun, 14 Sep 2025 21:56:49 +0000 Subject: [PATCH 21/22] chore: Changelog drop legacy Python dist metadata --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4345b5b..854fd724 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Removed +- [Python] Dropped legacy .egg-info metadata distribution artifacts ([#324](https://github.com/cucumber/messages/pull/324)) ## [29.0.1] - 2025-09-08 ### Fixed From a2947a7c25d5053972acdd755dc8defd097e71db Mon Sep 17 00:00:00 2001 From: Kieran Ryan Date: Sun, 14 Sep 2025 22:27:03 +0000 Subject: [PATCH 22/22] fix: Run Python workflow when pre-commit modified --- .github/workflows/test-python.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 3fc903b2..13977ba3 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -7,6 +7,7 @@ on: - main - renovate/** paths: + - .pre-commit-config.yaml - python/** - Makefile - .github/** @@ -14,6 +15,7 @@ on: branches: - main paths: + - .pre-commit-config.yaml - python/** - Makefile - .github/**