diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..2e9f5cd4 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,23 @@ +name: Publish + +on: + release: + types: [ created ] + +jobs: + run: + name: "Build and publish release" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v3 + with: + version: "0.8.10" + + - run: uv python install 3.12 + - run: uv build + - run: uv publish + env: + UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/vrplib.yml b/.github/workflows/vrplib.yml index 4025b8f7..ac5c3b5b 100644 --- a/.github/workflows/vrplib.yml +++ b/.github/workflows/vrplib.yml @@ -5,68 +5,46 @@ on: branches: [ main ] pull_request: branches: [ main ] - release: - types: [created] - jobs: build: runs-on: ubuntu-latest strategy: matrix: - python-version: [ '3.9', '3.10', '3.11', '3.12' ] + python-version: [ '3.10', '3.11', '3.12', '3.13' ] steps: - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Update pip and poetry - run: | - python -m pip install --upgrade pip - pip install poetry - - name: Cache Python dependencies - uses: actions/cache@v4 - id: cache-python + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@v6 with: - path: ~/.cache/pypoetry - key: python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }} - - name: Install Python dependencies - if: steps.cache-python.outputs.cache-hit != 'true' - run: poetry install + version: "0.8.10" + enable-cache: true + + - name: Install Python version + run: uv python install ${{ matrix.python-version }} + + - name: Install the project + run: uv sync + - name: Cache pre-commit uses: actions/cache@v4 id: cache-pre-commit with: path: ~/.cache/pre-commit/ - key: pre-commit-${{ env.pythonLocation }}-${{ hashFiles('.pre-commit-config.yaml') }} + key: pre-commit-${{ matrix.python-version }}-${{ hashFiles('.pre-commit-config.yaml') }} + - name: Install pre-commit if: steps.cache-pre-commit.outputs.cache-hit != 'true' - run: poetry run pre-commit install --install-hooks + run: uv run pre-commit install --install-hooks + - name: Run pre-commit - run: poetry run pre-commit run --all-files - - name: Run pytest - run: poetry run pytest - - uses: codecov/codecov-action@v3 + run: uv run pre-commit run --all-files + + - name: Run tests + run: uv run pytest + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - deploy: - needs: build - if: github.event_name == 'release' && github.event.action == 'created' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: 3.9 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install poetry - - name: Deploy to PyPI - run: | - poetry config pypi-token.pypi ${{ secrets.PYPI_TOKEN }} - poetry build - poetry publish diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c7a4f506..3ccde1de 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,25 +1,20 @@ fail_fast: true repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 hooks: - - id: debug-statements - id: trailing-whitespace - id: end-of-file-fixer + - id: debug-statements + - id: end-of-file-fixer -- repo: https://github.com/psf/black - rev: 23.3.0 + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.12.8 hooks: - - id: black + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format -- repo: https://github.com/charliermarsh/ruff-pre-commit - rev: 'v0.0.261' + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.17.1 hooks: - - id: ruff - args: [--fix] - -- repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.2.0 - hooks: - - id: mypy + - id: mypy diff --git a/README.md b/README.md index 79f54e27..550a6285 100644 --- a/README.md +++ b/README.md @@ -108,25 +108,6 @@ Vehicle types: [1, 2, 3] ``` -### Downloading from CVRPLIB - -> [!WARNING] -> This functionality is deprecated and will be removed in the next major version. - -``` python -import vrplib - -# Download an instance and a solution file -vrplib.download_instance("X-n101-k25", "/path/to/instances/") -vrplib.download_solution("X-n101-k25", "/path/to/solutions/") - -# List all instance names that can be downloaded -vrplib.list_names() # All instance names -vrplib.list_names(low=100, high=200) # Instances with between [100, 200] customers -vrplib.list_names(vrp_type="cvrp") # Only CVRP instances -vrplib.list_names(vrp_type="vrptw") # Only VRPTW instances -``` - ## Documentation - [VRPLIB instance format](#vrplib-instance-format) @@ -246,6 +227,5 @@ Reading the above example solution returns the following dictionary: ``` ### Other remarks -- The `XML100` benchmark set is not listed in `list_names` and cannot be downloaded through this package. You can download these instances directly from [CVRPLIB](http://vrp.atd-lab.inf.puc-rio.br/index.php/en/). - In the literature, some instances use rounding conventions different from what is specified in the instance. For example, X instance set proposed by [Uchoa et al. (2017)](http://vrp.atd-lab.inf.puc-rio.br/index.php/en/new-instances) assumes that the distances are rounded to the nearest integer. When you use the `vrplib` package to read this instance, it will return non-rounded Euclidean distances because the instance specifies the `EUC_2D` edge weight type which implies no rounding. To adhere to the convention used in the literature, you can manually round the distances matrix. - For large instances (>5000 customers) it's recommended to set the `compute_edge_weights` argument to `False` in `read_instance`. diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index 09b1349d..00000000 --- a/poetry.lock +++ /dev/null @@ -1,621 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.0 and should not be changed by hand. - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "cfgv" -version = "3.4.0" -description = "Validate configuration and produce human readable error messages." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, - {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, -] - -[[package]] -name = "charset-normalizer" -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.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]] -name = "codecov" -version = "2.1.13" -description = "Hosted coverage reports for GitHub, Bitbucket and Gitlab" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "codecov-2.1.13-py2.py3-none-any.whl", hash = "sha256:c2ca5e51bba9ebb43644c43d0690148a55086f7f5e6fd36170858fa4206744d5"}, - {file = "codecov-2.1.13.tar.gz", hash = "sha256:2362b685633caeaf45b9951a9b76ce359cd3581dd515b430c6c3f5dfb4d92a8c"}, -] - -[package.dependencies] -coverage = "*" -requests = ">=2.7.9" - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "coverage" -version = "7.6.2" -description = "Code coverage measurement for Python" -optional = false -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] -tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} - -[package.extras] -toml = ["tomli"] - -[[package]] -name = "distlib" -version = "0.3.9" -description = "Distribution utilities" -optional = false -python-versions = "*" -files = [ - {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, - {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "filelock" -version = "3.16.1" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.8" -files = [ - {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, - {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] -typing = ["typing-extensions (>=4.12.2)"] - -[[package]] -name = "identify" -version = "2.6.1" -description = "File identification library for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0"}, - {file = "identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98"}, -] - -[package.extras] -license = ["ukkonen"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {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 = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "nodeenv" -version = "1.9.1" -description = "Node.js virtual environment builder" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, - {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, -] - -[[package]] -name = "numpy" -version = "2.0.2" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece"}, - {file = "numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04"}, - {file = "numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66"}, - {file = "numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b"}, - {file = "numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd"}, - {file = "numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318"}, - {file = "numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8"}, - {file = "numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326"}, - {file = "numpy-2.0.2-cp310-cp310-win32.whl", hash = "sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97"}, - {file = "numpy-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131"}, - {file = "numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448"}, - {file = "numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195"}, - {file = "numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57"}, - {file = "numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a"}, - {file = "numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669"}, - {file = "numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951"}, - {file = "numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9"}, - {file = "numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15"}, - {file = "numpy-2.0.2-cp311-cp311-win32.whl", hash = "sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4"}, - {file = "numpy-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc"}, - {file = "numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b"}, - {file = "numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e"}, - {file = "numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c"}, - {file = "numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c"}, - {file = "numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692"}, - {file = "numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a"}, - {file = "numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c"}, - {file = "numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded"}, - {file = "numpy-2.0.2-cp312-cp312-win32.whl", hash = "sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5"}, - {file = "numpy-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a"}, - {file = "numpy-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9059e10581ce4093f735ed23f3b9d283b9d517ff46009ddd485f1747eb22653c"}, - {file = "numpy-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:423e89b23490805d2a5a96fe40ec507407b8ee786d66f7328be214f9679df6dd"}, - {file = "numpy-2.0.2-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:2b2955fa6f11907cf7a70dab0d0755159bca87755e831e47932367fc8f2f2d0b"}, - {file = "numpy-2.0.2-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:97032a27bd9d8988b9a97a8c4d2c9f2c15a81f61e2f21404d7e8ef00cb5be729"}, - {file = "numpy-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e795a8be3ddbac43274f18588329c72939870a16cae810c2b73461c40718ab1"}, - {file = "numpy-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b258c385842546006213344c50655ff1555a9338e2e5e02a0756dc3e803dd"}, - {file = "numpy-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fec9451a7789926bcf7c2b8d187292c9f93ea30284802a0ab3f5be8ab36865d"}, - {file = "numpy-2.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9189427407d88ff25ecf8f12469d4d39d35bee1db5d39fc5c168c6f088a6956d"}, - {file = "numpy-2.0.2-cp39-cp39-win32.whl", hash = "sha256:905d16e0c60200656500c95b6b8dca5d109e23cb24abc701d41c02d74c6b3afa"}, - {file = "numpy-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:a3f4ab0caa7f053f6797fcd4e1e25caee367db3112ef2b6ef82d749530768c73"}, - {file = "numpy-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f0a0c6f12e07fa94133c8a67404322845220c06a9e80e85999afe727f7438b8"}, - {file = "numpy-2.0.2-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:312950fdd060354350ed123c0e25a71327d3711584beaef30cdaa93320c392d4"}, - {file = "numpy-2.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26df23238872200f63518dd2aa984cfca675d82469535dc7162dc2ee52d9dd5c"}, - {file = "numpy-2.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a46288ec55ebbd58947d31d72be2c63cbf839f0a63b49cb755022310792a3385"}, - {file = "numpy-2.0.2.tar.gz", hash = "sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pre-commit" -version = "2.21.0" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pre_commit-2.21.0-py2.py3-none-any.whl", hash = "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad"}, - {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"}, -] - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -virtualenv = ">=20.10.0" - -[[package]] -name = "pytest" -version = "7.4.4" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-cov" -version = "4.1.0" -description = "Pytest plugin for measuring coverage." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, - {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, -] - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "tomli" -version = "2.0.2" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, -] - -[[package]] -name = "urllib3" -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.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "virtualenv" -version = "20.26.6" -description = "Virtual Python Environment builder" -optional = false -python-versions = ">=3.7" -files = [ - {file = "virtualenv-20.26.6-py3-none-any.whl", hash = "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2"}, - {file = "virtualenv-20.26.6.tar.gz", hash = "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48"}, -] - -[package.dependencies] -distlib = ">=0.3.7,<1" -filelock = ">=3.12.2,<4" -platformdirs = ">=3.9.1,<5" - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9" -content-hash = "45ec912f2551234863a75f338a4c7e0d77654a87b256a544e8c52e372532621d" diff --git a/pyproject.toml b/pyproject.toml index 8a08a2eb..f68ca405 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,52 +1,76 @@ -[tool.poetry] +[project] name = "vrplib" version = "1.5.1" description = "Python library for reading and writing VRP instances." -authors = ["Leon Lan "] +authors = [ + { name = "Leon Lan", email = "leon.lanyidong@gmail.com" }, +] license = "MIT" +license-files = ["LICENSE.md"] +keywords = [ + "vehicle routing problem", + "benchmarking", +] +classifiers = [ + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Development Status :: 5 - Production/Stable", + "Topic :: Software Development", + "Topic :: Scientific/Engineering", + "Programming Language :: Python :: 3", +] +requires-python = ">=3.10" +dependencies = [ + "numpy>=1.19.3; python_version < '3.12'", + "numpy>=1.26.0; python_version >= '3.12'", +] readme = "README.md" repository = "https://github.com/PyVRP/VRPLIB" -[tool.poetry.dependencies] -python = "^3.9" -numpy = ">=1.19.3" -[tool.poetry.group.dev.dependencies] -pytest = "^7.1.2" -codecov = "^2.1.13" -pytest-cov = "^4.0.0" -pre-commit = "^2.19.0" +[project.urls] +source = "https://github.com/PyVRP/VRPLIB" +issues = "https://github.com/PyVRP/VRPLIB/issues" + + +[dependency-groups] +dev = [ + "pre-commit>=2.20.0", + "pytest>=7.1.2", + "pytest-cov>=6.1.1", + "codecov", +] + [build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" +requires = ["uv_build>=0.8.10,<0.9.0"] +build-backend = "uv_build" -[tool.black] -line-length = 79 -[tool.mypy] -ignore_missing_imports = true +[tool.uv.build-backend] +module-name = "vrplib" +module-root = "" + [tool.ruff] +line-length = 79 + + +[tool.ruff.lint] select = [ - "E", # pycodestyle errors - "W", # pycodestyle warnings - "F", # pyflakes - "I", # isort - "C", # flake8-comprehensions -] -ignore = [ - "E501", # line too long, handled by black - "C901", # too complex + "E", "F", "I", "NPY", "PYI", "Q", "RET", "RSE", "RUF", "SLF", "SIM", "TC", ] -[tool.ruff.per-file-ignores] -"__init__.py" = ["F401"] + +[tool.mypy] +ignore_missing_imports = true + [tool.pytest.ini_options] addopts = "--cov=. --cov-report=xml" pythonpath = [".", "vrplib"] + [tool.coverage.run] omit = [ "tests/*", diff --git a/tests/download/__init__.py b/tests/download/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/download/test_download_instance.py b/tests/download/test_download_instance.py deleted file mode 100644 index 699be06f..00000000 --- a/tests/download/test_download_instance.py +++ /dev/null @@ -1,87 +0,0 @@ -import os - -import pytest -from numpy.testing import assert_, assert_equal - -from vrplib import download_instance - - -def test_deprecation_warning(tmp_path): - """ - Checks if a deprecation warning is raised when the function is called. - """ - with pytest.warns(DeprecationWarning): - download_instance("X-n101-k25", tmp_path / "tmp") - - -@pytest.mark.filterwarnings("ignore:The function") -def test_raise_invalid_name(tmp_path): - """ - Raise an error if the passed-in name is invalid. - """ - with pytest.raises(ValueError): - download_instance("invalid_name", tmp_path / "tmp") - - -@pytest.mark.filterwarnings("ignore:The function") -def test_download_vrplib_instance_file_name(tmp_path): - """ - Tests if a VRPLIB instance is correctly downloaded from CVRPLIB - and saved to the passed-in file path. - """ - name = "X-n101-k25" - fname = "random_file_name.txt" - file_path = tmp_path / fname - - download_instance(name, file_path) - assert_(os.path.exists(file_path)) - - with open(file_path, "r") as fi: - actual = fi.read() - - with open(f"tests/data/cvrplib/{name}.vrp", "r") as fi: - desired = fi.read() - - assert_equal(actual, desired) - - -@pytest.mark.filterwarnings("ignore:The function") -def test_download_vrplib_instance_dir_path(tmp_path): - """ - Tests if a VRPLIB instance is correctly downloaded from CVRPLIB - and saved to the passed-in directory. - """ - name = "X-n101-k25" - dir_path = tmp_path - file_path = dir_path / (name + ".vrp") - - download_instance(name, dir_path) - assert_(os.path.exists(file_path)) - - with open(file_path, "r") as fi: - actual = fi.read() - - with open(f"tests/data/cvrplib/{name}.vrp", "r") as fi: - desired = fi.read() - - assert_equal(actual, desired) - - -@pytest.mark.filterwarnings("ignore:The function") -def test_download_solomon_instance(tmp_path): - """ - Tests if a Solomon instance is correctly downloaded from CVRPLIB. - """ - name = "C101" - ext = ".txt" - loc = tmp_path / (name + ext) - - download_instance(name, loc) - - with open(loc, "r") as fi: - actual = fi.read() - - with open(f"tests/data/cvrplib/{name + ext}", "r") as fi: - desired = fi.read() - - assert_equal(actual, desired) diff --git a/tests/download/test_download_solution.py b/tests/download/test_download_solution.py deleted file mode 100644 index f11c5573..00000000 --- a/tests/download/test_download_solution.py +++ /dev/null @@ -1,93 +0,0 @@ -import os - -import pytest -from numpy.testing import assert_, assert_equal, assert_raises - -from vrplib import download_solution - - -def test_deprecation_warning(tmp_path): - """ - Checks if a deprecation warning is raised when the function is called. - """ - with pytest.warns(DeprecationWarning): - download_solution("X-n101-k25", tmp_path / "tmp") - - -@pytest.mark.filterwarnings("ignore:The function") -def test_raise_invalid_name(tmp_path): - """ - Raise an error if the passed-in name is invalid. - """ - with assert_raises(ValueError): - download_solution("invalid_name", tmp_path / "tmp") - - -@pytest.mark.filterwarnings("ignore:The function") -def test_download_vrplib_solution_file_name_path(tmp_path): - """ - Tests if a VRPLIB solution is correctly downloaded from CVRPLIB - and saved to the passed-in file path. - """ - name = "X-n101-k25" - fname = "random_file_name.txt" - file_path = tmp_path / fname - - download_solution(name, file_path) - assert_(os.path.exists(file_path)) - - with open(file_path, "r") as fi: - actual = fi.read() - - # The best known solution is known to be optimal, so the solution - # file in the repository will not be outdated. - with open(f"tests/data/cvrplib/{name}.sol", "r") as fi: - desired = fi.read() - - assert_equal(actual, desired) - - -@pytest.mark.filterwarnings("ignore:The function") -def test_download_vrplib_solution_dir_path(tmp_path): - """ - Tests if a VRPLIB solution is correctly downloaded from CVRPLIB - and saved to the passed-in directory. - """ - name = "X-n101-k25" - dir_path = tmp_path - file_path = dir_path / (name + ".sol") - - download_solution(name, dir_path) - assert_(os.path.exists(file_path)) - - with open(file_path, "r") as fi: - actual = fi.read() - - # The best known solution is known to be optimal, so the solution - # file in the repository will not be outdated. - with open(f"tests/data/cvrplib/{name}.sol", "r") as fi: - desired = fi.read() - - assert_equal(actual, desired) - - -@pytest.mark.filterwarnings("ignore:The function") -def test_download_solomon_solution(tmp_path): - """ - Tests if a Solomon solution is correctly downloaded from CVRPLIB. - """ - name = "C101" - ext = ".sol" - loc = tmp_path / (name + ext) - - download_solution(name, loc) - - with open(loc, "r") as fi: - actual = fi.read() - - # The best known solution is known to be optimal, so the solution - # file in the repository will not be outdated. - with open(f"tests/data/cvrplib/{name + ext}", "r") as fi: - desired = fi.read() - - assert_equal(actual, desired) diff --git a/tests/download/test_download_utils.py b/tests/download/test_download_utils.py deleted file mode 100644 index 6a41d0d0..00000000 --- a/tests/download/test_download_utils.py +++ /dev/null @@ -1,16 +0,0 @@ -import pytest -from numpy.testing import assert_equal - -from vrplib.download.download_utils import find_set - -from ..utils import selected_cases - - -@pytest.mark.parametrize("case", selected_cases()) -def test_find_dir(case): - assert_equal(find_set(case.instance_name), case.set_name) - - -def test_raise_invalid_name(): - with pytest.raises(ValueError): - find_set("test_name") diff --git a/tests/download/test_list_names.py b/tests/download/test_list_names.py deleted file mode 100644 index bae8c1a8..00000000 --- a/tests/download/test_list_names.py +++ /dev/null @@ -1,54 +0,0 @@ -import pytest -from numpy.testing import assert_ - -from vrplib import list_names - -from ..utils import selected_cases - - -def test_deprecationg_warning(): - """ - Check if the deprecation warning is raised. - """ - with pytest.warns(DeprecationWarning): - list_names(1, 2, "cvrp") - - -@pytest.mark.filterwarnings("ignore:The function") -@pytest.mark.parametrize("case", selected_cases()) -def test_list_names(case): - assert_(case.instance_name in list_names()) - - -@pytest.mark.filterwarnings("ignore:The function") -@pytest.mark.parametrize( - "low, high, vrp_type", - [ - (1, 2, "vrp"), # vrp not in [None, 'cvrp', 'vrptw'] - ], -) -def test_list_names_raise(low, high, vrp_type): - """ - Raise for invalid input paramaters. - """ - with pytest.raises(ValueError): - list_names(low, high, vrp_type) - - -@pytest.mark.filterwarnings("ignore:The function") -@pytest.mark.parametrize( - "name, low, high, vrp_type", - [ - ("A-n32-k5", 31, 31, "cvrp"), - ("ORTEC-n242-k12", 0, 241, "cvrp"), - ("Flanders2", 30000, None, "cvrp"), - ("X-n101-k25", 0, 100, None), - ("RC208", 0, 100, "vrptw"), - ("RC2_10_10", 1000, 1000, None), - ], -) -def test_list_names_n(name, low, high, vrp_type): - """ - Check if the passed-in name is in the list of names. - """ - assert_(name in list_names(low, high, vrp_type)) diff --git a/tests/parse/test_parse_solomon.py b/tests/parse/test_parse_solomon.py index 6b7e0bd0..86677c6e 100644 --- a/tests/parse/test_parse_solomon.py +++ b/tests/parse/test_parse_solomon.py @@ -26,9 +26,8 @@ ], ) def test_raise_invalid_solomon_instance_file(name): - with assert_raises(RuntimeError): - with open(DATA_DIR / name, "r") as fh: - parse_solomon(fh.read()) + with open(DATA_DIR / name, "r") as fh, assert_raises(RuntimeError): + parse_solomon(fh.read()) @mark.parametrize( @@ -43,8 +42,14 @@ def test_raise_invalid_solomon_instance_file(name): # no CUSTOMER in fifth line ["NAME", "VEHICLES", "NUMBER CAPACITY", "20 100", "wrong"], # missing headers in sixth line - ["NAME", "VEHICLES", "NUMBER CAPACITY", "20 100", "wrong"] - + ["CUST NO. XCOORD. YCOORD. DEMAND"], + [ + "NAME", + "VEHICLES", + "NUMBER CAPACITY", + "20 100", + "wrong", + "CUST NO. XCOORD. YCOORD. DEMAND", + ], ], ) def test_raise_invalid_solomon_instance_lines(lines): diff --git a/tests/parse/test_parse_vrplib.py b/tests/parse/test_parse_vrplib.py index 0c040c13..8daef486 100644 --- a/tests/parse/test_parse_vrplib.py +++ b/tests/parse/test_parse_vrplib.py @@ -27,9 +27,8 @@ def test_raise_invalid_vrplib_format(name): """ Tests if a RuntimeError is raised when the text is not in VRPLIB format. """ - with open(DATA_DIR / name, "r") as fh: - with assert_raises(RuntimeError): - parse_vrplib(fh.read()) + with open(DATA_DIR / name, "r") as fh, assert_raises(RuntimeError): + parse_vrplib(fh.read()) @mark.parametrize( diff --git a/tests/utils.py b/tests/utils.py deleted file mode 100644 index b6557460..00000000 --- a/tests/utils.py +++ /dev/null @@ -1,79 +0,0 @@ -from dataclasses import dataclass -from pathlib import Path - -from vrplib.download.download_utils import find_set - -CVRPLIB_DATA_DIR = Path("tests/data/cvrplib/") - - -@dataclass -class Case: - name: str - set_name: str - instance_name: str - instance_path: str - solution_path: str - dimension: int - capacity: int - cost: float - - -def make_case( - set_name, - instance_name, - dimension, - capacity, - cost, -): - """ - Return a test case based on the passed-in arguments. - """ - return Case( - name=set_name + "/" + instance_name, - set_name=set_name, - instance_name=instance_name, - instance_path=CVRPLIB_DATA_DIR - / ( - instance_name - + ( - ".txt" - if find_set(instance_name) in ["Solomon", "HG"] - else ".vrp" - ) - ), - solution_path=CVRPLIB_DATA_DIR / (instance_name + ".sol"), - dimension=dimension, - capacity=capacity, - cost=cost, - ) - - -def selected_cases(): - """ - A selection of test cases. - """ - A = make_case("A", "A-n32-k5", 32, 100, 784) - B = make_case("B", "B-n31-k5", 31, 100, 672) - C = make_case("CMT", "CMT6", 51, 160, 555.43) - D = make_case("D", "ORTEC-n242-k12", 242, 125, 123750) - E = make_case("E", "E-n13-k4", 13, 6000, 247) - F = make_case("F", "F-n72-k4", 72, 30000, 237) - G = make_case("Golden", "Golden_1", 241, 550, 5623.47) - L = make_case("Li", "Li_21", 561, 1200, 16212.82548) - M = make_case("M", "M-n101-k10", 101, 200, 820) - P = make_case("P", "P-n16-k8", 16, 35, 450) - X = make_case("X", "X-n101-k25", 101, 206, 27591) - - return [ - A, - B, - C, - D, - E, - F, - G, - L, - M, - P, - X, - ] diff --git a/vrplib/__init__.py b/vrplib/__init__.py index 380fe7ad..71545ed6 100644 --- a/vrplib/__init__.py +++ b/vrplib/__init__.py @@ -1,3 +1,4 @@ -from .download import download_instance, download_solution, list_names -from .read import read_instance, read_solution -from .write import write_instance, write_solution +from .read import read_instance as read_instance +from .read import read_solution as read_solution +from .write import write_instance as write_instance +from .write import write_solution as write_solution diff --git a/vrplib/download/__init__.py b/vrplib/download/__init__.py deleted file mode 100644 index 0fe0917e..00000000 --- a/vrplib/download/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .download_instance import download_instance -from .download_solution import download_solution -from .list_names import list_names diff --git a/vrplib/download/constants.py b/vrplib/download/constants.py deleted file mode 100644 index 62b036e8..00000000 --- a/vrplib/download/constants.py +++ /dev/null @@ -1,25 +0,0 @@ -CVRPLIB_URL = "http://vrp.atd-lab.inf.puc-rio.br/media/com_vrp/instances/" - - -CVRP_SETS = [ - "A", - "B", - "E", - "F", - "M", - "P", - "CMT", - "tai", - "Golden", - "Li", - "X", - "XXL", -] - -VRPTW_SETS = [ - "Solomon", - "HG", -] - -XXL_NAMES = ["Antwerp", "Brussels", "Flanders", "Ghent", "Leuven"] -DIMACS_NAMES = ["Loggi", "ORTEC"] diff --git a/vrplib/download/download_instance.py b/vrplib/download/download_instance.py deleted file mode 100644 index 7120c845..00000000 --- a/vrplib/download/download_instance.py +++ /dev/null @@ -1,41 +0,0 @@ -import os -import warnings -from pathlib import Path -from typing import Union -from urllib.request import urlopen - -from .constants import CVRPLIB_URL -from .download_utils import find_set, is_vrptw - - -def download_instance(name: str, path: Union[str, os.PathLike]): - """ - Downloads an instance file from CVRPLIB and saves it at the specified path. - - Parameters - ---------- - name - The name of the instance to download. Should be one of the names - listed in `vrplib.list_instances()`. - path - The path where the instance file should be saved. If a directory is - specified, the file will be saved in that directory with the original - file name. - """ - msg = ( - "The function 'download_instance' is deprecated and will be removed" - " in the next major version (vrplib v2.0.0)." - ) - warnings.warn(msg, DeprecationWarning) - - ext = "txt" if is_vrptw(name) else "vrp" - url = CVRPLIB_URL + f"{find_set(name)}/{name}.{ext}" - response = urlopen(url, timeout=30) - - instance_text = response.read().decode("utf-8") - - if os.path.isdir(path): - path = Path(path) / f"{name}.{ext}" - - with open(path, "w") as fi: - fi.write(instance_text) diff --git a/vrplib/download/download_solution.py b/vrplib/download/download_solution.py deleted file mode 100644 index ef4c639b..00000000 --- a/vrplib/download/download_solution.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import warnings -from pathlib import Path -from typing import Union -from urllib.request import urlopen - -from .constants import CVRPLIB_URL -from .download_utils import find_set - - -def download_solution(name: str, path: Union[str, os.PathLike]): - """ - Downloads a solution file from CVRPLIB and saves it at the specified path. - - Parameters - ---------- - name - The name of the instance to download. Should be one of the names - listed in `vrplib.list_instances`. - path - The path where the solution file should be saved. If a directory is - specified, the file will be saved in that directory with the original - file name. - """ - msg = ( - "The function 'download_solution' is deprecated and will be removed" - " in the next major version (vrplib v2.0.0)." - ) - warnings.warn(msg, DeprecationWarning) - - url = CVRPLIB_URL + f"{find_set(name)}/{name}.sol" - response = urlopen(url, timeout=30) - - solution_text = response.read().decode("utf-8") - - if os.path.isdir(path): - path = Path(path) / f"{name}.sol" - - with open(path, "w") as fi: - fi.write(solution_text) diff --git a/vrplib/download/download_utils.py b/vrplib/download/download_utils.py deleted file mode 100644 index e2da7faf..00000000 --- a/vrplib/download/download_utils.py +++ /dev/null @@ -1,43 +0,0 @@ -import re - -from .constants import CVRP_SETS, DIMACS_NAMES, XXL_NAMES - - -def find_set(instance_name: str) -> str: - """ - Find the set name of the instance. - - Notes - ----- - - VRPTW instances start with "C, R, RC" directly followed by 1 or 2. - HG instances have underscores ("_") in the name, whereas Solomon - instances do not. - - CVRP instance names and their corresponding set names share the same - first letter. the exceptions are XXL and DIMACS instances, which have - unique instance names - """ - if re.match("(R|C|RC)[12]", instance_name): - if "_" in instance_name: - return "HG" - else: - return "Solomon" - - if any([instance_name.startswith(xxl) for xxl in XXL_NAMES]): - return "XXL" - - if any([instance_name.startswith(dimacs) for dimacs in DIMACS_NAMES]): - return "D" - - for set_name in CVRP_SETS: - if instance_name.startswith(set_name): - return set_name - - raise ValueError(f"Set name not known for instance: {instance_name}.") - - -def is_vrptw(name: str) -> bool: - """ - Checks if the passed-in name is a VRPTW instance or not. Otherwise the - instance is a CVRP instance. - """ - return find_set(name) in ["HG", "Solomon"] diff --git a/vrplib/download/instance_data.csv b/vrplib/download/instance_data.csv deleted file mode 100644 index 20759ab5..00000000 --- a/vrplib/download/instance_data.csv +++ /dev/null @@ -1,631 +0,0 @@ -A-n32-k5,31,5,100,784,yes -A-n33-k5,32,5,100,661,yes -A-n33-k6,32,6,100,742,yes -A-n34-k5,33,5,100,778,yes -A-n36-k5,35,5,100,799,yes -A-n37-k5,36,5,100,669,yes -A-n37-k6,36,6,100,949,yes -A-n38-k5,37,5,100,730,yes -A-n39-k5,38,5,100,822,yes -A-n39-k6,38,6,100,831,yes -A-n44-k6,43,6,100,937,yes -A-n45-k6,44,6,100,944,yes -A-n45-k7,44,7,100,1146,yes -A-n46-k7,45,7,100,914,yes -A-n48-k7,47,7,100,1073,yes -A-n53-k7,52,7,100,1010,yes -A-n54-k7,53,7,100,1167,yes -A-n55-k9,54,9,100,1073,yes -A-n60-k9,59,9,100,1354,yes -A-n61-k9,60,9,100,1034,yes -A-n62-k8,61,8,100,1288,yes -A-n63-k9,62,9,100,1616,yes -A-n63-k10,62,10,100,1314,yes -A-n64-k9,63,9,100,1401,yes -A-n65-k9,64,9,100,1174,yes -A-n69-k9,68,9,100,1159,yes -A-n80-k10,79,10,100,1763,yes -B-n31-k5,30,5,100,672,yes -B-n34-k5,33,5,100,788,yes -B-n35-k5,34,5,100,955,yes -B-n38-k6,37,6,100,805,yes -B-n39-k5,38,5,100,549,yes -B-n41-k6,40,6,100,829,yes -B-n43-k6,42,6,100,742,yes -B-n44-k7,43,7,100,909,yes -B-n45-k5,44,5,100,751,yes -B-n45-k6,44,6,100,678,yes -B-n50-k7,49,7,100,741,yes -B-n50-k8,49,8,100,1312,yes -B-n51-k7,50,7,100,1032,yes -B-n52-k7,51,7,100,747,yes -B-n56-k7,55,7,100,707,yes -B-n57-k7,56,7,100,1153,yes -B-n57-k9,56,9,100,1598,yes -B-n63-k10,62,10,100,1496,yes -B-n64-k9,63,9,100,861,yes -B-n66-k9,65,9,100,1316,yes -B-n67-k10,66,10,100,1032,yes -B-n68-k9,67,9,100,1272,yes -B-n78-k10,77,10,100,1221,yes -E-n13-k4,12,4,6000,247,yes -E-n22-k4,21,4,6000,375,yes -E-n23-k3,22,3,4500,569,yes -E-n30-k3,29,3,4500,534,yes -E-n31-k7,30,7,140,379,yes -E-n33-k4,32,4,8000,835,yes -E-n51-k5,50,5,160,521,yes -E-n76-k7,75,7,220,682,yes -E-n76-k8,75,8,180,735,yes -E-n76-k10,75,10,140,830,yes -E-n76-k14,75,14,100,1021,yes -E-n101-k8,100,8,200,815,yes -E-n101-k14,100,14,112,1067,yes -F-n45-k4,44,4,2010,724,yes -F-n72-k4,71,4,30000,237,yes -F-n135-k7,134,7,2210,1162,yes -M-n101-k10,100,10,200,820,yes -M-n121-k7,120,7,200,1034,yes -M-n151-k12,150,12,200,1015,yes -M-n200-k16,199,16,200,1274,yes -M-n200-k17,199,17,200,1275,yes -P-n16-k8,15,8,35,450,yes -P-n19-k2,18,2,160,212,yes -P-n20-k2,19,2,160,216,yes -P-n21-k2,20,2,160,211,yes -P-n22-k2,21,2,160,216,yes -P-n22-k8,21,8,3000,603,yes -P-n23-k8,22,8,40,529,yes -P-n40-k5,39,5,140,458,yes -P-n45-k5,44,5,150,510,yes -P-n50-k7,49,7,150,554,yes -P-n50-k8,49,8,120,631,yes -P-n50-k10,49,10,100,696,yes -P-n51-k10,50,10,80,741,yes -P-n55-k7,54,7,170,568,yes -P-n55-k10,54,10,115,694,yes -P-n55-k15,54,15,70,989,yes -P-n60-k10,59,10,120,744,yes -P-n60-k15,59,15,80,968,yes -P-n65-k10,64,10,130,792,yes -P-n70-k10,69,10,135,827,yes -P-n76-k4,75,4,350,593,yes -P-n76-k5,75,5,280,627,yes -P-n101-k4,100,4,400,681,yes -CMT1,50,5,160,524.61,yes -CMT2,75,10,140,835.26,yes -CMT3,100,8,200,826.14,yes -CMT4,150,12,200,1028.42,yes -CMT5,199,17,200,1291.29,yes -CMT6,50,6,160,555.43,yes -CMT7,75,11,140,909.68,yes -CMT8,100,9,200,865.94,yes -CMT9,150,14,200,1162.55,yes -CMT10,199,18,200,1395.85,yes -CMT11,120,7,200,1042.12,yes -CMT12,100,10,200,819.56,yes -CMT13,120,11,200,1541.14,yes -CMT14,100,11,200,866.37,yes -tai75a,75,10,1445,1618.36,yes -tai75b,75,9,1679,1344.62,yes -tai75c,75,9,1122,1291.01,yes -tai75d,75,9,1699,1365.42,yes -tai100a,100,11,1409,2041.34,yes -tai100b,100,11,1842,1939.9,yes -tai100c,100,11,2043,1406.2,yes -tai100d,100,11,1297,1580.46,yes -tai150a,150,15,1544,3055.23,yes -tai150b,150,14,1918,2727.03,yes -tai150c,150,14,2021,2358.66,yes -tai150d,150,14,1874,2645.39,yes -tai385,385,46,65,24366.41,no -Golden_1,240,9,550,5623.47,no -Golden_2,320,10,700,8404.61,no -Golden_3,400,9,900,10997.8,no -Golden_4,480,10,1000,13588.6,no -Golden_5,200,5,900,6460.98,no -Golden_6,280,7,900,8400.33,no -Golden_7,360,8,900,10102.7,no -Golden_8,440,10,900,11635.3,no -Golden_9,255,14,1000,579.7,no -Golden_10,323,16,1000,735.43,no -Golden_11,399,17,1000,911.98,no -Golden_12,483,19,1000,1100.67,no -Golden_13,252,26,1000,857.19,yes -Golden_14,320,29,1000,1080.55,yes -Golden_15,396,33,1000,1337.27,no -Golden_16,480,36,1000,1611.28,no -Golden_17,240,22,200,707.76,yes -Golden_18,300,27,200,995.13,yes -Golden_19,360,33,200,1365.6,yes -Golden_20,420,38,200,1817.59,yes -Li_21,560,10,1200,16212.83,no -Li_22,600,15,900,14499.04,no -Li_23,640,10,1400,18801.13,no -Li_24,720,10,1500,21389.43,no -Li_25,760,19,900,16665.7,no -Li_26,800,10,1700,23977.73,no -Li_27,840,20,900,17320,no -Li_28,880,10,1800,26566.03,no -Li_29,960,10,2000,29154.34,no -Li_30,1040,10,2100,31742.64,no -Li_31,1120,10,2300,34330.94,no -Li_32,1200,11,2500,37159.41,no -X-n101-k25,100,25,206,27591,yes -X-n106-k14,105,14,600,26362,yes -X-n110-k13,109,13,66,14971,yes -X-n115-k10,114,10,169,12747,yes -X-n120-k6,119,6,21,13332,yes -X-n125-k30,124,30,188,55539,yes -X-n129-k18,128,18,39,28940,yes -X-n134-k13,133,13,643,10916,yes -X-n139-k10,138,10,106,13590,yes -X-n143-k7,142,7,1190,15700,yes -X-n148-k46,147,46,18,43448,yes -X-n153-k22,152,22,144,21220,yes -X-n157-k13,156,13,12,16876,yes -X-n162-k11,161,11,1174,14138,yes -X-n167-k10,166,10,133,20557,yes -X-n172-k51,171,51,161,45607,yes -X-n176-k26,175,26,142,47812,yes -X-n181-k23,180,23,8,25569,yes -X-n186-k15,185,15,974,24145,yes -X-n190-k8,189,8,138,16980,yes -X-n195-k51,194,51,181,44225,yes -X-n200-k36,199,36,402,58578,yes -X-n204-k19,203,19,836,19565,yes -X-n209-k16,208,16,101,30656,yes -X-n214-k11,213,11,944,10856,yes -X-n219-k73,218,73,3,117595,yes -X-n223-k34,222,34,37,40437,yes -X-n228-k23,227,23,154,25742,yes -X-n233-k16,232,16,631,19230,yes -X-n237-k14,236,14,18,27042,yes -X-n242-k48,241,48,28,82751,yes -X-n247-k50,246,47,134,37274,yes -X-n251-k28,250,28,69,38684,yes -X-n256-k16,255,16,1225,18839,yes -X-n261-k13,260,13,1081,26558,yes -X-n266-k58,265,58,35,75478,yes -X-n270-k35,269,35,585,35291,yes -X-n275-k28,274,28,10,21245,yes -X-n280-k17,279,17,192,33503,no -X-n284-k15,283,15,109,20215,yes -X-n289-k60,288,60,267,95151,yes -X-n294-k50,293,50,285,47161,no -X-n298-k31,297,31,55,34231,yes -X-n303-k21,302,21,794,21736,no -X-n308-k13,307,13,246,25859,no -X-n313-k71,312,71,248,94043,no -X-n317-k53,316,53,6,78355,yes -X-n322-k28,321,28,868,29834,yes -X-n327-k20,326,20,128,27532,no -X-n331-k15,330,15,23,31102,yes -X-n336-k84,335,84,203,139111,no -X-n344-k43,343,43,61,42050,no -X-n351-k40,350,40,436,25896,no -X-n359-k29,358,29,68,51505,no -X-n367-k17,366,17,218,22814,no -X-n376-k94,375,94,4,147713,yes -X-n384-k52,383,52,564,65928,no -X-n393-k38,392,38,78,38260,yes -X-n401-k29,400,29,745,66154,no -X-n411-k19,410,19,216,19712,no -X-n420-k130,419,130,18,107798,yes -X-n429-k61,428,61,536,65449,no -X-n439-k37,438,37,12,36391,yes -X-n449-k29,448,29,777,55233,no -X-n459-k26,458,26,1106,24139,no -X-n469-k138,468,138,256,221824,yes -X-n480-k70,479,70,52,89449,no -X-n491-k59,490,59,428,66483,no -X-n502-k39,501,39,13,69226,no -X-n513-k21,512,21,142,24201,no -X-n524-k153,523,137,125,154593,yes -X-n536-k96,535,96,371,94846,no -X-n548-k50,547,50,11,86700,yes -X-n561-k42,560,42,74,42717,no -X-n573-k30,572,30,210,50673,no -X-n586-k159,585,159,28,190316,no -X-n599-k92,598,92,487,108451,no -X-n613-k62,612,62,523,59535,no -X-n627-k43,626,43,110,62164,no -X-n641-k35,640,35,1381,63682,no -X-n655-k131,654,131,5,106780,yes -X-n670-k130,669,126,129,146332,no -X-n685-k75,684,75,408,68205,no -X-n701-k44,700,44,87,81923,no -X-n716-k35,715,35,1007,43373,no -X-n733-k159,732,159,25,136187,no -X-n749-k98,748,98,396,77269,no -X-n766-k71,765,71,166,114417,no -X-n783-k48,782,48,832,72386,no -X-n801-k40,800,40,20,73305,no -X-n819-k171,818,171,358,158121,no -X-n837-k142,836,142,44,193737,no -X-n856-k95,855,95,9,88965,yes -X-n876-k59,875,59,764,99299,no -X-n895-k37,894,37,1816,53860,no -X-n916-k207,915,207,33,329179,no -X-n936-k151,935,151,138,132715,no -X-n957-k87,956,87,11,85465,no -X-n979-k58,978,58,998,118976,no -X-n1001-k43,1000,43,131,72355,no -Antwerp1,6000,,30,477277,no -Antwerp2,7000,,100,291350,no -Brussels1,15000,,50,501719,no -Brussels2,16000,,150,345481,no -Flanders1,20000,,50,7240124,no -Flanders2,30000,,200,4373320,no -Ghent1,10000,,35,469531,no -Ghent2,11000,,170,257748,no -Leuven1,3000,,25,192848,no -Leuven2,4000,,150,111391,no -Loggi-n401-k23,400,23,100,336903,no -Loggi-n501-k24,500,24,120,177176,no -Loggi-n601-k19,600,19,180,113155,no -Loggi-n601-k42,600,42,80,347059,no -Loggi-n901-k42,900,42,120,246301,no -Loggi-n1001-k31,1000,31,180,284356,no -ORTEC-n242-k12,241,12,125,123750,no -ORTEC-n323-k21,322,21,100,214071,no -ORTEC-n405-k18,404,18,160,200986,no -ORTEC-n455-k41,454,41,70,292485,no -ORTEC-n510-k23,509,23,145,184529,no -ORTEC-n701-k64,700,64,80,445543,no -C101,100,,200,827.3,yes -C102,100,,200,827.3,yes -C103,100,,200,826.3,yes -C104,100,,200,822.9,yes -C105,100,,200,827.3,yes -C106,100,,200,827.3,yes -C107,100,,200,827.3,yes -C108,100,,200,827.3,yes -C109,100,,200,827.3,yes -C201,100,,700,589.1,yes -C202,100,,700,589.1,yes -C203,100,,700,588.7,yes -C204,100,,700,588.1,yes -C205,100,,700,586.4,yes -C206,100,,700,586,yes -C207,100,,700,585.8,yes -C208,100,,700,585.8,yes -R101,100,,200,1637.7,yes -R102,100,,200,1466.6,yes -R103,100,,200,1208.7,yes -R104,100,,200,971.5,yes -R105,100,,200,1355.3,yes -R106,100,,200,1234.6,yes -R107,100,,200,1064.6,yes -R108,100,,200,932.1,yes -R109,100,,200,1146.9,yes -R110,100,,200,1068,yes -R111,100,,200,1048.7,yes -R112,100,,200,948.6,yes -R201,100,,1000,1143.2,yes -R202,100,,1000,1029.6,yes -R203,100,,1000,870.8,yes -R204,100,,1000,731.3,yes -R205,100,,1000,949.8,yes -R206,100,,1000,875.9,yes -R207,100,,1000,794,yes -R208,100,,1000,701,yes -R209,100,,1000,854.8,yes -R210,100,,1000,900.5,yes -R211,100,,1000,746.7,yes -RC101,100,,200,1619.8,yes -RC102,100,,200,1457.4,yes -RC103,100,,200,1258,yes -RC104,100,,200,1132.3,yes -RC105,100,,200,1513.7,yes -RC106,100,,200,1372.7,yes -RC107,100,,200,1207.8,yes -RC108,100,,200,1114.2,yes -RC201,100,,1000,1261.8,yes -RC202,100,,1000,1092.3,yes -RC203,100,,1000,923.7,yes -RC204,100,,1000,783.5,yes -RC205,100,,1000,1154,yes -RC206,100,,1000,1051.1,yes -RC207,100,,1000,962.9,yes -RC208,100,,1000,776.1,yes -C1_2_1,200,,200,2698.6,yes -C1_2_2,200,,200,2694.3,yes -C1_2_3,200,,200,2675.8,yes -C1_2_4,200,,200,2625.6,yes -C1_2_5,200,,200,2694.9,yes -C1_2_6,200,,200,2694.9,yes -C1_2_7,200,,200,2694.9,yes -C1_2_8,200,,200,2684,yes -C1_2_9,200,,200,2639.6,yes -C1_2_10,200,,200,2624.7,yes -C2_2_1,200,,700,1922.1,yes -C2_2_2,200,,700,1851.4,yes -C2_2_3,200,,700,1763.4,yes -C2_2_4,200,,700,1695,no -C2_2_5,200,,700,1869.6,yes -C2_2_6,200,,700,1844.8,yes -C2_2_7,200,,700,1842.2,yes -C2_2_8,200,,700,1813.7,yes -C2_2_9,200,,700,1815,yes -C2_2_10,200,,700,1791.2,yes -R1_2_1,200,,200,4667.2,yes -R1_2_2,200,,200,3919.9,yes -R1_2_3,200,,200,3373.9,yes -R1_2_4,200,,200,3047.6,yes -R1_2_5,200,,200,4053.2,yes -R1_2_6,200,,200,3559.1,yes -R1_2_7,200,,200,3141.9,yes -R1_2_8,200,,200,2938.4,yes -R1_2_9,200,,200,3734.7,yes -R1_2_10,200,,200,3293.1,yes -R2_2_1,200,,1000,3468,yes -R2_2_2,200,,1000,3008.2,yes -R2_2_3,200,,1000,2537.5,yes -R2_2_4,200,,1000,1928.5,yes -R2_2_5,200,,1000,3061.1,yes -R2_2_6,200,,1000,2675.4,yes -R2_2_7,200,,1000,2304.7,yes -R2_2_8,200,,1000,1842.4,yes -R2_2_9,200,,1000,2843.3,yes -R2_2_10,200,,1000,2549.4,yes -RC1_2_1,200,,200,3516.9,yes -RC1_2_2,200,,200,3221.6,yes -RC1_2_3,200,,200,3001.4,yes -RC1_2_4,200,,200,2845.2,yes -RC1_2_5,200,,200,3325.6,yes -RC1_2_6,200,,200,3300.7,yes -RC1_2_7,200,,200,3177.8,yes -RC1_2_8,200,,200,3060,yes -RC1_2_9,200,,200,3073.3,no -RC1_2_10,200,,200,2990.5,no -RC2_2_1,200,,1000,2797.4,yes -RC2_2_2,200,,1000,2481.6,yes -RC2_2_3,200,,1000,2227.7,yes -RC2_2_4,200,,1000,1854.8,yes -RC2_2_5,200,,1000,2491.4,yes -RC2_2_6,200,,1000,2495.1,yes -RC2_2_7,200,,1000,2287.7,yes -RC2_2_8,200,,1000,2151.2,yes -RC2_2_9,200,,1000,2086.6,yes -RC2_2_10,200,,1000,1989.2,no -C1_4_1,400,,200,7138.8,no -C1_4_2,400,,200,7113.3,no -C1_4_3,400,,200,6929.9,no -C1_4_4,400,,200,6777.7,no -C1_4_5,400,,200,7138.8,no -C1_4_6,400,,200,7140.1,no -C1_4_7,400,,200,7136.2,no -C1_4_8,400,,200,7083,no -C1_4_9,400,,200,6927.8,no -C1_4_10,400,,200,6825.4,no -C2_4_1,400,,700,4100.3,no -C2_4_2,400,,700,3914.1,no -C2_4_3,400,,700,3755.2,no -C2_4_4,400,,700,3523.7,no -C2_4_5,400,,700,3923.2,no -C2_4_6,400,,700,3860.1,no -C2_4_7,400,,700,3870.9,no -C2_4_8,400,,700,3773.7,no -C2_4_9,400,,700,3842.1,no -C2_4_10,400,,700,3665.1,no -R1_4_1,400,,200,10305.8,no -R1_4_2,400,,200,8876,no -R1_4_3,400,,200,7787.8,no -R1_4_4,400,,200,7266.2,no -R1_4_5,400,,200,9186,no -R1_4_6,400,,200,8340.4,no -R1_4_7,400,,200,7599.8,no -R1_4_8,400,,200,7240.5,no -R1_4_9,400,,200,8677.5,no -R1_4_10,400,,200,8077.8,no -R2_4_1,400,,1000,7520.7,no -R2_4_2,400,,1000,6482.8,no -R2_4_3,400,,1000,5372.9,no -R2_4_4,400,,1000,4211.2,no -R2_4_5,400,,1000,6567.9,no -R2_4_6,400,,1000,5813.5,no -R2_4_7,400,,1000,4893.5,no -R2_4_8,400,,1000,4000.2,no -R2_4_9,400,,1000,6067.8,no -R2_4_10,400,,1000,5645.9,no -RC1_4_1,400,,200,8524,no -RC1_4_2,400,,200,7878.2,no -RC1_4_3,400,,200,7516.9,no -RC1_4_4,400,,200,7292.9,no -RC1_4_5,400,,200,8153,no -RC1_4_6,400,,200,8148,no -RC1_4_7,400,,200,7932.5,no -RC1_4_8,400,,200,7757.2,no -RC1_4_9,400,,200,7717.7,no -RC1_4_10,400,,200,7581.3,no -RC2_4_1,400,,1000,6147.3,no -RC2_4_2,400,,1000,5407.5,no -RC2_4_3,400,,1000,4573,no -RC2_4_4,400,,1000,3597.9,no -RC2_4_5,400,,1000,5392.3,no -RC2_4_6,400,,1000,5324.6,no -RC2_4_7,400,,1000,4987.8,no -RC2_4_8,400,,1000,4693.3,no -RC2_4_9,400,,1000,4510.4,no -RC2_4_10,400,,1000,4252.3,no -C1_6_1,600,,200,14076.6,no -C1_6_2,600,,200,13948.3,no -C1_6_3,600,,200,13757,no -C1_6_4,600,,200,13538.6,no -C1_6_5,600,,200,14066.8,no -C1_6_6,600,,200,14070.9,no -C1_6_7,600,,200,14066.8,no -C1_6_8,600,,200,13991.2,no -C1_6_9,600,,200,13664.5,no -C1_6_10,600,,200,13617.6,no -C2_6_1,600,,700,7752.2,no -C2_6_2,600,,700,7471.5,no -C2_6_3,600,,700,7215,no -C2_6_4,600,,700,6877.6,no -C2_6_5,600,,700,7553.8,no -C2_6_6,600,,700,7449.8,no -C2_6_7,600,,700,7491.4,no -C2_6_8,600,,700,7303.7,no -C2_6_9,600,,700,7303.2,no -C2_6_10,600,,700,7123.9,no -R1_6_1,600,,200,21274.2,no -R1_6_2,600,,200,18558.7,no -R1_6_3,600,,200,16874.9,no -R1_6_4,600,,200,15721.4,no -R1_6_5,600,,200,19305.6,no -R1_6_6,600,,200,17763.7,no -R1_6_7,600,,200,16496.2,no -R1_6_8,600,,200,15584.3,no -R1_6_9,600,,200,18481.5,no -R1_6_10,600,,200,17583.7,no -R2_6_1,600,,1000,15145.3,no -R2_6_2,600,,1000,12986.9,no -R2_6_3,600,,1000,10455.3,no -R2_6_4,600,,1000,7915.1,no -R2_6_5,600,,1000,13794.1,no -R2_6_6,600,,1000,11849.1,no -R2_6_7,600,,1000,9777.9,no -R2_6_8,600,,1000,7512.3,no -R2_6_9,600,,1000,12741.9,no -R2_6_10,600,,1000,11837.7,no -RC1_6_1,600,,200,16960.1,no -RC1_6_2,600,,200,15890.6,no -RC1_6_3,600,,200,15181.4,no -RC1_6_4,600,,200,14753.2,no -RC1_6_5,600,,200,16536.3,no -RC1_6_6,600,,200,16473.3,no -RC1_6_7,600,,200,16055.3,no -RC1_6_8,600,,200,15891.8,no -RC1_6_9,600,,200,15803.5,no -RC1_6_10,600,,200,15651.3,no -RC2_6_1,600,,1000,11966.1,no -RC2_6_2,600,,1000,10336.9,no -RC2_6_3,600,,1000,8894.9,no -RC2_6_4,600,,1000,6967.5,no -RC2_6_5,600,,1000,11080.7,no -RC2_6_6,600,,1000,10830.5,no -RC2_6_7,600,,1000,10293.4,no -RC2_6_8,600,,1000,9804.7,no -RC2_6_9,600,,1000,9436,no -RC2_6_10,600,,1000,8976.1,no -C1_8_1,800,,200,25156.9,no -C1_8_2,800,,200,24974.1,no -C1_8_3,800,,200,24170.7,no -C1_8_4,800,,200,23797.3,no -C1_8_5,800,,200,25138.6,no -C1_8_6,800,,200,25133.3,no -C1_8_7,800,,200,25127.3,no -C1_8_8,800,,200,24858.7,no -C1_8_9,800,,200,24200.4,no -C1_8_10,800,,200,24030.4,no -C2_8_1,800,,700,11631.9,no -C2_8_2,800,,700,11394.5,no -C2_8_3,800,,700,11138.1,no -C2_8_4,800,,700,10659.7,no -C2_8_5,800,,700,11395.6,no -C2_8_6,800,,700,11316.3,no -C2_8_7,800,,700,11332.9,no -C2_8_8,800,,700,11133.9,no -C2_8_9,800,,700,11140.4,no -C2_8_10,800,,700,10946,no -R1_8_1,800,,200,36393.3,no -R1_8_2,800,,200,32277.6,no -R1_8_3,800,,200,29304.5,no -R1_8_4,800,,200,27734.7,no -R1_8_5,800,,200,33494.2,no -R1_8_6,800,,200,30872.4,no -R1_8_7,800,,200,28789,no -R1_8_8,800,,200,27609.4,no -R1_8_9,800,,200,32257.3,no -R1_8_10,800,,200,30918.4,no -R2_8_1,800,,1000,24986.8,no -R2_8_2,800,,1000,21312.2,no -R2_8_3,800,,1000,17237.8,no -R2_8_4,800,,1000,13161.2,no -R2_8_5,800,,1000,22802,no -R2_8_6,800,,1000,19754.5,no -R2_8_7,800,,1000,16378.3,no -R2_8_8,800,,1000,12611.7,no -R2_8_9,800,,1000,21294.1,no -R2_8_10,800,,1000,20007,no -RC1_8_1,800,,200,29997.3,no -RC1_8_2,800,,200,28363.3,no -RC1_8_3,800,,200,27485.5,no -RC1_8_4,800,,200,26595.4,no -RC1_8_5,800,,200,29306.4,no -RC1_8_6,800,,200,29247.1,no -RC1_8_7,800,,200,28823.8,no -RC1_8_8,800,,200,28460.7,no -RC1_8_9,800,,200,28400.5,no -RC1_8_10,800,,200,28210.7,no -RC2_8_1,800,,1000,19203.8,no -RC2_8_2,800,,1000,16711.1,no -RC2_8_3,800,,1000,14028.9,no -RC2_8_4,800,,1000,10970.8,no -RC2_8_5,800,,1000,17466.1,no -RC2_8_6,800,,1000,17197.7,no -RC2_8_7,800,,1000,16366.5,no -RC2_8_8,800,,1000,15577.7,no -RC2_8_9,800,,1000,15184.8,no -RC2_8_10,800,,1000,14376.2,no -C1_10_1,1000,,200,42444.8,no -C1_10_2,1000,,200,41386.4,no -C1_10_3,1000,,200,40064.4,no -C1_10_4,1000,,200,39434.1,no -C1_10_5,1000,,200,42434.8,no -C1_10_6,1000,,200,42437,no -C1_10_7,1000,,200,42420.4,no -C1_10_8,1000,,200,41837.8,no -C1_10_9,1000,,200,40288.4,no -C1_10_10,1000,,200,39816.8,no -C2_10_1,1000,,700,16841.1,no -C2_10_2,1000,,700,16462.6,no -C2_10_3,1000,,700,16036.5,no -C2_10_4,1000,,700,15463.6,no -C2_10_5,1000,,700,16521.3,no -C2_10_6,1000,,700,16290.7,no -C2_10_7,1000,,700,16378.4,no -C2_10_8,1000,,700,16029.1,no -C2_10_9,1000,,700,16075.5,no -C2_10_10,1000,,700,15728.6,no -R1_10_1,1000,,200,53223.2,no -R1_10_2,1000,,200,48263.1,no -R1_10_3,1000,,200,44677.1,no -R1_10_4,1000,,200,42440.7,no -R1_10_5,1000,,200,50406.7,no -R1_10_6,1000,,200,46930.3,no -R1_10_7,1000,,200,43997.4,no -R1_10_8,1000,,200,42279.3,no -R1_10_9,1000,,200,49162.8,no -R1_10_10,1000,,200,47364.6,no -R2_10_1,1000,,1000,36891.3,no -R2_10_2,1000,,1000,31283.7,no -R2_10_3,1000,,1000,24418.1,no -R2_10_4,1000,,1000,17811.5,no -R2_10_5,1000,,1000,34141.1,no -R2_10_6,1000,,1000,29157.9,no -R2_10_7,1000,,1000,23103.2,no -R2_10_8,1000,,1000,17403.8,no -R2_10_9,1000,,1000,32049.5,no -R2_10_10,1000,,1000,29862,no -RC1_10_1,1000,,200,45790.8,no -RC1_10_2,1000,,200,43678.3,no -RC1_10_3,1000,,200,42122,no -RC1_10_4,1000,,200,41357.4,no -RC1_10_5,1000,,200,45028.1,no -RC1_10_6,1000,,200,44903.6,no -RC1_10_7,1000,,200,44417.1,no -RC1_10_8,1000,,200,43916.5,no -RC1_10_9,1000,,200,43858.1,no -RC1_10_10,1000,,200,43533.7,no -RC2_10_1,1000,,1000,28147.4,no -RC2_10_2,1000,,1000,24254.5,no -RC2_10_3,1000,,1000,19632.3,no -RC2_10_4,1000,,1000,15657,no -RC2_10_5,1000,,1000,25811.2,no -RC2_10_6,1000,,1000,25817.5,no -RC2_10_7,1000,,1000,24435.1,no -RC2_10_8,1000,,1000,23282.6,no -RC2_10_9,1000,,1000,22746,no -RC2_10_10,1000,,1000,21744.7,no diff --git a/vrplib/download/list_names.py b/vrplib/download/list_names.py deleted file mode 100644 index 1a29fb46..00000000 --- a/vrplib/download/list_names.py +++ /dev/null @@ -1,63 +0,0 @@ -import importlib.resources as pkg_resource -import warnings -from functools import lru_cache -from typing import Optional - -from .download_utils import is_vrptw - - -def list_names( - low: Optional[int] = None, - high: Optional[int] = None, - vrp_type: Optional[str] = None, -): - """ - Returns the names of the instances that can be downloaded from CVRPLIB. - - Parameters - ---------- - low - The minimum number of customers of the listed instances. - high - The maximum number of customers of the listed instances. - vrp_type - The vrp_type, one of ['cvrp', 'vrptw']. If not set, then instances - of both types are returned. - """ - instances = _read_instance_data() - msg = ( - "The function 'list_names' is deprecated and will be removed" - " in the next major version (vrplib v2.0.0)." - ) - warnings.warn(msg, DeprecationWarning) - - if low is not None: - instances = filter(lambda inst: inst["n_customers"] >= low, instances) - - if high is not None: - instances = filter(lambda inst: inst["n_customers"] <= high, instances) - - if vrp_type not in [None, "cvrp", "vrptw"]: - raise ValueError("vrp_type must be one of [None, 'cvrp', 'vrptw']") - - elif vrp_type == "cvrp": - instances = filter(lambda inst: not is_vrptw(inst["name"]), instances) - - elif vrp_type == "vrptw": - instances = filter(lambda inst: is_vrptw(inst["name"]), instances) - - return [inst["name"] for inst in instances] - - -@lru_cache() -def _read_instance_data(): - """ - Reads the instance data. All CVRPLIB instance names are stored in the - `instance_data.csv` file. - """ - fi = pkg_resource.read_text(__package__, "instance_data.csv") - instances = [line.strip().split(",") for line in fi.split()] - - return [ - {"name": inst[0], "n_customers": int(inst[1])} for inst in instances - ] diff --git a/vrplib/parse/__init__.py b/vrplib/parse/__init__.py index edd9a7f1..5e692434 100644 --- a/vrplib/parse/__init__.py +++ b/vrplib/parse/__init__.py @@ -1,3 +1,3 @@ -from .parse_solomon import parse_solomon -from .parse_solution import parse_solution -from .parse_vrplib import parse_vrplib +from .parse_solomon import parse_solomon as parse_solomon +from .parse_solution import parse_solution as parse_solution +from .parse_vrplib import parse_vrplib as parse_vrplib diff --git a/vrplib/parse/parse_distances.py b/vrplib/parse/parse_distances.py index 99bc0061..0530042d 100644 --- a/vrplib/parse/parse_distances.py +++ b/vrplib/parse/parse_distances.py @@ -1,5 +1,4 @@ from itertools import combinations -from typing import Optional, Union import numpy as np @@ -7,10 +6,10 @@ def parse_distances( data: list[float], edge_weight_type: str, - edge_weight_format: Optional[str] = None, - node_coord: Optional[np.ndarray] = None, - comment: Optional[str] = None, - **kwargs: Union[float, str, np.ndarray], # noqa + edge_weight_format: str | None = None, + node_coord: np.ndarray | None = None, + comment: str | None = None, + **kwargs: float | str | np.ndarray, ) -> np.ndarray: """ Parses the distances. The specification "edge_weight_type" describes how @@ -63,8 +62,8 @@ def parse_distances( # (C)VRPLIB format. Find a better way to identify Eilon instances. if comment is not None and "Eilon" in comment: return from_eilon(data) - else: - return from_lower_row(data) + + return from_lower_row(data) if edge_weight_format == "FULL_MATRIX": return np.array(data) diff --git a/vrplib/parse/parse_solomon.py b/vrplib/parse/parse_solomon.py index dbc4e8b1..f941dc24 100644 --- a/vrplib/parse/parse_solomon.py +++ b/vrplib/parse/parse_solomon.py @@ -1,11 +1,9 @@ -from typing import Union - import numpy as np from .parse_distances import pairwise_euclidean from .parse_utils import text2lines -Instance = dict[str, Union[str, float, np.ndarray]] +Instance = dict[str, str | float | np.ndarray] def parse_solomon(text: str, compute_edge_weights: bool = True) -> Instance: diff --git a/vrplib/parse/parse_solution.py b/vrplib/parse/parse_solution.py index 3cf384f9..d9517b58 100644 --- a/vrplib/parse/parse_solution.py +++ b/vrplib/parse/parse_solution.py @@ -1,8 +1,6 @@ -from typing import Union - from .parse_utils import infer_type, text2lines -Solution = dict[str, Union[float, str, list]] +Solution = dict[str, float | str | list] def parse_solution(text: str) -> Solution: diff --git a/vrplib/parse/parse_utils.py b/vrplib/parse/parse_utils.py index 39989a3e..e805a637 100644 --- a/vrplib/parse/parse_utils.py +++ b/vrplib/parse/parse_utils.py @@ -1,6 +1,3 @@ -from typing import Union - - def text2lines(text: str) -> list[str]: """ Takes a string and returns a list of non-empty, stripped lines. Also @@ -13,7 +10,7 @@ def text2lines(text: str) -> list[str]: ] -def infer_type(s: str) -> Union[int, float, str]: +def infer_type(s: str) -> int | float | str: try: return int(s) except ValueError: diff --git a/vrplib/parse/parse_vrplib.py b/vrplib/parse/parse_vrplib.py index 9cfd1640..d24a0d68 100644 --- a/vrplib/parse/parse_vrplib.py +++ b/vrplib/parse/parse_vrplib.py @@ -1,12 +1,11 @@ import re -from typing import Union import numpy as np from .parse_distances import parse_distances from .parse_utils import infer_type, text2lines -Instance = dict[str, Union[str, float, np.ndarray]] +Instance = dict[str, str | float | np.ndarray] def parse_vrplib(text: str, compute_edge_weights: bool = True) -> Instance: @@ -68,9 +67,11 @@ def group_specifications_and_sections(lines: list[str]): for idx, line in enumerate(lines): if "EOF" in line: break - elif idx < end_section: # Skip all lines of the current section + + if idx < end_section: # Skip all lines of the current section continue - elif ":" in line: + + if ":" in line: specs.append(line) elif "_SECTION" in line: start = lines.index(line) @@ -95,7 +96,7 @@ def group_specifications_and_sections(lines: list[str]): return specs, sections -def parse_specification(line: str) -> tuple[str, Union[float, str]]: +def parse_specification(line: str) -> tuple[str, float | str]: """ Parses a specification line as keyword-value pair, split at the first colon occurrence. The keyword is made lowercase and the value is unmodified. @@ -106,7 +107,7 @@ def parse_specification(line: str) -> tuple[str, Union[float, str]]: def parse_section( lines: list, instance: dict -) -> tuple[str, Union[list, np.ndarray]]: +) -> tuple[str, list | np.ndarray]: """ Parses the data section lines. """ diff --git a/vrplib/read/__init__.py b/vrplib/read/__init__.py index d766d53e..00b5da95 100644 --- a/vrplib/read/__init__.py +++ b/vrplib/read/__init__.py @@ -1,2 +1,2 @@ -from .read_instance import read_instance -from .read_solution import read_solution +from .read_instance import read_instance as read_instance +from .read_solution import read_solution as read_solution diff --git a/vrplib/read/read_instance.py b/vrplib/read/read_instance.py index 8451c4d9..21f2724c 100644 --- a/vrplib/read/read_instance.py +++ b/vrplib/read/read_instance.py @@ -1,11 +1,11 @@ import os -from typing import Any, Union +from typing import Any from vrplib.parse import parse_solomon, parse_vrplib def read_instance( - path: Union[str, os.PathLike], + path: str | os.PathLike, instance_format: str = "vrplib", compute_edge_weights: bool = True, ) -> dict[str, Any]: @@ -29,7 +29,8 @@ def read_instance( with open(path, "r") as fi: if instance_format == "vrplib": return parse_vrplib(fi.read(), compute_edge_weights) - elif instance_format == "solomon": + + if instance_format == "solomon": return parse_solomon(fi.read(), compute_edge_weights) raise ValueError(f"Format style {instance_format} not known.") diff --git a/vrplib/read/read_solution.py b/vrplib/read/read_solution.py index 4c670dbb..b476f4e1 100644 --- a/vrplib/read/read_solution.py +++ b/vrplib/read/read_solution.py @@ -1,10 +1,10 @@ import os -from typing import Any, Union +from typing import Any from vrplib.parse import parse_solution -def read_solution(path: Union[str, os.PathLike]) -> dict[str, Any]: +def read_solution(path: str | os.PathLike) -> dict[str, Any]: """ Reads the solution from the passed-in file path. diff --git a/vrplib/write/__init__.py b/vrplib/write/__init__.py index 50a09a0b..cd163961 100644 --- a/vrplib/write/__init__.py +++ b/vrplib/write/__init__.py @@ -1,2 +1,2 @@ -from .write_instance import write_instance -from .write_solution import write_solution +from .write_instance import write_instance as write_instance +from .write_solution import write_solution as write_solution diff --git a/vrplib/write/write_instance.py b/vrplib/write/write_instance.py index 8b2ca324..52313c6d 100644 --- a/vrplib/write/write_instance.py +++ b/vrplib/write/write_instance.py @@ -1,5 +1,5 @@ import os -from typing import TypeVar, Union +from typing import TypeVar import numpy as np @@ -7,8 +7,8 @@ def write_instance( - path: Union[str, os.PathLike], - data: dict[str, Union[str, int, float, _ArrayLike]], + path: str | os.PathLike, + data: dict[str, str | int | float | _ArrayLike], ): """ Writes a VRP instance to file following the VRPLIB format [1]. @@ -88,7 +88,4 @@ def _format_section(name: str, data: _ArrayLike) -> str: def _is_one_dimensional(data: _ArrayLike) -> bool: - for elt in data: - if isinstance(elt, (list, tuple, np.ndarray)): - return False - return True + return all(not isinstance(elt, (list, tuple, np.ndarray)) for elt in data) diff --git a/vrplib/write/write_solution.py b/vrplib/write/write_solution.py index 48da1054..fdde6502 100644 --- a/vrplib/write/write_solution.py +++ b/vrplib/write/write_solution.py @@ -1,11 +1,11 @@ import os -from typing import Any, Optional, Union +from typing import Any def write_solution( - path: Union[str, os.PathLike], + path: str | os.PathLike, routes: list[list[int]], - data: Optional[dict[str, Any]] = None, + data: dict[str, Any] | None = None, ): """ Writes a VRP solution to file following the VRPLIB convention.