diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6ab23893..4ef702e6 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,6 +10,10 @@ updates: schedule: interval: "monthly" timezone: "Asia/Tokyo" + groups: + dependencies: + patterns: + - "*" target-branch: "develop" ignore: - dependency-name: "*" @@ -20,6 +24,6 @@ updates: # default location of `.github/workflows` directory: "/" schedule: - interval: "weekly" + interval: "monthly" timezone: "Asia/Tokyo" target-branch: "develop" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2a4bee0d..721ba6b9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,11 +7,11 @@ jobs: name: Build the project runs-on: ${{ matrix.os }} strategy: - max-parallel: 18 + max-parallel: 15 fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - name: Checkout repository uses: actions/checkout@v4 @@ -19,7 +19,6 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - allow-prereleases: true # TODO: Remove this line when Python 3.12 is released - name: Install Poetry run: | pipx install poetry diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d2eee160..a0d9b9f2 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,10 +8,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 - - name: Set up Python 3.7 + - name: Set up Python 3.8 uses: actions/setup-python@v4 with: - python-version: "3.7" + python-version: "3.8" - name: Run linters run: | pipx install pre-commit diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index eafc9074..d7da4659 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,6 +4,9 @@ on: release: types: [published] +permissions: + contents: read + jobs: build-publish: runs-on: ubuntu-latest @@ -25,5 +28,6 @@ jobs: - name: Publish package uses: pypa/gh-action-pypi-publish@release/v1 with: + user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} verbose: true diff --git a/.github/workflows/test-example.yml b/.github/workflows/test-example.yml index 15e73991..53cb9802 100644 --- a/.github/workflows/test-example.yml +++ b/.github/workflows/test-example.yml @@ -8,8 +8,8 @@ on: jobs: test-example: name: Run tests for examples - container: kunlp/jumanpp-knp:ubuntu - runs-on: ubuntu-20.04 # to meet the ubuntu version in the kunlp/jumanpp-knp:ubuntu container + container: kunlp/jumanpp-knp:ubuntu22.04 + runs-on: ubuntu-22.04 strategy: max-parallel: 5 fail-fast: false @@ -20,24 +20,29 @@ jobs: uses: actions/checkout@v4 - name: Install required apt packages run: | - apt update -y - DEBIAN_FRONTEND=noninteractive apt install -y curl build-essential libsqlite3-dev libffi-dev + export DEBIAN_FRONTEND=noninteractive + apt-get update -yq + apt-get install -yq curl build-essential libsqlite3-dev libffi-dev - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - allow-prereleases: true # TODO: Remove this line when Python 3.12 is released - name: Install Poetry run: | python3 -m pip install --user pipx python3 -m pipx ensurepath python3 -m pipx install poetry - name: Add path for Python packages - run: echo "$HOME/.local/bin" >> $GITHUB_PATH + run: | + echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Install dependencies - run: poetry install --no-interaction --without dev,docs --extras=cli + run: | + poetry install --no-interaction --without dev,docs --extras=cli - name: Install KWJA - run: pipx install kwja + # KWJA does not support Python 3.12 + if: ${{ matrix.python-version != 3.12 }} + run: | + pipx install kwja - name: Run tests for all files under examples/apply_*.py shell: bash run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1e28bf86..8cb82652 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,25 +5,25 @@ on: [push, pull_request, workflow_dispatch] jobs: test: name: Run tests with pytest - container: kunlp/jumanpp-knp:ubuntu - runs-on: ubuntu-20.04 # to meet the ubuntu version in the kunlp/jumanpp-knp:ubuntu container + container: kunlp/jumanpp-knp:ubuntu22.04 + runs-on: ubuntu-22.04 strategy: - max-parallel: 6 + max-parallel: 5 fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install required apt packages run: | - apt update -y - DEBIAN_FRONTEND=noninteractive apt install -y curl build-essential libsqlite3-dev libffi-dev + export DEBIAN_FRONTEND=noninteractive + apt-get update -yq + apt-get install -yq curl build-essential libsqlite3-dev libffi-dev libssl-dev - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - allow-prereleases: true # TODO: Remove this line when Python 3.12 is released - name: Install Poetry run: | python3 -m pip install --user pipx @@ -36,8 +36,8 @@ jobs: run: | poetry install --no-interaction --without dev,docs --extras=cli - name: Install KWJA - # KWJA does not support Python 3.7 or 3.12 - if: ${{ matrix.python-version != 3.7 && matrix.python-version != 3.12 }} + # KWJA does not support Python 3.12 + if: ${{ matrix.python-version != 3.12 }} run: | pipx install kwja kwja --model-size tiny --text "テスト" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 997fc85c..61cb4ba4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: end-of-file-fixer - id: trailing-whitespace @@ -8,50 +8,43 @@ repos: - id: check-yaml - id: check-toml - id: check-added-large-files + exclude: "assets/logo.*" + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.1.4 + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.9.0 + rev: 23.11.0 hooks: - id: black - - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 - hooks: - - id: flake8 - additional_dependencies: [Flake8-pyproject] - - repo: https://github.com/PyCQA/isort - rev: 5.12.0 - hooks: - - id: isort - repo: https://github.com/MarcoGorelli/absolufy-imports rev: v0.3.1 hooks: - id: absolufy-imports - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.5.1 + rev: v1.6.1 hooks: - id: mypy additional_dependencies: - - types-PyYAML + - typing-extensions - typer + - types-PyYAML - rich - uvicorn - fastapi - - markdown-it-py==2.2.0 # markdown-it-py 3.0.0 requires Python 3.8+ - - repo: https://github.com/asottile/pyupgrade - rev: v3.10.1 - hooks: - - id: pyupgrade - args: - - --py37-plus + - jinja2 + - pygments - repo: https://github.com/PyCQA/pydocstyle rev: 6.3.0 hooks: - id: pydocstyle - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.2 + rev: v3.0.3 hooks: - id: prettier - repo: https://github.com/Riverside-Healthcare/djLint - rev: v1.32.1 + rev: v1.34.0 hooks: - id: djlint-jinja - id: djlint-reformat-jinja diff --git a/CITATION.cff b/CITATION.cff index 8eba3ce0..782f691a 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -6,6 +6,6 @@ authors: given-names: Hirokazu - family-names: Ueda given-names: Nobuhiro -version: 1.2.0 +version: 1.6.0 repository-code: "https://github.com/ku-nlp/rhoknp" -date-released: 2023-02-07 +date-released: 2023-11-08 diff --git a/README.md b/README.md index 5613b935..b6a1dd92 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ with open("result.jumanpp", "rt") as f: ## Requirements -- Python 3.7+ +- Python 3.8+ - (Optional) [Juman++](https://github.com/ku-nlp/jumanpp) v2.0.0-rc3+ - (Optional) [KNP](https://github.com/ku-nlp/knp) 5.0+ - (Optional) [KWJA](https://github.com/ku-nlp/kwja) 1.0.0+ diff --git a/assets/logo-original.png b/assets/logo-original.png new file mode 100644 index 00000000..d8e29371 Binary files /dev/null and b/assets/logo-original.png differ diff --git a/assets/logo-wide.xcf b/assets/logo-wide.xcf new file mode 100644 index 00000000..e299d6fe Binary files /dev/null and b/assets/logo-wide.xcf differ diff --git a/assets/logo.xcf b/assets/logo.xcf new file mode 100644 index 00000000..61445a30 Binary files /dev/null and b/assets/logo.xcf differ diff --git a/docs/cli/index.md b/docs/cli/index.md index 8bd3497f..c62b40a0 100644 --- a/docs/cli/index.md +++ b/docs/cli/index.md @@ -11,6 +11,17 @@ Before using the CLI, you need to install _rhoknp_ with the following command: pip install rhoknp[cli] ``` +## cat + +The `cat` command prints KNP files with syntax highlighting. + +```{eval-rst} +.. prompt:: + :prompts: $ + + rhoknp cat [--dark] +``` + ## serve The `serve` command starts a web server to provide a playground for the given language analyzer. diff --git a/docs/installation/index.md b/docs/installation/index.md index dafa891f..5b482968 100644 --- a/docs/installation/index.md +++ b/docs/installation/index.md @@ -3,7 +3,7 @@ ## Requirements - [Python](https://python.org/) - - Supported versions: 3.7+ + - Supported versions: 3.8+ - [Juman++](https://github.com/ku-nlp/jumanpp) (Optional) - Supported versions: v2.0.0-rc3+ - [KNP](https://github.com/ku-nlp/knp) (Optional) diff --git a/poetry.lock b/poetry.lock index 395cc2a5..4da660ee 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. [[package]] name = "alabaster" @@ -13,13 +13,13 @@ files = [ [[package]] name = "annotated-types" -version = "0.5.0" +version = "0.6.0" description = "Reusable constraint types to use with typing.Annotated" optional = true -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "annotated_types-0.5.0-py3-none-any.whl", hash = "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"}, - {file = "annotated_types-0.5.0.tar.gz", hash = "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802"}, + {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.dependencies] @@ -40,7 +40,6 @@ files = [ exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] @@ -60,34 +59,39 @@ files = [ [[package]] name = "asttokens" -version = "2.4.0" +version = "2.4.1" description = "Annotate AST trees with source code positions" optional = false python-versions = "*" files = [ - {file = "asttokens-2.4.0-py2.py3-none-any.whl", hash = "sha256:cf8fc9e61a86461aa9fb161a14a0841a03c405fa829ac6b202670b3495d2ce69"}, - {file = "asttokens-2.4.0.tar.gz", hash = "sha256:2e0171b991b2c959acc6c49318049236844a5da1d65ba2672c4880c1c894834e"}, + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, ] [package.dependencies] six = ">=1.12.0" [package.extras] -test = ["astroid", "pytest"] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] [[package]] name = "babel" -version = "2.12.1" +version = "2.13.1" description = "Internationalization utilities" optional = false python-versions = ">=3.7" files = [ - {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, - {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, + {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"}, + {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"}, ] [package.dependencies] pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} +setuptools = {version = "*", markers = "python_version >= \"3.12\""} + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "backcall" @@ -118,17 +122,6 @@ soupsieve = ">1.2" html5lib = ["html5lib"] lxml = ["lxml"] -[[package]] -name = "cached-property" -version = "1.5.2" -description = "A decorator for caching properties in classes." -optional = false -python-versions = "*" -files = [ - {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, - {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, -] - [[package]] name = "certifi" version = "2023.7.22" @@ -142,86 +135,101 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.2.0" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] [[package]] @@ -237,7 +245,6 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" @@ -252,128 +259,63 @@ files = [ [[package]] name = "coverage" -version = "6.5.0" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, - {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, - {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"}, - {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"}, - {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"}, - {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"}, - {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"}, - {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"}, - {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"}, - {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"}, - {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"}, - {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"}, - {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"}, - {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"}, - {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"}, - {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"}, - {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"}, - {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"}, - {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"}, - {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"}, - {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"}, - {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"}, - {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"}, - {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"}, - {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"}, - {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"}, - {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"}, - {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"}, - {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"}, - {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"}, - {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"}, - {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"}, - {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"}, - {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"}, - {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"}, - {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"}, - {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"}, - {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"}, - {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"}, - {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"}, - {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"}, - {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"}, - {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"}, - {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"}, - {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"}, - {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"}, - {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"}, - {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"}, - {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, - {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, -] - -[package.dependencies] -tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} - -[package.extras] -toml = ["tomli"] - -[[package]] -name = "coverage" -version = "7.3.1" +version = "7.3.2" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cd0f7429ecfd1ff597389907045ff209c8fdb5b013d38cfa7c60728cb484b6e3"}, - {file = "coverage-7.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:966f10df9b2b2115da87f50f6a248e313c72a668248be1b9060ce935c871f276"}, - {file = "coverage-7.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0575c37e207bb9b98b6cf72fdaaa18ac909fb3d153083400c2d48e2e6d28bd8e"}, - {file = "coverage-7.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:245c5a99254e83875c7fed8b8b2536f040997a9b76ac4c1da5bff398c06e860f"}, - {file = "coverage-7.3.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c96dd7798d83b960afc6c1feb9e5af537fc4908852ef025600374ff1a017392"}, - {file = "coverage-7.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:de30c1aa80f30af0f6b2058a91505ea6e36d6535d437520067f525f7df123887"}, - {file = "coverage-7.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:50dd1e2dd13dbbd856ffef69196781edff26c800a74f070d3b3e3389cab2600d"}, - {file = "coverage-7.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9c0c19f70d30219113b18fe07e372b244fb2a773d4afde29d5a2f7930765136"}, - {file = "coverage-7.3.1-cp310-cp310-win32.whl", hash = "sha256:770f143980cc16eb601ccfd571846e89a5fe4c03b4193f2e485268f224ab602f"}, - {file = "coverage-7.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:cdd088c00c39a27cfa5329349cc763a48761fdc785879220d54eb785c8a38520"}, - {file = "coverage-7.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74bb470399dc1989b535cb41f5ca7ab2af561e40def22d7e188e0a445e7639e3"}, - {file = "coverage-7.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:025ded371f1ca280c035d91b43252adbb04d2aea4c7105252d3cbc227f03b375"}, - {file = "coverage-7.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6191b3a6ad3e09b6cfd75b45c6aeeffe7e3b0ad46b268345d159b8df8d835f9"}, - {file = "coverage-7.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7eb0b188f30e41ddd659a529e385470aa6782f3b412f860ce22b2491c89b8593"}, - {file = "coverage-7.3.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75c8f0df9dfd8ff745bccff75867d63ef336e57cc22b2908ee725cc552689ec8"}, - {file = "coverage-7.3.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7eb3cd48d54b9bd0e73026dedce44773214064be93611deab0b6a43158c3d5a0"}, - {file = "coverage-7.3.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ac3c5b7e75acac31e490b7851595212ed951889918d398b7afa12736c85e13ce"}, - {file = "coverage-7.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5b4ee7080878077af0afa7238df1b967f00dc10763f6e1b66f5cced4abebb0a3"}, - {file = "coverage-7.3.1-cp311-cp311-win32.whl", hash = "sha256:229c0dd2ccf956bf5aeede7e3131ca48b65beacde2029f0361b54bf93d36f45a"}, - {file = "coverage-7.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:c6f55d38818ca9596dc9019eae19a47410d5322408140d9a0076001a3dcb938c"}, - {file = "coverage-7.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5289490dd1c3bb86de4730a92261ae66ea8d44b79ed3cc26464f4c2cde581fbc"}, - {file = "coverage-7.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ca833941ec701fda15414be400c3259479bfde7ae6d806b69e63b3dc423b1832"}, - {file = "coverage-7.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd694e19c031733e446c8024dedd12a00cda87e1c10bd7b8539a87963685e969"}, - {file = "coverage-7.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aab8e9464c00da5cb9c536150b7fbcd8850d376d1151741dd0d16dfe1ba4fd26"}, - {file = "coverage-7.3.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d38444efffd5b056fcc026c1e8d862191881143c3aa80bb11fcf9dca9ae204"}, - {file = "coverage-7.3.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8a07b692129b8a14ad7a37941a3029c291254feb7a4237f245cfae2de78de037"}, - {file = "coverage-7.3.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:2829c65c8faaf55b868ed7af3c7477b76b1c6ebeee99a28f59a2cb5907a45760"}, - {file = "coverage-7.3.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1f111a7d85658ea52ffad7084088277135ec5f368457275fc57f11cebb15607f"}, - {file = "coverage-7.3.1-cp312-cp312-win32.whl", hash = "sha256:c397c70cd20f6df7d2a52283857af622d5f23300c4ca8e5bd8c7a543825baa5a"}, - {file = "coverage-7.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:5ae4c6da8b3d123500f9525b50bf0168023313963e0e2e814badf9000dd6ef92"}, - {file = "coverage-7.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ca70466ca3a17460e8fc9cea7123c8cbef5ada4be3140a1ef8f7b63f2f37108f"}, - {file = "coverage-7.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f2781fd3cabc28278dc982a352f50c81c09a1a500cc2086dc4249853ea96b981"}, - {file = "coverage-7.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6407424621f40205bbe6325686417e5e552f6b2dba3535dd1f90afc88a61d465"}, - {file = "coverage-7.3.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:04312b036580ec505f2b77cbbdfb15137d5efdfade09156961f5277149f5e344"}, - {file = "coverage-7.3.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9ad38204887349853d7c313f53a7b1c210ce138c73859e925bc4e5d8fc18e7"}, - {file = "coverage-7.3.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:53669b79f3d599da95a0afbef039ac0fadbb236532feb042c534fbb81b1a4e40"}, - {file = "coverage-7.3.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:614f1f98b84eb256e4f35e726bfe5ca82349f8dfa576faabf8a49ca09e630086"}, - {file = "coverage-7.3.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f1a317fdf5c122ad642db8a97964733ab7c3cf6009e1a8ae8821089993f175ff"}, - {file = "coverage-7.3.1-cp38-cp38-win32.whl", hash = "sha256:defbbb51121189722420a208957e26e49809feafca6afeef325df66c39c4fdb3"}, - {file = "coverage-7.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:f4f456590eefb6e1b3c9ea6328c1e9fa0f1006e7481179d749b3376fc793478e"}, - {file = "coverage-7.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f12d8b11a54f32688b165fd1a788c408f927b0960984b899be7e4c190ae758f1"}, - {file = "coverage-7.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f09195dda68d94a53123883de75bb97b0e35f5f6f9f3aa5bf6e496da718f0cb6"}, - {file = "coverage-7.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6601a60318f9c3945be6ea0f2a80571f4299b6801716f8a6e4846892737ebe4"}, - {file = "coverage-7.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07d156269718670d00a3b06db2288b48527fc5f36859425ff7cec07c6b367745"}, - {file = "coverage-7.3.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:636a8ac0b044cfeccae76a36f3b18264edcc810a76a49884b96dd744613ec0b7"}, - {file = "coverage-7.3.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5d991e13ad2ed3aced177f524e4d670f304c8233edad3210e02c465351f785a0"}, - {file = "coverage-7.3.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:586649ada7cf139445da386ab6f8ef00e6172f11a939fc3b2b7e7c9082052fa0"}, - {file = "coverage-7.3.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4aba512a15a3e1e4fdbfed2f5392ec221434a614cc68100ca99dcad7af29f3f8"}, - {file = "coverage-7.3.1-cp39-cp39-win32.whl", hash = "sha256:6bc6f3f4692d806831c136c5acad5ccedd0262aa44c087c46b7101c77e139140"}, - {file = "coverage-7.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:553d7094cb27db58ea91332e8b5681bac107e7242c23f7629ab1316ee73c4981"}, - {file = "coverage-7.3.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:220eb51f5fb38dfdb7e5d54284ca4d0cd70ddac047d750111a68ab1798945194"}, - {file = "coverage-7.3.1.tar.gz", hash = "sha256:6cb7fe1581deb67b782c153136541e20901aa312ceedaf1467dcb35255787952"}, + {file = "coverage-7.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf"}, + {file = "coverage-7.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9"}, + {file = "coverage-7.3.2-cp310-cp310-win32.whl", hash = "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f"}, + {file = "coverage-7.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611"}, + {file = "coverage-7.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c"}, + {file = "coverage-7.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312"}, + {file = "coverage-7.3.2-cp311-cp311-win32.whl", hash = "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640"}, + {file = "coverage-7.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2"}, + {file = "coverage-7.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836"}, + {file = "coverage-7.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a"}, + {file = "coverage-7.3.2-cp312-cp312-win32.whl", hash = "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb"}, + {file = "coverage-7.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed"}, + {file = "coverage-7.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738"}, + {file = "coverage-7.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76"}, + {file = "coverage-7.3.2-cp38-cp38-win32.whl", hash = "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92"}, + {file = "coverage-7.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a"}, + {file = "coverage-7.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce"}, + {file = "coverage-7.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083"}, + {file = "coverage-7.3.2-cp39-cp39-win32.whl", hash = "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce"}, + {file = "coverage-7.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f"}, + {file = "coverage-7.3.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637"}, + {file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"}, ] [package.dependencies] @@ -393,17 +335,6 @@ files = [ {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, ] -[[package]] -name = "docutils" -version = "0.19" -description = "Docutils -- Python Documentation Utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, - {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, -] - [[package]] name = "docutils" version = "0.20.1" @@ -431,55 +362,38 @@ test = ["pytest (>=6)"] [[package]] name = "executing" -version = "1.2.0" +version = "2.0.1" description = "Get the currently executing AST node of a frame, and other information" optional = false -python-versions = "*" +python-versions = ">=3.5" files = [ - {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, - {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, + {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, + {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, ] [package.extras] -tests = ["asttokens", "littleutils", "pytest", "rich"] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] [[package]] name = "fastapi" -version = "0.103.1" +version = "0.104.1" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = true -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "fastapi-0.103.1-py3-none-any.whl", hash = "sha256:5e5f17e826dbd9e9b5a5145976c5cd90bcaa61f2bf9a69aca423f2bcebe44d83"}, - {file = "fastapi-0.103.1.tar.gz", hash = "sha256:345844e6a82062f06a096684196aaf96c1198b25c06b72c1311b882aa2d8a35d"}, + {file = "fastapi-0.104.1-py3-none-any.whl", hash = "sha256:752dc31160cdbd0436bb93bad51560b57e525cbb1d4bbf6f4904ceee75548241"}, + {file = "fastapi-0.104.1.tar.gz", hash = "sha256:e5e4540a7c5e1dcfbbcf5b903c234feddcdcd881f191977a1c5dfd917487e7ae"}, ] [package.dependencies] anyio = ">=3.7.1,<4.0.0" pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" starlette = ">=0.27.0,<0.28.0" -typing-extensions = ">=4.5.0" +typing-extensions = ">=4.8.0" [package.extras] all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] -[[package]] -name = "furo" -version = "2023.3.27" -description = "A clean customisable Sphinx documentation theme." -optional = false -python-versions = ">=3.7" -files = [ - {file = "furo-2023.3.27-py3-none-any.whl", hash = "sha256:4ab2be254a2d5e52792d0ca793a12c35582dd09897228a6dd47885dabd5c9521"}, - {file = "furo-2023.3.27.tar.gz", hash = "sha256:b99e7867a5cc833b2b34d7230631dd6558c7a29f93071fdbb5709634bb33c5a5"}, -] - -[package.dependencies] -beautifulsoup4 = "*" -pygments = ">=2.7" -sphinx = ">=5.0,<7.0" -sphinx-basic-ng = "*" - [[package]] name = "furo" version = "2023.9.10" @@ -508,88 +422,42 @@ files = [ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, ] -[package.dependencies] -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - -[[package]] -name = "httpcore" -version = "0.17.3" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.7" -files = [ - {file = "httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"}, - {file = "httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888"}, -] - -[package.dependencies] -anyio = ">=3.0,<5.0" -certifi = "*" -h11 = ">=0.13,<0.15" -sniffio = "==1.*" - -[package.extras] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] - [[package]] name = "httpcore" -version = "0.18.0" +version = "1.0.1" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-0.18.0-py3-none-any.whl", hash = "sha256:adc5398ee0a476567bf87467063ee63584a8bce86078bf748e48754f60202ced"}, - {file = "httpcore-0.18.0.tar.gz", hash = "sha256:13b5e5cd1dca1a6636a6aaea212b19f4f85cd88c366a2b82304181b769aab3c9"}, + {file = "httpcore-1.0.1-py3-none-any.whl", hash = "sha256:c5e97ef177dca2023d0b9aad98e49507ef5423e9f1d94ffe2cfe250aa28e63b0"}, + {file = "httpcore-1.0.1.tar.gz", hash = "sha256:fce1ddf9b606cfb98132ab58865c3728c52c8e4c3c46e2aabb3674464a186e92"}, ] [package.dependencies] -anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = "==1.*" [package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.23.0)"] [[package]] name = "httpx" -version = "0.24.1" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.7" -files = [ - {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"}, - {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"}, -] - -[package.dependencies] -certifi = "*" -httpcore = ">=0.15.0,<0.18.0" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] - -[[package]] -name = "httpx" -version = "0.25.0" +version = "0.25.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.25.0-py3-none-any.whl", hash = "sha256:181ea7f8ba3a82578be86ef4171554dd45fec26a02556a744db029a0a27b7100"}, - {file = "httpx-0.25.0.tar.gz", hash = "sha256:47ecda285389cb32bb2691cc6e069e3ab0205956f681c5b2ad2325719751d875"}, + {file = "httpx-0.25.1-py3-none-any.whl", hash = "sha256:fec7d6cc5c27c578a391f7e87b9aa7d3d8fbcd034f6399f9f79b45bcc12a866a"}, + {file = "httpx-0.25.1.tar.gz", hash = "sha256:ffd96d5cf901e63863d9f1b4b6807861dbea4d301613415d9e6e57ead15fc5d0"}, ] [package.dependencies] +anyio = "*" certifi = "*" -httpcore = ">=0.18.0,<0.19.0" +httpcore = "*" idna = "*" sniffio = "*" @@ -623,23 +491,22 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.7.0" +version = "6.8.0" description = "Read metadata from Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5"}, - {file = "importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4"}, + {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, + {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, ] [package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] [[package]] name = "iniconfig" @@ -670,49 +537,13 @@ tomli = {version = "*", markers = "python_version > \"3.6\" and python_version < [[package]] name = "ipython" -version = "7.34.0" -description = "IPython: Productive Interactive Computing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "ipython-7.34.0-py3-none-any.whl", hash = "sha256:c175d2440a1caff76116eb719d40538fbb316e214eda85c5515c303aacbfb23e"}, - {file = "ipython-7.34.0.tar.gz", hash = "sha256:af3bdb46aa292bce5615b1b2ebc76c2080c5f77f54bda2ec72461317273e7cd6"}, -] - -[package.dependencies] -appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -decorator = "*" -jedi = ">=0.16" -matplotlib-inline = "*" -pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" -prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" -pygments = "*" -setuptools = ">=18.5" -traitlets = ">=4.2" - -[package.extras] -all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"] -doc = ["Sphinx (>=1.3)"] -kernel = ["ipykernel"] -nbconvert = ["nbconvert"] -nbformat = ["nbformat"] -notebook = ["ipywidgets", "notebook"] -parallel = ["ipyparallel"] -qtconsole = ["qtconsole"] -test = ["ipykernel", "nbformat", "nose (>=0.10.1)", "numpy (>=1.17)", "pygments", "requests", "testpath"] - -[[package]] -name = "ipython" -version = "8.12.2" +version = "8.12.3" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.8" files = [ - {file = "ipython-8.12.2-py3-none-any.whl", hash = "sha256:ea8801f15dfe4ffb76dea1b09b847430ffd70d827b41735c64a0638a04103bfc"}, - {file = "ipython-8.12.2.tar.gz", hash = "sha256:c7b80eb7f5a855a88efc971fda506ff7a91c280b42cdae26643e0f601ea281ea"}, + {file = "ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c"}, + {file = "ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363"}, ] [package.dependencies] @@ -745,25 +576,23 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pa [[package]] name = "ipython" -version = "8.15.0" +version = "8.17.2" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.9" files = [ - {file = "ipython-8.15.0-py3-none-any.whl", hash = "sha256:45a2c3a529296870a97b7de34eda4a31bee16bc7bf954e07d39abe49caf8f887"}, - {file = "ipython-8.15.0.tar.gz", hash = "sha256:2baeb5be6949eeebf532150f81746f8333e2ccce02de1c7eedde3f23ed5e9f1e"}, + {file = "ipython-8.17.2-py3-none-any.whl", hash = "sha256:1e4d1d666a023e3c93585ba0d8e962867f7a111af322efff6b9c58062b3e5444"}, + {file = "ipython-8.17.2.tar.gz", hash = "sha256:126bb57e1895594bb0d91ea3090bbd39384f6fe87c3d57fd558d0670f50339bb"}, ] [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" colorama = {version = "*", markers = "sys_platform == \"win32\""} decorator = "*" exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" pygments = ">=2.4.0" stack-data = "*" @@ -771,27 +600,27 @@ traitlets = ">=5" typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] -all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] -doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] [[package]] name = "jedi" -version = "0.19.0" +version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.6" files = [ - {file = "jedi-0.19.0-py2.py3-none-any.whl", hash = "sha256:cb8ce23fbccff0025e9386b5cf85e892f94c9b822378f8da49970471335ac64e"}, - {file = "jedi-0.19.0.tar.gz", hash = "sha256:bcf9894f1753969cbac8022a8c2eaee06bfa3724e4192470aaffe7eb6272b0c4"}, + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, ] [package.dependencies] @@ -800,7 +629,7 @@ parso = ">=0.8.3,<0.9.0" [package.extras] docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] name = "jinja2" @@ -819,31 +648,6 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[[package]] -name = "markdown-it-py" -version = "2.2.0" -description = "Python port of markdown-it. Markdown parsing, done right!" -optional = false -python-versions = ">=3.7" -files = [ - {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, - {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, -] - -[package.dependencies] -mdurl = ">=0.1,<1.0" -typing_extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] -profiling = ["gprof2dot"] -rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - [[package]] name = "markdown-it-py" version = "3.0.0" @@ -895,6 +699,16 @@ files = [ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, @@ -941,25 +755,6 @@ files = [ [package.dependencies] traitlets = "*" -[[package]] -name = "mdit-py-plugins" -version = "0.3.5" -description = "Collection of plugins for markdown-it-py" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"}, - {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"}, -] - -[package.dependencies] -markdown-it-py = ">=1.0.0,<3.0.0" - -[package.extras] -code-style = ["pre-commit"] -rtd = ["attrs", "myst-parser (>=0.16.1,<0.17.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - [[package]] name = "mdit-py-plugins" version = "0.4.0" @@ -990,33 +785,6 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] -[[package]] -name = "myst-parser" -version = "1.0.0" -description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," -optional = false -python-versions = ">=3.7" -files = [ - {file = "myst-parser-1.0.0.tar.gz", hash = "sha256:502845659313099542bd38a2ae62f01360e7dd4b1310f025dd014dfc0439cdae"}, - {file = "myst_parser-1.0.0-py3-none-any.whl", hash = "sha256:69fb40a586c6fa68995e6521ac0a525793935db7e724ca9bac1d33be51be9a4c"}, -] - -[package.dependencies] -docutils = ">=0.15,<0.20" -jinja2 = "*" -markdown-it-py = ">=1.0.0,<3.0.0" -mdit-py-plugins = ">=0.3.4,<0.4.0" -pyyaml = "*" -sphinx = ">=5,<7" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - -[package.extras] -code-style = ["pre-commit (>=3.0,<4.0)"] -linkify = ["linkify-it-py (>=1.0,<2.0)"] -rtd = ["ipython", "pydata-sphinx-theme (==v0.13.0rc4)", "sphinx-autodoc2 (>=0.4.2,<0.5.0)", "sphinx-book-theme (==1.0.0rc2)", "sphinx-copybutton", "sphinx-design2", "sphinx-pyscript", "sphinx-tippy (>=0.3.1)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.7.5,<0.8.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] -testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=7,<8)", "pytest-cov", "pytest-param-files (>=0.3.4,<0.4.0)", "pytest-regressions", "sphinx-pytest"] -testing-docutils = ["pygments", "pytest (>=7,<8)", "pytest-param-files (>=0.3.4,<0.4.0)"] - [[package]] name = "myst-parser" version = "2.0.0" @@ -1045,13 +813,13 @@ testing-docutils = ["pygments", "pytest (>=7,<8)", "pytest-param-files (>=0.3.4, [[package]] name = "packaging" -version = "23.1" +version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] [[package]] @@ -1096,18 +864,15 @@ files = [ [[package]] name = "pluggy" -version = "1.2.0" +version = "1.3.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} - [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] @@ -1153,18 +918,18 @@ tests = ["pytest"] [[package]] name = "pydantic" -version = "2.3.0" +version = "2.4.2" description = "Data validation using Python type hints" optional = true python-versions = ">=3.7" files = [ - {file = "pydantic-2.3.0-py3-none-any.whl", hash = "sha256:45b5e446c6dfaad9444819a293b921a40e1db1aa61ea08aede0522529ce90e81"}, - {file = "pydantic-2.3.0.tar.gz", hash = "sha256:1607cc106602284cd4a00882986570472f193fde9cb1259bceeaedb26aa79a6d"}, + {file = "pydantic-2.4.2-py3-none-any.whl", hash = "sha256:bc3ddf669d234f4220e6e1c4d96b061abe0998185a8d7855c0126782b7abc8c1"}, + {file = "pydantic-2.4.2.tar.gz", hash = "sha256:94f336138093a5d7f426aac732dcfe7ab4eb4da243c88f891d65deb4a2556ee7"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.6.3" +pydantic-core = "2.10.1" typing-extensions = ">=4.6.1" [package.extras] @@ -1172,117 +937,117 @@ email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.6.3" +version = "2.10.1" description = "" optional = true python-versions = ">=3.7" files = [ - {file = "pydantic_core-2.6.3-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:1a0ddaa723c48af27d19f27f1c73bdc615c73686d763388c8683fe34ae777bad"}, - {file = "pydantic_core-2.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5cfde4fab34dd1e3a3f7f3db38182ab6c95e4ea91cf322242ee0be5c2f7e3d2f"}, - {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5493a7027bfc6b108e17c3383959485087d5942e87eb62bbac69829eae9bc1f7"}, - {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:84e87c16f582f5c753b7f39a71bd6647255512191be2d2dbf49458c4ef024588"}, - {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:522a9c4a4d1924facce7270c84b5134c5cabcb01513213662a2e89cf28c1d309"}, - {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaafc776e5edc72b3cad1ccedb5fd869cc5c9a591f1213aa9eba31a781be9ac1"}, - {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a750a83b2728299ca12e003d73d1264ad0440f60f4fc9cee54acc489249b728"}, - {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e8b374ef41ad5c461efb7a140ce4730661aadf85958b5c6a3e9cf4e040ff4bb"}, - {file = "pydantic_core-2.6.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b594b64e8568cf09ee5c9501ede37066b9fc41d83d58f55b9952e32141256acd"}, - {file = "pydantic_core-2.6.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2a20c533cb80466c1d42a43a4521669ccad7cf2967830ac62c2c2f9cece63e7e"}, - {file = "pydantic_core-2.6.3-cp310-none-win32.whl", hash = "sha256:04fe5c0a43dec39aedba0ec9579001061d4653a9b53a1366b113aca4a3c05ca7"}, - {file = "pydantic_core-2.6.3-cp310-none-win_amd64.whl", hash = "sha256:6bf7d610ac8f0065a286002a23bcce241ea8248c71988bda538edcc90e0c39ad"}, - {file = "pydantic_core-2.6.3-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:6bcc1ad776fffe25ea5c187a028991c031a00ff92d012ca1cc4714087e575973"}, - {file = "pydantic_core-2.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:df14f6332834444b4a37685810216cc8fe1fe91f447332cd56294c984ecbff1c"}, - {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b7486d85293f7f0bbc39b34e1d8aa26210b450bbd3d245ec3d732864009819"}, - {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a892b5b1871b301ce20d40b037ffbe33d1407a39639c2b05356acfef5536d26a"}, - {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:883daa467865e5766931e07eb20f3e8152324f0adf52658f4d302242c12e2c32"}, - {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4eb77df2964b64ba190eee00b2312a1fd7a862af8918ec70fc2d6308f76ac64"}, - {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce8c84051fa292a5dc54018a40e2a1926fd17980a9422c973e3ebea017aa8da"}, - {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:22134a4453bd59b7d1e895c455fe277af9d9d9fbbcb9dc3f4a97b8693e7e2c9b"}, - {file = "pydantic_core-2.6.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:02e1c385095efbd997311d85c6021d32369675c09bcbfff3b69d84e59dc103f6"}, - {file = "pydantic_core-2.6.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d79f1f2f7ebdb9b741296b69049ff44aedd95976bfee38eb4848820628a99b50"}, - {file = "pydantic_core-2.6.3-cp311-none-win32.whl", hash = "sha256:430ddd965ffd068dd70ef4e4d74f2c489c3a313adc28e829dd7262cc0d2dd1e8"}, - {file = "pydantic_core-2.6.3-cp311-none-win_amd64.whl", hash = "sha256:84f8bb34fe76c68c9d96b77c60cef093f5e660ef8e43a6cbfcd991017d375950"}, - {file = "pydantic_core-2.6.3-cp311-none-win_arm64.whl", hash = "sha256:5a2a3c9ef904dcdadb550eedf3291ec3f229431b0084666e2c2aa8ff99a103a2"}, - {file = "pydantic_core-2.6.3-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:8421cf496e746cf8d6b677502ed9a0d1e4e956586cd8b221e1312e0841c002d5"}, - {file = "pydantic_core-2.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bb128c30cf1df0ab78166ded1ecf876620fb9aac84d2413e8ea1594b588c735d"}, - {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37a822f630712817b6ecc09ccc378192ef5ff12e2c9bae97eb5968a6cdf3b862"}, - {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:240a015102a0c0cc8114f1cba6444499a8a4d0333e178bc504a5c2196defd456"}, - {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f90e5e3afb11268628c89f378f7a1ea3f2fe502a28af4192e30a6cdea1e7d5e"}, - {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:340e96c08de1069f3d022a85c2a8c63529fd88709468373b418f4cf2c949fb0e"}, - {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1480fa4682e8202b560dcdc9eeec1005f62a15742b813c88cdc01d44e85308e5"}, - {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f14546403c2a1d11a130b537dda28f07eb6c1805a43dae4617448074fd49c282"}, - {file = "pydantic_core-2.6.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a87c54e72aa2ef30189dc74427421e074ab4561cf2bf314589f6af5b37f45e6d"}, - {file = "pydantic_core-2.6.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f93255b3e4d64785554e544c1c76cd32f4a354fa79e2eeca5d16ac2e7fdd57aa"}, - {file = "pydantic_core-2.6.3-cp312-none-win32.whl", hash = "sha256:f70dc00a91311a1aea124e5f64569ea44c011b58433981313202c46bccbec0e1"}, - {file = "pydantic_core-2.6.3-cp312-none-win_amd64.whl", hash = "sha256:23470a23614c701b37252618e7851e595060a96a23016f9a084f3f92f5ed5881"}, - {file = "pydantic_core-2.6.3-cp312-none-win_arm64.whl", hash = "sha256:1ac1750df1b4339b543531ce793b8fd5c16660a95d13aecaab26b44ce11775e9"}, - {file = "pydantic_core-2.6.3-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:a53e3195f134bde03620d87a7e2b2f2046e0e5a8195e66d0f244d6d5b2f6d31b"}, - {file = "pydantic_core-2.6.3-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:f2969e8f72c6236c51f91fbb79c33821d12a811e2a94b7aa59c65f8dbdfad34a"}, - {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:672174480a85386dd2e681cadd7d951471ad0bb028ed744c895f11f9d51b9ebe"}, - {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:002d0ea50e17ed982c2d65b480bd975fc41086a5a2f9c924ef8fc54419d1dea3"}, - {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ccc13afee44b9006a73d2046068d4df96dc5b333bf3509d9a06d1b42db6d8bf"}, - {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:439a0de139556745ae53f9cc9668c6c2053444af940d3ef3ecad95b079bc9987"}, - {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d63b7545d489422d417a0cae6f9898618669608750fc5e62156957e609e728a5"}, - {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b44c42edc07a50a081672e25dfe6022554b47f91e793066a7b601ca290f71e42"}, - {file = "pydantic_core-2.6.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1c721bfc575d57305dd922e6a40a8fe3f762905851d694245807a351ad255c58"}, - {file = "pydantic_core-2.6.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5e4a2cf8c4543f37f5dc881de6c190de08096c53986381daebb56a355be5dfe6"}, - {file = "pydantic_core-2.6.3-cp37-none-win32.whl", hash = "sha256:d9b4916b21931b08096efed090327f8fe78e09ae8f5ad44e07f5c72a7eedb51b"}, - {file = "pydantic_core-2.6.3-cp37-none-win_amd64.whl", hash = "sha256:a8acc9dedd304da161eb071cc7ff1326aa5b66aadec9622b2574ad3ffe225525"}, - {file = "pydantic_core-2.6.3-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:5e9c068f36b9f396399d43bfb6defd4cc99c36215f6ff33ac8b9c14ba15bdf6b"}, - {file = "pydantic_core-2.6.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e61eae9b31799c32c5f9b7be906be3380e699e74b2db26c227c50a5fc7988698"}, - {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85463560c67fc65cd86153a4975d0b720b6d7725cf7ee0b2d291288433fc21b"}, - {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9616567800bdc83ce136e5847d41008a1d602213d024207b0ff6cab6753fe645"}, - {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e9b65a55bbabda7fccd3500192a79f6e474d8d36e78d1685496aad5f9dbd92c"}, - {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f468d520f47807d1eb5d27648393519655eadc578d5dd862d06873cce04c4d1b"}, - {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9680dd23055dd874173a3a63a44e7f5a13885a4cfd7e84814be71be24fba83db"}, - {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a718d56c4d55efcfc63f680f207c9f19c8376e5a8a67773535e6f7e80e93170"}, - {file = "pydantic_core-2.6.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8ecbac050856eb6c3046dea655b39216597e373aa8e50e134c0e202f9c47efec"}, - {file = "pydantic_core-2.6.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:788be9844a6e5c4612b74512a76b2153f1877cd845410d756841f6c3420230eb"}, - {file = "pydantic_core-2.6.3-cp38-none-win32.whl", hash = "sha256:07a1aec07333bf5adebd8264047d3dc518563d92aca6f2f5b36f505132399efc"}, - {file = "pydantic_core-2.6.3-cp38-none-win_amd64.whl", hash = "sha256:621afe25cc2b3c4ba05fff53525156d5100eb35c6e5a7cf31d66cc9e1963e378"}, - {file = "pydantic_core-2.6.3-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:813aab5bfb19c98ae370952b6f7190f1e28e565909bfc219a0909db168783465"}, - {file = "pydantic_core-2.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:50555ba3cb58f9861b7a48c493636b996a617db1a72c18da4d7f16d7b1b9952b"}, - {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19e20f8baedd7d987bd3f8005c146e6bcbda7cdeefc36fad50c66adb2dd2da48"}, - {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0a5d7edb76c1c57b95df719af703e796fc8e796447a1da939f97bfa8a918d60"}, - {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f06e21ad0b504658a3a9edd3d8530e8cea5723f6ea5d280e8db8efc625b47e49"}, - {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea053cefa008fda40f92aab937fb9f183cf8752e41dbc7bc68917884454c6362"}, - {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:171a4718860790f66d6c2eda1d95dd1edf64f864d2e9f9115840840cf5b5713f"}, - {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ed7ceca6aba5331ece96c0e328cd52f0dcf942b8895a1ed2642de50800b79d3"}, - {file = "pydantic_core-2.6.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:acafc4368b289a9f291e204d2c4c75908557d4f36bd3ae937914d4529bf62a76"}, - {file = "pydantic_core-2.6.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1aa712ba150d5105814e53cb141412217146fedc22621e9acff9236d77d2a5ef"}, - {file = "pydantic_core-2.6.3-cp39-none-win32.whl", hash = "sha256:44b4f937b992394a2e81a5c5ce716f3dcc1237281e81b80c748b2da6dd5cf29a"}, - {file = "pydantic_core-2.6.3-cp39-none-win_amd64.whl", hash = "sha256:9b33bf9658cb29ac1a517c11e865112316d09687d767d7a0e4a63d5c640d1b17"}, - {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d7050899026e708fb185e174c63ebc2c4ee7a0c17b0a96ebc50e1f76a231c057"}, - {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:99faba727727b2e59129c59542284efebbddade4f0ae6a29c8b8d3e1f437beb7"}, - {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fa159b902d22b283b680ef52b532b29554ea2a7fc39bf354064751369e9dbd7"}, - {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:046af9cfb5384f3684eeb3f58a48698ddab8dd870b4b3f67f825353a14441418"}, - {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:930bfe73e665ebce3f0da2c6d64455098aaa67e1a00323c74dc752627879fc67"}, - {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:85cc4d105747d2aa3c5cf3e37dac50141bff779545ba59a095f4a96b0a460e70"}, - {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b25afe9d5c4f60dcbbe2b277a79be114e2e65a16598db8abee2a2dcde24f162b"}, - {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e49ce7dc9f925e1fb010fc3d555250139df61fa6e5a0a95ce356329602c11ea9"}, - {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:2dd50d6a1aef0426a1d0199190c6c43ec89812b1f409e7fe44cb0fbf6dfa733c"}, - {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6595b0d8c8711e8e1dc389d52648b923b809f68ac1c6f0baa525c6440aa0daa"}, - {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ef724a059396751aef71e847178d66ad7fc3fc969a1a40c29f5aac1aa5f8784"}, - {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3c8945a105f1589ce8a693753b908815e0748f6279959a4530f6742e1994dcb6"}, - {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c8c6660089a25d45333cb9db56bb9e347241a6d7509838dbbd1931d0e19dbc7f"}, - {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:692b4ff5c4e828a38716cfa92667661a39886e71136c97b7dac26edef18767f7"}, - {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:f1a5d8f18877474c80b7711d870db0eeef9442691fcdb00adabfc97e183ee0b0"}, - {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:3796a6152c545339d3b1652183e786df648ecdf7c4f9347e1d30e6750907f5bb"}, - {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b962700962f6e7a6bd77e5f37320cabac24b4c0f76afeac05e9f93cf0c620014"}, - {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56ea80269077003eaa59723bac1d8bacd2cd15ae30456f2890811efc1e3d4413"}, - {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75c0ebbebae71ed1e385f7dfd9b74c1cff09fed24a6df43d326dd7f12339ec34"}, - {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:252851b38bad3bfda47b104ffd077d4f9604a10cb06fe09d020016a25107bf98"}, - {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:6656a0ae383d8cd7cc94e91de4e526407b3726049ce8d7939049cbfa426518c8"}, - {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d9140ded382a5b04a1c030b593ed9bf3088243a0a8b7fa9f071a5736498c5483"}, - {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d38bbcef58220f9c81e42c255ef0bf99735d8f11edef69ab0b499da77105158a"}, - {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:c9d469204abcca28926cbc28ce98f28e50e488767b084fb3fbdf21af11d3de26"}, - {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:48c1ed8b02ffea4d5c9c220eda27af02b8149fe58526359b3c07eb391cb353a2"}, - {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b2b1bfed698fa410ab81982f681f5b1996d3d994ae8073286515ac4d165c2e7"}, - {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf9d42a71a4d7a7c1f14f629e5c30eac451a6fc81827d2beefd57d014c006c4a"}, - {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4292ca56751aebbe63a84bbfc3b5717abb09b14d4b4442cc43fd7c49a1529efd"}, - {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7dc2ce039c7290b4ef64334ec7e6ca6494de6eecc81e21cb4f73b9b39991408c"}, - {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:615a31b1629e12445c0e9fc8339b41aaa6cc60bd53bf802d5fe3d2c0cda2ae8d"}, - {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1fa1f6312fb84e8c281f32b39affe81984ccd484da6e9d65b3d18c202c666149"}, - {file = "pydantic_core-2.6.3.tar.gz", hash = "sha256:1508f37ba9e3ddc0189e6ff4e2228bd2d3c3a4641cbe8c07177162f76ed696c7"}, + {file = "pydantic_core-2.10.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:d64728ee14e667ba27c66314b7d880b8eeb050e58ffc5fec3b7a109f8cddbd63"}, + {file = "pydantic_core-2.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:48525933fea744a3e7464c19bfede85df4aba79ce90c60b94d8b6e1eddd67096"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef337945bbd76cce390d1b2496ccf9f90b1c1242a3a7bc242ca4a9fc5993427a"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1392e0638af203cee360495fd2cfdd6054711f2db5175b6e9c3c461b76f5175"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0675ba5d22de54d07bccde38997e780044dcfa9a71aac9fd7d4d7a1d2e3e65f7"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:128552af70a64660f21cb0eb4876cbdadf1a1f9d5de820fed6421fa8de07c893"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f6e6aed5818c264412ac0598b581a002a9f050cb2637a84979859e70197aa9e"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ecaac27da855b8d73f92123e5f03612b04c5632fd0a476e469dfc47cd37d6b2e"}, + {file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3c01c2fb081fced3bbb3da78510693dc7121bb893a1f0f5f4b48013201f362e"}, + {file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:92f675fefa977625105708492850bcbc1182bfc3e997f8eecb866d1927c98ae6"}, + {file = "pydantic_core-2.10.1-cp310-none-win32.whl", hash = "sha256:420a692b547736a8d8703c39ea935ab5d8f0d2573f8f123b0a294e49a73f214b"}, + {file = "pydantic_core-2.10.1-cp310-none-win_amd64.whl", hash = "sha256:0880e239827b4b5b3e2ce05e6b766a7414e5f5aedc4523be6b68cfbc7f61c5d0"}, + {file = "pydantic_core-2.10.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:073d4a470b195d2b2245d0343569aac7e979d3a0dcce6c7d2af6d8a920ad0bea"}, + {file = "pydantic_core-2.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:600d04a7b342363058b9190d4e929a8e2e715c5682a70cc37d5ded1e0dd370b4"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39215d809470f4c8d1881758575b2abfb80174a9e8daf8f33b1d4379357e417c"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eeb3d3d6b399ffe55f9a04e09e635554012f1980696d6b0aca3e6cf42a17a03b"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a7902bf75779bc12ccfc508bfb7a4c47063f748ea3de87135d433a4cca7a2f"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3625578b6010c65964d177626fde80cf60d7f2e297d56b925cb5cdeda6e9925a"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa48fc31fc7243e50188197b5f0c4228956f97b954f76da157aae7f67269ae8"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:07ec6d7d929ae9c68f716195ce15e745b3e8fa122fc67698ac6498d802ed0fa4"}, + {file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6f31a17acede6a8cd1ae2d123ce04d8cca74056c9d456075f4f6f85de055607"}, + {file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d8f1ebca515a03e5654f88411420fea6380fc841d1bea08effb28184e3d4899f"}, + {file = "pydantic_core-2.10.1-cp311-none-win32.whl", hash = "sha256:6db2eb9654a85ada248afa5a6db5ff1cf0f7b16043a6b070adc4a5be68c716d6"}, + {file = "pydantic_core-2.10.1-cp311-none-win_amd64.whl", hash = "sha256:4a5be350f922430997f240d25f8219f93b0c81e15f7b30b868b2fddfc2d05f27"}, + {file = "pydantic_core-2.10.1-cp311-none-win_arm64.whl", hash = "sha256:5fdb39f67c779b183b0c853cd6b45f7db84b84e0571b3ef1c89cdb1dfc367325"}, + {file = "pydantic_core-2.10.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1f22a9ab44de5f082216270552aa54259db20189e68fc12484873d926426921"}, + {file = "pydantic_core-2.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8572cadbf4cfa95fb4187775b5ade2eaa93511f07947b38f4cd67cf10783b118"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db9a28c063c7c00844ae42a80203eb6d2d6bbb97070cfa00194dff40e6f545ab"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e2a35baa428181cb2270a15864ec6286822d3576f2ed0f4cd7f0c1708472aff"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05560ab976012bf40f25d5225a58bfa649bb897b87192a36c6fef1ab132540d7"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6495008733c7521a89422d7a68efa0a0122c99a5861f06020ef5b1f51f9ba7c"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14ac492c686defc8e6133e3a2d9eaf5261b3df26b8ae97450c1647286750b901"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8282bab177a9a3081fd3d0a0175a07a1e2bfb7fcbbd949519ea0980f8a07144d"}, + {file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:aafdb89fdeb5fe165043896817eccd6434aee124d5ee9b354f92cd574ba5e78f"}, + {file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f6defd966ca3b187ec6c366604e9296f585021d922e666b99c47e78738b5666c"}, + {file = "pydantic_core-2.10.1-cp312-none-win32.whl", hash = "sha256:7c4d1894fe112b0864c1fa75dffa045720a194b227bed12f4be7f6045b25209f"}, + {file = "pydantic_core-2.10.1-cp312-none-win_amd64.whl", hash = "sha256:5994985da903d0b8a08e4935c46ed8daf5be1cf217489e673910951dc533d430"}, + {file = "pydantic_core-2.10.1-cp312-none-win_arm64.whl", hash = "sha256:0d8a8adef23d86d8eceed3e32e9cca8879c7481c183f84ed1a8edc7df073af94"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:9badf8d45171d92387410b04639d73811b785b5161ecadabf056ea14d62d4ede"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:ebedb45b9feb7258fac0a268a3f6bec0a2ea4d9558f3d6f813f02ff3a6dc6698"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfe1090245c078720d250d19cb05d67e21a9cd7c257698ef139bc41cf6c27b4f"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e357571bb0efd65fd55f18db0a2fb0ed89d0bb1d41d906b138f088933ae618bb"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b3dcd587b69bbf54fc04ca157c2323b8911033e827fffaecf0cafa5a892a0904"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c120c9ce3b163b985a3b966bb701114beb1da4b0468b9b236fc754783d85aa3"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15d6bca84ffc966cc9976b09a18cf9543ed4d4ecbd97e7086f9ce9327ea48891"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5cabb9710f09d5d2e9e2748c3e3e20d991a4c5f96ed8f1132518f54ab2967221"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:82f55187a5bebae7d81d35b1e9aaea5e169d44819789837cdd4720d768c55d15"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1d40f55222b233e98e3921df7811c27567f0e1a4411b93d4c5c0f4ce131bc42f"}, + {file = "pydantic_core-2.10.1-cp37-none-win32.whl", hash = "sha256:14e09ff0b8fe6e46b93d36a878f6e4a3a98ba5303c76bb8e716f4878a3bee92c"}, + {file = "pydantic_core-2.10.1-cp37-none-win_amd64.whl", hash = "sha256:1396e81b83516b9d5c9e26a924fa69164156c148c717131f54f586485ac3c15e"}, + {file = "pydantic_core-2.10.1-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6835451b57c1b467b95ffb03a38bb75b52fb4dc2762bb1d9dbed8de31ea7d0fc"}, + {file = "pydantic_core-2.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b00bc4619f60c853556b35f83731bd817f989cba3e97dc792bb8c97941b8053a"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fa467fd300a6f046bdb248d40cd015b21b7576c168a6bb20aa22e595c8ffcdd"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d99277877daf2efe074eae6338453a4ed54a2d93fb4678ddfe1209a0c93a2468"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa7db7558607afeccb33c0e4bf1c9a9a835e26599e76af6fe2fcea45904083a6"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aad7bd686363d1ce4ee930ad39f14e1673248373f4a9d74d2b9554f06199fb58"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:443fed67d33aa85357464f297e3d26e570267d1af6fef1c21ca50921d2976302"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:042462d8d6ba707fd3ce9649e7bf268633a41018d6a998fb5fbacb7e928a183e"}, + {file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ecdbde46235f3d560b18be0cb706c8e8ad1b965e5c13bbba7450c86064e96561"}, + {file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ed550ed05540c03f0e69e6d74ad58d026de61b9eaebebbaaf8873e585cbb18de"}, + {file = "pydantic_core-2.10.1-cp38-none-win32.whl", hash = "sha256:8cdbbd92154db2fec4ec973d45c565e767ddc20aa6dbaf50142676484cbff8ee"}, + {file = "pydantic_core-2.10.1-cp38-none-win_amd64.whl", hash = "sha256:9f6f3e2598604956480f6c8aa24a3384dbf6509fe995d97f6ca6103bb8c2534e"}, + {file = "pydantic_core-2.10.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:655f8f4c8d6a5963c9a0687793da37b9b681d9ad06f29438a3b2326d4e6b7970"}, + {file = "pydantic_core-2.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e570ffeb2170e116a5b17e83f19911020ac79d19c96f320cbfa1fa96b470185b"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64322bfa13e44c6c30c518729ef08fda6026b96d5c0be724b3c4ae4da939f875"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:485a91abe3a07c3a8d1e082ba29254eea3e2bb13cbbd4351ea4e5a21912cc9b0"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7c2b8eb9fc872e68b46eeaf835e86bccc3a58ba57d0eedc109cbb14177be531"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a5cb87bdc2e5f620693148b5f8f842d293cae46c5f15a1b1bf7ceeed324a740c"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25bd966103890ccfa028841a8f30cebcf5875eeac8c4bde4fe221364c92f0c9a"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f323306d0556351735b54acbf82904fe30a27b6a7147153cbe6e19aaaa2aa429"}, + {file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0c27f38dc4fbf07b358b2bc90edf35e82d1703e22ff2efa4af4ad5de1b3833e7"}, + {file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f1365e032a477c1430cfe0cf2856679529a2331426f8081172c4a74186f1d595"}, + {file = "pydantic_core-2.10.1-cp39-none-win32.whl", hash = "sha256:a1c311fd06ab3b10805abb72109f01a134019739bd3286b8ae1bc2fc4e50c07a"}, + {file = "pydantic_core-2.10.1-cp39-none-win_amd64.whl", hash = "sha256:ae8a8843b11dc0b03b57b52793e391f0122e740de3df1474814c700d2622950a"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d43002441932f9a9ea5d6f9efaa2e21458221a3a4b417a14027a1d530201ef1b"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fcb83175cc4936a5425dde3356f079ae03c0802bbdf8ff82c035f8a54b333521"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:962ed72424bf1f72334e2f1e61b68f16c0e596f024ca7ac5daf229f7c26e4208"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2cf5bb4dd67f20f3bbc1209ef572a259027c49e5ff694fa56bed62959b41e1f9"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e544246b859f17373bed915182ab841b80849ed9cf23f1f07b73b7c58baee5fb"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c0877239307b7e69d025b73774e88e86ce82f6ba6adf98f41069d5b0b78bd1bf"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:53df009d1e1ba40f696f8995683e067e3967101d4bb4ea6f667931b7d4a01357"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a1254357f7e4c82e77c348dabf2d55f1d14d19d91ff025004775e70a6ef40ada"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:524ff0ca3baea164d6d93a32c58ac79eca9f6cf713586fdc0adb66a8cdeab96a"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f0ac9fb8608dbc6eaf17956bf623c9119b4db7dbb511650910a82e261e6600f"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:320f14bd4542a04ab23747ff2c8a778bde727158b606e2661349557f0770711e"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:63974d168b6233b4ed6a0046296803cb13c56637a7b8106564ab575926572a55"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:417243bf599ba1f1fef2bb8c543ceb918676954734e2dcb82bf162ae9d7bd514"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dda81e5ec82485155a19d9624cfcca9be88a405e2857354e5b089c2a982144b2"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:14cfbb00959259e15d684505263d5a21732b31248a5dd4941f73a3be233865b9"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:631cb7415225954fdcc2a024119101946793e5923f6c4d73a5914d27eb3d3a05"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:bec7dd208a4182e99c5b6c501ce0b1f49de2802448d4056091f8e630b28e9a52"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:149b8a07712f45b332faee1a2258d8ef1fb4a36f88c0c17cb687f205c5dc6e7d"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d966c47f9dd73c2d32a809d2be529112d509321c5310ebf54076812e6ecd884"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7eb037106f5c6b3b0b864ad226b0b7ab58157124161d48e4b30c4a43fef8bc4b"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:154ea7c52e32dce13065dbb20a4a6f0cc012b4f667ac90d648d36b12007fa9f7"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e562617a45b5a9da5be4abe72b971d4f00bf8555eb29bb91ec2ef2be348cd132"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:f23b55eb5464468f9e0e9a9935ce3ed2a870608d5f534025cd5536bca25b1402"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:e9121b4009339b0f751955baf4543a0bfd6bc3f8188f8056b1a25a2d45099934"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:0523aeb76e03f753b58be33b26540880bac5aa54422e4462404c432230543f33"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e0e2959ef5d5b8dc9ef21e1a305a21a36e254e6a34432d00c72a92fdc5ecda5"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da01bec0a26befab4898ed83b362993c844b9a607a86add78604186297eb047e"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f2e9072d71c1f6cfc79a36d4484c82823c560e6f5599c43c1ca6b5cdbd54f881"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f36a3489d9e28fe4b67be9992a23029c3cec0babc3bd9afb39f49844a8c721c5"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f64f82cc3443149292b32387086d02a6c7fb39b8781563e0ca7b8d7d9cf72bd7"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b4a6db486ac8e99ae696e09efc8b2b9fea67b63c8f88ba7a1a16c24a057a0776"}, + {file = "pydantic_core-2.10.1.tar.gz", hash = "sha256:0f8682dbdd2f67f8e1edddcbffcc29f60a6182b4901c367fc8c1c40d30bb0a82"}, ] [package.dependencies] @@ -1304,19 +1069,18 @@ plugins = ["importlib-metadata"] [[package]] name = "pytest" -version = "7.4.2" +version = "7.4.3" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"}, - {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"}, + {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, + {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" @@ -1436,13 +1200,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.5.3" +version = "13.6.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = true python-versions = ">=3.7.0" files = [ - {file = "rich-13.5.3-py3-none-any.whl", hash = "sha256:9257b468badc3d347e146a4faa268ff229039d4c2d176ab0cffb4c4fbc73d5d9"}, - {file = "rich-13.5.3.tar.gz", hash = "sha256:87b43e0543149efa1253f485cd845bb7ee54df16c9617b8a893650ab84b4acb6"}, + {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"}, + {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"}, ] [package.dependencies] @@ -1455,19 +1219,19 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "setuptools" -version = "68.0.0" +version = "68.2.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, - {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, + {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, + {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -1502,17 +1266,6 @@ files = [ {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] -[[package]] -name = "soupsieve" -version = "2.4.1" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = false -python-versions = ">=3.7" -files = [ - {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, - {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, -] - [[package]] name = "soupsieve" version = "2.5" @@ -1524,41 +1277,6 @@ files = [ {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, ] -[[package]] -name = "sphinx" -version = "5.3.0" -description = "Python documentation generator" -optional = false -python-versions = ">=3.6" -files = [ - {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"}, - {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"}, -] - -[package.dependencies] -alabaster = ">=0.7,<0.8" -babel = ">=2.9" -colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.20" -imagesize = ">=1.3" -importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} -Jinja2 = ">=3.0" -packaging = ">=21.0" -Pygments = ">=2.12" -requests = ">=2.5.0" -snowballstemmer = ">=2.0" -sphinxcontrib-applehelp = "*" -sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = ">=2.0.0" -sphinxcontrib-jsmath = "*" -sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.5" - -[package.extras] -docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"] -test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"] - [[package]] name = "sphinx" version = "7.1.2" @@ -1629,20 +1347,6 @@ sphinx = ">=1.8" code-style = ["pre-commit (==2.12.1)"] rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] -[[package]] -name = "sphinx-prompt" -version = "1.5.0" -description = "Sphinx directive to add unselectable prompt" -optional = false -python-versions = "*" -files = [ - {file = "sphinx_prompt-1.5.0-py3-none-any.whl", hash = "sha256:fa4e90d8088b5a996c76087d701fc7e31175f8b9dc4aab03a507e45051067162"}, -] - -[package.dependencies] -pygments = "*" -Sphinx = "*" - [[package]] name = "sphinx-prompt" version = "1.7.0" @@ -1675,21 +1379,6 @@ docutils = "*" pygments = "*" Sphinx = ">=7.0.0,<8.0.0" -[[package]] -name = "sphinxcontrib-applehelp" -version = "1.0.2" -description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" -optional = false -python-versions = ">=3.5" -files = [ - {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, - {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, -] - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - [[package]] name = "sphinxcontrib-applehelp" version = "1.0.4" @@ -1720,21 +1409,6 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.0.0" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -optional = false -python-versions = ">=3.6" -files = [ - {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, - {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, -] - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["html5lib", "pytest"] - [[package]] name = "sphinxcontrib-htmlhelp" version = "2.0.1" @@ -1796,13 +1470,13 @@ test = ["pytest"] [[package]] name = "stack-data" -version = "0.6.2" +version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" optional = false python-versions = "*" files = [ - {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, - {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, ] [package.dependencies] @@ -1844,53 +1518,18 @@ files = [ [[package]] name = "traitlets" -version = "5.9.0" -description = "Traitlets Python configuration system" -optional = false -python-versions = ">=3.7" -files = [ - {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, - {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, -] - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] - -[[package]] -name = "traitlets" -version = "5.10.0" +version = "5.13.0" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" files = [ - {file = "traitlets-5.10.0-py3-none-any.whl", hash = "sha256:417745a96681fbb358e723d5346a547521f36e9bd0d50ba7ab368fff5d67aa54"}, - {file = "traitlets-5.10.0.tar.gz", hash = "sha256:f584ea209240466e66e91f3c81aa7d004ba4cf794990b0c775938a1544217cd1"}, + {file = "traitlets-5.13.0-py3-none-any.whl", hash = "sha256:baf991e61542da48fe8aef8b779a9ea0aa38d8a54166ee250d5af5ecf4486619"}, + {file = "traitlets-5.13.0.tar.gz", hash = "sha256:9b232b9430c8f57288c1024b34a8f0251ddcc47268927367a0dd3eeaca40deb5"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.5.1)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] - -[[package]] -name = "typer" -version = "0.8.0" -description = "Typer, build great CLIs. Easy to code. Based on Python type hints." -optional = true -python-versions = ">=3.6" -files = [ - {file = "typer-0.8.0-py3-none-any.whl", hash = "sha256:07dd96b7961d11da53be3f9b9cd0eb76f413d5ef06df7942cb2f85bd03dd2633"}, - {file = "typer-0.8.0.tar.gz", hash = "sha256:7442b3a4369c8352b8bb684d04558b278b80fa92ae5d5760eb42c2f27c71f044"}, -] - -[package.dependencies] -click = ">=7.1.1,<9.0.0" - -[package.extras] -all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] -dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] -doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] -test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.6.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "typer" @@ -1915,24 +1554,24 @@ test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6. [[package]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.8.0" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, ] [[package]] name = "urllib3" -version = "2.0.4" +version = "2.0.7" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.7" files = [ - {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, - {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, + {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, + {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, ] [package.extras] @@ -1943,32 +1582,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "uvicorn" -version = "0.22.0" -description = "The lightning-fast ASGI server." -optional = true -python-versions = ">=3.7" -files = [ - {file = "uvicorn-0.22.0-py3-none-any.whl", hash = "sha256:e9434d3bbf05f310e762147f769c9f21235ee118ba2d2bf1155a7196448bd996"}, - {file = "uvicorn-0.22.0.tar.gz", hash = "sha256:79277ae03db57ce7d9aa0567830bbb51d7a612f54d6e1e3e92da3ef24c2c8ed8"}, -] - -[package.dependencies] -click = ">=7.0" -h11 = ">=0.8" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - -[package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] - -[[package]] -name = "uvicorn" -version = "0.23.2" +version = "0.24.0.post1" description = "The lightning-fast ASGI server." optional = true python-versions = ">=3.8" files = [ - {file = "uvicorn-0.23.2-py3-none-any.whl", hash = "sha256:1f9be6558f01239d4fdf22ef8126c39cb1ad0addf76c40e760549d2c2f43ab53"}, - {file = "uvicorn-0.23.2.tar.gz", hash = "sha256:4d3cc12d7727ba72b64d12d3cc7743124074c0a69f7b201512fc50c3e3f1569a"}, + {file = "uvicorn-0.24.0.post1-py3-none-any.whl", hash = "sha256:7c84fea70c619d4a710153482c0d230929af7bcf76c7bfa6de151f0a3a80121e"}, + {file = "uvicorn-0.24.0.post1.tar.gz", hash = "sha256:09c8e5a79dc466bdf28dead50093957db184de356fcdc48697bad3bde4c2588e"}, ] [package.dependencies] @@ -1981,34 +1601,34 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", [[package]] name = "wcwidth" -version = "0.2.6" +version = "0.2.9" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, - {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, + {file = "wcwidth-0.2.9-py2.py3-none-any.whl", hash = "sha256:9a929bd8380f6cd9571a968a9c8f4353ca58d7cd812a4822bba831f8d685b223"}, + {file = "wcwidth-0.2.9.tar.gz", hash = "sha256:a675d1a4a2d24ef67096a04b85b02deeecd8e226f57b5e3a72dbb9ed99d27da8"}, ] [[package]] name = "zipp" -version = "3.15.0" +version = "3.17.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, - {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [extras] -cli = ["PyYAML", "fastapi", "jinja2", "rich", "typer", "typer", "uvicorn", "uvicorn"] +cli = ["PyYAML", "fastapi", "jinja2", "pygments", "rich", "typer", "uvicorn"] [metadata] lock-version = "2.0" -python-versions = "^3.7" -content-hash = "28559da1c2153842f7eafd184e07038d840b4013900dfa0effc1575e8076cbd0" +python-versions = "^3.8" +content-hash = "590139cf7a34b997ceeb2990f87486fec6086f7b3df4232912692a294f4d0735" diff --git a/pyproject.toml b/pyproject.toml index 2a3a2268..b9233d4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,36 +1,53 @@ [tool.poetry] name = "rhoknp" -version = "1.5.1" +version = "1.6.0" description = "Yet another Python binding for Juman++/KNP/KWJA" license = "MIT" authors = [ "Hirokazu Kiyomaru ", "Nobuhiro Ueda ", ] +maintainers = [ + "Hirokazu Kiyomaru ", + "Nobuhiro Ueda ", +] readme = "README.md" +homepage = "https://github.com/ku-nlp/rhoknp" repository = "https://github.com/ku-nlp/rhoknp" documentation = "https://rhoknp.readthedocs.io/en/latest" -keywords = ["NLP"] +keywords = ["NLP", "Japanese", "Juman++", "KNP", "KWJA"] +classifiers = [ + "License :: OSI Approved :: MIT License", + "Natural Language :: Japanese", + "Operating System :: MacOS", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3", + "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", + "Topic :: Scientific/Engineering", + "Topic :: Software Development :: Libraries", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Text Processing", + "Topic :: Text Processing :: Linguistic", +] [tool.poetry.dependencies] -python = "^3.7" -cached-property = { version = "^1.5", python = "<3.8" } -importlib-metadata = { version = ">=5.2,<6.8", python = "<3.8" } -typer = [ - { version = ">=0.7,<0.9", python = "<3.8", optional = true }, - { version = ">=0.7", python = ">=3.8", optional = true }, -] +python = "^3.8" +typing-extensions = { version = ">=4.4", python = "<3.12" } +typer = { version = ">=0.7", optional = true } PyYAML = { version = "^6.0", optional = true } rich = { version = ">=12.6", optional = true } -uvicorn = [ - { version = ">=0.21.0,<0.23.0", python = "<3.8", optional = true }, - { version = ">=0.21.0", python = ">=3.8", optional = true }, -] -fastapi = { version = ">=0.92.0,<1", optional = true } +uvicorn = { version = ">=0.21.0", optional = true } +fastapi = { version = ">=0.92.0", optional = true } jinja2 = { version = "^3.1", optional = true } +pygments = { version = "^2.16", optional = true } [tool.poetry.group.dev.dependencies] -python = "^3.8" ipython = [ { version = "~8.12.1", python = "3.8" }, { version = "^8.13", python = ">=3.9" }, @@ -39,67 +56,55 @@ ipdb = "^0.13.13" [tool.poetry.group.test.dependencies] pytest = "^7.2" -coverage = [ - { version = "^6.5", python = "<3.8" }, - { version = "^7.3", python = ">=3.8" }, -] -pytest-cov = [ - { version = "^4.0", python = "<3.8" }, - { version = "^4.1", python = ">=3.8" }, -] -httpx = [ - { version = "^0.24.1", python = "<3.8" }, - { version = "^0.25.0", python = ">=3.8" }, -] +coverage = "^7.3" +pytest-cov = "^4.1" +httpx = "^0.25.0" [tool.poetry.group.docs.dependencies] -Sphinx = [ - { version = "^5.3", python = "<3.8" }, - { version = "^7.0", python = ">=3.8" }, -] +Sphinx = "^7.0" sphinx-prompt = [ - { version = "~1.5.0", python = "<3.8" }, { version = "^1.6", python = ">=3.8,<3.9" }, { version = "^1.8", python = ">=3.9" }, ] sphinx-copybutton = "^0.5.0" -myst-parser = [ - { version = "^1.0", python = "<3.8" }, - { version = "^2.0", python = ">=3.8" }, -] -markdown-it-py = [ - { version = "^2.2", python = "<3.8" }, - { version = "^3.0", python = ">=3.8" }, -] -furo = [ - { version = "^2023.3", python = "<3.8" }, - { version = "^2023.9", python = ">=3.8" }, -] +myst-parser = "^2.0" +markdown-it-py = "^3.0" +furo = "^2023.9" [tool.poetry.extras] -cli = ["typer", "PyYAML", "rich", "uvicorn", "fastapi", "jinja2"] +cli = ["typer", "PyYAML", "rich", "uvicorn", "fastapi", "jinja2", "pygments"] [tool.poetry.scripts] rhoknp = "rhoknp.cli.cli:app" [tool.black] line-length = 120 -target-version = ["py37", "py38", "py39", "py310", "py311", "py312"] +target-version = ["py38", "py39", "py310", "py311", "py312"] -[tool.isort] -line_length = 120 -py_version = 39 -profile = "black" +[tool.mypy] +python_version = 3.8 -[tool.flake8] -# E203 is not PEP8 compliant and black insert space around slice (https://black.readthedocs.io/en/stable/faq.html#why-are-flake8-s-e203-and-w503-violated) -# E501: Line too long. Disable it to allow long lines of comments and print lines which black allows. -# W503: line break before binary operator (https://www.flake8rules.com/rules/W503.html) -ignore = ["E203", "E501", "W503"] -max-line-length = 120 +[tool.ruff] +line-length = 120 +indent-width = 4 +src = ["src", "tests"] +target-version = "py38" +ignore = [ + "PLR0911", # Too many return statements + "PLR0912", # Too many branches + "PLR0913", # Too many arguments in function definition + "PLR0915", # Too many statements + "E501", # Line too long + "RUF001", # String contains ambiguous `ノ` (KATAKANA LETTER NO). Did you mean `/` (SOLIDUS)? + "RUF002", # Docstring contains ambiguous `,` (FULLWIDTH COMMA). Did you mean `,` (COMMA)? + "RUF003", # Comment contains ambiguous `(` (FULLWIDTH LEFT PARENTHESIS). Did you mean `(` (LEFT PARENTHESIS)? + "COM812", # Trailing comma missing + "PLR2004", # Magic value used in comparison +] +select = ["F", "E", "W", "I", "B", "PL", "PD", "NPY", "RUF", "UP", "TID", "COM", "PT"] -[tool.mypy] -python_version = 3.7 +[tool.ruff.flake8-bugbear] +extend-immutable-calls = ["typer.Argument", "typer.Option"] [build-system] requires = ["poetry-core"] diff --git a/src/rhoknp/__init__.py b/src/rhoknp/__init__.py index 5d8b5449..0da13048 100644 --- a/src/rhoknp/__init__.py +++ b/src/rhoknp/__init__.py @@ -1,7 +1,4 @@ -try: - from importlib.metadata import version -except ImportError: - from importlib_metadata import version +from importlib.metadata import version from rhoknp.processors import KNP, KWJA, Jumanpp, RegexSenter from rhoknp.units import BasePhrase, Clause, Document, Morpheme, Phrase, Sentence diff --git a/src/rhoknp/cli/__init__.py b/src/rhoknp/cli/__init__.py index e78fcf66..a1d10207 100644 --- a/src/rhoknp/cli/__init__.py +++ b/src/rhoknp/cli/__init__.py @@ -5,5 +5,5 @@ import rhoknp.cli.stats # noqa: F401 except ImportError as e: raise ImportError( - f"{e.msg}\nExtra dependencies are required to use the CLI. Install it with `pip install rhoknp[cli]`." - ) + f"{e.msg}\nExtra dependencies are required to use the CLI. Install them with `pip install rhoknp[cli]`." + ) from e diff --git a/src/rhoknp/cli/cat.py b/src/rhoknp/cli/cat.py new file mode 100644 index 00000000..25c2461f --- /dev/null +++ b/src/rhoknp/cli/cat.py @@ -0,0 +1,106 @@ +from typing import ClassVar, List + +from pygments import highlight +from pygments.formatters import TerminalFormatter +from pygments.lexer import RegexLexer, bygroups, default +from pygments.token import Comment, Generic, Literal, Name, Number, String, Text, Whitespace + +from rhoknp import BasePhrase, Document, Morpheme, Phrase + + +class KNPLexer(RegexLexer): + """KNP の出力を色付けするための Lexer.""" + + name: ClassVar[str] = "KNP" + url: ClassVar[str] = "https://github.com/ku-nlp/knp" + filenames: ClassVar[List[str]] = ["*.knp", "*.kwja"] + mimetypes: ClassVar[List[str]] = ["text/plain"] + + tokens = { # noqa: RUF012 + "root": [ + (r"\s+", Whitespace), + (rf"(?={Phrase.PAT.pattern})", Text, "phrase"), + (rf"(?={BasePhrase.PAT.pattern})", Text, "base_phrase"), + (rf"(?={Morpheme.PAT.pattern})", Text, "morpheme"), + (r"^#.*$", Comment.Single), + (r"^EOS$", Generic.Subheading), + ], + "phrase": [ + (r"\s+", Whitespace), + (r"^\*", Generic.Heading), + (r"(-?\d+)([DPAI])", bygroups(Number, Literal.String)), + (r"<", Name.Tag, "tag"), + default("#pop"), + ], + "base_phrase": [ + (r"\s+", Whitespace), + (r"^\+", Generic.Heading), + (r"(-?\d+)([DPAI])", bygroups(Number, Literal.String)), + (r":]+)(:)?([^>]+)?", bygroups(Name.Tag, Name.Tag, Name.Attribute)), + (r">", Name.Tag, "#pop"), + ], + "rel_tag": [ + (r"\s+", Whitespace), + (r'(\S+=)("\S+?")', bygroups(Name.Attribute, String)), + (r"/>", Name.Tag, "#pop"), + ], + } + + +def print_document(document: Document, is_dark: bool = False) -> None: + """KNP ファイルを色付きで表示. + + Args: + document (Document): 文書. + is_dark (bool, optional): ターミナルの背景色が dark なら True.デフォルトは False. + """ + if is_dark: + formatter = TerminalFormatter(bg="dark") + else: + formatter = TerminalFormatter(bg="light") + print(highlight(document.to_knp(), KNPLexer(), formatter), end="") diff --git a/src/rhoknp/cli/cli.py b/src/rhoknp/cli/cli.py index d2afc5f1..60581926 100644 --- a/src/rhoknp/cli/cli.py +++ b/src/rhoknp/cli/cli.py @@ -1,4 +1,5 @@ import json +import sys from pathlib import Path from typing import List, Optional @@ -6,6 +7,7 @@ import yaml from rhoknp import Document, __version__ +from rhoknp.cli.cat import print_document from rhoknp.cli.serve import AnalyzerType, serve_analyzer from rhoknp.cli.show import draw_tree from rhoknp.cli.stats import get_document_statistics @@ -32,6 +34,25 @@ def main( pass +@app.command(help="Print KNP files with syntax highlighting.") +def cat( + knp_path: Optional[Path] = typer.Argument(None, exists=True, dir_okay=False, help="Path to knp file to show."), + dark: bool = typer.Option(False, "--dark", "-d", help="Use dark background."), +) -> None: + """KNP ファイルを色付きで表示. + + Args: + knp_path: KNP ファイルのパス. + dark: True なら背景を黒にする. + """ + if knp_path is None: + knp_text = sys.stdin.read() + else: + knp_text = knp_path.read_text() + doc = Document.from_knp(knp_text) + print_document(doc, is_dark=dark) + + @app.command(help="Print given file content in tree format.") def show( knp_path: Path = typer.Argument(..., exists=True, dir_okay=False, help="Path to knp file to show"), diff --git a/src/rhoknp/cli/serve.py b/src/rhoknp/cli/serve.py index 445649bc..0c58d0ee 100644 --- a/src/rhoknp/cli/serve.py +++ b/src/rhoknp/cli/serve.py @@ -66,8 +66,7 @@ def _get_string_diff(pre_text: str, post_text) -> List[_Span]: if span.text: spans.append(span) span = _Span(character, tag) - else: - spans.append(span) + spans.append(span) return spans @@ -165,7 +164,7 @@ async def index(request: fastapi.Request, text: str = ""): try: analyzed_document = processor.apply(text) except Exception as e: - raise _HTTPExceptionForIndex(fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e)) + raise _HTTPExceptionForIndex(fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e)) from e return templates.TemplateResponse( template_name, {"request": request, "text": text, "analyzed_document": analyzed_document}, @@ -190,7 +189,7 @@ async def analyze(text: str): result = analyzed_document.to_knp() return {"text": text, "result": result} except Exception as e: - raise _HTTPExceptionForAnalyze(fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e)) + raise _HTTPExceptionForAnalyze(fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e)) from e return app diff --git a/src/rhoknp/cli/show.py b/src/rhoknp/cli/show.py index c2b67ec7..ecf6e16f 100644 --- a/src/rhoknp/cli/show.py +++ b/src/rhoknp/cli/show.py @@ -72,20 +72,19 @@ def draw_tree( elif j == parent_index: if dep_type in (DepType.PARALLEL, DepType.IMPERFECT_PARALLEL, DepType.APPOSITION): item[i][j] = str(dep_type.value) + elif active_column[j] == 2: + item[i][j] = "┨" + elif active_column[j] == 1: + item[i][j] = "┤" else: - if active_column[j] == 2: - item[i][j] = "┨" - elif active_column[j] == 1: - item[i][j] = "┤" - else: - item[i][j] = "┐" + item[i][j] = "┐" if active_column[j] == 2: pass elif para_row: active_column[j] = 2 else: active_column[j] = 1 - else: + else: # noqa: PLR5501 if active_column[j] == 2: item[i][j] = "┃" elif active_column[j] == 1: @@ -153,13 +152,13 @@ def _get_core_text(base_phrase: BasePhrase) -> str: """Get the core text without ancillary words.""" morphemes = base_phrase.morphemes start_index = 0 - for i, morpheme in enumerate(morphemes): + for morpheme in morphemes: if morpheme.pos in ("助詞", "特殊", "判定詞"): start_index += 1 else: break end_index = len(morphemes) - for i, morpheme in enumerate(reversed(morphemes)): + for morpheme in reversed(morphemes): if morpheme.pos in ("助詞", "特殊", "判定詞"): end_index -= 1 else: diff --git a/src/rhoknp/cohesion/argument.py b/src/rhoknp/cohesion/argument.py index c3deb9ad..619c2bf9 100644 --- a/src/rhoknp/cohesion/argument.py +++ b/src/rhoknp/cohesion/argument.py @@ -91,7 +91,7 @@ def __init__( self.base_phrase = base_phrase #: 項の核となる基本句. def __repr__(self) -> str: - return f"<{self.__module__}.{self.__class__.__name__}: {repr(self.case)}, {repr(self.base_phrase.text)}>" + return f"<{self.__module__}.{self.__class__.__name__}: {self.case!r}, {self.base_phrase.text!r}>" def __str__(self) -> str: return self.base_phrase.text @@ -164,8 +164,8 @@ def __init__(self, case: str, exophora_referent: ExophoraReferent, eid: int) -> def __repr__(self) -> str: return ( - f"{self.__class__.__name__}(case={repr(self.case)}, exophora_referent={repr(self.exophora_referent)}, " - f"eid={repr(self.eid)})" + f"{self.__class__.__name__}(case={self.case!r}, exophora_referent={self.exophora_referent!r}, " + f"eid={self.eid!r})" ) def __str__(self) -> str: diff --git a/src/rhoknp/cohesion/coreference.py b/src/rhoknp/cohesion/coreference.py index add8608d..2f8b0ad1 100644 --- a/src/rhoknp/cohesion/coreference.py +++ b/src/rhoknp/cohesion/coreference.py @@ -1,5 +1,5 @@ import logging -from typing import TYPE_CHECKING, Dict, List, Optional +from typing import TYPE_CHECKING, ClassVar, Dict, List, Optional from rhoknp.cohesion.argument import ExophoraArgument from rhoknp.cohesion.exophora import ExophoraReferent @@ -74,9 +74,9 @@ def __str__(self) -> str: if self.exophora_referent: return str(self.exophora_referent) if self.mentions: - return str(list(self.mentions)[0]) + return next(iter(self.mentions)).text elif self.mentions_nonidentical: - return str(list(self.mentions_nonidentical)[0]) + return next(iter(self.mentions_nonidentical)).text else: return "" @@ -95,7 +95,7 @@ def __hash__(self) -> int: class EntityManager: """文書全体のエンティティを管理.""" - entities: Dict[int, Entity] = {} #: ID をキーとするエンティティの辞書. + entities: ClassVar[Dict[int, Entity]] = {} #: ID をキーとするエンティティの辞書. @classmethod def get_or_create_entity( diff --git a/src/rhoknp/cohesion/exophora.py b/src/rhoknp/cohesion/exophora.py index d772a81f..33fb7664 100644 --- a/src/rhoknp/cohesion/exophora.py +++ b/src/rhoknp/cohesion/exophora.py @@ -62,7 +62,7 @@ def __str__(self) -> str: return self.text def __repr__(self) -> str: - return f"{self.__class__.__name__}(text={repr(self.text)})" + return f"{self.__class__.__name__}(text={self.text!r})" def __eq__(self, other: Any) -> bool: if not isinstance(other, type(self)) or self.type != other.type: diff --git a/src/rhoknp/cohesion/pas.py b/src/rhoknp/cohesion/pas.py index 2849144b..a2a52052 100644 --- a/src/rhoknp/cohesion/pas.py +++ b/src/rhoknp/cohesion/pas.py @@ -75,7 +75,9 @@ def parse_pas_string(self, base_phrase: "BasePhrase", pas_string: str, format_: # language=RegExp cfid_pat = r"(.*?):([^:/]+?)" # 食べる/たべる:動1 match = re.match( - r"{cfid}(:(?P{args}(;{args})*))?$".format(cfid=cfid_pat, args=self.ARGUMENT_PAT.pattern), + r"{cfid}(:(?P{args}(;{args})*))?$".format( # noqa: UP032 + cfid=cfid_pat, args=self.ARGUMENT_PAT.pattern + ), pas_string, ) @@ -232,7 +234,7 @@ def set_arguments_optional(self, case: str) -> None: logger.info(f"marked {arg} as optional in {self.sid}") def __repr__(self) -> str: - return f"<{self.__module__}.{self.__class__.__name__}: {repr(self.predicate.text)}>" + return f"<{self.__module__}.{self.__class__.__name__}: {self.predicate.text!r}>" def normalize_case(case: str) -> str: diff --git a/src/rhoknp/cohesion/predicate.py b/src/rhoknp/cohesion/predicate.py index f186ff41..8d4d90e1 100644 --- a/src/rhoknp/cohesion/predicate.py +++ b/src/rhoknp/cohesion/predicate.py @@ -79,7 +79,7 @@ def __str__(self) -> str: return self.text def __repr__(self) -> str: - return f"<{self.__module__}.{self.__class__.__name__}: {repr(self.text)}>" + return f"<{self.__module__}.{self.__class__.__name__}: {self.text!r}>" def __eq__(self, other: Any) -> bool: if not isinstance(other, type(self)) or self.base_phrase != other.base_phrase: diff --git a/src/rhoknp/cohesion/rel.py b/src/rhoknp/cohesion/rel.py index 6c4916a1..88389c24 100644 --- a/src/rhoknp/cohesion/rel.py +++ b/src/rhoknp/cohesion/rel.py @@ -110,7 +110,7 @@ def __post_init__(self): if self.type.startswith("="): if self.type not in COREF_TYPES: logger.warning(f"Unknown coreference type: {self.type} ({self})") - else: + else: # noqa: PLR5501 if self.type not in CASE_TYPES: logger.warning(f"Unknown case type: {self.type} ({self})") diff --git a/src/rhoknp/processors/jumanpp.py b/src/rhoknp/processors/jumanpp.py index 2d5b03bf..e63aee0c 100644 --- a/src/rhoknp/processors/jumanpp.py +++ b/src/rhoknp/processors/jumanpp.py @@ -7,6 +7,11 @@ from threading import Lock from typing import List, Optional, Union +try: + from typing import override # type: ignore +except ImportError: + from typing_extensions import override + from rhoknp.processors.processor import Processor from rhoknp.processors.senter import RegexSenter from rhoknp.units import Document, Sentence @@ -48,16 +53,16 @@ def __init__( self.start_process(skip_sanity_check) def __repr__(self) -> str: - arg_string = f"executable={repr(self.executable)}" + arg_string = f"executable={self.executable!r}" if self.options: - arg_string += f", options={repr(self.options)}" + arg_string += f", options={self.options!r}" if self.senter is not None: - arg_string += f", senter={repr(self.senter)}" + arg_string += f", senter={self.senter!r}" return f"{self.__class__.__name__}({arg_string})" def __del__(self) -> None: if self._proc is not None: - self._proc.kill() + self._proc.terminate() def start_process(self, skip_sanity_check: bool = False) -> None: """Juman++ を開始する. @@ -67,7 +72,7 @@ def start_process(self, skip_sanity_check: bool = False) -> None: skip_sanity_check: True なら,Juman++ の起動時に sanity check をスキップする. """ if self._proc is not None: - self._proc.kill() + self._proc.terminate() try: self._proc = Popen(self.run_command, stdin=PIPE, stdout=PIPE, stderr=PIPE, encoding="utf-8") if skip_sanity_check is False: @@ -79,6 +84,7 @@ def is_available(self) -> bool: """Jumanpp が利用可能であれば True を返す.""" return self._proc is not None and self._proc.poll() is None + @override def apply_to_document(self, document: Union[Document, str], timeout: int = 10) -> Document: """文書に Jumanpp を適用する. @@ -97,6 +103,7 @@ def apply_to_document(self, document: Union[Document, str], timeout: int = 10) - if isinstance(document, str): document = Document(document) + doc_id = document.doc_id if document.is_senter_required(): if self.senter is None: @@ -107,8 +114,14 @@ def apply_to_document(self, document: Union[Document, str], timeout: int = 10) - sentences: List[Sentence] = [] for sentence in document.sentences: sentences.append(self.apply_to_sentence(sentence, timeout=timeout - int(time.time() - start))) - return Document.from_sentences(sentences) + ret = Document.from_sentences(sentences) + if doc_id != "": + ret.doc_id = doc_id + for sentence in ret.sentences: + sentence.doc_id = doc_id + return ret + @override def apply_to_sentence(self, sentence: Union[Sentence, str], timeout: int = 10) -> Sentence: """文に Jumanpp を適用する. @@ -177,13 +190,13 @@ def get_version(self) -> str: """Juman++ のバージョンを返す.""" if not self.is_available(): raise RuntimeError("Juman++ is not available.") - p = subprocess.run(self.version_command, capture_output=True, encoding="utf-8") + p = subprocess.run(self.version_command, capture_output=True, encoding="utf-8", check=True) return p.stdout.strip() @property def run_command(self) -> List[str]: """解析時に実行するコマンド.""" - return [self.executable] + self.options + return [self.executable, *self.options] @property def version_command(self) -> List[str]: diff --git a/src/rhoknp/processors/knp.py b/src/rhoknp/processors/knp.py index c45c595c..644b1577 100644 --- a/src/rhoknp/processors/knp.py +++ b/src/rhoknp/processors/knp.py @@ -7,6 +7,11 @@ from threading import Lock from typing import List, Optional, Union +try: + from typing import override # type: ignore +except ImportError: + from typing_extensions import override + from rhoknp.processors.jumanpp import Jumanpp from rhoknp.processors.processor import Processor from rhoknp.processors.senter import RegexSenter @@ -55,18 +60,18 @@ def __init__( self.start_process(skip_sanity_check) def __repr__(self) -> str: - arg_string = f"executable={repr(self.executable)}" + arg_string = f"executable={self.executable!r}" if self.options: - arg_string += f", options={repr(self.options)}" + arg_string += f", options={self.options!r}" if self.senter is not None: - arg_string += f", senter={repr(self.senter)}" + arg_string += f", senter={self.senter!r}" if self.jumanpp is not None: - arg_string += f", jumanpp={repr(self.jumanpp)}" + arg_string += f", jumanpp={self.jumanpp!r}" return f"{self.__class__.__name__}({arg_string})" def __del__(self) -> None: if self._proc is not None: - self._proc.kill() + self._proc.terminate() def start_process(self, skip_sanity_check: bool = False) -> None: """KNP を起動する. @@ -76,11 +81,11 @@ def start_process(self, skip_sanity_check: bool = False) -> None: skip_sanity_check: True なら,KNP の起動時に sanity check をスキップする. """ if self._proc is not None: - self._proc.kill() + self._proc.terminate() try: self._proc = Popen(self.run_command, stdin=PIPE, stdout=PIPE, stderr=PIPE, encoding="utf-8") if skip_sanity_check is False: - _ = self.apply(Sentence.from_jumanpp("")) + _ = self.apply(Sentence.from_jumanpp("EOS")) except Exception as e: logger.warning(f"failed to start KNP: {e}") @@ -88,6 +93,7 @@ def is_available(self) -> bool: """KNP が利用可能であれば True を返す.""" return self._proc is not None and self._proc.poll() is None + @override def apply_to_document(self, document: Union[Document, str], timeout: int = 10) -> Document: """文書に KNP を適用する. @@ -108,6 +114,7 @@ def apply_to_document(self, document: Union[Document, str], timeout: int = 10) - if isinstance(document, str): document = Document(document) + doc_id = document.doc_id if document.is_senter_required(): if self.senter is None: @@ -118,8 +125,14 @@ def apply_to_document(self, document: Union[Document, str], timeout: int = 10) - sentences: List[Sentence] = [] for sentence in document.sentences: sentences.append(self.apply_to_sentence(sentence, timeout=timeout - int(time.time() - start))) - return Document.from_sentences(sentences) + ret = Document.from_sentences(sentences) + if doc_id != "": + ret.doc_id = doc_id + for sentence in ret.sentences: + sentence.doc_id = doc_id + return ret + @override def apply_to_sentence(self, sentence: Union[Sentence, str], timeout: int = 10) -> Sentence: """文に KNP を適用する. @@ -203,13 +216,13 @@ def get_version(self) -> str: """Juman++ のバージョンを返す.""" if not self.is_available(): raise RuntimeError("KNP is not available.") - p = subprocess.run(self.version_command, capture_output=True, encoding="utf-8") + p = subprocess.run(self.version_command, capture_output=True, encoding="utf-8", check=True) return p.stderr.strip() @property def run_command(self) -> List[str]: """解析時に実行するコマンド.""" - return [self.executable] + self.options + return [self.executable, *self.options] @property def version_command(self) -> List[str]: diff --git a/src/rhoknp/processors/kwja.py b/src/rhoknp/processors/kwja.py index 6a94599c..4185b021 100644 --- a/src/rhoknp/processors/kwja.py +++ b/src/rhoknp/processors/kwja.py @@ -6,6 +6,11 @@ from threading import Lock from typing import List, Optional, Union +try: + from typing import override # type: ignore +except ImportError: + from typing_extensions import override + from rhoknp.processors.processor import Processor from rhoknp.units import Document, Morpheme, Sentence from rhoknp.utils.comment import is_comment_line @@ -41,6 +46,7 @@ def __init__( self._proc: Optional[Popen] = None self._lock = Lock() self._output_format: str = "knp" + self._input_format: str = "raw" if "--tasks" in self.options: tasks: List[str] = self.options[self.options.index("--tasks") + 1].split(",") if "word" in tasks: @@ -49,23 +55,27 @@ def __init__( self._output_format = "jumanpp" elif "char" in tasks: self._output_format = "words" - elif "senter" in tasks: - self._output_format = "line_by_line" elif "typo" in tasks: self._output_format = "raw" else: raise ValueError(f"invalid task: {tasks}") + # `--input-format` option is available since KWJA v2.2.0 + if "--input-format" in self.options: + input_format: str = self.options[self.options.index("--input-format") + 1] + if input_format not in ("raw", "jumanpp", "knp"): + raise ValueError(f"invalid input format: {input_format}") + self._input_format = input_format self.start_process(skip_sanity_check) def __repr__(self) -> str: - arg_string = f"executable={repr(self.executable)}" + arg_string = f"executable={self.executable!r}" if self.options: - arg_string += f", options={repr(self.options)}" + arg_string += f", options={self.options!r}" return f"{self.__class__.__name__}({arg_string})" def __del__(self) -> None: if self._proc is not None: - self._proc.kill() + self._proc.terminate() def start_process(self, skip_sanity_check: bool = False) -> None: """KWJA を起動する. @@ -75,12 +85,18 @@ def start_process(self, skip_sanity_check: bool = False) -> None: skip_sanity_check: True なら,KWJA の起動時に sanity check をスキップする. """ if self._proc is not None: - self._proc.kill() + self._proc.terminate() try: self._proc = Popen(self.run_command, stdin=PIPE, stdout=PIPE, stderr=PIPE, encoding="utf-8") if skip_sanity_check is False: - # TODO: replace "こんにちは" with an empty string after KWJA v2.2.0 is released - _ = self.apply(Document.from_raw_text("こんにちは")) + if self._input_format == "raw": + empty_document = Document.from_raw_text("") + elif self._input_format == "jumanpp": + empty_document = Document.from_jumanpp("EOS\n") + else: + assert self._input_format == "knp" + empty_document = Document.from_knp("EOS\n") + _ = self.apply(empty_document) except Exception as e: logger.warning(f"failed to start KWJA: {e}") @@ -88,6 +104,7 @@ def is_available(self) -> bool: """KWJA が利用可能であれば True を返す.""" return self._proc is not None and self._proc.poll() is None + @override def apply_to_document(self, document: Union[Document, str], timeout: int = 30) -> Document: """文書に KWJA を適用する. @@ -111,8 +128,7 @@ def worker() -> None: assert self._proc.stdout is not None assert self._proc.stderr is not None - self._proc.stdin.write(document.text.rstrip("\n") + "\n") # TODO: Keep the sentence IDs - self._proc.stdin.write(Document.EOD + "\n") + self._proc.stdin.write(self._gen_input_text(document)) self._proc.stdin.flush() stdout_text = "" @@ -149,6 +165,7 @@ def worker() -> None: return self._create_document(stdout_text) + @override def apply_to_sentence(self, sentence: Union[Sentence, str], timeout: int = 10) -> Sentence: """文に KWJA を適用する. @@ -158,11 +175,20 @@ def apply_to_sentence(self, sentence: Union[Sentence, str], timeout: int = 10) - """ raise NotImplementedError("KWJA does not support apply_to_sentence() currently.") + def _gen_input_text(self, document: Document) -> str: + if self._input_format == "raw": + input_text = document.text.rstrip("\n") + "\n" + elif self._input_format == "jumanpp": + input_text = document.to_jumanpp() + elif self._input_format == "knp": + input_text = document.to_knp() + else: + raise AssertionError(f"invalid input format: {self._input_format}") + return input_text + Document.EOD + "\n" + def _create_document(self, text: str) -> Document: if self._output_format == "raw": return Document.from_raw_text(text) - elif self._output_format == "line_by_line": - return Document.from_line_by_line_text(text) elif self._output_format == "jumanpp": return Document.from_jumanpp(text) elif self._output_format == "words": @@ -218,13 +244,13 @@ def get_version(self) -> str: """Juman++ のバージョンを返す.""" if not self.is_available(): raise RuntimeError("KWJA is not available.") - p = subprocess.run(self.version_command, capture_output=True, encoding="utf-8") + p = subprocess.run(self.version_command, capture_output=True, encoding="utf-8", check=True) return p.stdout.strip() @property def run_command(self) -> List[str]: """解析時に実行するコマンド.""" - return [self.executable] + self.options + return [self.executable, *self.options] @property def version_command(self) -> List[str]: diff --git a/src/rhoknp/processors/processor.py b/src/rhoknp/processors/processor.py index e91504dc..b1bcc859 100644 --- a/src/rhoknp/processors/processor.py +++ b/src/rhoknp/processors/processor.py @@ -65,7 +65,7 @@ def apply(self, text: Union[str, Sentence, Document], timeout: int = 10) -> Unio 引数の型が ``Sentence`` の場合は ``apply_to_sentence`` を呼び出す. 引数の型が ``Document`` の場合は ``apply_to_document`` を呼び出す. """ - if isinstance(text, str) or isinstance(text, Document): + if isinstance(text, (Document, str)): return self.apply_to_document(text, timeout=timeout) elif isinstance(text, Sentence): return self.apply_to_sentence(text, timeout=timeout) diff --git a/src/rhoknp/processors/senter.py b/src/rhoknp/processors/senter.py index 8b73e5b9..06fd1822 100644 --- a/src/rhoknp/processors/senter.py +++ b/src/rhoknp/processors/senter.py @@ -3,6 +3,11 @@ import threading from typing import ClassVar, List, Union +try: + from typing import override # type: ignore +except ImportError: + from typing_extensions import override + from rhoknp.processors.processor import Processor from rhoknp.units import Document, Sentence @@ -23,6 +28,7 @@ class RegexSenter(Processor): def __repr__(self) -> str: return f"{self.__class__.__name__}()" + @override def apply_to_document(self, document: Union[Document, str], timeout: int = 10) -> Document: """文書に RegexSenter を適用する. @@ -32,6 +38,7 @@ def apply_to_document(self, document: Union[Document, str], timeout: int = 10) - """ if isinstance(document, str): document = Document(document) + doc_id = document.doc_id sentences: List[str] = [] done_event: threading.Event = threading.Event() @@ -48,8 +55,14 @@ def worker() -> None: if thread.is_alive(): raise TimeoutError("Operation timed out.") - return Document.from_sentences(sentences) + ret = Document.from_sentences(sentences) + if doc_id != "": + ret.doc_id = doc_id + for sentence in ret.sentences: + sentence.doc_id = doc_id + return ret + @override def apply_to_sentence(self, sentence: Union[Sentence, str], timeout: int = 10) -> Sentence: """文に RegexSenter を適用する. diff --git a/src/rhoknp/props/feature.py b/src/rhoknp/props/feature.py index 7fb51dfe..b52cad23 100644 --- a/src/rhoknp/props/feature.py +++ b/src/rhoknp/props/feature.py @@ -1,6 +1,6 @@ import logging import re -from typing import Dict, Union +from typing import ClassVar, Dict, Set, Union logger = logging.getLogger(__name__) @@ -8,9 +8,9 @@ class FeatureDict(Dict[str, Union[str, bool]]): """文節,基本句,形態素の素性情報を表すクラス.""" - IGNORE_TAG_PREFIXES = {"rel ", "memo "} - PAT = re.compile(r'(?P(<([^>"\\]|"[^"]*?"|\\>?)+>)*)') - FEATURE_PAT = re.compile( + IGNORE_TAG_PREFIXES: ClassVar[Set[str]] = {"rel ", "memo "} + PAT: ClassVar[re.Pattern] = re.compile(r'(?P(<([^>"\\]|"[^"]*?"|\\>?)+>)*)') + FEATURE_PAT: ClassVar[re.Pattern] = re.compile( rf"<(?!({'|'.join(IGNORE_TAG_PREFIXES)}))(?P([^:\"]|\".*?\")+?)(:(?P([^>\\]|\\>?)+))?>" ) diff --git a/src/rhoknp/units/base_phrase.py b/src/rhoknp/units/base_phrase.py index b0acd57f..bc8890a0 100644 --- a/src/rhoknp/units/base_phrase.py +++ b/src/rhoknp/units/base_phrase.py @@ -2,12 +2,13 @@ import itertools import logging import re +from functools import cached_property from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set try: - from functools import cached_property # type: ignore + from typing import override # type: ignore except ImportError: - from cached_property import cached_property + from typing_extensions import override from rhoknp.cohesion.argument import Argument, EndophoraArgument, ExophoraArgument from rhoknp.cohesion.coreference import Entity, EntityManager @@ -84,6 +85,7 @@ def __setstate__(self, state) -> None: entity.eid = eid self.__dict__.update(state) # Entity objects are hashed by eid. + @override def __post_init__(self) -> None: super().__post_init__() @@ -98,7 +100,8 @@ def __post_init__(self) -> None: self.pas.parse_pas_string(self, pas_string, format_=CaseInfoFormat.CASE) # Parse the rel tags. - for rel_tag in self.rel_tags: + for rel_tag_orig in self.rel_tags: + rel_tag = rel_tag_orig if rel_tag.sid == "": # The target is considered to be in the same sentence. rel_tag = dataclasses.replace(rel_tag, sid=self.sentence.sid) @@ -110,6 +113,7 @@ def __post_init__(self) -> None: logger.warning(f"{self.sentence.sid}: unknown rel type found: {rel_tag}") self._add_argument(rel_tag) + @override def __eq__(self, other: Any) -> bool: if not isinstance(other, type(self)): return False diff --git a/src/rhoknp/units/clause.py b/src/rhoknp/units/clause.py index 1b28eb6f..02909e1e 100644 --- a/src/rhoknp/units/clause.py +++ b/src/rhoknp/units/clause.py @@ -1,10 +1,11 @@ import logging +from functools import cached_property +from typing import TYPE_CHECKING, Any, List, Optional try: - from functools import cached_property # type: ignore + from typing import override # type: ignore except ImportError: - from cached_property import cached_property -from typing import TYPE_CHECKING, Any, List, Optional + from typing_extensions import override from rhoknp.cohesion.discourse import DiscourseRelation from rhoknp.units.base_phrase import BasePhrase @@ -38,6 +39,7 @@ def __init__(self) -> None: self.index = self.count #: 文内におけるインデックス. Clause.count += 1 + @override def __post_init__(self) -> None: super().__post_init__() @@ -68,6 +70,7 @@ def __post_init__(self) -> None: if relation not in relation.modifier.discourse_relations: relation.modifier.discourse_relations.append(relation) + @override def __eq__(self, other: Any) -> bool: if not isinstance(other, type(self)): return False @@ -210,9 +213,8 @@ def from_knp(cls, knp_text: str) -> "Clause": phrases.append(Phrase.from_knp("\n".join(phrase_lines))) phrase_lines = [] phrase_lines.append(line) - else: - phrase = Phrase.from_knp("\n".join(phrase_lines)) - phrases.append(phrase) + phrase = Phrase.from_knp("\n".join(phrase_lines)) + phrases.append(phrase) clause.phrases = phrases return clause diff --git a/src/rhoknp/units/document.py b/src/rhoknp/units/document.py index 6725a416..b11724c5 100644 --- a/src/rhoknp/units/document.py +++ b/src/rhoknp/units/document.py @@ -1,6 +1,11 @@ import logging from typing import Any, List, Optional, Sequence, Union +try: + from typing import override # type: ignore +except ImportError: + from typing_extensions import override + from rhoknp.cohesion.pas import Pas from rhoknp.props.named_entity import NamedEntity from rhoknp.units.base_phrase import BasePhrase @@ -41,6 +46,7 @@ def __init__(self, text: Optional[str] = None) -> None: self.doc_id: str = "" #: 文書 ID. + @override def __post_init__(self) -> None: super().__post_init__() @@ -53,6 +59,7 @@ def __post_init__(self) -> None: f"'doc_id' is not consistent; use 'doc_id' extracted from the first sentence: {self.doc_id}." ) + @override def __eq__(self, other: Any) -> bool: if not isinstance(other, Document): return False diff --git a/src/rhoknp/units/morpheme.py b/src/rhoknp/units/morpheme.py index 199181b3..9754026d 100644 --- a/src/rhoknp/units/morpheme.py +++ b/src/rhoknp/units/morpheme.py @@ -1,10 +1,11 @@ import re +from functools import cached_property +from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Tuple, Union try: - from functools import cached_property # type: ignore + from typing import override # type: ignore except ImportError: - from cached_property import cached_property -from typing import TYPE_CHECKING, Any, ClassVar, List, Optional, Tuple, Union + from typing_extensions import override from rhoknp.props.feature import FeatureDict from rhoknp.props.semantics import SemanticsDict @@ -22,7 +23,7 @@ class Morpheme(Unit): """形態素クラス.""" _ATTRIBUTES = ( - "_surf", + "surf", "reading", "lemma", "pos", @@ -35,10 +36,10 @@ class Morpheme(Unit): "conjform_id", ) - _ATTRIBUTE_PAT = re.compile( + _ATTRIBUTE_PAT: ClassVar[re.Pattern] = re.compile( r"([^ ]+| [^ ]*) ([^ ]+| [^ ]*) ([^ ]+) (\d+) ([^ ]+) (\d+) ([^ ]+) (\d+) ([^ ]+) (\d+)" ) - _ATTRIBUTE_PAT_REPEATED = re.compile( + _ATTRIBUTE_PAT_REPEATED: ClassVar[re.Pattern] = re.compile( r"(?P.+) ((?P=pat)) ([^ ]+) (\d+) ([^ ]+) (\d+) ([^ ]+) (\d+) ([^ ]+) (\d+)" ) @@ -54,9 +55,14 @@ class Morpheme(Unit): + rf"( {SemanticsDict.PAT.pattern})?" + rf"( {FeatureDict.PAT.pattern})?$" ) - - _ESCAPE_MAP = {" ": " ", '"': "”"} - _UNESCAPE_MAP = {v: k for k, v in _ESCAPE_MAP.items()} + # https://github.com/ku-nlp/jumanpp/blob/v2.0.0-rc3/src/jumandic/shared/juman_format.cc#L44 + _ESCAPE_MAP_HALF_TO_FULL_WIDTH: ClassVar[Dict[str, str]] = {" ": " ", '"': "”", "<": "<", ">": ">"} + _UNESCAPE_MAP_HALF_TO_FULL_WIDTH: ClassVar[Dict[str, str]] = { + v: k for k, v in _ESCAPE_MAP_HALF_TO_FULL_WIDTH.items() + } + # https://github.com/ku-nlp/jumanpp/blob/v2.0.0-rc4/src/jumandic/shared/juman_format.cc#L44 + _ESCAPE_MAP_CONTROL_CHAR: ClassVar[Dict[str, str]] = {"\t": r"\t", " ": r"\␣"} + _UNESCAPE_MAP_CONTROL_CHAR: ClassVar[Dict[str, str]] = {v: k for k, v in _ESCAPE_MAP_CONTROL_CHAR.items()} count = 0 @@ -79,7 +85,6 @@ def __init__( ) -> None: super().__init__() self.text = text - self._text_escaped = text self.reading = reading #: 読み. self.lemma = lemma #: 原形. self.pos = pos #: 品詞. @@ -103,10 +108,7 @@ def __init__( if homograph is False: Morpheme.count += 1 - # Resume text if it is escaped - if self.semantics.get("元半角") is True: - self.text = self._UNESCAPE_MAP.get(self.text, self.text) - + @override def __eq__(self, other: Any) -> bool: if not isinstance(other, type(self)): return False @@ -210,11 +212,6 @@ def surf(self) -> str: """表層表現.""" return self.text - @property - def _surf(self) -> str: - """表層表現(Juman/KNP フォーマット出力用).""" - return self._text_escaped - @property def canon(self) -> Optional[str]: """代表表記.""" @@ -297,14 +294,23 @@ def _from_jumanpp_line(cls, jumanpp_line: str, homograph: bool = False) -> "Morp match = cls.PAT.match(jumanpp_line) or cls.PAT_REPEATED.match(jumanpp_line) if match is None: raise ValueError(f"malformed morpheme line: {jumanpp_line}") - surf = match["surf"] match_attr = cls._ATTRIBUTE_PAT.match(match["attrs"]) or cls._ATTRIBUTE_PAT_REPEATED.match(match["attrs"]) assert match_attr is not None attributes = match_attr.groups() + surf, reading, lemma = match["surf"], attributes[0], attributes[1] + semantics = SemanticsDict.from_sstring(match["sems"] or "") + + # Resume text if it is escaped (Juman++ 2.0.0-rc3) + if semantics.get("元半角") is True: + surf, reading, lemma = ( # pragma: no cover + cls._UNESCAPE_MAP_HALF_TO_FULL_WIDTH.get(s, s) for s in (surf, reading, lemma) + ) + surf, reading, lemma = (cls._UNESCAPE_MAP_CONTROL_CHAR.get(s, s) for s in (surf, reading, lemma)) + return cls( surf, - attributes[0], - attributes[1], + reading, + lemma, attributes[2], int(attributes[3]), attributes[4], @@ -313,16 +319,14 @@ def _from_jumanpp_line(cls, jumanpp_line: str, homograph: bool = False) -> "Morp int(attributes[7]), attributes[8], int(attributes[9]), - semantics=SemanticsDict.from_sstring(match["sems"] or ""), + semantics=semantics, features=FeatureDict.from_fstring(match["feats"] or ""), homograph=homograph, ) def to_jumanpp(self) -> str: """Juman++ フォーマットに変換.""" - ret = " ".join(str(getattr(self, attr)) for attr in self._ATTRIBUTES) - if self.semantics or self.semantics.is_nil(): - ret += f" {self.semantics.to_sstring()}" + ret = self._to_jumanpp_line() if self.features: ret += f" {self.features.to_fstring()}" ret += "\n" @@ -332,9 +336,7 @@ def to_jumanpp(self) -> str: def to_knp(self) -> str: """KNP フォーマットに変換.""" - ret = " ".join(str(getattr(self, attr)) for attr in self._ATTRIBUTES) - if self.semantics or self.semantics.is_nil(): - ret += f" {self.semantics.to_sstring()}" + ret = self._to_jumanpp_line() features = FeatureDict(self.features) # deep copy for homograph in self.homographs: alt_feature_key = "ALT-{}-{}-{}-{}-{}-{}-{}-{}".format( @@ -353,6 +355,19 @@ def to_knp(self) -> str: ret += "\n" return ret + def _to_jumanpp_line(self) -> str: + """Juman++ フォーマットに変換.""" + attrs: List[str] = [] + for attr_name in self._ATTRIBUTES: + attr = getattr(self, attr_name) + if attr_name in ("surf", "reading", "lemma"): + attr = self._ESCAPE_MAP_CONTROL_CHAR.get(attr, attr) + attrs.append(str(attr)) + ret = " ".join(attrs) + if self.semantics or self.semantics.is_nil(): + ret += f" {self.semantics.to_sstring()}" + return ret + @staticmethod def is_morpheme_line(line: str) -> bool: """形態素行なら True を返す.""" diff --git a/src/rhoknp/units/phrase.py b/src/rhoknp/units/phrase.py index 42c0dfdd..a03e8fa2 100644 --- a/src/rhoknp/units/phrase.py +++ b/src/rhoknp/units/phrase.py @@ -1,10 +1,11 @@ import re +from functools import cached_property +from typing import TYPE_CHECKING, Any, List, Optional, Union try: - from functools import cached_property # type: ignore + from typing import override # type: ignore except ImportError: - from cached_property import cached_property -from typing import TYPE_CHECKING, Any, List, Optional, Union + from typing_extensions import override from rhoknp.props.dependency import DepType from rhoknp.props.feature import FeatureDict @@ -46,6 +47,7 @@ def __init__( self.index = self.count #: 文内におけるインデックス. Phrase.count += 1 + @override def __eq__(self, other: Any) -> bool: if not isinstance(other, type(self)): return False @@ -194,8 +196,7 @@ def from_knp(cls, knp_text: str) -> "Phrase": base_phrases.append(BasePhrase.from_knp("\n".join(base_phrase_lines))) base_phrase_lines = [] base_phrase_lines.append(line) - else: - base_phrases.append(BasePhrase.from_knp("\n".join(base_phrase_lines))) + base_phrases.append(BasePhrase.from_knp("\n".join(base_phrase_lines))) phrase.base_phrases = base_phrases return phrase diff --git a/src/rhoknp/units/sentence.py b/src/rhoknp/units/sentence.py index b4d56504..0bb5adff 100644 --- a/src/rhoknp/units/sentence.py +++ b/src/rhoknp/units/sentence.py @@ -2,6 +2,11 @@ import re from typing import TYPE_CHECKING, Any, List, Optional, Union +try: + from typing import override # type: ignore +except ImportError: + from typing_extensions import override + from rhoknp.cohesion import EntityManager, Pas from rhoknp.props.named_entity import NamedEntity from rhoknp.units.base_phrase import BasePhrase @@ -58,6 +63,7 @@ def __init__(self, text: Optional[str] = None): self.index = self.count #: 文書全体におけるインデックス. Sentence.count += 1 + @override def __post_init__(self) -> None: super().__post_init__() @@ -75,6 +81,7 @@ def __post_init__(self) -> None: if named_entity is not None: self.named_entities.append(named_entity) + @override def __eq__(self, other: Any) -> bool: if not isinstance(other, type(self)): return False diff --git a/src/rhoknp/units/unit.py b/src/rhoknp/units/unit.py index e524b880..28689097 100644 --- a/src/rhoknp/units/unit.py +++ b/src/rhoknp/units/unit.py @@ -21,7 +21,7 @@ def __str__(self) -> str: return self.text def __repr__(self) -> str: - return f"<{self.__module__}.{self.__class__.__name__}: {repr(self.text)}>" + return f"<{self.__module__}.{self.__class__.__name__}: {self.text!r}>" @property @abstractmethod diff --git a/tests/cli/test_cat.py b/tests/cli/test_cat.py new file mode 100644 index 00000000..786c0b54 --- /dev/null +++ b/tests/cli/test_cat.py @@ -0,0 +1,39 @@ +import textwrap + +from rhoknp.cli.cat import print_document +from rhoknp.units import Document + +knp = textwrap.dedent( + """\ + # S-ID:1 + * 1D + + 1D + 望遠 ぼうえん 望遠 名詞 6 普通名詞 1 * 0 * 0 "代表表記:望遠/ぼうえん カテゴリ:抽象物" + + 2D + 鏡 きょう 鏡 名詞 6 普通名詞 1 * 0 * 0 "代表表記:鏡/きょう カテゴリ:人工物-その他 漢字読み:音" + で で で 助詞 9 格助詞 1 * 0 * 0 NIL + * 2D + + 3D + 泳いで およいで 泳ぐ 動詞 2 * 0 子音動詞ガ行 4 タ系連用テ形 14 "代表表記:泳ぐ/およぐ" + いる いる いる 接尾辞 14 動詞性接尾辞 7 母音動詞 1 基本形 2 "代表表記:いる/いる" + * 3D + + 4D + 少女 しょうじょ 少女 名詞 6 普通名詞 1 * 0 * 0 "代表表記:少女/しょうじょ カテゴリ:人" + を を を 助詞 9 格助詞 1 * 0 * 0 NIL + * -1D + + -1D <節-区切><節-主辞> + 見た みた 見る 動詞 2 * 0 母音動詞 1 タ形 10 "代表表記:見る/みる 自他動詞:自:見える/みえる 補文ト" + 。 。 。 特殊 1 句点 1 * 0 * 0 NIL + EOS + """ +) + + +def test_print_document() -> None: + document = Document.from_knp(knp) + print_document(document) + + +def test_print_document_dark() -> None: + document = Document.from_knp(knp) + print_document(document, is_dark=True) diff --git a/tests/cli/test_cli.py b/tests/cli/test_cli.py index a667f666..d134a145 100644 --- a/tests/cli/test_cli.py +++ b/tests/cli/test_cli.py @@ -1,6 +1,7 @@ import tempfile import textwrap +import pytest from typer.testing import CliRunner from rhoknp import Document, __version__ @@ -9,7 +10,7 @@ runner = CliRunner() -knp = textwrap.dedent( +knp_text = textwrap.dedent( """\ # S-ID:1 * 1D @@ -41,8 +42,28 @@ def test_version() -> None: assert result.stdout.strip() == f"rhoknp version: {__version__}" +def test_cat() -> None: + doc = Document.from_knp(knp_text) + with tempfile.NamedTemporaryFile("wt") as f: + f.write(doc.to_knp()) + f.flush() + result = runner.invoke(app, ["cat", f.name]) + assert result.exit_code == 0 + + +@pytest.fixture() +def _mock_stdin(monkeypatch: pytest.MonkeyPatch): + monkeypatch.setattr("sys.stdin", knp_text) + + +@pytest.mark.usefixtures("_mock_stdin") +def test_cat_stdin() -> None: + result = runner.invoke(app, ["cat"]) + assert result.exit_code == 0 + + def test_show() -> None: - doc = Document.from_knp(knp) + doc = Document.from_knp(knp_text) with tempfile.NamedTemporaryFile("wt") as f: f.write(doc.to_knp()) f.flush() @@ -56,7 +77,7 @@ def test_show_error() -> None: def test_stats() -> None: - doc = Document.from_knp(knp) + doc = Document.from_knp(knp_text) with tempfile.NamedTemporaryFile("wt") as f: f.write(doc.to_knp()) f.flush() @@ -65,7 +86,7 @@ def test_stats() -> None: def test_stats_json() -> None: - doc = Document.from_knp(knp) + doc = Document.from_knp(knp_text) with tempfile.NamedTemporaryFile("wt") as f: f.write(doc.to_knp()) result = runner.invoke(app, ["stats", f.name, "--json"]) diff --git a/tests/cli/test_serve.py b/tests/cli/test_serve.py index 41fde3c5..8cd67b2b 100644 --- a/tests/cli/test_serve.py +++ b/tests/cli/test_serve.py @@ -1,5 +1,5 @@ import textwrap -from typing import Generator, List +from typing import List import pytest from fastapi.testclient import TestClient @@ -13,10 +13,10 @@ @pytest.mark.skipif(not is_jumanpp_available, reason="Juman++ is not available") -@pytest.fixture -def jumanpp_client() -> Generator[TestClient, None, None]: +@pytest.fixture() +def jumanpp_client() -> TestClient: app = create_app(AnalyzerType.JUMANPP) - yield TestClient(app) + return TestClient(app) @pytest.mark.skipif(not is_jumanpp_available, reason="Juman++ is not available") @@ -50,10 +50,10 @@ def test_index_jumanpp(jumanpp_client: TestClient, text: str) -> None: @pytest.mark.skipif(not is_knp_available, reason="KNP is not available") -@pytest.fixture -def knp_client() -> Generator[TestClient, None, None]: +@pytest.fixture() +def knp_client() -> TestClient: app = create_app(AnalyzerType.KNP) - yield TestClient(app) + return TestClient(app) @pytest.mark.skipif(not is_knp_available, reason="KNP is not available") @@ -104,10 +104,10 @@ def test_index_knp_error(knp_client: TestClient) -> None: @pytest.mark.skipif(not is_kwja_available, reason="KWJA is not available") -@pytest.fixture -def kwja_client() -> Generator[TestClient, None, None]: - app = create_app(AnalyzerType.KWJA, options=["--model-size", "tiny", "--tasks", "senter,char,word"]) - yield TestClient(app) +@pytest.fixture() +def kwja_client() -> TestClient: + app = create_app(AnalyzerType.KWJA, options=["--model-size", "tiny", "--tasks", "char,word"]) + return TestClient(app) @pytest.mark.skipif(not is_kwja_available, reason="KWJA is not available") @@ -141,7 +141,7 @@ def test_cli_serve_index_kwja(kwja_client: TestClient, text: str) -> None: @pytest.mark.parametrize( - "pre_text, post_text, expected", + ("pre_text", "post_text", "expected"), [ ("あ", "あ", [_Span("あ", "=")]), ("あ", "い", [_Span("あ", "-"), _Span("い", "+")]), diff --git a/tests/cohesion/test_argument.py b/tests/cohesion/test_argument.py index 6703bc45..a7ed1227 100644 --- a/tests/cohesion/test_argument.py +++ b/tests/cohesion/test_argument.py @@ -91,7 +91,7 @@ def test_exophora_argument() -> None: assert argument.pas == pas assert argument.exophora_referent == exophora_referent assert argument.eid == 3 - assert repr(argument) == f"ExophoraArgument(case='ガ', exophora_referent={repr(exophora_referent)}, eid=3)" + assert repr(argument) == f"ExophoraArgument(case='ガ', exophora_referent={exophora_referent!r}, eid=3)" assert eval(repr(argument)) == argument assert str(argument) == "不特定:人" assert argument != "test" diff --git a/tests/cohesion/test_coreference.py b/tests/cohesion/test_coreference.py index 2be2ee18..23fecbd4 100644 --- a/tests/cohesion/test_coreference.py +++ b/tests/cohesion/test_coreference.py @@ -264,7 +264,7 @@ def test_coref2() -> None: assert (mentions[3].text, mentions[3].global_index, {e.eid for e in mentions[3].entities}) == ("皆様", 17, {14}) -@pytest.mark.parametrize("doc_id", ["w201106-0000060560", "w201106-0000060560", "w201106-0000060877"]) +@pytest.mark.parametrize("doc_id", ["w201106-0000060050", "w201106-0000060560", "w201106-0000060877"]) def test_coref_link(doc_id: str) -> None: document = Document.from_knp(Path(f"tests/data/{doc_id}.knp").read_text()) entities: List[Entity] = sorted(EntityManager.entities.values(), key=lambda e: e.eid) @@ -320,7 +320,7 @@ def test_coref_with_self() -> None: entity = entities[0] assert entity.exophora_referent is None assert len(entity.mentions) == 1 - mention = list(entity.mentions)[0] + mention = next(iter(entity.mentions)) assert (mention.text, mention.global_index, {e.eid for e in mention.entities}) == ("わたし", 0, {0}) assert len(entities[0].mentions_all) == 1 diff --git a/tests/cohesion/test_discourse.py b/tests/cohesion/test_discourse.py index e355aa06..ea926de7 100644 --- a/tests/cohesion/test_discourse.py +++ b/tests/cohesion/test_discourse.py @@ -7,7 +7,7 @@ @pytest.mark.parametrize( - "tag, label", + ("tag", "label"), [ (DiscourseRelationTag.NO_RELATION, DiscourseRelationLabel.NO_RELATION), (DiscourseRelationTag.CAUSE_REASON, DiscourseRelationLabel.CAUSE_REASON), diff --git a/tests/cohesion/test_pas.py b/tests/cohesion/test_pas.py index 3eb608e3..2d6e2ed9 100644 --- a/tests/cohesion/test_pas.py +++ b/tests/cohesion/test_pas.py @@ -326,10 +326,10 @@ def test_attribute(case: Dict[str, Any]) -> None: def test_get_arguments(case: Dict[str, Any]) -> None: doc = Document.from_knp(case["knp"]) pas = doc.base_phrases[case["base_phrase_index"]].pas - for case, args_expected in case["arguments"].items(): + for pas_case, args_expected in case["arguments"].items(): args_actual = { (str(arg), (arg.base_phrase.global_index if isinstance(arg, EndophoraArgument) else -1), arg.type) - for arg in pas.get_arguments(case, relax=False) + for arg in pas.get_arguments(pas_case, relax=False) } assert args_actual == args_expected diff --git a/tests/processors/test_jumanpp.py b/tests/processors/test_jumanpp.py index 404e7331..1bb28ea9 100644 --- a/tests/processors/test_jumanpp.py +++ b/tests/processors/test_jumanpp.py @@ -42,6 +42,7 @@ def test_apply() -> None: "キャリッジ\rリターン", # carriage return "ライン\nフィード", # line feed "CR\r\nLF", # CR+LF + "タブ\t文字", # tab ], ) def test_apply_to_sentence(text: str) -> None: @@ -63,6 +64,7 @@ def test_apply_to_sentence(text: str) -> None: "キャリッジ\rリターン", # carriage return "ライン\nフィード", # line feed "CR\r\nLF", # CR+LF + "タブ\t文字", # tab ], ) def test_apply_to_document(text: str) -> None: @@ -110,10 +112,48 @@ def test_whitespace() -> None: sent = jumanpp.apply(text) assert len(sent.morphemes) == 3 assert "".join(m.text for m in sent.morphemes) == text + assert sent.morphemes[1].reading == " " + assert sent.morphemes[1].lemma == " " assert sent.morphemes[1].pos == "特殊" assert sent.morphemes[1].subpos == "空白" +def test_keep_id_sentence() -> None: + jumanpp = Jumanpp() + sent = Sentence.from_raw_text("外国人参政権") + sent.doc_id = "test" + sent.sent_id = "test-1" + sent = jumanpp.apply_to_sentence(sent) + assert sent.doc_id == "test" + assert sent.sent_id == "test-1" + + +def test_keep_doc_id_document() -> None: + jumanpp = Jumanpp() + doc = Document.from_sentences(["米原発の電力供給", "米原発の521系の列車"]) + doc.doc_id = "test" + for sent in doc.sentences: + sent.doc_id = "test" + doc = jumanpp.apply_to_document(doc) + assert doc.doc_id == "test" + for sent in doc.sentences: + assert sent.doc_id == "test" + + +def test_keep_id_document() -> None: + jumanpp = Jumanpp() + doc = Document.from_sentences(["米原発の電力供給", "米原発の521系の列車"]) + doc.doc_id = "test" + for idx, sent in enumerate(doc.sentences): + sent.doc_id = "test" + sent.sent_id = f"test-{idx}" + doc = jumanpp.apply_to_document(doc) + assert doc.doc_id == "test" + for idx, sent in enumerate(doc.sentences): + assert sent.doc_id == "test" + assert sent.sent_id == f"test-{idx}" + + @pytest.mark.skipif(not is_jumanpp_available, reason="Juman++ is not available") def test_get_version() -> None: jumanpp = Jumanpp() diff --git a/tests/processors/test_knp.py b/tests/processors/test_knp.py index 9cdb76b4..0f08a502 100644 --- a/tests/processors/test_knp.py +++ b/tests/processors/test_knp.py @@ -67,6 +67,7 @@ def test_apply() -> None: "キャリッジ\rリターン", # carriage return "ライン\nフィード", # line feed "CR\r\nLF", # CR+LF + "タブ\t文字", # tab ], ) def test_apply_to_sentence(text: str) -> None: @@ -101,6 +102,7 @@ def test_thread_safe() -> None: "キャリッジ\rリターン", # carriage return "ライン\nフィード", # line feed "CR\r\nLF", # CR+LF + "タブ\t文字", # tab ], ) def test_apply_to_document(text: str) -> None: @@ -109,6 +111,42 @@ def test_apply_to_document(text: str) -> None: assert doc.text == text.replace("\r", "").replace("\n", "") +def test_keep_id_sentence() -> None: + knp = KNP() + sent = Sentence.from_raw_text("外国人参政権") + sent.doc_id = "test" + sent.sent_id = "test-1" + sent = knp.apply_to_sentence(sent) + assert sent.doc_id == "test" + assert sent.sent_id == "test-1" + + +def test_keep_doc_id_document() -> None: + knp = KNP() + doc = Document.from_sentences(["米原発の電力供給", "米原発の521系の列車"]) + doc.doc_id = "test" + for sent in doc.sentences: + sent.doc_id = "test" + doc = knp.apply_to_document(doc) + assert doc.doc_id == "test" + for sent in doc.sentences: + assert sent.doc_id == "test" + + +def test_keep_id_document() -> None: + knp = KNP() + doc = Document.from_sentences(["米原発の電力供給", "米原発の521系の列車"]) + doc.doc_id = "test" + for idx, sent in enumerate(doc.sentences): + sent.doc_id = "test" + sent.sent_id = f"test-{idx}" + doc = knp.apply_to_document(doc) + assert doc.doc_id == "test" + for idx, sent in enumerate(doc.sentences): + assert sent.doc_id == "test" + assert sent.sent_id == f"test-{idx}" + + @pytest.mark.skipif(not is_knp_available, reason="KNP is not available") def test_get_version() -> None: knp = KNP() @@ -156,8 +194,10 @@ def test_runtime_error2() -> None: def test_invalid_option() -> None: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="`-tab` option is required when you use KNP."): _ = KNP(options=["--anaphora"]) + # with pytest.raises(ValueError): + # _ = KNP(options=["-tab", "--anaphora"]) def test_repr() -> None: diff --git a/tests/processors/test_kwja.py b/tests/processors/test_kwja.py index b878f588..288e1a03 100644 --- a/tests/processors/test_kwja.py +++ b/tests/processors/test_kwja.py @@ -1,8 +1,8 @@ import pytest -from rhoknp import KWJA, Document, Sentence +from rhoknp import KNP, KWJA, Document, Jumanpp, Sentence -is_kwja_available = KWJA(options=["--model-size", "tiny", "--tasks", "senter"]).is_available() +is_kwja_available = KWJA(options=["--model-size", "tiny", "--tasks", "typo"]).is_available() @pytest.mark.skipif(not is_kwja_available, reason="KWJA is not available") @@ -38,50 +38,36 @@ def test_typo() -> None: @pytest.mark.skipif(not is_kwja_available, reason="KWJA is not available") -def test_senter() -> None: - kwja = KWJA(options=["--model-size", "tiny", "--tasks", "senter"]) - text = "こんにちは。さようなら。" - document = kwja.apply_to_document(text) - sentences = document.sentences - assert len(sentences) == 2 - assert sentences[0].text == "こんにちは。" - assert sentences[1].text == "さようなら。" - - -@pytest.mark.skipif(not is_kwja_available, reason="KWJA is not available") -def test_seq2seq() -> None: - kwja = KWJA(options=["--model-size", "tiny", "--tasks", "senter,seq2seq"]) +def test_char() -> None: + kwja = KWJA(options=["--model-size", "tiny", "--tasks", "char"]) text = "こんにちは。さようなら。" doc = kwja.apply_to_document(text) - assert isinstance(doc, Document) morphemes = doc.morphemes assert len(morphemes) > 0 morpheme = morphemes[0] assert text.startswith(morpheme.text) - assert text.startswith(morpheme.reading) - assert text.startswith(morpheme.lemma) + assert morpheme.reading == "*" + assert morpheme.lemma == "*" @pytest.mark.skipif(not is_kwja_available, reason="KWJA is not available") -def test_char() -> None: - kwja = KWJA(options=["--model-size", "tiny", "--tasks", "senter,char"]) +def test_seq2seq() -> None: + kwja = KWJA(options=["--model-size", "tiny", "--tasks", "char,seq2seq"]) text = "こんにちは。さようなら。" doc = kwja.apply_to_document(text) - assert isinstance(doc, Document) morphemes = doc.morphemes assert len(morphemes) > 0 morpheme = morphemes[0] assert text.startswith(morpheme.text) - assert morpheme.reading == "*" - assert morpheme.lemma == "*" + assert text.startswith(morpheme.reading) + assert text.startswith(morpheme.lemma) @pytest.mark.skipif(not is_kwja_available, reason="KWJA is not available") def test_word() -> None: - kwja = KWJA(options=["--model-size", "tiny", "--tasks", "senter,char,word"]) + kwja = KWJA(options=["--model-size", "tiny", "--tasks", "char,word"]) text = "こんにちは。さようなら。" doc = kwja.apply_to_document(text) - assert isinstance(doc, Document) morphemes = doc.morphemes assert len(morphemes) > 0 assert text.startswith(morphemes[0].text) @@ -96,6 +82,41 @@ def test_word() -> None: assert text.startswith(clauses[0].text) +@pytest.mark.skipif(not is_kwja_available, reason="KWJA is not available") +def test_raw_input() -> None: + kwja = KWJA(options=["--model-size", "tiny", "--tasks", "typo", "--input-format", "raw"]) + text = "人口知能" + doc = kwja.apply_to_document(text) + assert doc.text == "人工知能" + + +@pytest.mark.skipif(not is_kwja_available, reason="KWJA is not available") +def test_jumanpp_input() -> None: + kwja = KWJA(options=["--model-size", "tiny", "--tasks", "word", "--input-format", "jumanpp"]) + text = "こんにちは。さようなら。" + doc1 = Jumanpp().apply_to_document(text) + # TODO: Pass test without setting sid + doc1.did = "test" + assert len(doc1.sentences) == 2 + doc1.sentences[0].sid = "test-0" + doc1.sentences[1].sid = "test-1" + assert not doc1.is_jumanpp_required() + doc2 = kwja.apply_to_document(doc1) + assert [sent.text for sent in doc2.sentences] == [sent.text for sent in doc1.sentences] + assert [mrph.text for mrph in doc2.morphemes] == [mrph.text for mrph in doc1.morphemes] + + +@pytest.mark.skipif(not is_kwja_available, reason="KWJA is not available") +def test_knp_input() -> None: + kwja = KWJA(options=["--model-size", "tiny", "--tasks", "word", "--input-format", "knp"]) + text = "こんにちは。さようなら。" + doc1 = KNP().apply_to_document(text) + assert not doc1.is_knp_required() + doc2 = kwja.apply_to_document(doc1) + assert [sent.text for sent in doc2.sentences] == [sent.text for sent in doc1.sentences] + assert [mrph.text for mrph in doc2.morphemes] == [mrph.text for mrph in doc1.morphemes] + + @pytest.mark.skipif(not is_kwja_available, reason="KWJA is not available") def test_apply() -> None: kwja = KWJA(options=["--model-size", "tiny"]) @@ -108,6 +129,34 @@ def test_apply() -> None: _ = kwja.apply(1) # type: ignore +# TODO: uncomment +# def test_keep_doc_id_document() -> None: +# kwja = KWJA(options=["--model-size", "tiny"]) +# doc = Document.from_sentences(["こんにちは。", "さようなら。"]) +# doc.doc_id = "test" +# for sent in doc.sentences: +# sent.doc_id = "test" +# doc = kwja.apply_to_document(doc) +# assert doc.doc_id == "test" +# for sent in doc.sentences: +# assert sent.doc_id == "test" + + +# TODO: uncomment +# def test_keep_id_document() -> None: +# kwja = KWJA(options=["--model-size", "tiny"]) +# doc = Document.from_sentences(["こんにちは。", "さようなら。"]) +# doc.doc_id = "test" +# for idx, sent in enumerate(doc.sentences): +# sent.doc_id = "test" +# sent.sent_id = f"test-{idx}" +# doc = kwja.apply_to_document(doc) +# assert doc.doc_id == "test" +# for idx, sent in enumerate(doc.sentences): +# assert sent.doc_id == "test" +# assert sent.sent_id == f"test-{idx}" + + def test_timeout_error() -> None: kwja = KWJA("tests/bin/kwja-mock.sh", skip_sanity_check=True) with pytest.raises(TimeoutError): @@ -121,8 +170,10 @@ def test_runtime_error() -> None: def test_unsupported_option() -> None: - with pytest.raises(ValueError): - _ = KWJA(options=["--model-size", "tiny", "--tasks", "wakati"]) + with pytest.raises(ValueError, match=r"invalid task: \['wakachi'\]"): + _ = KWJA(options=["--model-size", "tiny", "--tasks", "wakachi"]) + with pytest.raises(ValueError, match="invalid input format: seq2seq"): + _ = KWJA(options=["--model-size", "tiny", "--input-format", "seq2seq"]) def test_apply_to_sentence() -> None: @@ -132,5 +183,5 @@ def test_apply_to_sentence() -> None: def test_repr() -> None: - kwja = KWJA(options=["--model-size", "tiny", "--tasks", "senter,char,word"]) - assert repr(kwja) == "KWJA(executable='kwja', options=['--model-size', 'tiny', '--tasks', 'senter,char,word'])" + kwja = KWJA(options=["--model-size", "tiny", "--tasks", "char,word"]) + assert repr(kwja) == "KWJA(executable='kwja', options=['--model-size', 'tiny', '--tasks', 'char,word'])" diff --git a/tests/processors/test_regex_senter.py b/tests/processors/test_regex_senter.py index 9f818ad0..500cae01 100644 --- a/tests/processors/test_regex_senter.py +++ b/tests/processors/test_regex_senter.py @@ -4,11 +4,11 @@ import pytest -from rhoknp import RegexSenter +from rhoknp import Document, RegexSenter, Sentence @pytest.mark.parametrize( - "document, sentence_strings", + ("document", "sentence_strings"), [ ( "", @@ -106,6 +106,26 @@ def test_apply_to_sentence() -> None: assert sent.text == text +def test_keep_id_sentence() -> None: + senter = RegexSenter() + sent = Sentence.from_raw_text("天気がいいので散歩した。") + sent.doc_id = "test" + sent.sent_id = "test-1" + sent = senter.apply_to_sentence(sent) + assert sent.doc_id == "test" + assert sent.sent_id == "test-1" + + +def test_keep_id_document() -> None: + senter = RegexSenter() + doc = Document.from_raw_text("天気がいいので散歩した。散歩の途中で先生に出会った。") + doc.doc_id = "test" + doc = senter.apply_to_document(doc) + assert doc.doc_id == "test" + for sent in doc.sentences: + assert sent.doc_id == "test" + + def test_repr() -> None: senter = RegexSenter() assert repr(senter) == "RegexSenter()" diff --git a/tests/props/test_features.py b/tests/props/test_features.py index 6ef8c85f..961e4fb1 100644 --- a/tests/props/test_features.py +++ b/tests/props/test_features.py @@ -58,7 +58,7 @@ class FeaturesTestCase: ] -@pytest.mark.parametrize("fstring, features, length", [astuple(case) for case in cases + cases_with_ignored_tag]) +@pytest.mark.parametrize(("fstring", "features", "length"), [astuple(case) for case in cases + cases_with_ignored_tag]) def test_from_fstring(fstring: str, features: Dict[str, Union[str, bool]], length: int) -> None: fs = FeatureDict.from_fstring(fstring) assert len(fs) == length @@ -66,7 +66,7 @@ def test_from_fstring(fstring: str, features: Dict[str, Union[str, bool]], lengt assert fs.get("dummy") is None -@pytest.mark.parametrize("fstring, features, length", [astuple(case) for case in cases]) +@pytest.mark.parametrize(("fstring", "features", "length"), [astuple(case) for case in cases]) def test_to_fstring(fstring: str, features: Dict[str, Union[str, bool]], length: int) -> None: fs = FeatureDict.from_fstring(fstring) assert fs.to_fstring() == fstring diff --git a/tests/units/test_base_phrase.py b/tests/units/test_base_phrase.py index 31e97a15..80783a92 100644 --- a/tests/units/test_base_phrase.py +++ b/tests/units/test_base_phrase.py @@ -323,7 +323,7 @@ def test_from_knp(case: Dict[str, str]) -> None: def test_from_knp_error() -> None: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="malformed base phrase line: MALFORMED LINE"): _ = BasePhrase.from_knp("MALFORMED LINE") diff --git a/tests/units/test_document.py b/tests/units/test_document.py index 8c2cbb46..2cb6491c 100644 --- a/tests/units/test_document.py +++ b/tests/units/test_document.py @@ -2,13 +2,13 @@ import pickle import textwrap from pathlib import Path -from typing import Dict +from typing import Dict, List, Union import pytest from rhoknp import Document, Sentence -CASES = [ +CASES: List[Dict[str, Union[str, List[str]]]] = [ { "raw_text": "天気がいいので散歩した。", "sentences": ["天気がいいので散歩した。"], @@ -343,7 +343,7 @@ def test_from_jumanpp_error(): EOS """ ) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="malformed line: .*"): _ = Document.from_jumanpp(invalid_jumanpp_text) @@ -355,7 +355,7 @@ def test_from_jumanpp_control_character() -> None: + ぷらす + 未定義語 15 その他 1 * 0 * 0 @ あっと @ 未定義語 15 その他 1 * 0 * 0 EOS いーおーえす EOS 未定義語 15 アルファベット 3 * 0 * 0 - \u0020 すぺーす \u0020 特殊 1 空白 6 * 0 * 0 + \\␣ すぺーす \\␣ 特殊 1 空白 6 * 0 * 0 < < < 特殊 1 括弧始 3 * 0 * 0 > > > 特殊 1 括弧終 4 * 0 * 0 " " " 特殊 1 括弧終 4 * 0 * 0 @@ -368,7 +368,7 @@ def test_from_jumanpp_control_character() -> None: + ぷらす + 未定義語 15 その他 1 * 0 * 0 @ あっと @ 未定義語 15 その他 1 * 0 * 0 EOS いーおーえす EOS 未定義語 15 アルファベット 3 * 0 * 0 - \u0020 すぺーす \u0020 特殊 1 空白 6 * 0 * 0 + \\␣ すぺーす \\␣ 特殊 1 空白 6 * 0 * 0 < < < 特殊 1 括弧始 3 * 0 * 0 > > > 特殊 1 括弧終 4 * 0 * 0 " " " 特殊 1 括弧終 4 * 0 * 0 @@ -433,7 +433,7 @@ def test_from_knp_error(): EOS """ ) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="malformed line: .*"): _ = Document.from_knp(invalid_knp_text) @@ -685,30 +685,30 @@ def test_morphemes(case: Dict[str, str]) -> None: @pytest.mark.parametrize("case", CASES) def test_reference(case: Dict[str, str]) -> None: - doc = Document.from_knp(case["knp"]) - for sentence in doc.sentences: - assert sentence.document == doc - assert sentence == sentence + document = Document.from_knp(case["knp"]) + for sentence in document.sentences: + assert sentence.document == document + assert sentence == sentence # noqa: PLR0124 for clause in sentence.clauses: - assert clause.document == doc + assert clause.document == document assert clause.sentence == sentence - assert clause == clause + assert clause == clause # noqa: PLR0124 for phrase in clause.phrases: - assert phrase.document == doc + assert phrase.document == document assert phrase.sentence == sentence assert phrase.clause == clause for base_phrase in phrase.base_phrases: - assert base_phrase.document == doc + assert base_phrase.document == document assert base_phrase.sentence == sentence assert base_phrase.phrase == phrase - assert base_phrase == base_phrase + assert base_phrase == base_phrase # noqa: PLR0124 for morpheme in base_phrase.morphemes: - assert morpheme.document == doc + assert morpheme.document == document assert morpheme.sentence == sentence assert morpheme.clause == clause assert morpheme.phrase == phrase assert morpheme.base_phrase == base_phrase - assert morpheme == morpheme + assert morpheme == morpheme # noqa: PLR0124 for morpheme in phrase.morphemes: assert morpheme.phrase == phrase for base_phrase in clause.base_phrases: @@ -721,14 +721,14 @@ def test_reference(case: Dict[str, str]) -> None: assert base_phrase.sentence == sentence for morpheme in sentence.morphemes: assert morpheme.sentence == sentence - for clause in doc.clauses: - assert clause.document == doc - for phrase in doc.phrases: - assert phrase.document == doc - for base_phrase in doc.base_phrases: - assert base_phrase.document == doc - for morpheme in doc.morphemes: - assert morpheme.document == doc + for clause in document.clauses: + assert clause.document == document + for phrase in document.phrases: + assert phrase.document == document + for base_phrase in document.base_phrases: + assert base_phrase.document == document + for morpheme in document.morphemes: + assert morpheme.document == document @pytest.mark.parametrize( @@ -742,7 +742,7 @@ def test_reference_with_no_clause_tag(knp: str) -> None: document = Document.from_knp(knp) for sentence in document.sentences: assert sentence.document == document - assert sentence == sentence + assert sentence == sentence # noqa: PLR0124 for phrase in sentence.phrases: assert phrase.document == document assert phrase.sentence == sentence @@ -750,13 +750,13 @@ def test_reference_with_no_clause_tag(knp: str) -> None: assert base_phrase.document == document assert base_phrase.sentence == sentence assert base_phrase.phrase == phrase - assert base_phrase == base_phrase + assert base_phrase == base_phrase # noqa: PLR0124 for morpheme in base_phrase.morphemes: assert morpheme.document == document assert morpheme.sentence == sentence assert morpheme.phrase == phrase assert morpheme.base_phrase == base_phrase - assert morpheme == morpheme + assert morpheme == morpheme # noqa: PLR0124 for morpheme in phrase.morphemes: assert morpheme.phrase == phrase for phrase in sentence.phrases: @@ -834,7 +834,7 @@ def test_cut_paste(case: Dict[str, str]) -> None: @pytest.mark.parametrize("case", CASES) @pytest.mark.parametrize( "key", - ("raw_text", "sentences", "line_by_line_text", "jumanpp", "knp_with_no_clause_tag", "knp"), + ["raw_text", "sentences", "line_by_line_text", "jumanpp", "knp_with_no_clause_tag", "knp"], ) def test_reparse(case: Dict[str, str], key: str) -> None: if key == "raw_text": @@ -872,8 +872,8 @@ def test_to_knp_wac() -> None: assert doc.to_knp() == knp -@pytest.mark.parametrize("doc_id", ("w201106-0000060050", "wiki00100176")) -def test_id(doc_id) -> None: +@pytest.mark.parametrize("doc_id", ["w201106-0000060050", "wiki00100176"]) +def test_id(doc_id: str) -> None: doc = Document.from_knp(Path(f"tests/data/{doc_id}.knp").read_text()) assert doc.doc_id == doc_id assert doc.did == doc_id diff --git a/tests/units/test_morpheme.py b/tests/units/test_morpheme.py index fea11c05..0f7f0ea5 100644 --- a/tests/units/test_morpheme.py +++ b/tests/units/test_morpheme.py @@ -254,7 +254,7 @@ "canon": None, }, { - "jumanpp": " 特殊 1 空白 6 * 0 * 0\n", + "jumanpp": "\\␣ \\␣ \\␣ 特殊 1 空白 6 * 0 * 0\n", "text": " ", "surf": " ", "reading": " ", @@ -446,7 +446,7 @@ def test_from_jumanpp(case: Dict[str, str]) -> None: def test_from_jumanpp_error() -> None: jumanpp = "であり であり だ 判定詞 4 * 0 判定詞 25 デアル列基本連用形 18 MALFORMED_STRING\n" - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="malformed morpheme line: .*"): _ = Morpheme.from_jumanpp(jumanpp) @@ -474,29 +474,29 @@ def test_semantics(case: Dict[str, str]) -> None: @pytest.mark.parametrize("case", JUMANPP_SNIPPETS) def test_document_error(case: Dict[str, str]) -> None: + morpheme = Morpheme.from_jumanpp(case["jumanpp"]) with pytest.raises(AttributeError): - morpheme = Morpheme.from_jumanpp(case["jumanpp"]) _ = morpheme.document @pytest.mark.parametrize("case", JUMANPP_SNIPPETS) def test_sentence_error(case: Dict[str, str]) -> None: + morpheme = Morpheme.from_jumanpp(case["jumanpp"]) with pytest.raises(AttributeError): - morpheme = Morpheme.from_jumanpp(case["jumanpp"]) _ = morpheme.sentence @pytest.mark.parametrize("case", JUMANPP_SNIPPETS) def test_phrase_error(case: Dict[str, str]) -> None: + morpheme = Morpheme.from_jumanpp(case["jumanpp"]) with pytest.raises(AttributeError): - morpheme = Morpheme.from_jumanpp(case["jumanpp"]) _ = morpheme.phrase @pytest.mark.parametrize("case", JUMANPP_SNIPPETS) def test_base_phrase_error(case: Dict[str, str]) -> None: + morpheme = Morpheme.from_jumanpp(case["jumanpp"]) with pytest.raises(AttributeError): - morpheme = Morpheme.from_jumanpp(case["jumanpp"]) _ = morpheme.base_phrase diff --git a/tests/units/test_phrase.py b/tests/units/test_phrase.py index c667e363..17aae123 100644 --- a/tests/units/test_phrase.py +++ b/tests/units/test_phrase.py @@ -250,7 +250,7 @@ def test_from_knp(case: Dict[str, str]) -> None: def test_from_knp_error() -> None: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="malformed phrase line: MALFORMED LINE"): _ = Phrase.from_knp("MALFORMED LINE") @@ -268,22 +268,22 @@ def test_text(case: Dict[str, str]) -> None: @pytest.mark.parametrize("case", KNP_SNIPPETS) def test_document_error(case: Dict[str, str]) -> None: + phrase = Phrase.from_knp(case["knp"]) with pytest.raises(AttributeError): - phrase = Phrase.from_knp(case["knp"]) _ = phrase.document @pytest.mark.parametrize("case", KNP_SNIPPETS) def test_sentence_error(case: Dict[str, str]) -> None: + phrase = Phrase.from_knp(case["knp"]) with pytest.raises(AttributeError): - phrase = Phrase.from_knp(case["knp"]) _ = phrase.sentence @pytest.mark.parametrize("case", KNP_SNIPPETS) def test_clause_error(case: Dict[str, str]) -> None: + phrase = Phrase.from_knp(case["knp"]) with pytest.raises(AttributeError): - phrase = Phrase.from_knp(case["knp"]) _ = phrase.clause diff --git a/tests/units/test_sentence.py b/tests/units/test_sentence.py index 8529e7a1..338a55b4 100644 --- a/tests/units/test_sentence.py +++ b/tests/units/test_sentence.py @@ -338,7 +338,7 @@ def test_from_jumanpp_control_character() -> None: + ぷらす + 未定義語 15 その他 1 * 0 * 0 @ あっと @ 未定義語 15 その他 1 * 0 * 0 EOS いーおーえす EOS 未定義語 15 アルファベット 3 * 0 * 0 - \u0020 すぺーす \u0020 特殊 1 空白 6 * 0 * 0 + \\␣ すぺーす \\␣ 特殊 1 空白 6 * 0 * 0 < < < 特殊 1 括弧始 3 * 0 * 0 > > > 特殊 1 括弧終 4 * 0 * 0 " " " 特殊 1 括弧終 4 * 0 * 0 @@ -410,7 +410,7 @@ def test_from_knp_empty_line(): def test_from_knp_invalid_input(): - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="malformed line: ;; Invalid input"): _ = Sentence.from_knp( textwrap.dedent( """\ @@ -616,7 +616,7 @@ def test_morphemes(case: Dict[str, str]) -> None: @pytest.mark.parametrize("case", CASES) @pytest.mark.parametrize( "key", - ("raw_text", "sentences", "line_by_line_text", "jumanpp", "knp_with_no_clause_tag", "knp"), + ["raw_text", "sentences", "line_by_line_text", "jumanpp", "knp_with_no_clause_tag", "knp"], ) def test_reparse(case: Dict[str, str], key: str) -> None: if key == "raw_text": diff --git a/tests/utils/test_comment.py b/tests/utils/test_comment.py index 098cce71..e8b4d247 100644 --- a/tests/utils/test_comment.py +++ b/tests/utils/test_comment.py @@ -8,7 +8,7 @@ @pytest.mark.parametrize( - "line, expected", + ("line", "expected"), [ ("# S-ID:1", True), ("# foo-bar", True), @@ -24,7 +24,7 @@ def test_is_comment_line(line: str, expected: bool) -> None: @pytest.mark.parametrize( - "pat, line, doc_id, sent_id", + ("pat", "line", "doc_id", "sent_id"), [ (Sentence.SID_PAT, "# S-ID:", "", ""), (Sentence.SID_PAT, "# S-ID:1", "", "1"), diff --git a/tests/utils/test_reader.py b/tests/utils/test_reader.py index dbbcf9c7..61be765a 100644 --- a/tests/utils/test_reader.py +++ b/tests/utils/test_reader.py @@ -185,7 +185,7 @@ def test_chunk_by_document(case: Dict[str, Any]) -> None: def test_chunk_by_document_value_error() -> None: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="Invalid doc_id_format: ERROR"): _ = list(chunk_by_document(StringIO(""), doc_id_format="ERROR")) # type: ignore