diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 98d4d615..07492f5c 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -10,8 +10,8 @@ jobs: linting: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 - uses: snok/install-poetry@v1 - name: Install dependencies run: | @@ -31,20 +31,20 @@ jobs: fail-fast: false matrix: os: ["ubuntu-latest", "windows-latest", "macos-latest"] - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] exclude: - - os: macos-latest - python-version: "3.9" - os: macos-latest python-version: "3.10" - os: macos-latest python-version: "3.11" - - os: windows-latest - python-version: "3.9" + - os: macos-latest + python-version: "3.12" - os: windows-latest python-version: "3.10" - os: windows-latest python-version: "3.11" + - os: windows-latest + python-version: "3.12" runs-on: ${{ matrix.os }} defaults: @@ -52,10 +52,10 @@ jobs: shell: bash steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -67,7 +67,7 @@ jobs: - name: Load cached venv id: cached-pip-wheels - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cache key: venv-${{ runner.os }}-${{ matrix.python-version }} @@ -80,7 +80,7 @@ jobs: run: | poetry run pytest --junitxml=test-reports/report-${{ matrix.os }}-${{ matrix.python-version }}.xml -o junit_suite_name=suite-${{ matrix.os }}-${{ matrix.python-version }} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: always() with: name: report-${{ matrix.os }}-${{ matrix.python-version }} @@ -99,7 +99,7 @@ jobs: steps: - name: Download Test Result Artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: path: test-reports diff --git a/README.rst b/README.rst index 289326d7..6fd6921b 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ aioslsk aioslsk is a Python library for the SoulSeek protocol built on top of asyncio. -Supported Python versions are currently 3.8 - 3.12 +Supported Python versions are currently 3.9 - 3.13 You can find the full documentation `here `_ diff --git a/docs/source/USAGE.rst b/docs/source/USAGE.rst index e5537be2..44cccd3e 100644 --- a/docs/source/USAGE.rst +++ b/docs/source/USAGE.rst @@ -278,9 +278,9 @@ A couple of methods are available to retrieve transfers: from aioslsk.transfer.model import Transfer - all_transfers = List[Transfer] = client.transfers.transfers - downloads: List[Transfer] = client.transfers.get_downloads() - uploads: List[Transfer] = client.transfers.get_uploads() + all_transfers = list[Transfer] = client.transfers.transfers + downloads: list[Transfer] = client.transfers.get_downloads() + uploads: list[Transfer] = client.transfers.get_uploads() Events are available to listen for the transfer progress: @@ -591,7 +591,7 @@ Example a strategy that places files in a directory containing the current date: class DatetimeDirectoryStrategy(NamingStrategy): # Override the apply method - def apply(self, remote_path: str, local_dir: str, local_filename: str) -> Tuple[str, str]: + def apply(self, remote_path: str, local_dir: str, local_filename: str) -> tuple[str, str]: current_datetime = datetime.now().strftime('%Y-%M-%d') return os.path.join(local_dir, current_datetime), local_filename diff --git a/poetry.lock b/poetry.lock index 92cbe086..8fd78a3e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,113 +13,113 @@ files = [ [[package]] name = "aiohappyeyeballs" -version = "2.4.0" +version = "2.4.3" description = "Happy Eyeballs for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "aiohappyeyeballs-2.4.0-py3-none-any.whl", hash = "sha256:7ce92076e249169a13c2f49320d1967425eaf1f407522d707d59cac7628d62bd"}, - {file = "aiohappyeyeballs-2.4.0.tar.gz", hash = "sha256:55a1714f084e63d49639800f95716da97a1f173d46a16dfcfda0016abb93b6b2"}, + {file = "aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572"}, + {file = "aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586"}, ] [[package]] name = "aiohttp" -version = "3.10.5" +version = "3.10.10" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.8" files = [ - {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3"}, - {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:94fac7c6e77ccb1ca91e9eb4cb0ac0270b9fb9b289738654120ba8cebb1189c6"}, - {file = "aiohttp-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f1f1c75c395991ce9c94d3e4aa96e5c59c8356a15b1c9231e783865e2772699"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f7acae3cf1a2a2361ec4c8e787eaaa86a94171d2417aae53c0cca6ca3118ff6"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94c4381ffba9cc508b37d2e536b418d5ea9cfdc2848b9a7fea6aebad4ec6aac1"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c31ad0c0c507894e3eaa843415841995bf8de4d6b2d24c6e33099f4bc9fc0d4f"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0912b8a8fadeb32ff67a3ed44249448c20148397c1ed905d5dac185b4ca547bb"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d93400c18596b7dc4794d48a63fb361b01a0d8eb39f28800dc900c8fbdaca91"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3c5e0d764a5c9aa5a62d99728c56d455310bcc288a79cab10157b3af426f"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d742c36ed44f2798c8d3f4bc511f479b9ceef2b93f348671184139e7d708042c"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:814375093edae5f1cb31e3407997cf3eacefb9010f96df10d64829362ae2df69"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8224f98be68a84b19f48e0bdc14224b5a71339aff3a27df69989fa47d01296f3"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9a487ef090aea982d748b1b0d74fe7c3950b109df967630a20584f9a99c0683"}, - {file = "aiohttp-3.10.5-cp310-cp310-win32.whl", hash = "sha256:d9ef084e3dc690ad50137cc05831c52b6ca428096e6deb3c43e95827f531d5ef"}, - {file = "aiohttp-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:66bf9234e08fe561dccd62083bf67400bdbf1c67ba9efdc3dac03650e97c6088"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8c6a4e5e40156d72a40241a25cc226051c0a8d816610097a8e8f517aeacd59a2"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c634a3207a5445be65536d38c13791904fda0748b9eabf908d3fe86a52941cf"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4aff049b5e629ef9b3e9e617fa6e2dfeda1bf87e01bcfecaf3949af9e210105e"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1942244f00baaacaa8155eca94dbd9e8cc7017deb69b75ef67c78e89fdad3c77"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e04a1f2a65ad2f93aa20f9ff9f1b672bf912413e5547f60749fa2ef8a644e061"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f2bfc0032a00405d4af2ba27f3c429e851d04fad1e5ceee4080a1c570476697"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:424ae21498790e12eb759040bbb504e5e280cab64693d14775c54269fd1d2bb7"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:975218eee0e6d24eb336d0328c768ebc5d617609affaca5dbbd6dd1984f16ed0"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4120d7fefa1e2d8fb6f650b11489710091788de554e2b6f8347c7a20ceb003f5"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b90078989ef3fc45cf9221d3859acd1108af7560c52397ff4ace8ad7052a132e"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ba5a8b74c2a8af7d862399cdedce1533642fa727def0b8c3e3e02fcb52dca1b1"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:02594361128f780eecc2a29939d9dfc870e17b45178a867bf61a11b2a4367277"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4fc029e135859f533025bc82047334e24b0d489e75513144f25408ecaf058"}, - {file = "aiohttp-3.10.5-cp311-cp311-win32.whl", hash = "sha256:e1ca1ef5ba129718a8fc827b0867f6aa4e893c56eb00003b7367f8a733a9b072"}, - {file = "aiohttp-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:349ef8a73a7c5665cca65c88ab24abe75447e28aa3bc4c93ea5093474dfdf0ff"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:305be5ff2081fa1d283a76113b8df7a14c10d75602a38d9f012935df20731487"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3a1c32a19ee6bbde02f1cb189e13a71b321256cc1d431196a9f824050b160d5a"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:61645818edd40cc6f455b851277a21bf420ce347baa0b86eaa41d51ef58ba23d"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c225286f2b13bab5987425558baa5cbdb2bc925b2998038fa028245ef421e75"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ba01ebc6175e1e6b7275c907a3a36be48a2d487549b656aa90c8a910d9f3178"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8eaf44ccbc4e35762683078b72bf293f476561d8b68ec8a64f98cf32811c323e"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c43eb1ab7cbf411b8e387dc169acb31f0ca0d8c09ba63f9eac67829585b44f"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de7a5299827253023c55ea549444e058c0eb496931fa05d693b95140a947cb73"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4790f0e15f00058f7599dab2b206d3049d7ac464dc2e5eae0e93fa18aee9e7bf"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:44b324a6b8376a23e6ba25d368726ee3bc281e6ab306db80b5819999c737d820"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0d277cfb304118079e7044aad0b76685d30ecb86f83a0711fc5fb257ffe832ca"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:54d9ddea424cd19d3ff6128601a4a4d23d54a421f9b4c0fff740505813739a91"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4f1c9866ccf48a6df2b06823e6ae80573529f2af3a0992ec4fe75b1a510df8a6"}, - {file = "aiohttp-3.10.5-cp312-cp312-win32.whl", hash = "sha256:dc4826823121783dccc0871e3f405417ac116055bf184ac04c36f98b75aacd12"}, - {file = "aiohttp-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:22c0a23a3b3138a6bf76fc553789cb1a703836da86b0f306b6f0dc1617398abc"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7f6b639c36734eaa80a6c152a238242bedcee9b953f23bb887e9102976343092"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f29930bc2921cef955ba39a3ff87d2c4398a0394ae217f41cb02d5c26c8b1b77"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f489a2c9e6455d87eabf907ac0b7d230a9786be43fbe884ad184ddf9e9c1e385"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:123dd5b16b75b2962d0fff566effb7a065e33cd4538c1692fb31c3bda2bfb972"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b98e698dc34966e5976e10bbca6d26d6724e6bdea853c7c10162a3235aba6e16"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3b9162bab7e42f21243effc822652dc5bb5e8ff42a4eb62fe7782bcbcdfacf6"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1923a5c44061bffd5eebeef58cecf68096e35003907d8201a4d0d6f6e387ccaa"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55f011da0a843c3d3df2c2cf4e537b8070a419f891c930245f05d329c4b0689"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:afe16a84498441d05e9189a15900640a2d2b5e76cf4efe8cbb088ab4f112ee57"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8112fb501b1e0567a1251a2fd0747baae60a4ab325a871e975b7bb67e59221f"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e72589da4c90337837fdfe2026ae1952c0f4a6e793adbbfbdd40efed7c63599"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4d46c7b4173415d8e583045fbc4daa48b40e31b19ce595b8d92cf639396c15d5"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987"}, - {file = "aiohttp-3.10.5-cp313-cp313-win32.whl", hash = "sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04"}, - {file = "aiohttp-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f6f18898ace4bcd2d41a122916475344a87f1dfdec626ecde9ee802a711bc569"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5ede29d91a40ba22ac1b922ef510aab871652f6c88ef60b9dcdf773c6d32ad7a"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:673f988370f5954df96cc31fd99c7312a3af0a97f09e407399f61583f30da9bc"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58718e181c56a3c02d25b09d4115eb02aafe1a732ce5714ab70326d9776457c3"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b38b1570242fbab8d86a84128fb5b5234a2f70c2e32f3070143a6d94bc854cf"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:074d1bff0163e107e97bd48cad9f928fa5a3eb4b9d33366137ffce08a63e37fe"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd31f176429cecbc1ba499d4aba31aaccfea488f418d60376b911269d3b883c5"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7384d0b87d4635ec38db9263e6a3f1eb609e2e06087f0aa7f63b76833737b471"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8989f46f3d7ef79585e98fa991e6ded55d2f48ae56d2c9fa5e491a6e4effb589"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c83f7a107abb89a227d6c454c613e7606c12a42b9a4ca9c5d7dad25d47c776ae"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cde98f323d6bf161041e7627a5fd763f9fd829bcfcd089804a5fdce7bb6e1b7d"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:676f94c5480d8eefd97c0c7e3953315e4d8c2b71f3b49539beb2aa676c58272f"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2d21ac12dc943c68135ff858c3a989f2194a709e6e10b4c8977d7fcd67dfd511"}, - {file = "aiohttp-3.10.5-cp38-cp38-win32.whl", hash = "sha256:17e997105bd1a260850272bfb50e2a328e029c941c2708170d9d978d5a30ad9a"}, - {file = "aiohttp-3.10.5-cp38-cp38-win_amd64.whl", hash = "sha256:1c19de68896747a2aa6257ae4cf6ef59d73917a36a35ee9d0a6f48cff0f94db8"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7e2fe37ac654032db1f3499fe56e77190282534810e2a8e833141a021faaab0e"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5bf3ead3cb66ab990ee2561373b009db5bc0e857549b6c9ba84b20bc462e172"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b2c16a919d936ca87a3c5f0e43af12a89a3ce7ccbce59a2d6784caba945b68b"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad146dae5977c4dd435eb31373b3fe9b0b1bf26858c6fc452bf6af394067e10b"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c5c6fa16412b35999320f5c9690c0f554392dc222c04e559217e0f9ae244b92"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95c4dc6f61d610bc0ee1edc6f29d993f10febfe5b76bb470b486d90bbece6b22"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da452c2c322e9ce0cfef392e469a26d63d42860f829026a63374fde6b5c5876f"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:898715cf566ec2869d5cb4d5fb4be408964704c46c96b4be267442d265390f32"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:391cc3a9c1527e424c6865e087897e766a917f15dddb360174a70467572ac6ce"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:380f926b51b92d02a34119d072f178d80bbda334d1a7e10fa22d467a66e494db"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce91db90dbf37bb6fa0997f26574107e1b9d5ff939315247b7e615baa8ec313b"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9093a81e18c45227eebe4c16124ebf3e0d893830c6aca7cc310bfca8fe59d857"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ee40b40aa753d844162dcc80d0fe256b87cba48ca0054f64e68000453caead11"}, - {file = "aiohttp-3.10.5-cp39-cp39-win32.whl", hash = "sha256:03f2645adbe17f274444953bdea69f8327e9d278d961d85657cb0d06864814c1"}, - {file = "aiohttp-3.10.5-cp39-cp39-win_amd64.whl", hash = "sha256:d17920f18e6ee090bdd3d0bfffd769d9f2cb4c8ffde3eb203777a3895c128862"}, - {file = "aiohttp-3.10.5.tar.gz", hash = "sha256:f071854b47d39591ce9a17981c46790acb30518e2f83dfca8db2dfa091178691"}, + {file = "aiohttp-3.10.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:be7443669ae9c016b71f402e43208e13ddf00912f47f623ee5994e12fc7d4b3f"}, + {file = "aiohttp-3.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b06b7843929e41a94ea09eb1ce3927865387e3e23ebe108e0d0d09b08d25be9"}, + {file = "aiohttp-3.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:333cf6cf8e65f6a1e06e9eb3e643a0c515bb850d470902274239fea02033e9a8"}, + {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:274cfa632350225ce3fdeb318c23b4a10ec25c0e2c880eff951a3842cf358ac1"}, + {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9e5e4a85bdb56d224f412d9c98ae4cbd032cc4f3161818f692cd81766eee65a"}, + {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b606353da03edcc71130b52388d25f9a30a126e04caef1fd637e31683033abd"}, + {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab5a5a0c7a7991d90446a198689c0535be89bbd6b410a1f9a66688f0880ec026"}, + {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:578a4b875af3e0daaf1ac6fa983d93e0bbfec3ead753b6d6f33d467100cdc67b"}, + {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8105fd8a890df77b76dd3054cddf01a879fc13e8af576805d667e0fa0224c35d"}, + {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3bcd391d083f636c06a68715e69467963d1f9600f85ef556ea82e9ef25f043f7"}, + {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fbc6264158392bad9df19537e872d476f7c57adf718944cc1e4495cbabf38e2a"}, + {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e48d5021a84d341bcaf95c8460b152cfbad770d28e5fe14a768988c461b821bc"}, + {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2609e9ab08474702cc67b7702dbb8a80e392c54613ebe80db7e8dbdb79837c68"}, + {file = "aiohttp-3.10.10-cp310-cp310-win32.whl", hash = "sha256:84afcdea18eda514c25bc68b9af2a2b1adea7c08899175a51fe7c4fb6d551257"}, + {file = "aiohttp-3.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:9c72109213eb9d3874f7ac8c0c5fa90e072d678e117d9061c06e30c85b4cf0e6"}, + {file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c30a0eafc89d28e7f959281b58198a9fa5e99405f716c0289b7892ca345fe45f"}, + {file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:258c5dd01afc10015866114e210fb7365f0d02d9d059c3c3415382ab633fcbcb"}, + {file = "aiohttp-3.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:15ecd889a709b0080f02721255b3f80bb261c2293d3c748151274dfea93ac871"}, + {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3935f82f6f4a3820270842e90456ebad3af15810cf65932bd24da4463bc0a4c"}, + {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:413251f6fcf552a33c981c4709a6bba37b12710982fec8e558ae944bfb2abd38"}, + {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1720b4f14c78a3089562b8875b53e36b51c97c51adc53325a69b79b4b48ebcb"}, + {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:679abe5d3858b33c2cf74faec299fda60ea9de62916e8b67e625d65bf069a3b7"}, + {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79019094f87c9fb44f8d769e41dbb664d6e8fcfd62f665ccce36762deaa0e911"}, + {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2fb38c2ed905a2582948e2de560675e9dfbee94c6d5ccdb1301c6d0a5bf092"}, + {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a3f00003de6eba42d6e94fabb4125600d6e484846dbf90ea8e48a800430cc142"}, + {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1bbb122c557a16fafc10354b9d99ebf2f2808a660d78202f10ba9d50786384b9"}, + {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30ca7c3b94708a9d7ae76ff281b2f47d8eaf2579cd05971b5dc681db8caac6e1"}, + {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df9270660711670e68803107d55c2b5949c2e0f2e4896da176e1ecfc068b974a"}, + {file = "aiohttp-3.10.10-cp311-cp311-win32.whl", hash = "sha256:aafc8ee9b742ce75044ae9a4d3e60e3d918d15a4c2e08a6c3c3e38fa59b92d94"}, + {file = "aiohttp-3.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:362f641f9071e5f3ee6f8e7d37d5ed0d95aae656adf4ef578313ee585b585959"}, + {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c"}, + {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28"}, + {file = "aiohttp-3.10.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f"}, + {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138"}, + {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742"}, + {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7"}, + {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16"}, + {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8"}, + {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6"}, + {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a"}, + {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9"}, + {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a"}, + {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205"}, + {file = "aiohttp-3.10.10-cp312-cp312-win32.whl", hash = "sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628"}, + {file = "aiohttp-3.10.10-cp312-cp312-win_amd64.whl", hash = "sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf"}, + {file = "aiohttp-3.10.10-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ad7593bb24b2ab09e65e8a1d385606f0f47c65b5a2ae6c551db67d6653e78c28"}, + {file = "aiohttp-3.10.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1eb89d3d29adaf533588f209768a9c02e44e4baf832b08118749c5fad191781d"}, + {file = "aiohttp-3.10.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3fe407bf93533a6fa82dece0e74dbcaaf5d684e5a51862887f9eaebe6372cd79"}, + {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50aed5155f819873d23520919e16703fc8925e509abbb1a1491b0087d1cd969e"}, + {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f05e9727ce409358baa615dbeb9b969db94324a79b5a5cea45d39bdb01d82e6"}, + {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dffb610a30d643983aeb185ce134f97f290f8935f0abccdd32c77bed9388b42"}, + {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa6658732517ddabe22c9036479eabce6036655ba87a0224c612e1ae6af2087e"}, + {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:741a46d58677d8c733175d7e5aa618d277cd9d880301a380fd296975a9cdd7bc"}, + {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e00e3505cd80440f6c98c6d69269dcc2a119f86ad0a9fd70bccc59504bebd68a"}, + {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ffe595f10566f8276b76dc3a11ae4bb7eba1aac8ddd75811736a15b0d5311414"}, + {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdfcf6443637c148c4e1a20c48c566aa694fa5e288d34b20fcdc58507882fed3"}, + {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d183cf9c797a5291e8301790ed6d053480ed94070637bfaad914dd38b0981f67"}, + {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:77abf6665ae54000b98b3c742bc6ea1d1fb31c394bcabf8b5d2c1ac3ebfe7f3b"}, + {file = "aiohttp-3.10.10-cp313-cp313-win32.whl", hash = "sha256:4470c73c12cd9109db8277287d11f9dd98f77fc54155fc71a7738a83ffcc8ea8"}, + {file = "aiohttp-3.10.10-cp313-cp313-win_amd64.whl", hash = "sha256:486f7aabfa292719a2753c016cc3a8f8172965cabb3ea2e7f7436c7f5a22a151"}, + {file = "aiohttp-3.10.10-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1b66ccafef7336a1e1f0e389901f60c1d920102315a56df85e49552308fc0486"}, + {file = "aiohttp-3.10.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:acd48d5b80ee80f9432a165c0ac8cbf9253eaddb6113269a5e18699b33958dbb"}, + {file = "aiohttp-3.10.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3455522392fb15ff549d92fbf4b73b559d5e43dc522588f7eb3e54c3f38beee7"}, + {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45c3b868724137f713a38376fef8120c166d1eadd50da1855c112fe97954aed8"}, + {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:da1dee8948d2137bb51fbb8a53cce6b1bcc86003c6b42565f008438b806cccd8"}, + {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5ce2ce7c997e1971b7184ee37deb6ea9922ef5163c6ee5aa3c274b05f9e12fa"}, + {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28529e08fde6f12eba8677f5a8608500ed33c086f974de68cc65ab218713a59d"}, + {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7db54c7914cc99d901d93a34704833568d86c20925b2762f9fa779f9cd2e70f"}, + {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:03a42ac7895406220124c88911ebee31ba8b2d24c98507f4a8bf826b2937c7f2"}, + {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:7e338c0523d024fad378b376a79faff37fafb3c001872a618cde1d322400a572"}, + {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:038f514fe39e235e9fef6717fbf944057bfa24f9b3db9ee551a7ecf584b5b480"}, + {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:64f6c17757251e2b8d885d728b6433d9d970573586a78b78ba8929b0f41d045a"}, + {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:93429602396f3383a797a2a70e5f1de5df8e35535d7806c9f91df06f297e109b"}, + {file = "aiohttp-3.10.10-cp38-cp38-win32.whl", hash = "sha256:c823bc3971c44ab93e611ab1a46b1eafeae474c0c844aff4b7474287b75fe49c"}, + {file = "aiohttp-3.10.10-cp38-cp38-win_amd64.whl", hash = "sha256:54ca74df1be3c7ca1cf7f4c971c79c2daf48d9aa65dea1a662ae18926f5bc8ce"}, + {file = "aiohttp-3.10.10-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:01948b1d570f83ee7bbf5a60ea2375a89dfb09fd419170e7f5af029510033d24"}, + {file = "aiohttp-3.10.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9fc1500fd2a952c5c8e3b29aaf7e3cc6e27e9cfc0a8819b3bce48cc1b849e4cc"}, + {file = "aiohttp-3.10.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f614ab0c76397661b90b6851a030004dac502e48260ea10f2441abd2207fbcc7"}, + {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00819de9e45d42584bed046314c40ea7e9aea95411b38971082cad449392b08c"}, + {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05646ebe6b94cc93407b3bf34b9eb26c20722384d068eb7339de802154d61bc5"}, + {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:998f3bd3cfc95e9424a6acd7840cbdd39e45bc09ef87533c006f94ac47296090"}, + {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9010c31cd6fa59438da4e58a7f19e4753f7f264300cd152e7f90d4602449762"}, + {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ea7ffc6d6d6f8a11e6f40091a1040995cdff02cfc9ba4c2f30a516cb2633554"}, + {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ef9c33cc5cbca35808f6c74be11eb7f5f6b14d2311be84a15b594bd3e58b5527"}, + {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ce0cdc074d540265bfeb31336e678b4e37316849d13b308607efa527e981f5c2"}, + {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:597a079284b7ee65ee102bc3a6ea226a37d2b96d0418cc9047490f231dc09fe8"}, + {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:7789050d9e5d0c309c706953e5e8876e38662d57d45f936902e176d19f1c58ab"}, + {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e7f8b04d83483577fd9200461b057c9f14ced334dcb053090cea1da9c8321a91"}, + {file = "aiohttp-3.10.10-cp39-cp39-win32.whl", hash = "sha256:c02a30b904282777d872266b87b20ed8cc0d1501855e27f831320f471d54d983"}, + {file = "aiohttp-3.10.10-cp39-cp39-win_amd64.whl", hash = "sha256:edfe3341033a6b53a5c522c802deb2079eee5cbfbb0af032a55064bd65c73a23"}, + {file = "aiohttp-3.10.10.tar.gz", hash = "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a"}, ] [package.dependencies] @@ -129,7 +129,7 @@ async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""} attrs = ">=17.3.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" -yarl = ">=1.0,<2.0" +yarl = ">=1.12.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] @@ -150,13 +150,13 @@ frozenlist = ">=1.1.0" [[package]] name = "alabaster" -version = "0.7.13" -description = "A configurable sidebar-enabled Sphinx theme" +version = "0.7.16" +description = "A light, configurable Sphinx theme" optional = false -python-versions = ">=3.6" +python-versions = ">=3.9" files = [ - {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, - {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, + {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, + {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, ] [[package]] @@ -170,9 +170,6 @@ files = [ {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} - [[package]] name = "appdirs" version = "1.4.4" @@ -243,7 +240,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = ">1", markers = "python_version <= \"3.8\""} pydantic = ">=2.0,<3.0.0" pydantic-settings = ">=2.0,<3.0.0" Sphinx = ">=4.0" @@ -267,120 +263,132 @@ files = [ {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, ] -[package.dependencies] -pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} - [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.0" 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.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"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, ] [[package]] @@ -396,83 +404,73 @@ files = [ [[package]] name = "coverage" -version = "7.6.1" +version = "7.6.2" description = "Code coverage measurement for Python" optional = false -python-versions = ">=3.8" -files = [ - {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, - {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, - {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, - {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, - {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, - {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, - {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, - {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, - {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, - {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, - {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, - {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, - {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, - {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, - {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, - {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, - {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, - {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, +python-versions = ">=3.9" +files = [ + {file = "coverage-7.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9df1950fb92d49970cce38100d7e7293c84ed3606eaa16ea0b6bc27175bb667"}, + {file = "coverage-7.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:24500f4b0e03aab60ce575c85365beab64b44d4db837021e08339f61d1fbfe52"}, + {file = "coverage-7.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a663b180b6669c400b4630a24cc776f23a992d38ce7ae72ede2a397ce6b0f170"}, + {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfde025e2793a22efe8c21f807d276bd1d6a4bcc5ba6f19dbdfc4e7a12160909"}, + {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:087932079c065d7b8ebadd3a0160656c55954144af6439886c8bcf78bbbcde7f"}, + {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9c6b0c1cafd96213a0327cf680acb39f70e452caf8e9a25aeb05316db9c07f89"}, + {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6e85830eed5b5263ffa0c62428e43cb844296f3b4461f09e4bdb0d44ec190bc2"}, + {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62ab4231c01e156ece1b3a187c87173f31cbeee83a5e1f6dff17f288dca93345"}, + {file = "coverage-7.6.2-cp310-cp310-win32.whl", hash = "sha256:7b80fbb0da3aebde102a37ef0138aeedff45997e22f8962e5f16ae1742852676"}, + {file = "coverage-7.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:d20c3d1f31f14d6962a4e2f549c21d31e670b90f777ef4171be540fb7fb70f02"}, + {file = "coverage-7.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb21bac7783c1bf6f4bbe68b1e0ff0d20e7e7732cfb7995bc8d96e23aa90fc7b"}, + {file = "coverage-7.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7b2e437fbd8fae5bc7716b9c7ff97aecc95f0b4d56e4ca08b3c8d8adcaadb84"}, + {file = "coverage-7.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:536f77f2bf5797983652d1d55f1a7272a29afcc89e3ae51caa99b2db4e89d658"}, + {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f361296ca7054f0936b02525646b2731b32c8074ba6defab524b79b2b7eeac72"}, + {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7926d8d034e06b479797c199747dd774d5e86179f2ce44294423327a88d66ca7"}, + {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0bbae11c138585c89fb4e991faefb174a80112e1a7557d507aaa07675c62e66b"}, + {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fcad7d5d2bbfeae1026b395036a8aa5abf67e8038ae7e6a25c7d0f88b10a8e6a"}, + {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f01e53575f27097d75d42de33b1b289c74b16891ce576d767ad8c48d17aeb5e0"}, + {file = "coverage-7.6.2-cp311-cp311-win32.whl", hash = "sha256:7781f4f70c9b0b39e1b129b10c7d43a4e0c91f90c60435e6da8288efc2b73438"}, + {file = "coverage-7.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:9bcd51eeca35a80e76dc5794a9dd7cb04b97f0e8af620d54711793bfc1fbba4b"}, + {file = "coverage-7.6.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ebc94fadbd4a3f4215993326a6a00e47d79889391f5659bf310f55fe5d9f581c"}, + {file = "coverage-7.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9681516288e3dcf0aa7c26231178cc0be6cac9705cac06709f2353c5b406cfea"}, + {file = "coverage-7.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d9c5d13927d77af4fbe453953810db766f75401e764727e73a6ee4f82527b3e"}, + {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b92f9ca04b3e719d69b02dc4a69debb795af84cb7afd09c5eb5d54b4a1ae2191"}, + {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ff2ef83d6d0b527b5c9dad73819b24a2f76fdddcfd6c4e7a4d7e73ecb0656b4"}, + {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:47ccb6e99a3031ffbbd6e7cc041e70770b4fe405370c66a54dbf26a500ded80b"}, + {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a867d26f06bcd047ef716175b2696b315cb7571ccb951006d61ca80bbc356e9e"}, + {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cdfcf2e914e2ba653101157458afd0ad92a16731eeba9a611b5cbb3e7124e74b"}, + {file = "coverage-7.6.2-cp312-cp312-win32.whl", hash = "sha256:f9035695dadfb397bee9eeaf1dc7fbeda483bf7664a7397a629846800ce6e276"}, + {file = "coverage-7.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:5ed69befa9a9fc796fe015a7040c9398722d6b97df73a6b608e9e275fa0932b0"}, + {file = "coverage-7.6.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4eea60c79d36a8f39475b1af887663bc3ae4f31289cd216f514ce18d5938df40"}, + {file = "coverage-7.6.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa68a6cdbe1bc6793a9dbfc38302c11599bbe1837392ae9b1d238b9ef3dafcf1"}, + {file = "coverage-7.6.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ec528ae69f0a139690fad6deac8a7d33629fa61ccce693fdd07ddf7e9931fba"}, + {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed5ac02126f74d190fa2cc14a9eb2a5d9837d5863920fa472b02eb1595cdc925"}, + {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21c0ea0d4db8a36b275cb6fb2437a3715697a4ba3cb7b918d3525cc75f726304"}, + {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:35a51598f29b2a19e26d0908bd196f771a9b1c5d9a07bf20be0adf28f1ad4f77"}, + {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c9192925acc33e146864b8cf037e2ed32a91fdf7644ae875f5d46cd2ef086a5f"}, + {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf4eeecc9e10f5403ec06138978235af79c9a79af494eb6b1d60a50b49ed2869"}, + {file = "coverage-7.6.2-cp313-cp313-win32.whl", hash = "sha256:e4ee15b267d2dad3e8759ca441ad450c334f3733304c55210c2a44516e8d5530"}, + {file = "coverage-7.6.2-cp313-cp313-win_amd64.whl", hash = "sha256:c71965d1ced48bf97aab79fad56df82c566b4c498ffc09c2094605727c4b7e36"}, + {file = "coverage-7.6.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7571e8bbecc6ac066256f9de40365ff833553e2e0c0c004f4482facb131820ef"}, + {file = "coverage-7.6.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:078a87519057dacb5d77e333f740708ec2a8f768655f1db07f8dfd28d7a005f0"}, + {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e5e92e3e84a8718d2de36cd8387459cba9a4508337b8c5f450ce42b87a9e760"}, + {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebabdf1c76593a09ee18c1a06cd3022919861365219ea3aca0247ededf6facd6"}, + {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12179eb0575b8900912711688e45474f04ab3934aaa7b624dea7b3c511ecc90f"}, + {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:39d3b964abfe1519b9d313ab28abf1d02faea26cd14b27f5283849bf59479ff5"}, + {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:84c4315577f7cd511d6250ffd0f695c825efe729f4205c0340f7004eda51191f"}, + {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ff797320dcbff57caa6b2301c3913784a010e13b1f6cf4ab3f563f3c5e7919db"}, + {file = "coverage-7.6.2-cp313-cp313t-win32.whl", hash = "sha256:2b636a301e53964550e2f3094484fa5a96e699db318d65398cfba438c5c92171"}, + {file = "coverage-7.6.2-cp313-cp313t-win_amd64.whl", hash = "sha256:d03a060ac1a08e10589c27d509bbdb35b65f2d7f3f8d81cf2fa199877c7bc58a"}, + {file = "coverage-7.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c37faddc8acd826cfc5e2392531aba734b229741d3daec7f4c777a8f0d4993e5"}, + {file = "coverage-7.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab31fdd643f162c467cfe6a86e9cb5f1965b632e5e65c072d90854ff486d02cf"}, + {file = "coverage-7.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97df87e1a20deb75ac7d920c812e9326096aa00a9a4b6d07679b4f1f14b06c90"}, + {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343056c5e0737487a5291f5691f4dfeb25b3e3c8699b4d36b92bb0e586219d14"}, + {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4ef1c56b47b6b9024b939d503ab487231df1f722065a48f4fc61832130b90e"}, + {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fca4a92c8a7a73dee6946471bce6d1443d94155694b893b79e19ca2a540d86e"}, + {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69f251804e052fc46d29d0e7348cdc5fcbfc4861dc4a1ebedef7e78d241ad39e"}, + {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e8ea055b3ea046c0f66217af65bc193bbbeca1c8661dc5fd42698db5795d2627"}, + {file = "coverage-7.6.2-cp39-cp39-win32.whl", hash = "sha256:6c2ba1e0c24d8fae8f2cf0aeb2fc0a2a7f69b6d20bd8d3749fd6b36ecef5edf0"}, + {file = "coverage-7.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:2186369a654a15628e9c1c9921409a6b3eda833e4b91f3ca2a7d9f77abb4987c"}, + {file = "coverage-7.6.2-pp39.pp310-none-any.whl", hash = "sha256:667952739daafe9616db19fbedbdb87917eee253ac4f31d70c7587f7ab531b4e"}, + {file = "coverage-7.6.2.tar.gz", hash = "sha256:a5f81e68aa62bc0cfca04f7b19eaa8f9c826b53fc82ab9e2121976dc74f131f3"}, ] [package.dependencies] @@ -621,15 +619,18 @@ files = [ [[package]] name = "idna" -version = "3.8" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" files = [ - {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, - {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "imagesize" version = "1.4.1" @@ -643,22 +644,26 @@ files = [ [[package]] name = "importlib-metadata" -version = "8.4.0" +version = "8.5.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"}, - {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"}, + {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, + {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, ] [package.dependencies] -zipp = ">=0.5" +zipp = ">=3.20" [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] perf = ["ipython"] -test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["pytest-mypy"] [[package]] name = "iniconfig" @@ -690,51 +695,49 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "libcst" -version = "1.1.0" -description = "A concrete syntax tree with AST-like properties for Python 3.5, 3.6, 3.7, 3.8, 3.9, and 3.10 programs." -optional = false -python-versions = ">=3.8" -files = [ - {file = "libcst-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:63f75656fd733dc20354c46253fde3cf155613e37643c3eaf6f8818e95b7a3d1"}, - {file = "libcst-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ae11eb1ea55a16dc0cdc61b41b29ac347da70fec14cc4381248e141ee2fbe6c"}, - {file = "libcst-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bc745d0c06420fe2644c28d6ddccea9474fb68a2135904043676deb4fa1e6bc"}, - {file = "libcst-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c1f2da45f1c45634090fd8672c15e0159fdc46853336686959b2d093b6e10fa"}, - {file = "libcst-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:003e5e83a12eed23542c4ea20fdc8de830887cc03662432bb36f84f8c4841b81"}, - {file = "libcst-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:3ebbb9732ae3cc4ae7a0e97890bed0a57c11d6df28790c2b9c869f7da653c7c7"}, - {file = "libcst-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d68c34e3038d3d1d6324eb47744cbf13f2c65e1214cf49db6ff2a6603c1cd838"}, - {file = "libcst-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9dffa1795c2804d183efb01c0f1efd20a7831db6a21a0311edf90b4100d67436"}, - {file = "libcst-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc9b6ac36d7ec9db2f053014ea488086ca2ed9c322be104fbe2c71ca759da4bb"}, - {file = "libcst-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b7a38ec4c1c009ac39027d51558b52851fb9234669ba5ba62283185963a31c"}, - {file = "libcst-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5297a16e575be8173185e936b7765c89a3ca69d4ae217a4af161814a0f9745a7"}, - {file = "libcst-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:7ccaf53925f81118aeaadb068a911fac8abaff608817d7343da280616a5ca9c1"}, - {file = "libcst-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:75816647736f7e09c6120bdbf408456f99b248d6272277eed9a58cf50fb8bc7d"}, - {file = "libcst-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c8f26250f87ca849a7303ed7a4fd6b2c7ac4dec16b7d7e68ca6a476d7c9bfcdb"}, - {file = "libcst-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d37326bd6f379c64190a28947a586b949de3a76be00176b0732c8ee87d67ebe"}, - {file = "libcst-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3d8cf974cfa2487b28f23f56c4bff90d550ef16505e58b0dca0493d5293784b"}, - {file = "libcst-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82d1271403509b0a4ee6ff7917c2d33b5a015f44d1e208abb1da06ba93b2a378"}, - {file = "libcst-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:bca1841693941fdd18371824bb19a9702d5784cd347cb8231317dbdc7062c5bc"}, - {file = "libcst-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f36f592e035ef84f312a12b75989dde6a5f6767fe99146cdae6a9ee9aff40dd0"}, - {file = "libcst-1.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f561c9a84eca18be92f4ad90aa9bd873111efbea995449301719a1a7805dbc5c"}, - {file = "libcst-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97fbc73c87e9040e148881041fd5ffa2a6ebf11f64b4ccb5b52e574b95df1a15"}, - {file = "libcst-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99fdc1929703fd9e7408aed2e03f58701c5280b05c8911753a8d8619f7dfdda5"}, - {file = "libcst-1.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bf69cbbab5016d938aac4d3ae70ba9ccb3f90363c588b3b97be434e6ba95403"}, - {file = "libcst-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:fe41b33aa73635b1651f64633f429f7aa21f86d2db5748659a99d9b7b1ed2a90"}, - {file = "libcst-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:73c086705ed34dbad16c62c9adca4249a556c1b022993d511da70ea85feaf669"}, - {file = "libcst-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3a07ecfabbbb8b93209f952a365549e65e658831e9231649f4f4e4263cad24b1"}, - {file = "libcst-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c653d9121d6572d8b7f8abf20f88b0a41aab77ff5a6a36e5a0ec0f19af0072e8"}, - {file = "libcst-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f1cd308a4c2f71d5e4eec6ee693819933a03b78edb2e4cc5e3ad1afd5fb3f07"}, - {file = "libcst-1.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8afb6101b8b3c86c5f9cec6b90ab4da16c3c236fe7396f88e8b93542bb341f7c"}, - {file = "libcst-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:d22d1abfe49aa60fc61fa867e10875a9b3024ba5a801112f4d7ba42d8d53242e"}, - {file = "libcst-1.1.0.tar.gz", hash = "sha256:0acbacb9a170455701845b7e940e2d7b9519db35a86768d86330a0b0deae1086"}, +version = "1.5.0" +description = "A concrete syntax tree with AST-like properties for Python 3.0 through 3.13 programs." +optional = false +python-versions = ">=3.9" +files = [ + {file = "libcst-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:23d0e07fd3ed11480f8993a1e99d58a45f914a711b14f858b8db08ae861a8a34"}, + {file = "libcst-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d92c5ae2e2dc9356ad7e3d05077d9b7e5065423e45788fd86729c88729e45c6e"}, + {file = "libcst-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96adc45e96476350df6b8a5ddbb1e1d6a83a7eb3f13087e52eb7cd2f9b65bcc7"}, + {file = "libcst-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d5978fd60c66794bb60d037b2e6427ea52d032636e84afce32b0f04e1cf500a"}, + {file = "libcst-1.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6502aeb11412afc759036160c686be1107eb5a4466db56b207c786b9b4da7c4"}, + {file = "libcst-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:9cccfc0a78e110c0d0a9d2c6fdeb29feb5274c9157508a8baef7edf352420f6d"}, + {file = "libcst-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:585b3aa705b3767d717d2100935d8ef557275ecdd3fac81c3e28db0959efb0ea"}, + {file = "libcst-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8935dd3393e30c2f97344866a4cb14efe560200e232166a8db1de7865c2ef8b2"}, + {file = "libcst-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc80ea16c7d44e38f193e4d4ef7ff1e0ba72d8e60e8b61ac6f4c87f070a118bd"}, + {file = "libcst-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02be4aab728261bb76d16e77c9a457884cebb60d09c8edee844de43b0e08aff7"}, + {file = "libcst-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8fcd78be4d9ce3c36d0c5d0bdd384e0c7d5f72970a9e4ebd56070141972b4ad"}, + {file = "libcst-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:52b6aadfe54e3ae52c3b815eaaa17ba4da9ff010d5e8adf6a70697872886dd10"}, + {file = "libcst-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:83bc5fbe34d33597af1d5ea113dcb9b5dd5afe5a5f4316bac4293464d5e3971a"}, + {file = "libcst-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f10124bf99a0b075eae136ef0ce06204e5f6b8da4596a9c4853a0663e80ddf3"}, + {file = "libcst-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48e581af6127c5af4c9f483e5986d94f0c6b2366967ee134f0a8eba0aa4c8c12"}, + {file = "libcst-1.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dba93cca0a5c6d771ed444c44d21ce8ea9b277af7036cea3743677aba9fbbb8"}, + {file = "libcst-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80b5c4d87721a7bab265c202575809b810815ab81d5e2e7a5d4417a087975840"}, + {file = "libcst-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:b48bf71d52c1e891a0948465a94d9817b5fc1ec1a09603566af90585f3b11948"}, + {file = "libcst-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:88520b6dea59eaea0cae80f77c0a632604a82c5b2d23dedb4b5b34035cbf1615"}, + {file = "libcst-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:208ea92d80b2eeed8cbc879d5f39f241582a5d56b916b1b65ed2be2f878a2425"}, + {file = "libcst-1.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4592872aaf5b7fa5c2727a7d73c0985261f1b3fe7eff51f4fd5b8174f30b4e2"}, + {file = "libcst-1.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2788b2b5838b78fe15df8e9fa6b6903195ea49b2d2ba43e8f423f6c90e4b69f"}, + {file = "libcst-1.5.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b5b5bcd3a9ba92840f27ad34eaa038acbee195ec337da39536c0a2efbbf28efd"}, + {file = "libcst-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:4d6acb0bdee1e55b44c6215c59755ec4693ac01e74bb1fde04c37358b378835d"}, + {file = "libcst-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6453b5a8755a6eee3ad67ee246f13a8eac9827d2cfc8e4a269e8bf0393db74bc"}, + {file = "libcst-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:40748361f4ea66ab6cdd82f8501c82c29808317ac7a3bd132074efd5fd9bfae2"}, + {file = "libcst-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f71aed85932c2ea92058fd9bbd99a6478bd69eada041c3726b4f4c9af1f564e"}, + {file = "libcst-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60b09abcc2848ab52d479c3a9b71b606d91a941e3779616efd083bb87dbe8ad"}, + {file = "libcst-1.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fb324ed20f3a725d152df5dba8d80f7e126d9c93cced581bf118a5fc18c1065"}, + {file = "libcst-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:99e7c52150a135d66716b03e00c7b1859a44336dc2a2bf8f9acc164494308531"}, + {file = "libcst-1.5.0.tar.gz", hash = "sha256:8478abf21ae3861a073e898d80b822bd56e578886331b33129ba77fec05b8c24"}, ] [package.dependencies] pyyaml = ">=5.2" -typing-extensions = ">=3.7.4.2" -typing-inspect = ">=0.4.0" [package.extras] -dev = ["Sphinx (>=5.1.1)", "black (==23.9.1)", "build (>=0.10.0)", "coverage (>=4.5.4)", "fixit (==2.0.0.post1)", "flake8 (>=3.7.8,<5)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "jinja2 (==3.1.2)", "jupyter (>=1.0.0)", "maturin (>=0.8.3,<0.16)", "nbsphinx (>=0.4.2)", "prompt-toolkit (>=2.0.9)", "pyre-check (==0.9.18)", "setuptools-rust (>=1.5.2)", "setuptools-scm (>=6.0.1)", "slotscheck (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "ufmt (==2.2.0)", "usort (==1.0.7)"] +dev = ["Sphinx (>=5.1.1)", "black (==24.8.0)", "build (>=0.10.0)", "coverage[toml] (>=4.5.4)", "fixit (==2.1.0)", "flake8 (==7.1.1)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "jinja2 (==3.1.4)", "jupyter (>=1.0.0)", "maturin (>=1.7.0,<1.8)", "nbsphinx (>=0.4.2)", "prompt-toolkit (>=2.0.9)", "pyre-check (==0.9.18)", "setuptools-rust (>=1.5.2)", "setuptools-scm (>=6.0.1)", "slotscheck (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "ufmt (==2.7.3)", "usort (==1.0.8.post1)"] [[package]] name = "lxml" @@ -892,71 +895,72 @@ source = ["Cython (>=3.0.11)"] [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.1" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" -files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +python-versions = ">=3.9" +files = [ + {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, + {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, ] [[package]] @@ -1183,6 +1187,113 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "propcache" +version = "0.2.0" +description = "Accelerated property cache" +optional = false +python-versions = ">=3.8" +files = [ + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, + {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, + {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, + {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, + {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, + {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, + {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, + {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, + {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, + {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, + {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, + {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, + {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, + {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, + {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, +] + [[package]] name = "pycodestyle" version = "2.12.1" @@ -1208,7 +1319,10 @@ files = [ [package.dependencies] annotated-types = ">=0.6.0" pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +typing-extensions = [ + {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, + {version = ">=4.6.1", markers = "python_version < \"3.13\""}, +] [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1476,17 +1590,6 @@ files = [ [package.extras] cli = ["click (>=5.0)"] -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - [[package]] name = "pyyaml" version = "6.0.2" @@ -1583,38 +1686,39 @@ files = [ [[package]] name = "sphinx" -version = "7.1.2" +version = "7.4.7" description = "Python documentation generator" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "sphinx-7.1.2-py3-none-any.whl", hash = "sha256:d170a81825b2fcacb6dfd5a0d7f578a053e45d3f2b153fecc948c37344eb4cbe"}, - {file = "sphinx-7.1.2.tar.gz", hash = "sha256:780f4d32f1d7d1126576e0e5ecc19dc32ab76cd24e950228dcf7b1f6d3d9e22f"}, + {file = "sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239"}, + {file = "sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe"}, ] [package.dependencies] -alabaster = ">=0.7,<0.8" -babel = ">=2.9" -colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.18.1,<0.21" +alabaster = ">=0.7.14,<0.8.0" +babel = ">=2.13" +colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} +docutils = ">=0.20,<0.22" imagesize = ">=1.3" -importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} -Jinja2 = ">=3.0" -packaging = ">=21.0" -Pygments = ">=2.13" -requests = ">=2.25.0" -snowballstemmer = ">=2.0" +importlib-metadata = {version = ">=6.0", markers = "python_version < \"3.10\""} +Jinja2 = ">=3.1" +packaging = ">=23.0" +Pygments = ">=2.17" +requests = ">=2.30.0" +snowballstemmer = ">=2.2" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" sphinxcontrib-htmlhelp = ">=2.0.0" sphinxcontrib-jsmath = "*" sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.5" +sphinxcontrib-serializinghtml = ">=1.1.9" +tomli = {version = ">=2", markers = "python_version < \"3.11\""} [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] -test = ["cython", "filelock", "html5lib", "pytest (>=4.6)"] +lint = ["flake8 (>=6.0)", "importlib-metadata (>=6.0)", "mypy (==1.10.1)", "pytest (>=6.0)", "ruff (==0.5.2)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-docutils (==0.21.0.20240711)", "types-requests (>=2.30.0)"] +test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] [[package]] name = "sphinx-rtd-theme" @@ -1637,47 +1741,50 @@ dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] [[package]] name = "sphinxcontrib-applehelp" -version = "1.0.4" +version = "2.0.0" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, - {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, + {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, + {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" -version = "1.0.2" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +version = "2.0.0" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, - {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, + {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, + {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.0.1" +version = "2.1.0" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, - {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, + {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, + {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] [[package]] @@ -1710,43 +1817,45 @@ test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" -version = "1.0.3" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +version = "2.0.0" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, - {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, + {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, + {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["defusedxml (>=0.7.1)", "pytest"] [[package]] name = "sphinxcontrib-serializinghtml" -version = "1.1.5" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +version = "2.0.0" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, - {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, + {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, + {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "termcolor" -version = "2.4.0" +version = "2.5.0" description = "ANSI color formatting for output in terminal" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "termcolor-2.4.0-py3-none-any.whl", hash = "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63"}, - {file = "termcolor-2.4.0.tar.gz", hash = "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a"}, + {file = "termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8"}, + {file = "termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f"}, ] [package.extras] @@ -1754,13 +1863,13 @@ tests = ["pytest", "pytest-cov"] [[package]] name = "tomli" -version = "2.0.1" +version = "2.0.2" description = "A lil' TOML parser" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, + {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, + {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, ] [[package]] @@ -1785,30 +1894,15 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] -[[package]] -name = "typing-inspect" -version = "0.9.0" -description = "Runtime inspection utilities for typing module." -optional = false -python-versions = "*" -files = [ - {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, - {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, -] - -[package.dependencies] -mypy-extensions = ">=0.3.0" -typing-extensions = ">=3.7.4" - [[package]] name = "urllib3" -version = "2.2.2" +version = "2.2.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, - {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, ] [package.extras] @@ -1819,13 +1913,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "voluptuous" -version = "0.14.2" +version = "0.15.2" description = "Python data validation library" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "voluptuous-0.14.2-py3-none-any.whl", hash = "sha256:efc1dadc9ae32a30cc622602c1400a17b7bf8ee2770d64f70418144860739c3b"}, - {file = "voluptuous-0.14.2.tar.gz", hash = "sha256:533e36175967a310f1b73170d091232bf881403e4ebe52a9b4ade8404d151f5d"}, + {file = "voluptuous-0.15.2-py3-none-any.whl", hash = "sha256:016348bc7788a9af9520b1764ebd4de0df41fe2138ebe9e06fa036bf86a65566"}, + {file = "voluptuous-0.15.2.tar.gz", hash = "sha256:6ffcab32c4d3230b4d2af3a577c87e1908a714a11f6f95570456b1849b0279aa"}, ] [[package]] @@ -1892,116 +1986,125 @@ test = ["gevent (>=20.6.2)"] [[package]] name = "yarl" -version = "1.9.4" +version = "1.15.0" description = "Yet another URL library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, - {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, - {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, - {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, - {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, - {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, - {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, - {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, - {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, - {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, - {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, - {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, - {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, - {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, - {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, - {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, - {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, - {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, + {file = "yarl-1.15.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e61b2019ebb5345510b833c4dd1f4afb1f0c07753f86f184c63836ffc3fb08ba"}, + {file = "yarl-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:25a4e29ee758596b2a0daffa4814714e9b464077ca862baf78ed0e8698e46b61"}, + {file = "yarl-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:928f7a61c4311f3dd003af19bb779f99683f97a0559b765c80fdb8846dab0452"}, + {file = "yarl-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4b25de7e85ba90b2ff230153123b6b000a7f69c41d84a3a0dc3f878334c8509"}, + {file = "yarl-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0127bc2ea72c1eaae6808ace661f0edf222f32ffa987d37f2dbb4798288f2656"}, + {file = "yarl-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2508ee2bad8381b5254eadc35d32fe800d12eb2c63b744183341f3a66e435a7"}, + {file = "yarl-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:748dcacc19c69957f7063ea4fb359fa2180735b1a638c81a4a96b86a382a6f29"}, + {file = "yarl-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4d9c221cc8e32b14196498679bf2b324bec1d1127c4ba934d98e19298faa661"}, + {file = "yarl-1.15.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:676d7356bb30825b7dbdad4fdd7a9feac379d074e5d4a36299767d72857ded42"}, + {file = "yarl-1.15.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:5eef9804e65eb292e9c5587e88fe6a27a11f121d358312ac47211e8f42876751"}, + {file = "yarl-1.15.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2bece7fdc13e23db005879b67190db0d397f6ba89c81dc7e3c77e9f5819aff7f"}, + {file = "yarl-1.15.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e1ddf05eeb422810b1aa919095db0691493442eebbf9cfb0f1e478a7b2fbdf3d"}, + {file = "yarl-1.15.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:85e273e59b8b1a5f60a89df82cddeaf918181abd7ae7a2f2f899b68b0c774ff1"}, + {file = "yarl-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d772ae3c12d3b8629db656050c86ee66924eaa98f7125a889175a59cfaafdb19"}, + {file = "yarl-1.15.0-cp310-cp310-win32.whl", hash = "sha256:4b1ab96a1ac91bd1233706d638ade35f663684deaa4e5e5f190858cba044afb9"}, + {file = "yarl-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:a2fe45c1143eefb680a4589c55e671fabd482a7f8c7791f311ea3bcc20139246"}, + {file = "yarl-1.15.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c8b034b60e74fb29064f765851e77e5910055e1c4a3cb75c32eccf2b470fc00f"}, + {file = "yarl-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:70ac7893e67a81ed1346ee3e71203ca4b0c3550c005b1d1cf87bc1e61eecd04b"}, + {file = "yarl-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6237637b496bc04819190e724a4e61ff2f251abf432f70cf491b3bc4a3f2f253"}, + {file = "yarl-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cc25cbd9ae01d49ac7b504ef5f3cbdcc8d139f9750dcfa0b80d405b4645cc2"}, + {file = "yarl-1.15.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4f882e42c6cea89488b9a16919edde8c0b1a98f307c05abdd3dd3bc4368af40"}, + {file = "yarl-1.15.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7711d83dafe52cda16ff2dd205cd83c05e4c06d5aaac596ae2cf7d50d094a530"}, + {file = "yarl-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3b08d9e98d1a15338fcfbd52c02003704322c2d460c9b9be7df08f2952bdce6"}, + {file = "yarl-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06040266b5e6512a37b4703684d1798124764b43328254799e9678c588882a6"}, + {file = "yarl-1.15.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97fcaf530318369da3cfd6ff52f5ab38daf8cb10ecee9a76efebf8031de09eef"}, + {file = "yarl-1.15.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:994d27b24b61b1870f3571395c840433faabec5dcd239bd11ff6af7e34234bb6"}, + {file = "yarl-1.15.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:18614630533ac37ec373bd8035aec8fa4dd9aedac641209c06de7e082622ff77"}, + {file = "yarl-1.15.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c9c405ca78c70c3599d8956e53be0c9def9c51ad949964a49ad96c79729a5b1a"}, + {file = "yarl-1.15.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4c5ff3e7609c214667c7d7e00d5f4f3576fefde47ebcb7e492c015117dafebbf"}, + {file = "yarl-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9fac5416c44e8e1d8ea9440096f88e1a7273257f3157184c5c715060e0c448a1"}, + {file = "yarl-1.15.0-cp311-cp311-win32.whl", hash = "sha256:a94c9058c5703c172904103d7b479f7e23dd4e5f8e67b49f6cd256d35ff169cb"}, + {file = "yarl-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:229f222bb47cd7ab225648efd1ae47fe6943f18e4c91bce66471faf09fe33128"}, + {file = "yarl-1.15.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9084d99933824ed8d665f10f4ce62d08fed714e7678d5ff11a8c2c98b2dc18f9"}, + {file = "yarl-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:df57f3c3ef760489f2e82192e6c93286c2bc80d6d854ef940e5345ae7153cd4b"}, + {file = "yarl-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6ca160b4c649f0d56daef04751eef4571de46ed4b80f9051a87d090fef32f08e"}, + {file = "yarl-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27c323b28723faed046f906c70466144c4dd12046a0128a301b29a65cfeff758"}, + {file = "yarl-1.15.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2eafb4e92f72a3b6c27f1d5e921d046e2728850af8887f86857c3fe868a5b5c0"}, + {file = "yarl-1.15.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:06306c74f0775621a70fa5acd292119bbb6961d1f9a5f3d657a4c8c15b86f7b9"}, + {file = "yarl-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f713d8f3c4e2eac0d91b741e8ef2e1082022de244685601ec83e899b445d86a"}, + {file = "yarl-1.15.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d816969b55a970b3accc7f9e4ea8f60043e3f7de96f21c06063d747ffc2f18ba"}, + {file = "yarl-1.15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e24a778470f3a9e9c11250d09daf5dea93369bc51aefca6605dbc963737a117"}, + {file = "yarl-1.15.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d3f5e201bd170fb97c643e84df58e221372cd053fbb291ebbd878b165ea5057e"}, + {file = "yarl-1.15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4424082edff76fe46ff08851e91865097c0ad780fa79b87063dc5d5b80efc9d6"}, + {file = "yarl-1.15.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:350b468a217d433cbb4482e9414a14dfd360a3d5ab92013175925abb234364cc"}, + {file = "yarl-1.15.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c7f2deac59dc3e0528bdded248e637e789e5111ba1723a8d7a262eb93e133e15"}, + {file = "yarl-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2429a651a2191c3fb8c9de21546c6046da539034d51dcb8df52302748004593d"}, + {file = "yarl-1.15.0-cp312-cp312-win32.whl", hash = "sha256:e4f7efb38331e8327c1cc7fb2a2905a7db03d1a7fdb04706bf6465d0e44d41d4"}, + {file = "yarl-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:9ae454916aa3abe28d0ef1c21ca1e8e36a14ccf52183d465dfaccffaa7ed462c"}, + {file = "yarl-1.15.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a3f8be3e785009ffa148e66474fea5c787ccb203b3d0bd1f22e1e22f7da0f3b3"}, + {file = "yarl-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8b7f902f13a230686f01bcff17cd9ba045653069811c8fd5027f0f414b417e2f"}, + {file = "yarl-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:627bb5bc4ed3d3ebceb9fb55717cec6cd58bb47fdb5669169ebbc248e9bf156c"}, + {file = "yarl-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1208f2e081d34832f509cbe311237a0543effe23d60b2fa14c0d3f86e6d1d07"}, + {file = "yarl-1.15.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c791a2d42da20ac568e5c0cc9b8af313188becd203a936ad959b578dafbcebb"}, + {file = "yarl-1.15.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd042e6c3bf36448e3e3ed302b12ce79762480f4aff8e7a167cdf8c35dc93297"}, + {file = "yarl-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eae041f535fe2e57681954f7cccb81854d777ce4c2a87749428ebe6c71c02ec0"}, + {file = "yarl-1.15.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:454707fb16f180984da6338d1f51897f0b8d8c4c2e0592d9d1e9fa02a5bb8218"}, + {file = "yarl-1.15.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6960b0d2e713e726cb2914e3051e080b12412f70dcb8731cf7a8fb52c37931bb"}, + {file = "yarl-1.15.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c9b9159eeeb7cd1c7131dc7f5878454f97a4dc20cd157e6474174ccac448b844"}, + {file = "yarl-1.15.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fee9acd5e39c8611957074dfba06552e430020eea831caf5eb2cea30f10e06bd"}, + {file = "yarl-1.15.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ddea4abc4606c10dddb70651b210b7ab5b663148d6d7bc85d76963c923629891"}, + {file = "yarl-1.15.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:2add8ed2acf42398dfaa7dffd32e4d18ffbae341d62c8d4765bd9929336379b5"}, + {file = "yarl-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:32840ff92c713053591ff0e66845d4e9f4bea8fd5fba3da00f8d92e77722f24e"}, + {file = "yarl-1.15.0-cp313-cp313-win32.whl", hash = "sha256:eb964d18c01b7a1263a6f07b88d63711fcd564fc429d934279cf12f4b467bf53"}, + {file = "yarl-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:ceb200918c9bd163bd390cc169b254b23b4be121026b003be93a4f2f5b554b4b"}, + {file = "yarl-1.15.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:83363a5789f128618041b9a737c7b146f1965abddf4294b0444591406b437c1e"}, + {file = "yarl-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2124c642b8cc9b68e5981e429842dadc32bb850b010cccec9d24236253a19f60"}, + {file = "yarl-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5107d89c9edec6ee077970a95fb9eeb4776ea8c2337b6a39c0ade9a58f50f3e4"}, + {file = "yarl-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33896afca6fb4e1988c099534c52823870dfc8730bc6f96a3831f24c1e0ab814"}, + {file = "yarl-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4224bbbc8a2e9b9a3828d36c1bab7458441d7fb9fb3af321eb735732ba8ee89d"}, + {file = "yarl-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1edaf4171fc1582352ac5d9b2783966fa0f4ff86187279ef2a491613d23b894a"}, + {file = "yarl-1.15.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73c4af08e9bb9a9aa7df6c789b05b924b9a0c6a368bb0e418d0b85181b64b631"}, + {file = "yarl-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4aa7cca009817789fd5b8e52e8122f9e85dc580c88b816a93321c00a8acbced"}, + {file = "yarl-1.15.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:c0a86dd3e85c6aa3fc73236eb5cf7ce69dd8ad7abcd23f8ae1126831c8e40c2f"}, + {file = "yarl-1.15.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:db903458a457a53ee0f764ed11c5b5368398e216b442c42dca9d90fbd2bbf31c"}, + {file = "yarl-1.15.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:8f074a24aa9a6a3d406474ec889ebb5d661f329349068e05e8dfcb3c4be67752"}, + {file = "yarl-1.15.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:dc63bb79e896d6ce6aaf672ac304b54969280e949c45727867fc154a17ec7ab2"}, + {file = "yarl-1.15.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:ef780f9d480ffb423380abeb4cfcad66ecb8f93526dfa367d322fdad9ec7c25f"}, + {file = "yarl-1.15.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:e7e38bf6e52797084c5c396db5bb519615727e491e9003e2449631457bf77738"}, + {file = "yarl-1.15.0-cp38-cp38-win32.whl", hash = "sha256:d885dcdca7bae42bc9a2f6cbf766abcb2a6cc043b1905fc3782c6ea1f74a2b95"}, + {file = "yarl-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:e4f64c8c52dde564bf3251b41d7a6746564b0fc0516cebe9c9e6695224440d22"}, + {file = "yarl-1.15.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5156c12a97405339ec93facbc7860566db381af2de1bec338195563fb64f37ef"}, + {file = "yarl-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1e5fa4c4e55cdacef1844f609bc9a02c8cd29c324a71ca1d3ee454701d4bb496"}, + {file = "yarl-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e1cc7823f43781390965c4762b54262cfcf76b6f152e489d00a5a1ac63063e4"}, + {file = "yarl-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38cab8f91b1085f1fd0765d40c46c8f43282f109018d5fcd017c46ac3eaba0cf"}, + {file = "yarl-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbe72c41cdd55c88b238a8925849fde4069c0cdcdef83f8d967f8f3982659326"}, + {file = "yarl-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0358b697abdf1f2d68038bd02ef8ddcc4813835744f79c755f8743aa485585e7"}, + {file = "yarl-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b93a666cd8cfd43f605d1b81a32b9e290bf45c74c2bfd51ba705449c78448c7"}, + {file = "yarl-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81edbd9bf9f25cd995e6d51c307e1d279587d40b7473e258fef6d5e548560cd2"}, + {file = "yarl-1.15.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad2e487824ba4cda87851a371139e255410e45d3bf2e334194789278d709cec"}, + {file = "yarl-1.15.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:553a1e3537aeeb29c0eb29ef28b80e0e801697fa71d96ac60675b284ff8e582a"}, + {file = "yarl-1.15.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:06b5b462cadf59c1df28ffbb0a3971fa16b60cf0c9d59a38bf5679a986d18685"}, + {file = "yarl-1.15.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:097094a979af7b31520517c59179f6817b8426724343cecbec0eb3af1f8fb6cf"}, + {file = "yarl-1.15.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:75d9762f65205a86381298eb9079f27c60b84de0c262e402dcf45c6cbc385234"}, + {file = "yarl-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e2e3cb74684ff357e6b3c82dd71031d3c1fd7ee9f9b0a5205e5568c963e074f9"}, + {file = "yarl-1.15.0-cp39-cp39-win32.whl", hash = "sha256:a616c2e4b60cb8cdd9eb3b0c6fda4ab5f3e26244b427aaade560dcf63c5754fb"}, + {file = "yarl-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:7aa9f9af452c3e8486a0b88fddd58352e6cea17b691b18861d26e46cf65ffff0"}, + {file = "yarl-1.15.0-py3-none-any.whl", hash = "sha256:1656a8b531a96427f26f498b7d0f19931166ff30e4344eca99bdb27faca14fc5"}, + {file = "yarl-1.15.0.tar.gz", hash = "sha256:efc0430b80ed834c80c99c32946cfc6ee29dfcd7c62ad3c8f15657322ade7942"}, ] [package.dependencies] idna = ">=2.0" multidict = ">=4.0" +propcache = ">=0.2.0" [[package]] name = "zipp" -version = "3.20.1" +version = "3.20.2" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"}, - {file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"}, + {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, + {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, ] [package.extras] @@ -2014,5 +2117,5 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" -python-versions = ">=3.8,<3.13" -content-hash = "94915b4125b3fb276a945493c5519683180221566db963c53d6172dcedba3b09" +python-versions = ">=3.9,<3.14" +content-hash = "6d26825471d0fc9f88e5c53ae685b8c017314be5554837f034859687c5468882" diff --git a/pyproject.toml b/pyproject.toml index c475cbd2..1e2ceac3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,16 +11,16 @@ packages = [{include = "aioslsk", from = "src"}] keywords = ["soulseek", "p2p", "async"] classifiers = [ "Development Status :: 4 - Beta", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Communications :: File Sharing" ] [tool.poetry.dependencies] -python = ">=3.8,<3.13" +python = ">=3.9,<3.14" mutagen = "^1.47.0" aiofiles = ">=22.1,<25.0" async-upnp-client = ">=0.33,<0.42" @@ -31,7 +31,7 @@ typing-extensions = "^4.12.2" multidict = "^6.0.5" [tool.poetry.group.dev.dependencies] -flake8 = { version = ">=6,<8", python = ">=3.8.1,<3.13" } +flake8 = { version = ">=6,<8", python = ">=3.9.1,<3.14" } mypy = "^1.11.2" no-implicit-optional = "^1.4" pytest = ">=7.4.2,<9.0.0" @@ -40,7 +40,7 @@ pytest-unordered = ">=0.5.2,<0.7.0" pytest-asyncio = ">=0.21.1,<0.25.0" sphinx = "^7.0.0" sphinx-rtd-theme = "^2.0.0" -autodoc-pydantic = { version = "^2.2.0", python = ">=3.8.1,<3.13" } +autodoc-pydantic = { version = "^2.2.0", python = ">=3.9.1,<3.14" } [tool.poetry.group.tools] optional = true diff --git a/src/aioslsk/base_manager.py b/src/aioslsk/base_manager.py index ee82b5dd..8517133d 100644 --- a/src/aioslsk/base_manager.py +++ b/src/aioslsk/base_manager.py @@ -1,6 +1,5 @@ from abc import ABC import asyncio -from typing import List class BaseManager(ABC): @@ -23,7 +22,7 @@ async def start(self): loading the data but before connecting """ - async def stop(self) -> List[asyncio.Task]: + async def stop(self) -> list[asyncio.Task]: """Cancel all running tasks. The implementation of this method should simply cancel the task and return, the code calling this method should be responsible for awaiting the cancellation diff --git a/src/aioslsk/client.py b/src/aioslsk/client.py index 0839ffa5..8fa8defa 100644 --- a/src/aioslsk/client.py +++ b/src/aioslsk/client.py @@ -2,7 +2,7 @@ import asyncio from async_timeout import timeout as atimeout import logging -from typing import List, Optional +from typing import Optional from .base_manager import BaseManager from .commands import BaseCommand, RC, RT @@ -82,7 +82,7 @@ def __init__( self.searches: SearchManager = self.create_search_manager() self.server_manager: ServerManager = self.create_server_manager() - self.services: List[BaseManager] = [ + self.services: list[BaseManager] = [ self.users, self.rooms, self.interests, diff --git a/src/aioslsk/commands.py b/src/aioslsk/commands.py index 5c6307cc..dcf217f8 100644 --- a/src/aioslsk/commands.py +++ b/src/aioslsk/commands.py @@ -3,11 +3,9 @@ import time from typing import ( Generic, - List, NamedTuple, Optional, Union, - Tuple, TypeVar, TYPE_CHECKING, ) @@ -77,9 +75,9 @@ RT = TypeVar('RT') """Response value type""" -Recommendations = Tuple[List[Recommendation], List[Recommendation]] -UserInterests = Tuple[List[str], List[str]] -SharesReply = Tuple[List[DirectoryData], List[DirectoryData]] +Recommendations = tuple[list[Recommendation], list[Recommendation]] +UserInterests = tuple[list[str], list[str]] +SharesReply = tuple[list[DirectoryData], list[DirectoryData]] class UserStatusInfo(NamedTuple): @@ -171,7 +169,7 @@ def handle_response(self, client: SoulSeekClient, response: GetUserStats.Respons ) -class GetRoomListCommand(BaseCommand[RoomList.Response, List[Room]]): +class GetRoomListCommand(BaseCommand[RoomList.Response, list[Room]]): async def send(self, client: SoulSeekClient): await client.network.send_server_messages( @@ -184,7 +182,7 @@ def build_expected_response(self, client: SoulSeekClient) -> Optional[ExpectedRe RoomList.Response ) - def handle_response(self, client: SoulSeekClient, response: RoomList.Response) -> List[Room]: + def handle_response(self, client: SoulSeekClient, response: RoomList.Response) -> list[Room]: return [ room for name, room in client.rooms.rooms.items() if name in response.rooms @@ -238,7 +236,7 @@ def handle_response(self, client: SoulSeekClient, response: LeaveRoom.Response) return client.rooms.get_or_create_room(response.room) -class GrantRoomMembershipCommand(BaseCommand[PrivateRoomGrantMembership.Response, Tuple[Room, User]]): +class GrantRoomMembershipCommand(BaseCommand[PrivateRoomGrantMembership.Response, tuple[Room, User]]): def __init__(self, room: str, username: str): self.room: str = room @@ -260,14 +258,14 @@ def build_expected_response(self, client: SoulSeekClient) -> Optional[ExpectedRe ) def handle_response( - self, client: SoulSeekClient, response: PrivateRoomGrantMembership.Response) -> Tuple[Room, User]: + self, client: SoulSeekClient, response: PrivateRoomGrantMembership.Response) -> tuple[Room, User]: return ( client.rooms.get_or_create_room(response.room), client.users.get_user_object(response.username) ) -class RevokeRoomMembershipCommand(BaseCommand[PrivateRoomRevokeMembership.Response, Tuple[Room, User]]): +class RevokeRoomMembershipCommand(BaseCommand[PrivateRoomRevokeMembership.Response, tuple[Room, User]]): def __init__(self, room: str, username: str): self.room: str = room @@ -289,7 +287,7 @@ def build_expected_response(self, client: SoulSeekClient) -> Optional[ExpectedRe ) def handle_response( - self, client: SoulSeekClient, response: PrivateRoomRevokeMembership.Response) -> Tuple[Room, User]: + self, client: SoulSeekClient, response: PrivateRoomRevokeMembership.Response) -> tuple[Room, User]: return ( client.rooms.get_or_create_room(response.room), client.users.get_user_object(response.username) @@ -329,7 +327,7 @@ async def send(self, client: SoulSeekClient): ) -class GetItemRecommendationsCommand(BaseCommand[GetItemRecommendations.Response, List[Recommendation]]): +class GetItemRecommendationsCommand(BaseCommand[GetItemRecommendations.Response, list[Recommendation]]): def __init__(self, item: str): self.item: str = item @@ -349,7 +347,7 @@ def build_expected_response(self, client: SoulSeekClient) -> Optional[ExpectedRe ) def handle_response( - self, client: SoulSeekClient, response: GetItemRecommendations.Response) -> List[Recommendation]: + self, client: SoulSeekClient, response: GetItemRecommendations.Response) -> list[Recommendation]: return response.recommendations @@ -387,7 +385,7 @@ def handle_response(self, client: SoulSeekClient, response: GetGlobalRecommendat return response.recommendations, response.unrecommendations -class GetItemSimilarUsersCommand(BaseCommand[GetItemSimilarUsers.Response, List[User]]): +class GetItemSimilarUsersCommand(BaseCommand[GetItemSimilarUsers.Response, list[User]]): def __init__(self, item: str): self.item: str = item @@ -406,11 +404,11 @@ def build_expected_response(self, client: SoulSeekClient) -> Optional[ExpectedRe } ) - def handle_response(self, client: SoulSeekClient, response: GetItemSimilarUsers.Response) -> List[User]: + def handle_response(self, client: SoulSeekClient, response: GetItemSimilarUsers.Response) -> list[User]: return list(map(client.users.get_user_object, response.usernames)) -class GetSimilarUsersCommand(BaseCommand[GetSimilarUsers.Response, List[Tuple[User, int]]]): +class GetSimilarUsersCommand(BaseCommand[GetSimilarUsers.Response, list[tuple[User, int]]]): async def send(self, client: SoulSeekClient): await client.network.send_server_messages( @@ -423,7 +421,7 @@ def build_expected_response(self, client: SoulSeekClient) -> Optional[ExpectedRe GetSimilarUsers.Response ) - def handle_response(self, client: SoulSeekClient, response: GetSimilarUsers.Response) -> List[Tuple[User, int]]: + def handle_response(self, client: SoulSeekClient, response: GetSimilarUsers.Response) -> list[tuple[User, int]]: similar_users = [] for similar_user in response.users: similar_users.append( @@ -436,7 +434,7 @@ def handle_response(self, client: SoulSeekClient, response: GetSimilarUsers.Resp return similar_users -class GetPeerAddressCommand(BaseCommand[GetPeerAddress.Response, Tuple[str, int, Optional[int]]]): +class GetPeerAddressCommand(BaseCommand[GetPeerAddress.Response, tuple[str, int, Optional[int]]]): def __init__(self, username: str): self.username: str = username @@ -456,7 +454,7 @@ def build_expected_response(self, client: SoulSeekClient) -> Optional[ExpectedRe ) def handle_response( - self, client: SoulSeekClient, response: GetPeerAddress.Response) -> Tuple[str, int, Optional[int]]: + self, client: SoulSeekClient, response: GetPeerAddress.Response) -> tuple[str, int, Optional[int]]: return (response.ip, response.port, response.obfuscated_port) @@ -633,8 +631,8 @@ async def send(self, client: SoulSeekClient): class PrivateMessageUsersCommand(BaseCommand[None, None]): """Sends a private message to multiple users""" - def __init__(self, usernames: List[str], message: str): - self.usernames: List[str] = usernames + def __init__(self, usernames: list[str], message: str): + self.usernames: list[str] = usernames self.message: str = message async def send(self, client: SoulSeekClient): @@ -926,7 +924,7 @@ def handle_response( return response.directories, locked_dirs -class PeerGetDirectoryContentCommand(BaseCommand[PeerDirectoryContentsReply.Request, List[DirectoryData]]): +class PeerGetDirectoryContentCommand(BaseCommand[PeerDirectoryContentsReply.Request, list[DirectoryData]]): def __init__(self, username: str, directory: str): self.username: str = username @@ -951,5 +949,5 @@ def build_expected_response(self, client: SoulSeekClient) -> Optional[ExpectedRe ) def handle_response( - self, client: SoulSeekClient, response: PeerDirectoryContentsReply.Request) -> List[DirectoryData]: + self, client: SoulSeekClient, response: PeerDirectoryContentsReply.Request) -> list[DirectoryData]: return response.directories diff --git a/src/aioslsk/constants.py b/src/aioslsk/constants.py index 90736103..b1c4724b 100644 --- a/src/aioslsk/constants.py +++ b/src/aioslsk/constants.py @@ -1,5 +1,4 @@ import re -from typing import List DEFAULT_LISTENING_HOST: str = '0.0.0.0' @@ -28,7 +27,7 @@ UPNP_DEFAULT_CHECK_INTERVAL: int = 600 UPNP_DEFAULT_LEASE_DURATION: int = 6 * 60 * 60 UPNP_DEFAULT_SEARCH_TIMEOUT: int = 10 -UPNP_MAPPING_SERVICES: List[str] = ["WANIPC", "WANPPP"] +UPNP_MAPPING_SERVICES: list[str] = ["WANIPC", "WANPPP"] POTENTIAL_PARENTS_CACHE_SIZE: int = 20 """Maximum amount of potential parents stored""" DEFAULT_COMMAND_TIMEOUT: float = 10 diff --git a/src/aioslsk/distributed.py b/src/aioslsk/distributed.py index fd83cd03..0dfb004b 100644 --- a/src/aioslsk/distributed.py +++ b/src/aioslsk/distributed.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from functools import partial import logging -from typing import Deque, List, Optional, Union, Tuple +from typing import Optional, Union from .base_manager import BaseManager from .constants import ( @@ -86,10 +86,10 @@ def __init__(self, settings: Settings, event_bus: EventBus, network: Network): """Distributed parent. This variable is `None` if we are looking for a parent """ - self.children: List[DistributedPeer] = [] - self.potential_parents: Deque[str] = deque( + self.children: list[DistributedPeer] = [] + self.potential_parents: deque[str] = deque( maxlen=POTENTIAL_PARENTS_CACHE_SIZE) - self.distributed_peers: List[DistributedPeer] = [] + self.distributed_peers: list[DistributedPeer] = [] # State parameters sent by the server self.parent_min_speed: Optional[int] = None @@ -104,7 +104,7 @@ def __init__(self, settings: Settings, event_bus: EventBus, network: Network): self.register_listeners() - self._potential_parent_tasks: List[asyncio.Task] = [] + self._potential_parent_tasks: list[asyncio.Task] = [] def register_listeners(self): self._event_bus.register( @@ -118,7 +118,7 @@ def register_listeners(self): self._event_bus.register( SessionDestroyedEvent, self._on_session_destroyed) - def _get_advertised_branch_values(self) -> Tuple[str, int]: + def _get_advertised_branch_values(self) -> tuple[str, int]: """Returns the advertised branch values. These values are to be sent to the children and the server to let them know where we are in the distributed tree. @@ -634,7 +634,7 @@ async def send_messages_to_children(self, *messages: Union[MessageDataclass, byt if child.connection: child.connection.queue_messages(*messages) - async def stop(self) -> List[asyncio.Task]: + async def stop(self) -> list[asyncio.Task]: """Cancels all pending tasks :return: a list of tasks that have been cancelled so that they can be @@ -642,7 +642,7 @@ async def stop(self) -> List[asyncio.Task]: """ return self._cancel_potential_parent_tasks() - def _cancel_potential_parent_tasks(self) -> List[asyncio.Task]: + def _cancel_potential_parent_tasks(self) -> list[asyncio.Task]: cancelled_tasks = [] for task in self._potential_parent_tasks: diff --git a/src/aioslsk/events.py b/src/aioslsk/events.py index 6dd75872..ac09dd67 100644 --- a/src/aioslsk/events.py +++ b/src/aioslsk/events.py @@ -1,21 +1,10 @@ from __future__ import annotations import asyncio +from collections.abc import Callable, Coroutine from dataclasses import dataclass import inspect import logging -from typing import ( - Any, - Callable, - Coroutine, - Dict, - List, - Optional, - Tuple, - Type, - TypeVar, - TYPE_CHECKING, - Union -) +from typing import Any, Optional, TypeVar, TYPE_CHECKING, Union from .room.model import Room, RoomMessage from .user.model import ChatMessage, User @@ -91,7 +80,7 @@ # Internal functions -def on_message(message_class: Type[MessageDataclass]): +def on_message(message_class: type[MessageDataclass]): """Decorator for methods listening to specific `MessageData` events""" def register(event_func): event_func._registered_message = message_class @@ -100,9 +89,9 @@ def register(event_func): return register -def build_message_map(obj: object) -> Dict[Type[MessageDataclass], Callable]: +def build_message_map(obj: object) -> dict[type[MessageDataclass], Callable]: methods = inspect.getmembers(obj, predicate=inspect.ismethod) - mapping: Dict[Type[MessageDataclass], Callable] = {} + mapping: dict[type[MessageDataclass], Callable] = {} for _, method in methods: registered_message = getattr(method, '_registered_message', None) if registered_message: @@ -115,9 +104,9 @@ def build_message_map(obj: object) -> Dict[Type[MessageDataclass], Callable]: class EventBus: def __init__(self): - self._events: Dict[Type[Event], List[Tuple[int, EventListener]]] = {} + self._events: dict[type[Event], list[tuple[int, EventListener]]] = {} - def register(self, event_class: Type[E], listener: EventListener, priority: int = 100): + def register(self, event_class: type[E], listener: EventListener, priority: int = 100): """Registers an event listener to listen on an event class. The order in which the listeners are called can be managed using the ``priority`` parameter @@ -238,7 +227,7 @@ class UserInfoUpdateEvent(Event): @dataclass(frozen=True) class RoomListEvent(Event): - rooms: List[Room] + rooms: list[Room] raw_message: RoomList.Response @@ -252,7 +241,7 @@ class RoomMessageEvent(Event): class RoomTickersEvent(Event): """Emitted when a list of tickers has been received for a room""" room: Room - tickers: Dict[str, str] + tickers: dict[str, str] raw_message: RoomTickers.Response @@ -348,7 +337,7 @@ class RoomOperatorRevokedEvent(Event): class RoomOperatorsEvent(Event): """Emitted when the server sends us a list of operators in a room""" room: Room - operators: List[User] + operators: list[User] raw_message: PrivateRoomOperators.Response @@ -358,7 +347,7 @@ class RoomMembersEvent(Event): of members always excludes the owner of the room """ room: Room - members: List[User] + members: list[User] raw_message: PrivateRoomMembers.Response @@ -410,50 +399,50 @@ class SearchRequestReceivedEvent(Event): @dataclass(frozen=True) class SimilarUsersEvent(Event): - users: List[Tuple[User, int]] + users: list[tuple[User, int]] raw_message: GetSimilarUsers.Response @dataclass(frozen=True) class ItemSimilarUsersEvent(Event): item: str - users: List[User] + users: list[User] raw_message: GetItemSimilarUsers.Response @dataclass(frozen=True) class RecommendationsEvent(Event): - recommendations: List[Recommendation] - unrecommendations: List[Recommendation] + recommendations: list[Recommendation] + unrecommendations: list[Recommendation] raw_message: GetRecommendations.Response @dataclass(frozen=True) class GlobalRecommendationsEvent(Event): - recommendations: List[Recommendation] - unrecommendations: List[Recommendation] + recommendations: list[Recommendation] + unrecommendations: list[Recommendation] raw_message: GetGlobalRecommendations.Response @dataclass(frozen=True) class ItemRecommendationsEvent(Event): item: str - recommendations: List[Recommendation] + recommendations: list[Recommendation] raw_message: GetItemRecommendations.Response @dataclass(frozen=True) class UserInterestsEvent(Event): user: User - interests: List[str] - hated_interests: List[str] + interests: list[str] + hated_interests: list[str] raw_message: GetUserInterests.Response @dataclass(frozen=True) class PrivilegedUsersEvent(Event): """Emitted when the list of privileged users has been received""" - users: List[User] + users: list[User] raw_message: PrivilegedUsers.Response @@ -478,8 +467,8 @@ class PrivilegesUpdateEvent(Event): @dataclass(frozen=True) class UserSharesReplyEvent(Event): user: User - directories: List[DirectoryData] - locked_directories: List[DirectoryData] + directories: list[DirectoryData] + locked_directories: list[DirectoryData] raw_message: PeerSharesReply.Request @@ -487,7 +476,7 @@ class UserSharesReplyEvent(Event): class UserDirectoryEvent(Event): user: User directory: str - directories: List[DirectoryData] + directories: list[DirectoryData] raw_message: PeerDirectoryContentsReply.Request @@ -514,7 +503,7 @@ class TransferProgressEvent(Event): since the previous event. If there are no updates the event will no be called """ - updates: List[Tuple[Transfer, TransferProgressSnapshot, TransferProgressSnapshot]] + updates: list[tuple[Transfer, TransferProgressSnapshot, TransferProgressSnapshot]] """List of progress updates: transfer instance, previous snapshot, current snapshot """ diff --git a/src/aioslsk/log_utils.py b/src/aioslsk/log_utils.py index 716a4f08..029a3717 100644 --- a/src/aioslsk/log_utils.py +++ b/src/aioslsk/log_utils.py @@ -1,11 +1,12 @@ +from collections.abc import Collection import logging -from typing import Collection, Type, Union +from typing import Union from .exceptions import AioSlskException from .protocol.primitives import MessageDataclass from .protocol import messages -def resolve(message_class: str) -> Type[MessageDataclass]: +def resolve(message_class: str) -> type[MessageDataclass]: message_root, req_resp = message_class.split('.') if root_message := getattr(messages, message_root, None): @@ -22,7 +23,7 @@ def resolve(message_class: str) -> Type[MessageDataclass]: class MessageFilter(logging.Filter): """Logging filter for protocol messages""" - def __init__(self, message_types: Collection[Union[Type[MessageDataclass], str]]): + def __init__(self, message_types: Collection[Union[type[MessageDataclass], str]]): super().__init__() converted = [] for message_type in message_types: @@ -32,7 +33,7 @@ def __init__(self, message_types: Collection[Union[Type[MessageDataclass], str]] mtype = message_type converted.append(mtype) - self.message_types: Collection[Type[MessageDataclass]] = converted + self.message_types: Collection[type[MessageDataclass]] = converted def filter(self, record: logging.LogRecord) -> bool: if message_type := getattr(record, 'message_type', None): diff --git a/src/aioslsk/naming.py b/src/aioslsk/naming.py index afbfec8e..9ee05a18 100644 --- a/src/aioslsk/naming.py +++ b/src/aioslsk/naming.py @@ -1,6 +1,5 @@ import os import re -from typing import List, Tuple from .utils import split_remote_path @@ -11,7 +10,7 @@ class NamingStrategy: def should_be_applied(self, local_dir: str, local_filename: str) -> bool: return True - def apply(self, remote_path: str, local_dir: str, local_filename: str) -> Tuple[str, str]: + def apply(self, remote_path: str, local_dir: str, local_filename: str) -> tuple[str, str]: """Apply the naming changes :param remote_path: the original remote path @@ -28,14 +27,14 @@ class DefaultNamingStrategy(NamingStrategy): `remote_path` parameter. The `local_filename` parameter is ignored """ - def apply(self, remote_path: str, local_dir: str, local_filename: str) -> Tuple[str, str]: + def apply(self, remote_path: str, local_dir: str, local_filename: str) -> tuple[str, str]: return local_dir, split_remote_path(remote_path)[-1] class KeepDirectoryStrategy(NamingStrategy): """Keeps the original directory the remote file was in""" - def apply(self, remote_path: str, local_dir: str, local_filename: str) -> Tuple[str, str]: + def apply(self, remote_path: str, local_dir: str, local_filename: str) -> tuple[str, str]: # -1 filename # -2 the containing directory remote_path_parts = split_remote_path(remote_path) @@ -67,7 +66,7 @@ class NumberDuplicateStrategy(DuplicateNamingStrategy): """ PATTERN = r' \((\d+)\)' - def apply(self, remote_path: str, local_dir: str, local_filename: str) -> Tuple[str, str]: + def apply(self, remote_path: str, local_dir: str, local_filename: str) -> tuple[str, str]: # Find all files which are already numbered filename, extension = os.path.splitext(local_filename) pattern = re.escape(filename) + self.PATTERN + re.escape(extension) @@ -88,7 +87,7 @@ def apply(self, remote_path: str, local_dir: str, local_filename: str) -> Tuple[ return local_dir, new_filename -def chain_strategies(strategies: List[NamingStrategy], remote_path: str, local_dir: str) -> Tuple[str, str]: +def chain_strategies(strategies: list[NamingStrategy], remote_path: str, local_dir: str) -> tuple[str, str]: """Chains strategies together to find the target location and filename to which the file should be written. diff --git a/src/aioslsk/network/connection.py b/src/aioslsk/network/connection.py index abad66ee..1b044b61 100644 --- a/src/aioslsk/network/connection.py +++ b/src/aioslsk/network/connection.py @@ -3,16 +3,9 @@ from aiofiles.threadpool.binary import AsyncBufferedIOBase, AsyncBufferedReader import asyncio from async_timeout import Timeout, timeout as atimeout +from collections.abc import Callable, Coroutine from enum import auto, Enum -from typing import ( - Any, - Callable, - Coroutine, - List, - Optional, - TYPE_CHECKING, - Union, -) +from typing import Any, Optional, TYPE_CHECKING, Union import logging import socket import struct @@ -206,7 +199,7 @@ def __init__( self._writer: Optional[asyncio.StreamWriter] = None self._reader_task: Optional[asyncio.Task] = None - self._queued_messages: List[asyncio.Task] = [] + self._queued_messages: list[asyncio.Task] = [] self._read_timeout_object: Optional[Timeout] = None self.read_timeout: float = read_timeout @@ -439,7 +432,7 @@ def queue_message(self, message: Union[bytes, MessageDataclass]) -> asyncio.Task task.add_done_callback(self._queued_messages.remove) return task - def queue_messages(self, *messages: Union[bytes, MessageDataclass]) -> List[asyncio.Task]: + def queue_messages(self, *messages: Union[bytes, MessageDataclass]) -> list[asyncio.Task]: return [ self.queue_message(message) for message in messages diff --git a/src/aioslsk/network/network.py b/src/aioslsk/network/network.py index ccc9e82c..98933ec3 100644 --- a/src/aioslsk/network/network.py +++ b/src/aioslsk/network/network.py @@ -9,13 +9,9 @@ import logging from typing import ( Any, - Dict, - List, Optional, Union, - Tuple, TypeVar, - Type, TYPE_CHECKING ) @@ -74,7 +70,7 @@ T = TypeVar('T', bound='MessageDataclass') -ListeningConnections = Tuple[Optional[ListeningConnection], Optional[ListeningConnection]] +ListeningConnections = tuple[Optional[ListeningConnection], Optional[ListeningConnection]] class ListeningConnectionErrorMode(enum.Enum): @@ -96,16 +92,16 @@ class ExpectedResponse(asyncio.Future): """Future for an expected response message""" def __init__( - self, connection_class: Type[Union[PeerConnection, ServerConnection]], - message_class: Type[MessageDataclass], - peer: Optional[str] = None, fields: Optional[Dict[str, Any]] = None, + self, connection_class: type[Union[PeerConnection, ServerConnection]], + message_class: type[MessageDataclass], + peer: Optional[str] = None, fields: Optional[dict[str, Any]] = None, loop: Optional[asyncio.AbstractEventLoop] = None): super().__init__(loop=loop) - self.connection_class: Type[Union[PeerConnection, ServerConnection]] = connection_class - self.message_class: Type[MessageDataclass] = message_class + self.connection_class: type[Union[PeerConnection, ServerConnection]] = connection_class + self.message_class: type[MessageDataclass] = message_class self.peer: Optional[str] = peer - self.fields: Dict[str, Any] = {} if fields is None else fields + self.fields: dict[str, Any] = {} if fields is None else fields def matches(self, connection: DataConnection, response: MessageDataclass) -> bool: if connection.__class__ != self.connection_class: @@ -145,13 +141,13 @@ def __init__(self, settings: Settings, event_bus: EventBus): self._event_bus: EventBus = event_bus self._upnp = upnp.UPNP() self._ticket_generator = ticket_generator() - self._expected_response_futures: List[ExpectedResponse] = [] - self._expected_connection_futures: Dict[int, asyncio.Future] = {} + self._expected_response_futures: list[ExpectedResponse] = [] + self._expected_connection_futures: dict[int, asyncio.Future] = {} # List of connections self.server_connection: ServerConnection = self.create_server_connection() self.listening_connections: ListeningConnections = self.create_listening_connections() - self.peer_connections: List[PeerConnection] = [] + self.peer_connections: list[PeerConnection] = [] self._MESSAGE_MAP = build_message_map(self) @@ -162,10 +158,10 @@ def __init__(self, settings: Settings, event_bus: EventBus): self._settings.network.limits.download_speed_kbps) # Debugging - self._ip_overrides: Dict[str, str] = self._settings.debug.ip_overrides + self._ip_overrides: dict[str, str] = self._settings.debug.ip_overrides # Operational - self._create_peer_connection_tasks: List[asyncio.Task] = [] + self._create_peer_connection_tasks: list[asyncio.Task] = [] self._log_connections_task: BackgroundTask = BackgroundTask( interval=10, task_coro=self._log_connections_job, @@ -280,7 +276,7 @@ async def disconnect(self): """ self._cancel_all_tasks() - connections: List[Connection] = [self.server_connection] + connections: list[Connection] = [self.server_connection] connections.extend(self.peer_connections) connections.extend(conn for conn in self.listening_connections if conn) @@ -291,7 +287,7 @@ async def disconnect(self): ) logger.info("network disconnected") - def get_listening_ports(self) -> Tuple[int, int]: + def get_listening_ports(self) -> tuple[int, int]: """Gets the currently connected listening ports :return: ``tuple`` with 2 elements: the non-obfuscated- and obfuscated @@ -398,7 +394,7 @@ async def _upnp_job(self): interval, the check interval could be shorter if the job detects that the lease duration of a port is about to expire """ - def filter_mapped_port(mapped_ports: List[PortMappingEntry], internal_ip: str, port: int) -> PortMappingEntry: + def filter_mapped_port(mapped_ports: list[PortMappingEntry], internal_ip: str, port: int) -> PortMappingEntry: expected_values = (True, 'TCP', IPv4Address(internal_ip), port) for mapped_port in mapped_ports: values = ( @@ -480,7 +476,7 @@ async def start_upnp_job(self): def stop_upnp_job(self): self._upnp_task.cancel() - def select_port(self, port, obfuscated_port) -> Tuple[int, bool]: + def select_port(self, port, obfuscated_port) -> tuple[int, bool]: """Selects the port used for making a connection. This attempts to take into account the ``network.peer.obfuscate`` parameter however falls back on using whatever port is available if necessary @@ -564,7 +560,7 @@ async def create_peer_connection( PeerInitializedEvent(connection, requested=True)) return connection - async def _get_peer_address(self, username: str) -> Tuple[str, int, int]: + async def _get_peer_address(self, username: str) -> tuple[str, int, int]: """Requests the peer address for the given ``username`` from the server. :raise PeerConnectionError: if no IP address or no valid ports were @@ -612,7 +608,7 @@ def _remove_connection_future(self, ticket: int, connection_future: asyncio.Futu self._expected_connection_futures.pop(ticket) def create_server_response_future( - self, message_class: Type[T], fields: Optional[Dict[str, Any]] = None) -> ExpectedResponse: + self, message_class: type[T], fields: Optional[dict[str, Any]] = None) -> ExpectedResponse: """Creates a future for a server message to arrive, the message must match the ``message_class`` and fields defined in the keyword arguments. @@ -638,7 +634,7 @@ def register_response_future(self, expected_response: ExpectedResponse): expected_response.add_done_callback(self._remove_response_future) async def wait_for_server_message( - self, message_class: Type[T], fields: Optional[Dict[str, Any]] = None, timeout: float = 10) -> T: + self, message_class: type[T], fields: Optional[dict[str, Any]] = None, timeout: float = 10) -> T: """Waits for a message from the server :param message_class: Class of the expected server message @@ -659,7 +655,7 @@ async def wait_for_server_message( return response def create_peer_response_future( - self, peer: str, message_class: Type[T], fields: Optional[Dict[str, Any]] = None) -> ExpectedResponse: + self, peer: str, message_class: type[T], fields: Optional[dict[str, Any]] = None) -> ExpectedResponse: """Creates a future for a peer message to arrive, the message must match the ``message_class`` and fields defined in the keyword arguments and must be coming from a connection by ``peer``. @@ -682,7 +678,7 @@ def create_peer_response_future( return future async def wait_for_peer_message( - self, peer: str, message_class: Type[T], fields: Optional[Dict[str, Any]] = None, timeout: float = 60) -> T: + self, peer: str, message_class: type[T], fields: Optional[dict[str, Any]] = None, timeout: float = 60) -> T: future = self.create_peer_response_future( peer=peer, @@ -698,7 +694,7 @@ async def wait_for_peer_message( return response - def get_peer_connections(self, username: str, typ: str) -> List[PeerConnection]: + def get_peer_connections(self, username: str, typ: str) -> list[PeerConnection]: """Returns all connections for peer with given username and peer connection types. @@ -712,7 +708,7 @@ def get_peer_connections(self, username: str, typ: str) -> List[PeerConnection]: ] def get_active_peer_connections( - self, username: str, typ: str) -> List[PeerConnection]: + self, username: str, typ: str) -> list[PeerConnection]: """Return a list of currently active messaging connections for given peer connection type. @@ -901,7 +897,7 @@ async def send_peer_messages( if not raise_on_error: return list(zip(messages, results)) - def queue_server_messages(self, *messages: Union[bytes, MessageDataclass]) -> List[asyncio.Task]: + def queue_server_messages(self, *messages: Union[bytes, MessageDataclass]) -> list[asyncio.Task]: """Queues server messages :param messages: list of messages to queue diff --git a/src/aioslsk/network/upnp.py b/src/aioslsk/network/upnp.py index be6621b9..2e163aea 100644 --- a/src/aioslsk/network/upnp.py +++ b/src/aioslsk/network/upnp.py @@ -1,7 +1,6 @@ from __future__ import annotations from functools import partial from ipaddress import IPv4Address -from typing import List import logging from async_upnp_client.aiohttp import AiohttpRequester from async_upnp_client.client_factory import UpnpFactory @@ -24,8 +23,8 @@ class UPNP: def __init__(self): self._factory: UpnpFactory = UpnpFactory(AiohttpRequester()) - async def search_igd_devices(self, source_ip: str, timeout: int = UPNP_DEFAULT_SEARCH_TIMEOUT) -> List[IgdDevice]: - devices: List[IgdDevice] = [] + async def search_igd_devices(self, source_ip: str, timeout: int = UPNP_DEFAULT_SEARCH_TIMEOUT) -> list[IgdDevice]: + devices: list[IgdDevice] = [] logger.info("starting search for IGD devices") await async_search( partial(self._search_callback, devices), @@ -36,7 +35,7 @@ async def search_igd_devices(self, source_ip: str, timeout: int = UPNP_DEFAULT_S logger.info("found %d IGD devices", len(devices)) return devices - async def _search_callback(self, devices: List[IgdDevice], headers): + async def _search_callback(self, devices: list[IgdDevice], headers): if headers['ST'] not in IgdDevice.DEVICE_TYPES: return @@ -45,7 +44,7 @@ async def _search_callback(self, devices: List[IgdDevice], headers): devices.append(IgdDevice(device, None)) - async def get_mapped_ports(self, device: IgdDevice) -> List[PortMappingEntry]: + async def get_mapped_ports(self, device: IgdDevice) -> list[PortMappingEntry]: entry_count = await device.async_get_port_mapping_number_of_entries() if entry_count: @@ -55,7 +54,7 @@ async def get_mapped_ports(self, device: IgdDevice) -> List[PortMappingEntry]: else: return await self._get_mapped_ports_unknown(device) - async def _get_mapped_ports_known(self, device: IgdDevice, count: int) -> List[PortMappingEntry]: + async def _get_mapped_ports_known(self, device: IgdDevice, count: int) -> list[PortMappingEntry]: entries = [] for idx in range(count): logger.debug("getting port map with index %d on device %r", idx, device.name) @@ -72,7 +71,7 @@ async def _get_mapped_ports_known(self, device: IgdDevice, count: int) -> List[P return entries - async def _get_mapped_ports_unknown(self, device: IgdDevice) -> List[PortMappingEntry]: + async def _get_mapped_ports_unknown(self, device: IgdDevice) -> list[PortMappingEntry]: """Gets all mapped port entries for the given device when the length of the total amount of ports is not known. """ diff --git a/src/aioslsk/protocol/messages.py b/src/aioslsk/protocol/messages.py index 07377e10..59d6853c 100644 --- a/src/aioslsk/protocol/messages.py +++ b/src/aioslsk/protocol/messages.py @@ -18,7 +18,7 @@ """ from dataclasses import dataclass, field import logging -from typing import ClassVar, List, Optional +from typing import ClassVar, Optional from ..exceptions import UnknownMessageError from .primitives import ( @@ -265,13 +265,13 @@ class Request(MessageDataclass): class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x0E) room: str = field(metadata={'type': string}) - users: List[str] = field(metadata={'type': array, 'subtype': string}) - users_status: List[int] = field(metadata={'type': array, 'subtype': uint32}) - users_stats: List[UserStats] = field(metadata={'type': array, 'subtype': UserStats}) - users_slots_free: List[int] = field(metadata={'type': array, 'subtype': uint32}) - users_countries: List[str] = field(metadata={'type': array, 'subtype': string}) + users: list[str] = field(metadata={'type': array, 'subtype': string}) + users_status: list[int] = field(metadata={'type': array, 'subtype': uint32}) + users_stats: list[UserStats] = field(metadata={'type': array, 'subtype': UserStats}) + users_slots_free: list[int] = field(metadata={'type': array, 'subtype': uint32}) + users_countries: list[str] = field(metadata={'type': array, 'subtype': string}) owner: Optional[str] = field(default=None, metadata={'type': string, 'optional': True}) - operators: Optional[List[str]] = field( + operators: Optional[list[str]] = field( default=None, metadata={ 'type': array, @@ -498,7 +498,7 @@ class Request(MessageDataclass): class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x32) item: str = field(metadata={'type': string}) - recommendations: List[str] = field(metadata={'type': array, 'subtype': string}) + recommendations: list[str] = field(metadata={'type': array, 'subtype': string}) class AddInterest(ServerMessage): @@ -526,10 +526,10 @@ class Request(MessageDataclass): @dataclass(order=True) class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x36) - recommendations: List[Recommendation] = field( + recommendations: list[Recommendation] = field( metadata={'type': array, 'subtype': Recommendation} ) - unrecommendations: List[Recommendation] = field( + unrecommendations: list[Recommendation] = field( metadata={'type': array, 'subtype': Recommendation} ) @@ -543,7 +543,7 @@ class Request(MessageDataclass): @dataclass(order=True) class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x37) - interests: List[str] = field(metadata={'type': array, 'subtype': string}) + interests: list[str] = field(metadata={'type': array, 'subtype': string}) class GetGlobalRecommendations(ServerMessage): @@ -555,10 +555,10 @@ class Request(MessageDataclass): @dataclass(order=True) class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x38) - recommendations: List[Recommendation] = field( + recommendations: list[Recommendation] = field( metadata={'type': array, 'subtype': Recommendation} ) - unrecommendations: List[Recommendation] = field( + unrecommendations: list[Recommendation] = field( metadata={'type': array, 'subtype': Recommendation} ) @@ -574,8 +574,8 @@ class Request(MessageDataclass): class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x39) username: str = field(metadata={'type': string}) - interests: List[str] = field(metadata={'type': array, 'subtype': string}) - hated_interests: List[str] = field(metadata={'type': array, 'subtype': string}) + interests: list[str] = field(metadata={'type': array, 'subtype': string}) + hated_interests: list[str] = field(metadata={'type': array, 'subtype': string}) class ExecuteCommand(ServerMessage): @@ -584,7 +584,7 @@ class ExecuteCommand(ServerMessage): class Request(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x3A) command_type: str = field(metadata={'type': string}) - arguments: List[str] = field(metadata={'type': array, 'subtype': string}) + arguments: list[str] = field(metadata={'type': array, 'subtype': string}) class RoomList(ServerMessage): @@ -596,13 +596,13 @@ class Request(MessageDataclass): @dataclass(order=True) class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x40) - rooms: List[str] = field(metadata={'type': array, 'subtype': string}) - rooms_user_count: List[int] = field(metadata={'type': array, 'subtype': uint32}) - rooms_private_owned: List[str] = field(metadata={'type': array, 'subtype': string}) - rooms_private_owned_user_count: List[int] = field(metadata={'type': array, 'subtype': uint32}) - rooms_private: List[str] = field(metadata={'type': array, 'subtype': string}) - rooms_private_user_count: List[int] = field(metadata={'type': array, 'subtype': uint32}) - rooms_private_operated: List[str] = field(metadata={'type': array, 'subtype': string}) + rooms: list[str] = field(metadata={'type': array, 'subtype': string}) + rooms_user_count: list[int] = field(metadata={'type': array, 'subtype': uint32}) + rooms_private_owned: list[str] = field(metadata={'type': array, 'subtype': string}) + rooms_private_owned_user_count: list[int] = field(metadata={'type': array, 'subtype': uint32}) + rooms_private: list[str] = field(metadata={'type': array, 'subtype': string}) + rooms_private_user_count: list[int] = field(metadata={'type': array, 'subtype': uint32}) + rooms_private_operated: list[str] = field(metadata={'type': array, 'subtype': string}) class ExactFileSearch(ServerMessage): @@ -645,11 +645,11 @@ class Request(MessageDataclass): @dataclass(order=True) class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x43) - users: List[str] = field(metadata={'type': array, 'subtype': string}) - users_status: List[int] = field(metadata={'type': array, 'subtype': uint32}) - users_stats: List[UserStats] = field(metadata={'type': array, 'subtype': UserStats}) - users_slots_free: List[int] = field(metadata={'type': array, 'subtype': uint32}) - users_countries: List[str] = field(metadata={'type': array, 'subtype': string}) + users: list[str] = field(metadata={'type': array, 'subtype': string}) + users_status: list[int] = field(metadata={'type': array, 'subtype': uint32}) + users_stats: list[UserStats] = field(metadata={'type': array, 'subtype': UserStats}) + users_slots_free: list[int] = field(metadata={'type': array, 'subtype': uint32}) + users_countries: list[str] = field(metadata={'type': array, 'subtype': string}) class TunneledMessage(ServerMessage): @@ -678,7 +678,7 @@ class PrivilegedUsers(ServerMessage): @dataclass(order=True) class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x45) - users: List[str] = field(metadata={'type': array, 'subtype': string}) + users: list[str] = field(metadata={'type': array, 'subtype': string}) class ToggleParentSearch(ServerMessage): @@ -805,7 +805,7 @@ class PotentialParents(ServerMessage): @dataclass(order=True) class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x66) - entries: List[PotentialParent] = field(metadata={'type': array, 'subtype': PotentialParent}) + entries: list[PotentialParent] = field(metadata={'type': array, 'subtype': PotentialParent}) class WishlistSearch(ServerMessage): @@ -834,7 +834,7 @@ class Request(MessageDataclass): @dataclass(order=True) class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x6E) - users: List[SimilarUser] = field(metadata={'type': array, 'subtype': SimilarUser}) + users: list[SimilarUser] = field(metadata={'type': array, 'subtype': SimilarUser}) class GetItemRecommendations(ServerMessage): @@ -848,7 +848,7 @@ class Request(MessageDataclass): class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x6F) item: str = field(metadata={'type': string}) - recommendations: List[Recommendation] = field(metadata={'type': array, 'subtype': Recommendation}) + recommendations: list[Recommendation] = field(metadata={'type': array, 'subtype': Recommendation}) class GetItemSimilarUsers(ServerMessage): @@ -862,7 +862,7 @@ class Request(MessageDataclass): class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x70) item: str = field(metadata={'type': string}) - usernames: List[str] = field(metadata={'type': array, 'subtype': string}) + usernames: list[str] = field(metadata={'type': array, 'subtype': string}) class RoomTickers(ServerMessage): @@ -871,7 +871,7 @@ class RoomTickers(ServerMessage): class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x71) room: str = field(metadata={'type': string}) - tickers: List[RoomTicker] = field(metadata={'type': array, 'subtype': RoomTicker}) + tickers: list[RoomTicker] = field(metadata={'type': array, 'subtype': RoomTicker}) class RoomTickerAdded(ServerMessage): @@ -1013,7 +1013,7 @@ class PrivateRoomMembers(ServerMessage): class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x85) room: str = field(metadata={'type': string}) - usernames: List[str] = field(metadata={'type': array, 'subtype': string}) + usernames: list[str] = field(metadata={'type': array, 'subtype': string}) class PrivateRoomGrantMembership(ServerMessage): @@ -1151,7 +1151,7 @@ class PrivateRoomOperators(ServerMessage): class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x94) room: str = field(metadata={'type': string}) - usernames: List[str] = field(metadata={'type': array, 'subtype': string}) + usernames: list[str] = field(metadata={'type': array, 'subtype': string}) class PrivateChatMessageUsers(ServerMessage): @@ -1159,7 +1159,7 @@ class PrivateChatMessageUsers(ServerMessage): @dataclass(order=True) class Request(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x95) - usernames: List[str] = field(metadata={'type': array, 'subtype': string}) + usernames: list[str] = field(metadata={'type': array, 'subtype': string}) message: str = field(metadata={'type': string}) @@ -1198,7 +1198,7 @@ class Request(MessageDataclass): class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x99) query: str = field(metadata={'type': string}) - related_searches: List[str] = field(metadata={'type': array, 'subtype': string}) + related_searches: list[str] = field(metadata={'type': array, 'subtype': string}) class ExcludedSearchPhrases(ServerMessage): @@ -1206,7 +1206,7 @@ class ExcludedSearchPhrases(ServerMessage): @dataclass(order=True) class Response(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0xA0) - phrases: List[str] = field(metadata={'type': array, 'subtype': string}) + phrases: list[str] = field(metadata={'type': array, 'subtype': string}) class CannotConnect(ServerMessage): @@ -1286,14 +1286,14 @@ class PeerSharesReply(PeerMessage): @dataclass(order=True) class Request(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x05) - directories: List[DirectoryData] = field( + directories: list[DirectoryData] = field( metadata={'type': array, 'subtype': DirectoryData} ) # Unknown field that always seems to be 0, possibilities: # * This was another list, but it always empty (not tested) # * This is a ticket: See explanation of ticket in PeerSharesRequest unknown: int = field(default=0, metadata={'type': uint32}) - locked_directories: Optional[List[DirectoryData]] = field( + locked_directories: Optional[list[DirectoryData]] = field( default=None, metadata={'type': array, 'subtype': DirectoryData, 'optional': True} ) @@ -1313,7 +1313,7 @@ class Request(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x09) username: str = field(metadata={'type': string}) ticket: int = field(metadata={'type': uint32}) - results: List[FileData] = field(metadata={'type': array, 'subtype': FileData}) + results: list[FileData] = field(metadata={'type': array, 'subtype': FileData}) has_slots_free: bool = field(metadata={'type': boolean}) avg_speed: int = field(metadata={'type': uint32}) # Note: queue_size and unknown. queue_size is described as uint64 in the @@ -1322,7 +1322,7 @@ class Request(MessageDataclass): # locked results: the same can be seen in PeerSharesReply queue_size: int = field(metadata={'type': uint32}) unknown: Optional[int] = field(default=0, metadata={'type': uint32}) - locked_results: Optional[List[FileData]] = field( + locked_results: Optional[list[FileData]] = field( default=None, metadata={'type': array, 'subtype': FileData, 'optional': True} ) @@ -1373,7 +1373,7 @@ class Request(MessageDataclass): MESSAGE_ID: ClassVar[uint32] = uint32(0x25) ticket: int = field(metadata={'type': uint32}) directory: str = field(metadata={'type': string}) - directories: List[DirectoryData] = field(metadata={'type': array, 'subtype': DirectoryData}) + directories: list[DirectoryData] = field(metadata={'type': array, 'subtype': DirectoryData}) def serialize(self, compress: bool = True) -> bytes: return super().serialize(compress) diff --git a/src/aioslsk/protocol/primitives.py b/src/aioslsk/protocol/primitives.py index 3a4205b6..c32aa8ff 100644 --- a/src/aioslsk/protocol/primitives.py +++ b/src/aioslsk/protocol/primitives.py @@ -39,12 +39,8 @@ from typing import ( Any, ClassVar, - Dict, - List, Optional, Protocol, - Tuple, - Type, TypeVar, Union ) @@ -61,7 +57,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: ... @classmethod - def deserialize(cls, pos: int, data: bytes) -> Tuple[int, Self]: + def deserialize(cls, pos: int, data: bytes) -> tuple[int, Self]: ... def serialize(self, *args, **kwargs) -> bytes: @@ -82,7 +78,7 @@ def serialize(self) -> bytes: return self.STRUCT.pack(self) @classmethod - def deserialize(cls, pos: int, data: bytes) -> Tuple[int, int]: + def deserialize(cls, pos: int, data: bytes) -> tuple[int, int]: return pos + cls.STRUCT.size, cls.STRUCT.unpack_from(data, offset=pos)[0] @@ -93,7 +89,7 @@ def serialize(self) -> bytes: return self.STRUCT.pack(self) @classmethod - def deserialize(cls, pos: int, data: bytes) -> Tuple[int, int]: + def deserialize(cls, pos: int, data: bytes) -> tuple[int, int]: return pos + cls.STRUCT.size, cls.STRUCT.unpack_from(data, offset=pos)[0] @@ -104,7 +100,7 @@ def serialize(self) -> bytes: return self.STRUCT.pack(self) @classmethod - def deserialize(cls, pos: int, data: bytes) -> Tuple[int, int]: + def deserialize(cls, pos: int, data: bytes) -> tuple[int, int]: return pos + cls.STRUCT.size, cls.STRUCT.unpack_from(data, offset=pos)[0] @@ -116,7 +112,7 @@ def serialize(self) -> bytes: return self.STRUCT.pack(self) @classmethod - def deserialize(cls, pos: int, data: bytes) -> Tuple[int, int]: + def deserialize(cls, pos: int, data: bytes) -> tuple[int, int]: return pos + cls.STRUCT_SIZE, cls.STRUCT.unpack_from(data, offset=pos)[0] @@ -127,7 +123,7 @@ def serialize(self) -> bytes: return self.STRUCT.pack(self) @classmethod - def deserialize(cls, pos: int, data: bytes) -> Tuple[int, int]: + def deserialize(cls, pos: int, data: bytes) -> tuple[int, int]: return pos + cls.STRUCT.size, cls.STRUCT.unpack_from(data, offset=pos)[0] @@ -139,7 +135,7 @@ def serialize(self, encoding: str = 'utf-8') -> bytes: return uint32(len(byte_string)).serialize() + byte_string @classmethod - def deserialize(cls, pos: int, data: bytes) -> Tuple[int, str]: + def deserialize(cls, pos: int, data: bytes) -> tuple[int, str]: pos_after_len, length = uint32.deserialize(pos, data) end_pos = pos_after_len + length value = data[pos_after_len:end_pos] @@ -156,7 +152,7 @@ def serialize(self) -> bytes: return uint32(length).serialize() + bytes(self) @classmethod - def deserialize(cls, pos: int, data: bytes) -> Tuple[int, bytes]: + def deserialize(cls, pos: int, data: bytes) -> tuple[int, bytes]: pos_after_len, length = uint32.deserialize(pos, data) value = data[pos_after_len:pos_after_len + length] return pos_after_len + length, value @@ -170,7 +166,7 @@ def serialize(self) -> bytes: return self.STRUCT.pack(bytes(reversed(ip_b))) @classmethod - def deserialize(cls, pos: int, data) -> Tuple[int, str]: + def deserialize(cls, pos: int, data: bytes) -> tuple[int, str]: value = cls.STRUCT.unpack(data[pos:pos + 4])[0] ip_addr = socket.inet_ntoa(bytes(reversed(value))) return pos + 4, ip_addr @@ -183,13 +179,13 @@ def serialize(self) -> bytes: return self.STRUCT.pack(self) @classmethod - def deserialize(cls, pos: int, data: bytes) -> Tuple[int, bool]: + def deserialize(cls, pos: int, data: bytes) -> tuple[int, bool]: return pos + cls.STRUCT.size, cls.STRUCT.unpack_from(data, offset=pos)[0] class array(list): - def serialize(self, element_type: Type[Serializable]) -> bytes: + def serialize(self, element_type: type[Serializable]) -> bytes: body = uint32(len(self)).serialize() is_protocoldc = is_dataclass(element_type) for value in self: @@ -200,7 +196,7 @@ def serialize(self, element_type: Type[Serializable]) -> bytes: return body @classmethod - def deserialize(cls, pos: int, data: bytes, element_type: Type[T]) -> Tuple[int, List[T]]: + def deserialize(cls, pos: int, data: bytes, element_type: type[T]) -> tuple[int, list[T]]: items = [] pos, array_len = uint32.deserialize(pos, data) for _ in range(array_len): @@ -225,7 +221,7 @@ class CustomDataclass(ProtocolDataclass): password: str = field(metadata={'type': string}) has_privileges: bool = field(metadata={'type': boolean}) """ - _CACHED_FIELDS: Optional[Tuple[Field, ...]] = None + _CACHED_FIELDS: Optional[tuple[Field, ...]] = None """Cache version of the ``dataclasses.fields`` return for the current class """ @@ -245,7 +241,7 @@ def serialize(self) -> bytes: # Serialize try: - proto_type: Type[Serializable] = obj_field.metadata['type'] + proto_type: type[Serializable] = obj_field.metadata['type'] except KeyError: raise Exception(f"no 'type' for field {obj_field.name!r} defined") @@ -275,7 +271,7 @@ def deserialize(cls, pos: int, message: bytes): # cause too many issues cls._CACHED_FIELDS = fields(cls) # type: ignore[arg-type] - field_map: Dict[str, Any] = {} + field_map: dict[str, Any] = {} for obj_field in cls._CACHED_FIELDS: if not cls._field_needs_deserialization(obj_field, field_map, pos, message): continue @@ -298,7 +294,7 @@ def deserialize(cls, pos: int, message: bytes): return pos, cls(**field_map) @classmethod - def _field_needs_deserialization(cls, field: Field, field_map: Dict[str, Any], pos: int, message: bytes): + def _field_needs_deserialization(cls, field: Field, field_map: dict[str, Any], pos: int, message: bytes): # For if_true and if_false we need to return only if the condition is # is false as we still want to check the 'optional' field if 'if_true' in field.metadata: @@ -451,7 +447,7 @@ class FileData(ProtocolDataclass): filename: str = field(metadata={'type': string}) filesize: int = field(metadata={'type': uint64}) extension: str = field(metadata={'type': string}) - attributes: List[Attribute] = field(metadata={'type': array, 'subtype': Attribute}) + attributes: list[Attribute] = field(metadata={'type': array, 'subtype': Attribute}) @classmethod def deserialize(cls, pos: int, message: bytes): @@ -481,7 +477,7 @@ def serialize(self) -> bytes: @dataclass(frozen=True, order=True) class DirectoryData(ProtocolDataclass): name: str = field(metadata={'type': string}) - files: List[FileData] = field(metadata={'type': array, 'subtype': FileData}) + files: list[FileData] = field(metadata={'type': array, 'subtype': FileData}) @classmethod def deserialize(cls, pos: int, message: bytes): diff --git a/src/aioslsk/room/manager.py b/src/aioslsk/room/manager.py index b997d7de..12602e7d 100644 --- a/src/aioslsk/room/manager.py +++ b/src/aioslsk/room/manager.py @@ -1,7 +1,6 @@ from collections import OrderedDict import logging import time -from typing import Dict, List from ..base_manager import BaseManager from ..events import ( @@ -71,33 +70,33 @@ def __init__( self._user_manager: UserManager = user_manager self._network: Network = network - self._rooms: Dict[str, Room] = dict() + self._rooms: dict[str, Room] = dict() self._MESSAGE_MAP = build_message_map(self) self.register_listeners() @property - def rooms(self) -> Dict[str, Room]: + def rooms(self) -> dict[str, Room]: return self._rooms - def get_joined_rooms(self) -> List[Room]: + def get_joined_rooms(self) -> list[Room]: return [room for room in self._rooms.values() if room.joined] - def get_private_rooms(self) -> List[Room]: + def get_private_rooms(self) -> list[Room]: return [room for room in self._rooms.values() if room.private] - def get_public_rooms(self) -> List[Room]: + def get_public_rooms(self) -> list[Room]: return [room for room in self._rooms.values() if not room.private] - def get_owned_rooms(self) -> List[Room]: + def get_owned_rooms(self) -> list[Room]: me = self._user_manager.get_self() return [ room for room in self._rooms.values() if room.owner == me.name ] - def get_operated_rooms(self) -> List[Room]: + def get_operated_rooms(self) -> list[Room]: me = self._user_manager.get_self() return [ room for room in self._rooms.values() diff --git a/src/aioslsk/room/model.py b/src/aioslsk/room/model.py index 492cbde8..d2dd9fce 100644 --- a/src/aioslsk/room/model.py +++ b/src/aioslsk/room/model.py @@ -1,6 +1,6 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import Dict, List, Optional, Set +from typing import Optional from ..user.model import User @@ -8,19 +8,19 @@ class Room: name: str private: bool = False - users: List[User] = field(default_factory=list) + users: list[User] = field(default_factory=list) """Current list of joined users""" joined: bool = False user_count: int = 0 - tickers: Dict[str, str] = field(default_factory=dict) + tickers: dict[str, str] = field(default_factory=dict) """Room tickers (room wall)""" # Only for private rooms - members: Set[str] = field(default_factory=set) + members: set[str] = field(default_factory=set) """For private rooms, names of members of the room (excludes owner)""" owner: Optional[str] = None """For private rooms, name of the room owner""" - operators: Set[str] = field(default_factory=set) + operators: set[str] = field(default_factory=set) """For private rooms, names of operators""" def add_user(self, user: User): diff --git a/src/aioslsk/search/manager.py b/src/aioslsk/search/manager.py index 11563ac3..74bdf913 100644 --- a/src/aioslsk/search/manager.py +++ b/src/aioslsk/search/manager.py @@ -2,7 +2,7 @@ from collections import deque from functools import partial import logging -from typing import Deque, Dict, List, Optional, Union +from typing import Optional, Union from ..base_manager import BaseManager from ..constants import DEFAULT_WISHLIST_INTERVAL @@ -70,20 +70,20 @@ def __init__( self._ticket_generator = ticket_generator() self._session: Optional[Session] = None - self.received_searches: Deque[ReceivedSearch] = deque( + self.received_searches: deque[ReceivedSearch] = deque( list(), maxlen=self._settings.searches.receive.store_amount) - self.requests: Dict[int, SearchRequest] = {} + self.requests: dict[int, SearchRequest] = {} # Server variables self.search_inactivity_timeout: Optional[int] = None self.wishlist_interval: Optional[int] = None - self.excluded_search_phrases: List[str] = [] + self.excluded_search_phrases: list[str] = [] self.register_listeners() self._MESSAGE_MAP = build_message_map(self) - self._search_reply_tasks: List[asyncio.Task] = [] + self._search_reply_tasks: list[asyncio.Task] = [] self._wishlist_task: BackgroundTask = BackgroundTask( interval=DEFAULT_WISHLIST_INTERVAL, task_coro=self._wishlist_job, @@ -425,7 +425,7 @@ async def _on_session_initialized(self, event: SessionInitializedEvent): async def _on_session_destroyed(self, event: SessionDestroyedEvent): self._session = None - async def stop(self) -> List[asyncio.Task]: + async def stop(self) -> list[asyncio.Task]: """Cancels all pending tasks :return: a list of tasks that have been cancelled so that they can be diff --git a/src/aioslsk/search/model.py b/src/aioslsk/search/model.py index 377ed421..b389b7b0 100644 --- a/src/aioslsk/search/model.py +++ b/src/aioslsk/search/model.py @@ -1,9 +1,10 @@ +from collections.abc import Callable, Generator from dataclasses import dataclass, field import datetime from enum import auto, Enum import logging import re -from typing import Callable, Generator, List, Optional, Set +from typing import Optional from ..protocol.primitives import FileData from ..shares.utils import create_term_pattern @@ -33,9 +34,9 @@ class ReceivedSearch: @dataclass class SearchQuery: query: str - include_terms: Set[str] = field(default_factory=set) - exclude_terms: Set[str] = field(default_factory=set) - wildcard_terms: Set[str] = field(default_factory=set) + include_terms: set[str] = field(default_factory=set) + exclude_terms: set[str] = field(default_factory=set) + wildcard_terms: set[str] = field(default_factory=set) @classmethod def parse(cls, query: str) -> 'SearchQuery': @@ -89,8 +90,8 @@ class SearchResult: avg_speed: int = 0 queue_size: int = 0 - shared_items: List[FileData] = field(default_factory=list) - locked_results: List[FileData] = field(default_factory=list) + shared_items: list[FileData] = field(default_factory=list) + locked_results: list[FileData] = field(default_factory=list) @dataclass @@ -102,7 +103,7 @@ class SearchRequest: room: Optional[str] = None username: Optional[str] = None - results: List[SearchResult] = field(default_factory=list) + results: list[SearchResult] = field(default_factory=list) started: datetime.datetime = field(default_factory=datetime.datetime.now) timer: Optional[Timer] = None diff --git a/src/aioslsk/settings.py b/src/aioslsk/settings.py index d615d165..6b1e39a6 100644 --- a/src/aioslsk/settings.py +++ b/src/aioslsk/settings.py @@ -1,5 +1,5 @@ import os -from typing import Dict, List, Optional, Set +from typing import Optional from pydantic import BaseModel, Field, model_validator from pydantic_settings import BaseSettings @@ -16,7 +16,7 @@ class SharedDirectorySettingEntry(BaseModel, validate_assignment=True): path: str share_mode: DirectoryShareMode = DirectoryShareMode.EVERYONE - users: List[str] = Field(default_factory=list) + users: list[str] = Field(default_factory=list) class WishlistSettingEntry(BaseModel, validate_assignment=True): @@ -94,11 +94,11 @@ class SearchReceiveSettings(BaseModel, validate_assignment=True): class SearchSettings(BaseModel, validate_assignment=True): send: SearchSendSettings = Field(default_factory=SearchSendSettings) receive: SearchReceiveSettings = Field(default_factory=SearchReceiveSettings) - wishlist: List[WishlistSettingEntry] = Field(default_factory=list) + wishlist: list[WishlistSettingEntry] = Field(default_factory=list) @model_validator(mode='before') @classmethod - def handle_max_result_alias(cls, values: Dict): + def handle_max_result_alias(cls, values: dict): if 'max_results' in values: value = values.pop('max_results') if 'receive' not in values: @@ -129,28 +129,28 @@ class TransfersSettings(BaseModel, validate_assignment=True): class SharesSettings(BaseModel, validate_assignment=True): scan_on_start: bool = True download: str = os.getcwd() - directories: List[SharedDirectorySettingEntry] = Field(default_factory=list) + directories: list[SharedDirectorySettingEntry] = Field(default_factory=list) class RoomsSettings(BaseModel, validate_assignment=True): auto_join: bool = True private_room_invites: bool = True - favorites: Set[str] = Field(default_factory=set) + favorites: set[str] = Field(default_factory=set) class UsersSettings(BaseModel, validate_assignment=True): - friends: Set[str] = Field(default_factory=set) - blocked: Set[str] = Field(default_factory=set) + friends: set[str] = Field(default_factory=set) + blocked: set[str] = Field(default_factory=set) class InterestsSettings(BaseModel, validate_assignment=True): - liked: Set[str] = Field(default_factory=set) - hated: Set[str] = Field(default_factory=set) + liked: set[str] = Field(default_factory=set) + hated: set[str] = Field(default_factory=set) class DebugSettings(BaseModel, validate_assignment=True): search_for_parent: bool = True - ip_overrides: Dict[str, str] = Field(default_factory=dict) + ip_overrides: dict[str, str] = Field(default_factory=dict) log_connection_count: bool = False diff --git a/src/aioslsk/shares/cache.py b/src/aioslsk/shares/cache.py index b10a96e0..b7b5a1b9 100644 --- a/src/aioslsk/shares/cache.py +++ b/src/aioslsk/shares/cache.py @@ -1,25 +1,25 @@ import os import shelve -from typing import List, Protocol +from typing import Protocol from .model import SharedDirectory class SharesCache(Protocol): """Abstract base class for storing shares""" - def read(self) -> List[SharedDirectory]: + def read(self) -> list[SharedDirectory]: ... - def write(self, shared_directories: List[SharedDirectory]): + def write(self, shared_directories: list[SharedDirectory]): ... class SharesNullCache: - def read(self) -> List[SharedDirectory]: # pragma: no cover + def read(self) -> list[SharedDirectory]: # pragma: no cover return [] - def write(self, shared_directories: List[SharedDirectory]): # pragma: no cover + def write(self, shared_directories: list[SharedDirectory]): # pragma: no cover pass @@ -34,9 +34,9 @@ def __init__(self, data_directory: str, filename: str = DEFAULT_FILENAME): def _get_index_path(self) -> str: return os.path.join(self.data_directory, self.filename) - def read(self) -> List[SharedDirectory]: + def read(self) -> list[SharedDirectory]: with shelve.open(self._get_index_path(), 'c') as db: - directories: List[SharedDirectory] = db.get('index', list()) + directories: list[SharedDirectory] = db.get('index', list()) for directory in directories: new_items = set() for item in directory.items: @@ -45,6 +45,6 @@ def read(self) -> List[SharedDirectory]: directory.items = new_items return directories - def write(self, shared_directories: List[SharedDirectory]): + def write(self, shared_directories: list[SharedDirectory]): with shelve.open(self._get_index_path(), 'c') as db: db['index'] = shared_directories diff --git a/src/aioslsk/shares/manager.py b/src/aioslsk/shares/manager.py index e496940c..ea24cf1f 100644 --- a/src/aioslsk/shares/manager.py +++ b/src/aioslsk/shares/manager.py @@ -1,5 +1,6 @@ from aiofiles import os as asyncos import asyncio +from collections.abc import Callable from concurrent.futures import Executor from functools import partial import logging @@ -9,15 +10,7 @@ import re import sys import time -from typing import ( - Callable, - Dict, - List, - Optional, - Set, - Tuple, - Union, -) +from typing import Optional, Union import uuid from weakref import WeakSet @@ -50,7 +43,7 @@ logger = logging.getLogger(__name__) -ItemAttributes = List[Tuple[int, int]] +ItemAttributes = list[tuple[int, int]] ExecutorFactory = Callable[[], Executor] _COMPRESSED_FORMATS = [ @@ -69,7 +62,7 @@ def scan_directory( shared_directory: SharedDirectory, - children: Optional[List[SharedDirectory]] = None) -> Set[SharedItem]: + children: Optional[list[SharedDirectory]] = None) -> set[SharedItem]: """Scans the directory for items to share Warning: when using ProcessPoolExecutor on this method the returned items @@ -160,8 +153,8 @@ def __init__( self._settings: Settings = settings self._event_bus: EventBus = event_bus self._network: Network = network - self._term_map: Dict[str, WeakSet[SharedItem]] = {} - self._shared_directories: List[SharedDirectory] = [] + self._term_map: dict[str, WeakSet[SharedItem]] = {} + self._shared_directories: list[SharedDirectory] = [] self._session: Optional[Session] = None self.cache: SharesCache = cache if cache else SharesNullCache() @@ -223,7 +216,7 @@ async def start(self): if self.executor_factory: self.executor = self.executor_factory() - async def stop(self) -> List[asyncio.Task]: + async def stop(self) -> list[asyncio.Task]: if self.executor: self.executor.shutdown() self.executor = None @@ -242,7 +235,7 @@ def load_from_settings(self): will be updated, non-existing directories added, directories that no longer exist will be removed """ - new_shared_directories: List[SharedDirectory] = [] + new_shared_directories: list[SharedDirectory] = [] # Add or update directories for directory_entry in self._settings.shares.directories: @@ -345,7 +338,7 @@ async def get_shared_item(self, remote_path: str, username: Optional[str] = None def add_shared_directory( self, shared_directory: str, share_mode: DirectoryShareMode = DirectoryShareMode.EVERYONE, - users: Optional[List[str]] = None) -> SharedDirectory: + users: Optional[list[str]] = None) -> SharedDirectory: """Adds a shared directory. This method will call :meth:`generate_alias` and add the directory to the directory map. This method will not scan the directory, for scanning see the :meth:`scan`, @@ -390,7 +383,7 @@ def add_shared_directory( def update_shared_directory( self, directory: Union[str, SharedDirectory], share_mode: Optional[DirectoryShareMode] = None, - users: Optional[List[str]] = None) -> SharedDirectory: + users: Optional[list[str]] = None) -> SharedDirectory: """Updates `share_mode` and `users` values for the given directory :param directory: if a string is given this method will attempt to find @@ -507,7 +500,7 @@ async def scan_directory_files(self, shared_directory: SharedDirectory): logger.info("scheduling scan for directory : %r", shared_directory) try: - shared_items: Set[SharedItem] = await loop.run_in_executor( + shared_items: set[SharedItem] = await loop.run_in_executor( self.executor, partial( scan_directory, @@ -554,7 +547,7 @@ async def scan_directory_file_attributes(self, shared_directory: SharedDirectory loop = asyncio.get_running_loop() # Schedule the items on the executor - futures: List[asyncio.Future] = [] + futures: list[asyncio.Future] = [] for item in shared_directory.items: if item.attributes is None: future = loop.run_in_executor( @@ -621,7 +614,7 @@ async def get_filesize(self, shared_item: SharedItem) -> int: def query( self, query: Union[str, SearchQuery], username: Optional[str] = None, - excluded_search_phrases: Optional[List[str]] = None) -> Tuple[List[SharedItem], List[SharedItem]]: + excluded_search_phrases: Optional[list[str]] = None) -> tuple[list[SharedItem], list[SharedItem]]: """Performs a query on the ``shared_directories`` returning the matching items. If ``username`` is passed this method will return a list of visible results and list of locked results. If `None` the second list @@ -725,7 +718,7 @@ def query( else: return list(found_items), [] - def get_stats(self) -> Tuple[int, int]: + def get_stats(self) -> tuple[int, int]: """Gets the total amount of shared directories and files. :return: directory and file count as a ``tuple`` @@ -739,7 +732,7 @@ def get_stats(self) -> Tuple[int, int]: ) return dir_count, file_count - def calculate_download_path(self, remote_path: str) -> Tuple[str, str]: + def calculate_download_path(self, remote_path: str) -> tuple[str, str]: """Calculates the local download path for a remote path returned by another peer. @@ -753,7 +746,7 @@ def calculate_download_path(self, remote_path: str) -> Tuple[str, str]: download_dir ) - def get_shared_directories_for_user(self, username: str) -> Tuple[List[SharedDirectory], List[SharedDirectory]]: + def get_shared_directories_for_user(self, username: str) -> tuple[list[SharedDirectory], list[SharedDirectory]]: public_dirs = [] locked_dirs = [] for shared_dir in self._shared_directories: @@ -764,7 +757,7 @@ def get_shared_directories_for_user(self, username: str) -> Tuple[List[SharedDir return public_dirs, locked_dirs - def create_shares_reply(self, username: str) -> Tuple[List[DirectoryData], List[DirectoryData]]: + def create_shares_reply(self, username: str) -> tuple[list[DirectoryData], list[DirectoryData]]: """Creates a complete list of the currently shared items as a reply to a :class:`.PeerSharesRequest` messages @@ -773,8 +766,8 @@ def create_shares_reply(self, username: str) -> Tuple[List[DirectoryData], List[ :return: ``tuple`` with two lists: public directories and locked directories """ - def list_unique_directories(directories: List[SharedDirectory]) -> Dict[Tuple[str, ...], List[SharedItem]]: - response_dirs: Dict[Tuple[str, ...], List[SharedItem]] = {} + def list_unique_directories(directories: list[SharedDirectory]) -> dict[tuple[str, ...], list[SharedItem]]: + response_dirs: dict[tuple[str, ...], list[SharedItem]] = {} for directory in directories: for item in directory.items: @@ -790,7 +783,7 @@ def list_unique_directories(directories: List[SharedDirectory]) -> Dict[Tuple[st return response_dirs - def convert_to_directory_shares(directory_map: Dict[Tuple[str, ...], List[SharedItem]]) -> List[DirectoryData]: + def convert_to_directory_shares(directory_map: dict[tuple[str, ...], list[SharedItem]]) -> list[DirectoryData]: public_shares = [] for directory, files in directory_map.items(): public_shares.append( @@ -809,7 +802,7 @@ def convert_to_directory_shares(directory_map: Dict[Tuple[str, ...], List[Shared return visible_shares, locked_shares - def create_directory_reply(self, remote_directory: str) -> List[DirectoryData]: + def create_directory_reply(self, remote_directory: str) -> list[DirectoryData]: """Lists directory data as a response to a directory request. This will not contain any information about subdirectories, only the files within that directory @@ -822,7 +815,7 @@ def create_directory_reply(self, remote_directory: str) -> List[DirectoryData]: :return: list of directories. Empty if the directory is not shared, a list with one entry if the directory is found """ - items: List[SharedItem] = [] + items: list[SharedItem] = [] remote_dir_parts = tuple(remote_directory.split('\\')) remote_dir_parts_len = len(remote_dir_parts) @@ -865,7 +858,7 @@ def _cleanup_term_map(self): if len(values) > 0 } - def _get_parent_directories(self, shared_directory: SharedDirectory) -> List[SharedDirectory]: + def _get_parent_directories(self, shared_directory: SharedDirectory) -> list[SharedDirectory]: """Returns a list of parent shared directories. The parent directories will be sorted by length of the absolute path (longest last) """ diff --git a/src/aioslsk/shares/model.py b/src/aioslsk/shares/model.py index e225164d..1d19152a 100644 --- a/src/aioslsk/shares/model.py +++ b/src/aioslsk/shares/model.py @@ -1,7 +1,7 @@ from dataclasses import dataclass, field import enum import os -from typing import List, Optional, Set, Tuple, Union +from typing import Optional, Union from ..exceptions import FileNotFoundError from .utils import normalize_remote_path @@ -22,8 +22,8 @@ class SharedDirectory: absolute_path: str alias: str share_mode: DirectoryShareMode = field(default=DirectoryShareMode.EVERYONE, compare=False, hash=False) - users: List[str] = field(default_factory=list, compare=False, hash=False) - items: Set['SharedItem'] = field(default_factory=set, init=False, compare=False, hash=False, repr=False) + users: list[str] = field(default_factory=list, compare=False, hash=False) + items: set['SharedItem'] = field(default_factory=set, init=False, compare=False, hash=False, repr=False) def is_parent_of(self, directory: Union[str, 'SharedDirectory']) -> bool: """Returns true if the current directory is a parent of the passed @@ -58,7 +58,7 @@ def get_item_by_remote_path(self, remote_path: str) -> 'SharedItem': raise FileNotFoundError( f"file with remote path {remote_path!r} not found in directory {self!r}") - def get_items_for_directory(self, directory: 'SharedDirectory') -> Set['SharedItem']: + def get_items_for_directory(self, directory: 'SharedDirectory') -> set['SharedItem']: """Gets items that are part of given directory""" items = set() for item in self.items: @@ -73,7 +73,7 @@ class SharedItem: subdir: str filename: str modified: float - attributes: Optional[List[Tuple[int, int]]] = field( + attributes: Optional[list[tuple[int, int]]] = field( default=None, init=False, compare=False, @@ -101,7 +101,7 @@ def get_remote_directory_path(self) -> str: return normalize_remote_path( '@@' + os.path.join(self.shared_directory.alias, self.subdir)) - def get_remote_directory_path_parts(self) -> Tuple[str, ...]: + def get_remote_directory_path_parts(self) -> tuple[str, ...]: """Returns the remote directory path split into parts""" return tuple(self.get_remote_directory_path().split('\\')) diff --git a/src/aioslsk/shares/utils.py b/src/aioslsk/shares/utils.py index 77457e93..8cc3b342 100644 --- a/src/aioslsk/shares/utils.py +++ b/src/aioslsk/shares/utils.py @@ -2,7 +2,7 @@ import logging import os import re -from typing import List, Pattern, TYPE_CHECKING +from typing import TYPE_CHECKING from ..constants import PATH_SEPERATOR_PATTERN from ..protocol.primitives import Attribute, FileData @@ -22,7 +22,7 @@ def normalize_remote_path(path: str) -> str: return re.sub(PATH_SEPERATOR_PATTERN, '\\\\', path).rstrip('\\/') -def create_term_pattern(term: str, wildcard: bool = False) -> Pattern: +def create_term_pattern(term: str, wildcard: bool = False) -> re.Pattern: """Creates the matching pattern for a single search term of a query""" if wildcard: return re.compile( @@ -63,7 +63,7 @@ def convert_item_to_file_data( ) -def convert_items_to_file_data(shared_items: List[SharedItem], use_full_path=True) -> List[FileData]: +def convert_items_to_file_data(shared_items: list[SharedItem], use_full_path=True) -> list[FileData]: """Converts a list of :class:`.SharedItem` instances to a list of :class:`.FileData` instances. If an exception occurs when converting the item an error will be logged and the item will be omitted from the list diff --git a/src/aioslsk/tasks.py b/src/aioslsk/tasks.py index 6e1c0343..d14c1747 100644 --- a/src/aioslsk/tasks.py +++ b/src/aioslsk/tasks.py @@ -1,6 +1,7 @@ import asyncio +from collections.abc import Callable, Coroutine import logging -from typing import Any, Callable, Coroutine, Optional, Union +from typing import Any, Optional, Union logger = logging.getLogger(__name__) diff --git a/src/aioslsk/transfer/cache.py b/src/aioslsk/transfer/cache.py index 2a55cab2..d20053bc 100644 --- a/src/aioslsk/transfer/cache.py +++ b/src/aioslsk/transfer/cache.py @@ -2,7 +2,7 @@ import logging import os import shelve -from typing import List, Protocol +from typing import Protocol from .model import Transfer @@ -12,20 +12,20 @@ class TransferCache(Protocol): """Abstract base class for storing shares""" - def read(self) -> List['Transfer']: + def read(self) -> list['Transfer']: ... - def write(self, transfers: List['Transfer']): + def write(self, transfers: list['Transfer']): ... class TransferNullCache: """Transfer cache object that does not perform any caching""" - def read(self) -> List['Transfer']: # pragma: no cover + def read(self) -> list['Transfer']: # pragma: no cover return [] - def write(self, transfers: List['Transfer']): # pragma: no cover + def write(self, transfers: list['Transfer']): # pragma: no cover pass @@ -39,7 +39,7 @@ class TransferShelveCache: def __init__(self, data_directory: str): self.data_directory = data_directory - def read(self) -> List['Transfer']: + def read(self) -> list['Transfer']: db_path = os.path.join(self.data_directory, self.DEFAULT_FILENAME) transfers = [] @@ -51,7 +51,7 @@ def read(self) -> List['Transfer']: return transfers - def write(self, transfers: List['Transfer']): + def write(self, transfers: list['Transfer']): db_path = os.path.join(self.data_directory, self.DEFAULT_FILENAME) logger.info("writing %d transfers to : %s", len(transfers), db_path) diff --git a/src/aioslsk/transfer/manager.py b/src/aioslsk/transfer/manager.py index 40a26ae2..a4c9da5a 100644 --- a/src/aioslsk/transfer/manager.py +++ b/src/aioslsk/transfer/manager.py @@ -6,7 +6,7 @@ import logging from operator import itemgetter import os -from typing import Dict, List, Optional, Set, Tuple, TYPE_CHECKING +from typing import Optional, TYPE_CHECKING from ..base_manager import BaseManager from .cache import TransferNullCache, TransferCache @@ -97,8 +97,8 @@ def __init__( self.cache: TransferCache = cache if cache else TransferNullCache() self._ticket_generator = ticket_generator() - self._transfers: List[Transfer] = [] - self._file_connection_futures: Dict[int, asyncio.Future] = {} + self._transfers: list[Transfer] = [] + self._file_connection_futures: dict[int, asyncio.Future] = {} self._progress_reporting_task: BackgroundTask = BackgroundTask( interval=self._settings.transfers.report_interval, task_coro=self._progress_reporting_job, @@ -125,7 +125,7 @@ async def read_cache(self): """Reads the transfers from the caches and corrects the state of those transfers """ - transfers: List[Transfer] = self.cache.read() + transfers: list[Transfer] = self.cache.read() for transfer in transfers: # Analyze the current state of the stored transfers and set them to # the correct state @@ -159,7 +159,7 @@ async def store_data(self): async def start(self): await self.start_progress_reporting_task() - async def stop(self) -> List[asyncio.Task]: + async def stop(self) -> list[asyncio.Task]: """Cancel all current transfer tasks :return: a list of tasks that have been cancelled so that they can be @@ -327,10 +327,10 @@ async def remove(self, transfer: Transfer): await self.manage_transfers() - def get_uploads(self) -> List[Transfer]: + def get_uploads(self) -> list[Transfer]: return [transfer for transfer in self._transfers if transfer.is_upload()] - def get_downloads(self) -> List[Transfer]: + def get_downloads(self) -> list[Transfer]: return [transfer for transfer in self._transfers if transfer.is_download()] def get_upload_slots(self) -> int: @@ -356,7 +356,7 @@ def get_queue_size(self) -> int: if transfer.is_upload() and transfer.state == TransferState.QUEUED ]) - def get_downloading(self) -> List[Transfer]: + def get_downloading(self) -> list[Transfer]: """Returns all transfers that are currently downloading or an attempt is is made to start downloading """ @@ -365,7 +365,7 @@ def get_downloading(self) -> List[Transfer]: if transfer.is_download() and transfer.is_processing() ] - def get_uploading(self) -> List[Transfer]: + def get_uploading(self) -> list[Transfer]: """Returns all transfers that are currently uploading or an attempt is is made to start uploading """ @@ -374,7 +374,7 @@ def get_uploading(self) -> List[Transfer]: if transfer.is_upload() and transfer.is_processing() ] - def get_finished_transfers(self) -> List[Transfer]: + def get_finished_transfers(self) -> list[Transfer]: """Returns a complete list of transfers that are in a finalized state (COMPLETE, ABORTED, FAILED) """ @@ -383,7 +383,7 @@ def get_finished_transfers(self) -> List[Transfer]: if transfer.is_finalized() ] - def get_unfinished_transfers(self) -> List[Transfer]: + def get_unfinished_transfers(self) -> list[Transfer]: """Returns a complete list of transfers that are not in a finalized state (COMPLETE, ABORTED, FAILED) """ @@ -493,20 +493,20 @@ async def manage_transfers(self): upload._transfer_task_complete ) - def _get_queued_transfers(self) -> Tuple[List[Transfer], List[Transfer]]: + def _get_queued_transfers(self) -> tuple[list[Transfer], list[Transfer]]: """Returns all transfers eligable for being initialized :return: a tuple containing 2 lists: the eligable downloads and eligable uploads """ - uploading_users: Set[str] = { + uploading_users: set[str] = { transfer.username for transfer in self._transfers if transfer.is_upload() and transfer.is_processing() } - users_with_queued_upload: Set[str] = set() + users_with_queued_upload: set[str] = set() - queued_downloads: List[Transfer] = [] - queued_uploads: List[Transfer] = [] + queued_downloads: list[Transfer] = [] + queued_uploads: list[Transfer] = [] for transfer in self._transfers: # Get the user object from the user manager, if the user is tracked # this user object will be returned. Otherwise a new user object is @@ -543,7 +543,7 @@ def _get_queued_transfers(self) -> Tuple[List[Transfer], List[Transfer]]: return queued_downloads, queued_uploads - def _prioritize_uploads(self, uploads: List[Transfer]) -> List[Transfer]: + def _prioritize_uploads(self, uploads: list[Transfer]) -> list[Transfer]: """Ranks the queued uploads by priority based on certain parameters :return: sorted list of provided by uploads by priority diff --git a/src/aioslsk/transfer/model.py b/src/aioslsk/transfer/model.py index 37f38a73..9873e1ab 100644 --- a/src/aioslsk/transfer/model.py +++ b/src/aioslsk/transfer/model.py @@ -5,7 +5,7 @@ from enum import Enum import logging import time -from typing import Deque, List, Optional, Tuple +from typing import Optional from .state import TransferState, TransferStateListener, VirginState @@ -96,11 +96,11 @@ def __init__(self, username: str, remote_path: str, direction: TransferDirection """Snapshot of the transfer progress. Used internally to report progress at set intervals """ - self._speed_log: Deque[Tuple[float, int]] = deque(maxlen=SPEED_LOG_ENTRIES) + self._speed_log: deque[tuple[float, int]] = deque(maxlen=SPEED_LOG_ENTRIES) self._remotely_queue_task: Optional[asyncio.Task] = None self._transfer_task: Optional[asyncio.Task] = None self._state_lock: asyncio.Lock = asyncio.Lock() - self.state_listeners: List[TransferStateListener] = [] + self.state_listeners: list[TransferStateListener] = [] def __setstate__(self, obj_state): """Called when unpickling""" @@ -279,7 +279,7 @@ def is_transferring(self) -> bool: def is_transfered(self) -> bool: return self.filesize == self.bytes_transfered - def get_tasks(self) -> List[asyncio.Task]: + def get_tasks(self) -> list[asyncio.Task]: tasks = [] if self._remotely_queue_task is not None: tasks.append(self._remotely_queue_task) @@ -287,7 +287,7 @@ def get_tasks(self) -> List[asyncio.Task]: tasks.append(self._transfer_task) return tasks - def cancel_tasks(self) -> List[asyncio.Task]: + def cancel_tasks(self) -> list[asyncio.Task]: """Cancels all tasks for the transfer, this method returns the tasks which have been cancelled """ diff --git a/src/aioslsk/user/manager.py b/src/aioslsk/user/manager.py index 01f1b68d..c4d1d037 100644 --- a/src/aioslsk/user/manager.py +++ b/src/aioslsk/user/manager.py @@ -2,7 +2,7 @@ import copy from dataclasses import dataclass import logging -from typing import Dict, Optional, Set +from typing import Optional from weakref import WeakValueDictionary from ..base_manager import BaseManager @@ -85,8 +85,8 @@ def __init__(self, settings: Settings, event_bus: EventBus, network: Network): self._MESSAGE_MAP = build_message_map(self) self._users: WeakValueDictionary[str, User] = WeakValueDictionary() - self._tracked_users: Dict[str, TrackedUser] = dict() - self._privileged_users: Set[str] = set() + self._tracked_users: dict[str, TrackedUser] = dict() + self._privileged_users: set[str] = set() self.register_listeners() @@ -101,11 +101,11 @@ def register_listeners(self): SessionDestroyedEvent, self._on_session_destroyed) @property - def users(self) -> Dict[str, User]: + def users(self) -> dict[str, User]: return dict(self._users) @property - def privileged_users(self) -> Set[str]: + def privileged_users(self) -> set[str]: return self._privileged_users def get_self(self) -> User: diff --git a/src/aioslsk/user/model.py b/src/aioslsk/user/model.py index f9f91d3d..b8560fae 100644 --- a/src/aioslsk/user/model.py +++ b/src/aioslsk/user/model.py @@ -1,7 +1,7 @@ from __future__ import annotations from dataclasses import dataclass, field from enum import auto, Enum, Flag -from typing import Optional, Set +from typing import Optional from ..protocol.primitives import UserStats @@ -65,8 +65,8 @@ class User: upload_permissions: UploadPermissions = UploadPermissions.UNKNOWN # Interests - interests: Set[str] = field(default_factory=set) - hated_interests: Set[str] = field(default_factory=set) + interests: set[str] = field(default_factory=set) + hated_interests: set[str] = field(default_factory=set) def update_from_user_stats(self, user_stats: UserStats): self.avg_speed = user_stats.avg_speed diff --git a/src/aioslsk/utils.py b/src/aioslsk/utils.py index 3d40d805..9b8c188f 100644 --- a/src/aioslsk/utils.py +++ b/src/aioslsk/utils.py @@ -1,7 +1,7 @@ +from collections.abc import Generator import itertools import logging import re -from typing import Generator, List from .constants import PATH_SEPERATOR_PATTERN from .protocol.primitives import Attribute @@ -24,12 +24,12 @@ def try_decoding(value: bytes): raise -def split_remote_path(path: str) -> List[str]: +def split_remote_path(path: str) -> list[str]: """Splits a remote path into parts. Empty parts will be filtered out""" return [part for part in re.split(PATH_SEPERATOR_PATTERN, path) if part] -def get_duration(attributes: List[Attribute]) -> str: +def get_duration(attributes: list[Attribute]) -> str: duration = '' for attr in attributes: if attr.key == 1: @@ -40,7 +40,7 @@ def get_duration(attributes: List[Attribute]) -> str: return duration -def get_attribute_string(attributes: List[Attribute]) -> str: +def get_attribute_string(attributes: list[Attribute]) -> str: attr_str = [] for attr in attributes: if attr.key == 0: diff --git a/tests/e2e/fixtures.py b/tests/e2e/fixtures.py index 6077a795..a7e31354 100644 --- a/tests/e2e/fixtures.py +++ b/tests/e2e/fixtures.py @@ -1,11 +1,11 @@ import asyncio from async_timeout import timeout as atimeout +from collections.abc import AsyncGenerator import os from pathlib import Path import pytest_asyncio from pytest import FixtureRequest import shutil -from typing import AsyncGenerator, List from aioslsk.client import SoulSeekClient from aioslsk.events import SessionInitializedEvent @@ -137,8 +137,8 @@ async def client_2(tmp_path: Path) -> AsyncGenerator[SoulSeekClient, None]: @pytest_asyncio.fixture -async def clients(tmp_path: Path, request) -> AsyncGenerator[List[SoulSeekClient], None]: - clients: List[SoulSeekClient] = [] +async def clients(tmp_path: Path, request) -> AsyncGenerator[list[SoulSeekClient], None]: + clients: list[SoulSeekClient] = [] for idx in range(request.param): username = 'user' + str(idx).zfill(3) diff --git a/tests/e2e/mock/constants.py b/tests/e2e/mock/constants.py index fde88ce2..672330d8 100644 --- a/tests/e2e/mock/constants.py +++ b/tests/e2e/mock/constants.py @@ -1,8 +1,7 @@ import struct -from typing import List -DEFAULT_EXCLUDED_SEARCH_PHRASES: List[str] = ['banned phrase'] +DEFAULT_EXCLUDED_SEARCH_PHRASES: list[str] = ['banned phrase'] HEADER_SIZE: int = struct.calcsize('I') MAX_ITEM_RECOMMENDATIONS: int = 100 """Max items returned by GetItemRecommendations per list (value is known)""" diff --git a/tests/e2e/mock/distributed.py b/tests/e2e/mock/distributed.py index 947a33c4..3bef2244 100644 --- a/tests/e2e/mock/distributed.py +++ b/tests/e2e/mock/distributed.py @@ -1,7 +1,6 @@ from abc import ABC, abstractmethod from math import ceil import random -from typing import Dict, List from tests.e2e.mock.peer import Peer from tests.e2e.mock.model import DistributedValues, Settings @@ -9,12 +8,12 @@ class DistributedStrategy(ABC): def __init__( - self, settings: Settings, peers: List[Peer], - distributed_tree: Dict[str, DistributedValues]): + self, settings: Settings, peers: list[Peer], + distributed_tree: dict[str, DistributedValues]): self.settings: Settings = settings - self.peers: List[Peer] = peers - self.tree: Dict[str, DistributedValues] = distributed_tree + self.peers: list[Peer] = peers + self.tree: dict[str, DistributedValues] = distributed_tree @classmethod @abstractmethod @@ -22,23 +21,23 @@ def get_name(cls) -> str: ... @abstractmethod - def get_potential_parents(self, target_peer: Peer) -> List[Peer]: + def get_potential_parents(self, target_peer: Peer) -> list[Peer]: ... - def get_roots(self) -> List[Peer]: + def get_roots(self) -> list[Peer]: """Returns the distributed roots""" return self.get_potential_roots() - def get_potential_roots(self) -> List[Peer]: + def get_potential_roots(self) -> list[Peer]: return [ peer for peer in self._get_valid_peers() if self.tree[peer.user.name].level == 0 ] - def _get_valid_peers(self) -> List[Peer]: + def _get_valid_peers(self) -> list[Peer]: return [peer for peer in self.peers if peer.user] - def _get_peers_accepting_children(self) -> List[Peer]: + def _get_peers_accepting_children(self) -> list[Peer]: """Returns a list of all peers that are: * Have a valid user assigned @@ -54,7 +53,7 @@ def _get_peers_accepting_children(self) -> List[Peer]: return eligable_peers - def sort_peers_by_connect_time(self, peers: List[Peer], reverse: bool = False) -> List[Peer]: + def sort_peers_by_connect_time(self, peers: list[Peer], reverse: bool = False) -> list[Peer]: peers.sort( key=lambda p: p.connect_time, reverse=reverse @@ -69,13 +68,13 @@ class ConnectTimeOldestRootStrategy(DistributedStrategy): def get_name(cls) -> str: return 'connect_time_oldest_root' - def get_potential_parents(self, target_peer: Peer) -> List[Peer]: + def get_potential_parents(self, target_peer: Peer) -> list[Peer]: return [ peer for peer in self.get_roots() if peer != target_peer ] - def get_roots(self) -> List[Peer]: + def get_roots(self) -> list[Peer]: peers = self.sort_peers_by_connect_time(self.get_potential_roots()) if not peers: return [] @@ -92,7 +91,7 @@ class ConnectTimeChainStrategy(DistributedStrategy): def get_name(cls) -> str: return 'connect_time_chain' - def get_potential_parents(self, target_peer: Peer) -> List[Peer]: + def get_potential_parents(self, target_peer: Peer) -> list[Peer]: peers = [ peer for peer in self._get_peers_accepting_children() if peer != target_peer and peer.connect_time < target_peer.connect_time @@ -103,7 +102,7 @@ def get_potential_parents(self, target_peer: Peer) -> List[Peer]: return self.sort_peers_by_connect_time(peers, reverse=True)[:1] - def get_roots(self) -> List[Peer]: + def get_roots(self) -> list[Peer]: peers = self.get_potential_roots() if not peers: return [] @@ -120,7 +119,7 @@ class ChainParentsStrategy(DistributedStrategy): def get_name(cls) -> str: return 'chain' - def get_potential_parents(self, target_peer: Peer) -> List[Peer]: + def get_potential_parents(self, target_peer: Peer) -> list[Peer]: accepting_peers = self._get_peers_accepting_children() try: max_level = max([ @@ -143,10 +142,10 @@ class EveryoneRootStrategy(DistributedStrategy): def get_name(cls) -> str: return 'everyone_root' - def get_roots(self) -> List[Peer]: + def get_roots(self) -> list[Peer]: return self.peers - def get_potential_parents(self, target_peer: Peer) -> List[Peer]: + def get_potential_parents(self, target_peer: Peer) -> list[Peer]: return [] @@ -209,7 +208,7 @@ class RealisticParentsStrategy(DistributedStrategy): selection process. """ - def __init__(self, settings: Settings, peers: List[Peer]): + def __init__(self, settings: Settings, peers: list[Peer]): super().__init__(settings, peers) self.root_percentage: float = 0.01 @@ -217,7 +216,7 @@ def __init__(self, settings: Settings, peers: List[Peer]): def get_name(cls) -> str: return 'realistic' - def get_potential_parents(self, target_peer: Peer) -> List[Peer]: + def get_potential_parents(self, target_peer: Peer) -> list[Peer]: possible_peers = [] for peer in self._get_peers_accepting_children(): if peer == target_peer: @@ -228,7 +227,7 @@ def get_potential_parents(self, target_peer: Peer) -> List[Peer]: return random.choices(possible_peers, k=10) - def get_roots(self) -> List[Peer]: + def get_roots(self) -> list[Peer]: roots = sorted( self.get_potential_roots(), key=lambda p: p.user.avg_speed, diff --git a/tests/e2e/mock/model.py b/tests/e2e/mock/model.py index 067bd744..4f7269af 100644 --- a/tests/e2e/mock/model.py +++ b/tests/e2e/mock/model.py @@ -4,7 +4,7 @@ from aioslsk.protocol.messages import PrivateChatMessage from aioslsk.user.model import UserStatus import typing -from typing import Dict, List, Set, Optional +from typing import Optional from weakref import WeakValueDictionary @@ -86,11 +86,11 @@ class User: port: Optional[int] = None obfuscated_port: Optional[int] = None - interests: Set[str] = field(default_factory=set) - hated_interests: Set[str] = field(default_factory=set) + interests: set[str] = field(default_factory=set) + hated_interests: set[str] = field(default_factory=set) - queued_private_messages: List[QueuedPrivateMessage] = field(default_factory=list) - added_users: Dict[str, 'User'] = field(default_factory=WeakValueDictionary) + queued_private_messages: list[QueuedPrivateMessage] = field(default_factory=list) + added_users: dict[str, 'User'] = field(default_factory=WeakValueDictionary) # TODO: Investigate what the default values are enable_private_rooms: bool = False @@ -129,14 +129,14 @@ class RoomStatus(Enum): @dataclass class Room: name: str - joined_users: List[User] = field(default_factory=list) + joined_users: list[User] = field(default_factory=list) tickers: typing.OrderedDict[str, str] = field(default_factory=OrderedDict) registered_as_public: bool = False # Only for private rooms owner: Optional[User] = None - members: List[User] = field(default_factory=list) - operators: List[User] = field(default_factory=list) + members: list[User] = field(default_factory=list) + operators: list[User] = field(default_factory=list) @property def status(self) -> RoomStatus: @@ -148,7 +148,7 @@ def status(self) -> RoomStatus: return RoomStatus.UNCLAIMED @property - def all_members(self) -> List[User]: + def all_members(self) -> list[User]: return self.members + [self.owner, ] if self.owner else [] def can_join(self, user: User) -> bool: diff --git a/tests/e2e/mock/server.py b/tests/e2e/mock/server.py index 27919797..bff8e1db 100644 --- a/tests/e2e/mock/server.py +++ b/tests/e2e/mock/server.py @@ -1,14 +1,14 @@ import argparse import asyncio from collections import Counter +from collections.abc import Generator from dataclasses import fields from functools import partial import logging import re import socket import time -from typing import Dict, Generator, List, Optional, Set, Type, TypeVar -import typing +from typing import Optional, TypeVar from aioslsk.events import build_message_map from aioslsk.user.model import UserStatus @@ -137,7 +137,7 @@ def ticket_generator(initial: int = 1) -> Generator[int, None, None]: yield idx -def remove_0_values(counter: typing.Counter[str]): +def remove_0_values(counter: Counter[str]): recommendations_to_remove = [ key for key, value in counter.items() if value == 0 ] @@ -145,7 +145,7 @@ def remove_0_values(counter: typing.Counter[str]): del counter[to_remove] -def on_message(message_class: Type[MessageDataclass], require_user: bool = True): +def on_message(message_class: type[MessageDataclass], require_user: bool = True): """Decorator for methods listening to specific `MessageData` events """ def register(event_func): @@ -159,24 +159,24 @@ def register(event_func): class MockServer: def __init__( - self, hostname: str = '0.0.0.0', ports: Set[int] = {2416}, - excluded_search_phrases: List[str] = DEFAULT_EXCLUDED_SEARCH_PHRASES, + self, hostname: str = '0.0.0.0', ports: set[int] = {2416}, + excluded_search_phrases: list[str] = DEFAULT_EXCLUDED_SEARCH_PHRASES, potential_parent_interval: int = 0, - distributed_strategy_class: Type[DistributedStrategy] = EveryoneRootStrategy, + distributed_strategy_class: type[DistributedStrategy] = EveryoneRootStrategy, settings: Optional[Settings] = None, mock_variables: Optional[MockVariables] = None): self.hostname: str = hostname - self.ports: Set[int] = ports - self.connections: Dict[int, asyncio.Server] = {} + self.ports: set[int] = ports + self.connections: dict[int, asyncio.Server] = {} self.settings: Settings = settings or Settings() - self.users: List[User] = [] - self.rooms: List[Room] = [] - self.peers: List[Peer] = [] - self.distributed_tree: Dict[str, DistributedValues] = {} + self.users: list[User] = [] + self.rooms: list[Room] = [] + self.peers: list[Peer] = [] + self.distributed_tree: dict[str, DistributedValues] = {} - self.excluded_search_phrases: List[str] = excluded_search_phrases + self.excluded_search_phrases: list[str] = excluded_search_phrases self.distributed_strategy: DistributedStrategy = self._create_distributed_strategy(distributed_strategy_class) self.mock_variables: MockVariables = mock_variables or MockVariables() @@ -194,10 +194,10 @@ def __init__( self.periodic_search_task = asyncio.create_task( self.search_request_job(interval=self.mock_variables.search_interval)) - def _create_distributed_strategy(self, strategy_cls: Type[T]) -> T: + def _create_distributed_strategy(self, strategy_cls: type[T]) -> T: return strategy_cls(self.settings, self.peers, self.distributed_tree) - def set_distributed_strategy(self, strategy_cls: Type[DistributedStrategy]): + def set_distributed_strategy(self, strategy_cls: type[DistributedStrategy]): self.distributed_strategy = self._create_distributed_strategy(strategy_cls) async def notify_potential_parents(self): @@ -335,7 +335,7 @@ async def on_peer_message(self, message, peer: Peer): await method(message, peer) - def get_valid_peers(self) -> List[Peer]: + def get_valid_peers(self) -> list[Peer]: """Returns all peers which are logged in (user set)""" return [peer for peer in self.peers if peer.user] @@ -354,10 +354,10 @@ def find_room_by_name(self, name: str) -> Optional[Room]: if room.name == name: return room - def get_user_private_rooms(self, user: User) -> List[Room]: + def get_user_private_rooms(self, user: User) -> list[Room]: return [room for room in self.rooms if user in room.all_members] - def get_joined_rooms(self, user: User) -> List[Room]: + def get_joined_rooms(self, user: User) -> list[Room]: return [room for room in self.rooms if user in room.joined_users] async def set_upload_speed(self, username: str, uploads: int, speed: int): @@ -403,7 +403,7 @@ async def send_search_request(self, username: str, sender: str, query: str, tick await peer.send_message(message) async def send_potential_parents( - self, username: str, potential_parents: List[str] = None): + self, username: str, potential_parents: list[str] = None): """This is a utility method used for testing to send the potential parents to the peer with given username @@ -439,7 +439,7 @@ async def send_potential_parents( await peer.send_message(message) async def send_private_message( - self, message: str, sender: str, receivers: List[str]): + self, message: str, sender: str, receivers: list[str]): """Sends a private message to one or more users""" queued_message = QueuedPrivateMessage( @@ -472,10 +472,10 @@ async def send_queued_private_messages(self, peer: Peer): queued_message.to_protocol_message(is_direct=False)) def _create_room_list_message(self, user: User, min_users: int = 1): - public_rooms: List[Room] = [] - private_rooms: List[Room] = [] - private_rooms_owned: List[Room] = [] - private_rooms_operated: List[Room] = [] + public_rooms: list[Room] = [] + private_rooms: list[Room] = [] + private_rooms_owned: list[Room] = [] + private_rooms_operated: list[Room] = [] for room in self.rooms: if room.status == RoomStatus.PRIVATE: if room.owner == user: @@ -1110,7 +1110,7 @@ async def on_get_item_recommendations(self, message: GetItemRecommendations.Requ rec_counter = self.get_recommendations_for_item(message.item) del rec_counter[message.item] - recommendations: List[Recommendation] = [] + recommendations: list[Recommendation] = [] for rec, score in rec_counter.most_common(MAX_RECOMMENDATIONS): recommendations.append(Recommendation(rec, score)) @@ -1849,7 +1849,7 @@ async def revoke_operator(self, room: Room, user: User): AdminMessage.PRIVATE_ROOM_OPERATOR_REVOKED.format(user.name, room.name) ) - def get_global_recommendations(self) -> typing.Counter[str]: + def get_global_recommendations(self) -> Counter[str]: """Gets global recommendations :return: List of global recommendations for this item. This still needs @@ -1865,7 +1865,7 @@ def get_global_recommendations(self) -> typing.Counter[str]: return recommendations - def get_recommendations_for_item(self, item: str) -> typing.Counter[str]: + def get_recommendations_for_item(self, item: str) -> Counter[str]: """Gets item recommendations :return: List of recommendations for this item. This still includes @@ -1882,7 +1882,7 @@ def get_recommendations_for_item(self, item: str) -> typing.Counter[str]: return recommendations - def get_recommendations_for_user(self, user: User) -> typing.Counter[str]: + def get_recommendations_for_user(self, user: User) -> Counter[str]: """Gets all recommendations of a user based on his interests""" counter = Counter() for other_peer in self.get_valid_peers(): @@ -1912,7 +1912,7 @@ def get_recommendations_for_user(self, user: User) -> typing.Counter[str]: return counter -def _get_distributed_strategy_class(name: str) -> Type[DistributedStrategy]: +def _get_distributed_strategy_class(name: str) -> type[DistributedStrategy]: for strategy_cls in DistributedStrategy.__subclasses__(): if strategy_cls.get_name() == name: return strategy_cls @@ -1921,7 +1921,7 @@ def _get_distributed_strategy_class(name: str) -> Type[DistributedStrategy]: def _create_argument_group( - parser: argparse.ArgumentParser, dataclass_cls: Type[S], + parser: argparse.ArgumentParser, dataclass_cls: type[S], prefix: Optional[str] = None): """Creates an argparse argument group for a dataclass @@ -1945,7 +1945,7 @@ def _create_argument_group( ) -def _parse_argument_group(args, dataclass_cls: Type[S], prefix: Optional[str] = None) -> S: +def _parse_argument_group(args, dataclass_cls: type[S], prefix: Optional[str] = None) -> S: """Parses an argument group into a dataclass""" arg_prefix = f'{prefix}_' if prefix else '' diff --git a/tests/e2e/test_e2e_distributed.py b/tests/e2e/test_e2e_distributed.py index 98016ea5..b45c45fb 100644 --- a/tests/e2e/test_e2e_distributed.py +++ b/tests/e2e/test_e2e_distributed.py @@ -10,7 +10,6 @@ ) import asyncio import pytest -from typing import List async def set_upload_speed_for_client(mock_server: MockServer, client: SoulSeekClient, value: int = 10000): @@ -18,7 +17,7 @@ async def set_upload_speed_for_client(mock_server: MockServer, client: SoulSeekC await mock_server.set_upload_speed(username, uploads=10, speed=value) -async def set_upload_speed_for_clients(mock_server: MockServer, clients: List[SoulSeekClient], value: int = 10000): +async def set_upload_speed_for_clients(mock_server: MockServer, clients: list[SoulSeekClient], value: int = 10000): """Sets a dummy upload speed on the mock server for all clients. This is necessary in order for the clients to accept children """ @@ -32,7 +31,7 @@ class TestE2EDistributed: @pytest.mark.asyncio @pytest.mark.parametrize("clients", [2], indirect=True) - async def test_root_user(self, mock_server: MockServer, clients: List[SoulSeekClient]): + async def test_root_user(self, mock_server: MockServer, clients: list[SoulSeekClient]): """Tests when a user gets a search request directly from the server the peer becomes root """ @@ -60,7 +59,7 @@ async def test_root_user(self, mock_server: MockServer, clients: List[SoulSeekCl @pytest.mark.asyncio @pytest.mark.parametrize("clients", [2], indirect=True) - async def test_level1_user(self, mock_server: MockServer, clients: List[SoulSeekClient]): + async def test_level1_user(self, mock_server: MockServer, clients: list[SoulSeekClient]): """Tests when a user gets a search request directly from the server the peer becomes root """ @@ -100,7 +99,7 @@ async def test_level1_user(self, mock_server: MockServer, clients: List[SoulSeek @pytest.mark.asyncio @pytest.mark.parametrize("clients", [3], indirect=True) - async def test_level2_user(self, mock_server: MockServer, clients: List[SoulSeekClient]): + async def test_level2_user(self, mock_server: MockServer, clients: list[SoulSeekClient]): """Tests when a user gets a search request directly from the server the peer becomes root """ @@ -167,7 +166,7 @@ async def test_level2_user(self, mock_server: MockServer, clients: List[SoulSeek @pytest.mark.asyncio @pytest.mark.parametrize("clients", [4], indirect=True) - async def test_level2_sendSearchRequest(self, mock_server: MockServer, clients: List[SoulSeekClient]): + async def test_level2_sendSearchRequest(self, mock_server: MockServer, clients: list[SoulSeekClient]): """Tests if clients on multiple levels in the network receive a search request """ diff --git a/tests/e2e/test_e2e_search.py b/tests/e2e/test_e2e_search.py index c130793b..96a3cd76 100644 --- a/tests/e2e/test_e2e_search.py +++ b/tests/e2e/test_e2e_search.py @@ -14,7 +14,6 @@ wait_for_listener_awaited_events, ) import pytest -from typing import Tuple from unittest.mock import AsyncMock @@ -57,7 +56,7 @@ async def test_search_without_timeout( ) async def test_search_with_timeout( self, mock_server: MockServer, client_1: SoulSeekClient, - search_func_name: str, search_params: Tuple, search_type: SearchType): + search_func_name: str, search_params: tuple, search_type: SearchType): await wait_until_clients_initialized(mock_server, amount=1) diff --git a/tests/unit/network/test_network.py b/tests/unit/network/test_network.py index 03af08de..845c98f5 100644 --- a/tests/unit/network/test_network.py +++ b/tests/unit/network/test_network.py @@ -1,6 +1,6 @@ import pytest -from typing import Tuple from unittest.mock import AsyncMock, Mock +from typing import Optional from aioslsk.events import EventBus from aioslsk.exceptions import ConnectionFailedError, ListeningConnectionFailedError @@ -39,7 +39,7 @@ class TestNetworkManager: - def _create_network(self, settings=None) -> Network: + def _create_network(self, settings: Optional[Settings] = None) -> Network: sett = settings or Settings(**DEFAULT_SETTINGS) network = Network(sett, EventBus()) network.server_connection = Mock() @@ -58,7 +58,7 @@ def _create_network(self, settings=None) -> Network: (1, 2, True, (2, True)), ] ) - def test_selectPort(self, clear_port: int, obfuscated_port: int, prefer_obfuscated: bool, expected: Tuple[int, bool]): + def test_selectPort(self, clear_port: int, obfuscated_port: int, prefer_obfuscated: bool, expected: tuple[int, bool]): network = self._create_network() network._settings.network.peer.obfuscate = prefer_obfuscated actual = network.select_port(clear_port, obfuscated_port) diff --git a/tests/unit/shares/test_shares_manager.py b/tests/unit/shares/test_shares_manager.py index 2957562f..95611ee0 100644 --- a/tests/unit/shares/test_shares_manager.py +++ b/tests/unit/shares/test_shares_manager.py @@ -15,7 +15,7 @@ from pytest_unordered import unordered import os import sys -from typing import Optional, List, Type +from typing import Optional from unittest.mock import patch, AsyncMock @@ -163,7 +163,7 @@ class TestSharesManagerQuery: ('片仮名', ['item2', 'item3']) ] ) - def test_querySimpleTerms_matching(self, manager_query: SharesManager, query: str, expected_items: List[str]): + def test_querySimpleTerms_matching(self, manager_query: SharesManager, query: str, expected_items: list[str]): expected_items = [SHARED_ITEMS[item_name] for item_name in expected_items] actual_items, locked_items = manager_query.query(query) assert expected_items == unordered(actual_items) @@ -200,7 +200,7 @@ def test_querySimpleTerms_notMatching(self, manager_query: SharesManager, query: ('simple_band', ['item3']), ] ) - def test_querySpecialCharactersInTerm_matching(self, manager_query: SharesManager, query: str, expected_items: List[str]): + def test_querySpecialCharactersInTerm_matching(self, manager_query: SharesManager, query: str, expected_items: list[str]): expected_items = [SHARED_ITEMS[item_name] for item_name in expected_items] actual_items, locked_items = manager_query.query(query) assert expected_items == unordered(actual_items) @@ -221,7 +221,7 @@ def test_querySpecialCharactersInTerm_matching(self, manager_query: SharesManage ('*仮名', ['item2', 'item3']), ] ) - def test_queryWildcard_matching(self, manager_query: SharesManager, query: str, expected_items: List[str]): + def test_queryWildcard_matching(self, manager_query: SharesManager, query: str, expected_items: list[str]): expected_items = [SHARED_ITEMS[item_name] for item_name in expected_items] actual_items, locked_items = manager_query.query(query) assert expected_items == unordered(actual_items) @@ -240,7 +240,7 @@ def test_queryWildcard_matching(self, manager_query: SharesManager, query: str, ('simple -片仮名', ['item1']) ] ) - def test_queryExcludeTerm(self, manager_query: SharesManager, query: str, expected_items: List[str]): + def test_queryExcludeTerm(self, manager_query: SharesManager, query: str, expected_items: list[str]): expected_items = [SHARED_ITEMS[item_name] for item_name in expected_items] actual_items, locked_items = manager_query.query(query) assert expected_items == unordered(actual_items) @@ -266,7 +266,7 @@ def test_queryExcludedSearchPhrases(self, manager_query: SharesManager): ('simple -singer)_-_don\'t', ['item1', 'item3']), ] ) - def test_edgeCases(self, manager_query: SharesManager, query: str, expected_items: List[str]): + def test_edgeCases(self, manager_query: SharesManager, query: str, expected_items: list[str]): expected_items = [SHARED_ITEMS[item_name] for item_name in expected_items] actual_items, locked_items = manager_query.query(query) assert expected_items == unordered(actual_items) @@ -289,7 +289,7 @@ def test_edgeCases(self, manager_query: SharesManager, query: str, expected_item ('song -folk/folkalbum', ['item1', 'item2', 'item3']), ] ) - def test_queryTermsWithSlashes(self, manager_query: SharesManager, query: str, expected_items: List[str]): + def test_queryTermsWithSlashes(self, manager_query: SharesManager, query: str, expected_items: list[str]): expected_items = [SHARED_ITEMS[item_name] for item_name in expected_items] actual_items, locked_items = manager_query.query(query) assert expected_items == unordered(actual_items) @@ -326,7 +326,7 @@ def test_loadFromSettings(self, manager: SharesManager): ProcessPoolExecutor ] ) - async def test_scan(self, manager: SharesManager, executor: Optional[Type[Executor]]): + async def test_scan(self, manager: SharesManager, executor: Optional[type[Executor]]): manager.load_from_settings() manager.executor = executor() if executor else None diff --git a/tests/unit/transfer/test_transfer_cache.py b/tests/unit/transfer/test_transfer_cache.py index e921bd63..bb8b5adf 100644 --- a/tests/unit/transfer/test_transfer_cache.py +++ b/tests/unit/transfer/test_transfer_cache.py @@ -1,7 +1,6 @@ import copy import os from pytest_unordered import unordered -from typing import List import shutil from aioslsk.transfer.cache import TransferShelveCache @@ -16,7 +15,7 @@ RESOURCES = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'resources') -def create_transfers() -> List[Transfer]: +def create_transfers() -> list[Transfer]: download = Transfer('user0', '@abcdef\\file.mp3', TransferDirection.DOWNLOAD) download.state = CompleteState(download) download.start_time = 1.0 diff --git a/tests/unit/transfer/test_transfer_state.py b/tests/unit/transfer/test_transfer_state.py index 1b6fa9b0..656ef4ef 100644 --- a/tests/unit/transfer/test_transfer_state.py +++ b/tests/unit/transfer/test_transfer_state.py @@ -1,4 +1,3 @@ -from typing import Type from unittest.mock import MagicMock, patch import pytest @@ -44,7 +43,7 @@ async def test_whenTransitionVirginToQueued_shouldResetRemotelyQueued(self): UploadingState, ]) @pytest.mark.asyncio - async def test_whenTransitionToFailed_shouldSetStateAndCompleteTime(self, initial_state: Type[TransferState]): + async def test_whenTransitionToFailed_shouldSetStateAndCompleteTime(self, initial_state: type[TransferState]): time_mock = MagicMock(return_value=12.0) transfer = Transfer(None, None, TransferDirection.DOWNLOAD) @@ -63,7 +62,7 @@ async def test_whenTransitionToFailed_shouldSetStateAndCompleteTime(self, initia IncompleteState, ]) @pytest.mark.asyncio - async def test_whenTransitionToFailed_shouldSetState(self, initial_state: Type[TransferState]): + async def test_whenTransitionToFailed_shouldSetState(self, initial_state: type[TransferState]): transfer = Transfer(None, None, TransferDirection.DOWNLOAD) transfer.state = initial_state(transfer) await transfer.state.fail(reason='err') @@ -77,7 +76,7 @@ async def test_whenTransitionToFailed_shouldSetState(self, initial_state: Type[T UploadingState, ]) @pytest.mark.asyncio - async def test_whenTransitionToAborted_shouldSetStateAndCompleteTime(self, initial_state: Type[TransferState]): + async def test_whenTransitionToAborted_shouldSetStateAndCompleteTime(self, initial_state: type[TransferState]): time_mock = MagicMock(return_value=12.0) transfer = Transfer(None, None, TransferDirection.DOWNLOAD) @@ -95,7 +94,7 @@ async def test_whenTransitionToAborted_shouldSetStateAndCompleteTime(self, initi IncompleteState, ]) @pytest.mark.asyncio - async def test_whenTransitionToAborted_shouldSetState(self, initial_state: Type[TransferState]): + async def test_whenTransitionToAborted_shouldSetState(self, initial_state: type[TransferState]): transfer = Transfer(None, None, TransferDirection.DOWNLOAD) transfer.state = initial_state(transfer) await transfer.state.abort() @@ -107,7 +106,7 @@ async def test_whenTransitionToAborted_shouldSetState(self, initial_state: Type[ InitializingState, ]) @pytest.mark.asyncio - async def test_whenTransitionToQueued_shouldSetState(self, initial_state: Type[TransferState]): + async def test_whenTransitionToQueued_shouldSetState(self, initial_state: type[TransferState]): transfer = Transfer(None, None, TransferDirection.DOWNLOAD) transfer.state = initial_state(transfer) await transfer.state.queue() @@ -121,7 +120,7 @@ async def test_whenTransitionToQueued_shouldSetState(self, initial_state: Type[T FailedState, ]) @pytest.mark.asyncio - async def test_whenTransitionToQueued_shouldSetStateAndResetTimes(self, initial_state: Type[TransferState]): + async def test_whenTransitionToQueued_shouldSetStateAndResetTimes(self, initial_state: type[TransferState]): transfer = Transfer(None, None, TransferDirection.DOWNLOAD) transfer.state = initial_state(transfer) transfer.start_time = 1.0