diff --git a/.github/workflows/clear_self_hosted_persistent_caches.yaml b/.github/workflows/clear_self_hosted_persistent_caches.yaml index fb7fce9c7dd..50d69728c62 100644 --- a/.github/workflows/clear_self_hosted_persistent_caches.yaml +++ b/.github/workflows/clear_self_hosted_persistent_caches.yaml @@ -26,44 +26,6 @@ jobs: run: du -sh ~/.pex || true; rm -rf ~/.pex || true - name: df after run: df -h - clean_macos10_15_x86_64: - runs-on: - - self-hosted - - macOS-10.15-X64 - steps: - - name: df before - run: df -h - - name: Deleting ~/Library/Caches - run: du -sh ~/Library/Caches || true; rm -rf ~/Library/Caches || true - - name: Deleting ~/.cache - run: du -sh ~/.cache || true; rm -rf ~/.cache || true - - name: Deleting ~/.nce - run: du -sh ~/.nce || true; rm -rf ~/.nce || true - - name: Deleting ~/.rustup - run: du -sh ~/.rustup || true; rm -rf ~/.rustup || true - - name: Deleting ~/.pex - run: du -sh ~/.pex || true; rm -rf ~/.pex || true - - name: df after - run: df -h - clean_macos11_arm64: - runs-on: - - self-hosted - - macOS-11-ARM64 - steps: - - name: df before - run: df -h - - name: Deleting ~/Library/Caches - run: du -sh ~/Library/Caches || true; rm -rf ~/Library/Caches || true - - name: Deleting ~/.cache - run: du -sh ~/.cache || true; rm -rf ~/.cache || true - - name: Deleting ~/.nce - run: du -sh ~/.nce || true; rm -rf ~/.nce || true - - name: Deleting ~/.rustup - run: du -sh ~/.rustup || true; rm -rf ~/.rustup || true - - name: Deleting ~/.pex - run: du -sh ~/.pex || true; rm -rf ~/.pex || true - - name: df after - run: df -h name: Clear persistent caches on long-lived self-hosted runners 'on': workflow_dispatch: {} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ff75e1eb176..15a3d558e28 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -6,7 +6,7 @@ jobs: build_wheels_linux_arm64: container: - image: quay.io/pypa/manylinux2014_aarch64:latest + image: quay.io/pypa/manylinux_2_28_aarch64:latest env: ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true PANTS_REMOTE_CACHE_READ: 'false' @@ -23,7 +23,7 @@ jobs: - run-id=${{ github.run_id }} steps: - name: Check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 10 ref: ${{ needs.release_info.outputs.build-ref }} @@ -43,6 +43,14 @@ jobs: echo "/opt/python/cp39-cp39/bin" >> $GITHUB_PATH + echo "/opt/python/cp310-cp310/bin" >> $GITHUB_PATH + + echo "/opt/python/cp311-cp311/bin" >> $GITHUB_PATH + + echo "/opt/python/cp312-cp312/bin" >> $GITHUB_PATH + + echo "/opt/python/cp313-cp313/bin" >> $GITHUB_PATH + ' - name: Install Protoc uses: arduino/setup-protoc@9b1ee5b22b0a3f1feb8c2ff99b32c89b3c3191e9 @@ -58,7 +66,7 @@ jobs: - continue-on-error: true if: always() name: Upload pants.log - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: logs-wheels-and-pex-Linux-ARM64 overwrite: 'true' @@ -83,7 +91,7 @@ jobs: timeout-minutes: 90 build_wheels_linux_x86_64: container: - image: quay.io/pypa/manylinux2014_x86_64:latest + image: quay.io/pypa/manylinux_2_28_x86_64:latest env: ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true PANTS_REMOTE_CACHE_READ: 'false' @@ -96,7 +104,7 @@ jobs: - ubuntu-22.04 steps: - name: Check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 10 ref: ${{ needs.release_info.outputs.build-ref }} @@ -116,6 +124,14 @@ jobs: echo "/opt/python/cp39-cp39/bin" >> $GITHUB_PATH + echo "/opt/python/cp310-cp310/bin" >> $GITHUB_PATH + + echo "/opt/python/cp311-cp311/bin" >> $GITHUB_PATH + + echo "/opt/python/cp312-cp312/bin" >> $GITHUB_PATH + + echo "/opt/python/cp313-cp313/bin" >> $GITHUB_PATH + ' - name: Install Protoc uses: arduino/setup-protoc@9b1ee5b22b0a3f1feb8c2ff99b32c89b3c3191e9 @@ -123,7 +139,7 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} version: 23.x - name: Install Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: 1.19.5 - env: @@ -137,7 +153,7 @@ jobs: - continue-on-error: true if: always() name: Upload pants.log - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: logs-wheels-and-pex-Linux-x86_64 overwrite: 'true' @@ -167,24 +183,39 @@ jobs: \ needs.release_info.outputs.release-asset-upload-url }}?name=$(basename $WHL)\"\ \ \\\n --data-binary \"@$WHL\";\n" timeout-minutes: 90 - build_wheels_macos10_15_x86_64: + build_wheels_macos13_x86_64: env: ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: false PANTS_REMOTE_CACHE_READ: 'false' PANTS_REMOTE_CACHE_WRITE: 'false' if: github.repository_owner == 'pantsbuild' - name: Build wheels (macOS10-15-x86_64) + name: Build wheels (macOS13-x86_64) needs: - release_info runs-on: - - self-hosted - - macOS-10.15-X64 + - macos-13 steps: - name: Check out code uses: actions/checkout@v4 with: fetch-depth: 10 ref: ${{ needs.release_info.outputs.build-ref }} + - name: Set up Python 3.7, 3.8, 3.9, 3.10, 3.12, 3.13, 3.11 + uses: actions/setup-python@v5 + with: + python-version: '3.7 + + 3.8 + + 3.9 + + 3.10 + + 3.12 + + 3.13 + + 3.11' - name: Install Protoc uses: arduino/setup-protoc@9b1ee5b22b0a3f1feb8c2ff99b32c89b3c3191e9 with: @@ -195,7 +226,7 @@ jobs: - name: Cache Rust toolchain uses: actions/cache@v4 with: - key: macOS10-15-x86_64-rustup-${{ hashFiles('src/rust/engine/rust-toolchain') + key: macOS13-x86_64-rustup-${{ hashFiles('src/rust/engine/rust-toolchain') }}-v2 path: '~/.rustup/toolchains/1.82.0-* @@ -232,7 +263,7 @@ jobs: name: Upload pants.log uses: actions/upload-artifact@v4 with: - name: logs-wheels-and-pex-macOS10-15-x86_64 + name: logs-wheels-and-pex-macOS13-x86_64 overwrite: 'true' path: .pants.d/workdir/*.log - if: needs.release_info.outputs.is-release == 'true' @@ -253,24 +284,35 @@ jobs: \ needs.release_info.outputs.release-asset-upload-url }}?name=$(basename $WHL)\"\ \ \\\n --data-binary \"@$WHL\";\n" timeout-minutes: 90 - build_wheels_macos11_arm64: + build_wheels_macos14_arm64: env: ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: false PANTS_REMOTE_CACHE_READ: 'false' PANTS_REMOTE_CACHE_WRITE: 'false' if: github.repository_owner == 'pantsbuild' - name: Build wheels (macOS11-ARM64) + name: Build wheels (macOS14-ARM64) needs: - release_info runs-on: - - self-hosted - - macOS-11-ARM64 + - macos-14 steps: - name: Check out code uses: actions/checkout@v4 with: fetch-depth: 10 ref: ${{ needs.release_info.outputs.build-ref }} + - name: Set up Python 3.9, 3.10, 3.12, 3.13, 3.11 + uses: actions/setup-python@v5 + with: + python-version: '3.9 + + 3.10 + + 3.12 + + 3.13 + + 3.11' - name: Install Protoc uses: arduino/setup-protoc@9b1ee5b22b0a3f1feb8c2ff99b32c89b3c3191e9 with: @@ -281,7 +323,7 @@ jobs: - name: Cache Rust toolchain uses: actions/cache@v4 with: - key: macOS11-ARM64-rustup-${{ hashFiles('src/rust/engine/rust-toolchain') + key: macOS14-ARM64-rustup-${{ hashFiles('src/rust/engine/rust-toolchain') }}-v2 path: '~/.rustup/toolchains/1.82.0-* @@ -318,7 +360,7 @@ jobs: name: Upload pants.log uses: actions/upload-artifact@v4 with: - name: logs-wheels-and-pex-macOS11-ARM64 + name: logs-wheels-and-pex-macOS14-ARM64 overwrite: 'true' path: .pants.d/workdir/*.log - if: needs.release_info.outputs.is-release == 'true' @@ -347,8 +389,8 @@ jobs: needs: - build_wheels_linux_x86_64 - build_wheels_linux_arm64 - - build_wheels_macos10_15_x86_64 - - build_wheels_macos11_arm64 + - build_wheels_macos13_x86_64 + - build_wheels_macos14_arm64 - release_info runs-on: ubuntu-latest steps: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index a23a1c180b6..8d472031ffb 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -218,16 +218,16 @@ jobs: ./cargo doc' timeout-minutes: 60 - bootstrap_pants_macos12_x86_64: + bootstrap_pants_macos13_x86_64: env: PANTS_REMOTE_CACHE_READ: 'false' PANTS_REMOTE_CACHE_WRITE: 'false' if: (github.repository_owner == 'pantsbuild') && (needs.classify_changes.outputs.docs_only != 'true') - name: Bootstrap Pants, test Rust (macOS12-x86_64) + name: Bootstrap Pants, test Rust (macOS13-x86_64) needs: - classify_changes runs-on: - - macos-12 + - macos-13 steps: - name: Check out code uses: actions/checkout@v4 @@ -259,7 +259,7 @@ jobs: - name: Cache Rust toolchain uses: actions/cache@v4 with: - key: macOS12-x86_64-rustup-${{ hashFiles('src/rust/engine/rust-toolchain') }}-v2 + key: macOS13-x86_64-rustup-${{ hashFiles('src/rust/engine/rust-toolchain') }}-v2 path: '~/.rustup/toolchains/1.82.0-* ~/.rustup/update-hashes @@ -280,7 +280,7 @@ jobs: - name: Cache native engine uses: actions/cache@v4 with: - key: macOS12-x86_64-engine-${{ steps.get-engine-hash.outputs.hash }}-v1 + key: macOS13-x86_64-engine-${{ steps.get-engine-hash.outputs.hash }}-v1 path: 'src/python/pants/bin/native_client src/python/pants/engine/internals/native_engine.so @@ -305,13 +305,13 @@ jobs: name: Upload pants.log uses: actions/upload-artifact@v4 with: - name: logs-bootstrap-macOS12-x86_64 + name: logs-bootstrap-macOS13-x86_64 overwrite: 'true' path: .pants.d/workdir/*.log - name: Upload native binaries uses: actions/upload-artifact@v4 with: - name: native_binaries.${{ matrix.python-version }}.macOS12-x86_64 + name: native_binaries.${{ matrix.python-version }}.macOS13-x86_64 path: 'src/python/pants/bin/native_client src/python/pants/engine/internals/native_engine.so @@ -325,14 +325,14 @@ jobs: timeout-minutes: 60 build_wheels_linux_arm64: container: - image: quay.io/pypa/manylinux2014_aarch64:latest + image: quay.io/pypa/manylinux_2_28_aarch64:latest env: ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true MODE: debug PANTS_REMOTE_CACHE_READ: 'false' PANTS_REMOTE_CACHE_WRITE: 'false' - if: ((github.repository_owner == 'pantsbuild') && (needs.classify_changes.outputs.release == 'true')) && (needs.classify_changes.outputs.docs_only - != 'true') + if: ((github.repository_owner == 'pantsbuild') && (needs.classify_changes.outputs.release == 'true' || needs.classify_changes.outputs.ci_config + == 'true')) && (needs.classify_changes.outputs.docs_only != 'true') name: Build wheels (Linux-ARM64) needs: - classify_changes @@ -344,7 +344,7 @@ jobs: - run-id=${{ github.run_id }} steps: - name: Check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 10 - name: Configure Git @@ -362,6 +362,14 @@ jobs: echo "/opt/python/cp39-cp39/bin" >> $GITHUB_PATH + echo "/opt/python/cp310-cp310/bin" >> $GITHUB_PATH + + echo "/opt/python/cp311-cp311/bin" >> $GITHUB_PATH + + echo "/opt/python/cp312-cp312/bin" >> $GITHUB_PATH + + echo "/opt/python/cp313-cp313/bin" >> $GITHUB_PATH + ' - name: Install Protoc uses: arduino/setup-protoc@9b1ee5b22b0a3f1feb8c2ff99b32c89b3c3191e9 @@ -377,7 +385,7 @@ jobs: - continue-on-error: true if: always() name: Upload pants.log - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: logs-wheels-and-pex-Linux-ARM64 overwrite: 'true' @@ -385,14 +393,14 @@ jobs: timeout-minutes: 90 build_wheels_linux_x86_64: container: - image: quay.io/pypa/manylinux2014_x86_64:latest + image: quay.io/pypa/manylinux_2_28_x86_64:latest env: ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true MODE: debug PANTS_REMOTE_CACHE_READ: 'false' PANTS_REMOTE_CACHE_WRITE: 'false' - if: ((github.repository_owner == 'pantsbuild') && (needs.classify_changes.outputs.release == 'true')) && (needs.classify_changes.outputs.docs_only - != 'true') + if: ((github.repository_owner == 'pantsbuild') && (needs.classify_changes.outputs.release == 'true' || needs.classify_changes.outputs.ci_config + == 'true')) && (needs.classify_changes.outputs.docs_only != 'true') name: Build wheels (Linux-x86_64) needs: - classify_changes @@ -400,7 +408,7 @@ jobs: - ubuntu-22.04 steps: - name: Check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 10 - name: Configure Git @@ -418,6 +426,14 @@ jobs: echo "/opt/python/cp39-cp39/bin" >> $GITHUB_PATH + echo "/opt/python/cp310-cp310/bin" >> $GITHUB_PATH + + echo "/opt/python/cp311-cp311/bin" >> $GITHUB_PATH + + echo "/opt/python/cp312-cp312/bin" >> $GITHUB_PATH + + echo "/opt/python/cp313-cp313/bin" >> $GITHUB_PATH + ' - name: Install Protoc uses: arduino/setup-protoc@9b1ee5b22b0a3f1feb8c2ff99b32c89b3c3191e9 @@ -425,7 +441,7 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} version: 23.x - name: Install Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: 1.19.5 - env: @@ -439,31 +455,46 @@ jobs: - continue-on-error: true if: always() name: Upload pants.log - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: logs-wheels-and-pex-Linux-x86_64 overwrite: 'true' path: .pants.d/workdir/*.log timeout-minutes: 90 - build_wheels_macos10_15_x86_64: + build_wheels_macos13_x86_64: env: ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: false MODE: debug PANTS_REMOTE_CACHE_READ: 'false' PANTS_REMOTE_CACHE_WRITE: 'false' - if: ((github.repository_owner == 'pantsbuild') && (needs.classify_changes.outputs.release == 'true')) && (needs.classify_changes.outputs.docs_only - != 'true') - name: Build wheels (macOS10-15-x86_64) + if: ((github.repository_owner == 'pantsbuild') && (needs.classify_changes.outputs.release == 'true' || needs.classify_changes.outputs.ci_config + == 'true')) && (needs.classify_changes.outputs.docs_only != 'true') + name: Build wheels (macOS13-x86_64) needs: - classify_changes runs-on: - - self-hosted - - macOS-10.15-X64 + - macos-13 steps: - name: Check out code uses: actions/checkout@v4 with: fetch-depth: 10 + - name: Set up Python 3.7, 3.8, 3.9, 3.10, 3.12, 3.13, 3.11 + uses: actions/setup-python@v5 + with: + python-version: '3.7 + + 3.8 + + 3.9 + + 3.10 + + 3.12 + + 3.13 + + 3.11' - name: Install Protoc uses: arduino/setup-protoc@9b1ee5b22b0a3f1feb8c2ff99b32c89b3c3191e9 with: @@ -474,7 +505,7 @@ jobs: - name: Cache Rust toolchain uses: actions/cache@v4 with: - key: macOS10-15-x86_64-rustup-${{ hashFiles('src/rust/engine/rust-toolchain') }}-v2 + key: macOS13-x86_64-rustup-${{ hashFiles('src/rust/engine/rust-toolchain') }}-v2 path: '~/.rustup/toolchains/1.82.0-* ~/.rustup/update-hashes @@ -510,29 +541,40 @@ jobs: name: Upload pants.log uses: actions/upload-artifact@v4 with: - name: logs-wheels-and-pex-macOS10-15-x86_64 + name: logs-wheels-and-pex-macOS13-x86_64 overwrite: 'true' path: .pants.d/workdir/*.log timeout-minutes: 90 - build_wheels_macos11_arm64: + build_wheels_macos14_arm64: env: ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: false MODE: debug PANTS_REMOTE_CACHE_READ: 'false' PANTS_REMOTE_CACHE_WRITE: 'false' - if: ((github.repository_owner == 'pantsbuild') && (needs.classify_changes.outputs.release == 'true')) && (needs.classify_changes.outputs.docs_only - != 'true') - name: Build wheels (macOS11-ARM64) + if: ((github.repository_owner == 'pantsbuild') && (needs.classify_changes.outputs.release == 'true' || needs.classify_changes.outputs.ci_config + == 'true')) && (needs.classify_changes.outputs.docs_only != 'true') + name: Build wheels (macOS14-ARM64) needs: - classify_changes runs-on: - - self-hosted - - macOS-11-ARM64 + - macos-14 steps: - name: Check out code uses: actions/checkout@v4 with: fetch-depth: 10 + - name: Set up Python 3.9, 3.10, 3.12, 3.13, 3.11 + uses: actions/setup-python@v5 + with: + python-version: '3.9 + + 3.10 + + 3.12 + + 3.13 + + 3.11' - name: Install Protoc uses: arduino/setup-protoc@9b1ee5b22b0a3f1feb8c2ff99b32c89b3c3191e9 with: @@ -543,7 +585,7 @@ jobs: - name: Cache Rust toolchain uses: actions/cache@v4 with: - key: macOS11-ARM64-rustup-${{ hashFiles('src/rust/engine/rust-toolchain') }}-v2 + key: macOS14-ARM64-rustup-${{ hashFiles('src/rust/engine/rust-toolchain') }}-v2 path: '~/.rustup/toolchains/1.82.0-* ~/.rustup/update-hashes @@ -579,7 +621,7 @@ jobs: name: Upload pants.log uses: actions/upload-artifact@v4 with: - name: logs-wheels-and-pex-macOS11-ARM64 + name: logs-wheels-and-pex-macOS14-ARM64 overwrite: 'true' path: .pants.d/workdir/*.log timeout-minutes: 90 @@ -716,11 +758,11 @@ jobs: - check_release_notes - bootstrap_pants_linux_arm64 - bootstrap_pants_linux_x86_64 - - bootstrap_pants_macos12_x86_64 + - bootstrap_pants_macos13_x86_64 - build_wheels_linux_arm64 - build_wheels_linux_x86_64 - - build_wheels_macos10_15_x86_64 - - build_wheels_macos11_arm64 + - build_wheels_macos13_x86_64 + - build_wheels_macos14_arm64 - check_release_notes - classify_changes - lint_python @@ -735,7 +777,7 @@ jobs: - test_python_linux_x86_64_7 - test_python_linux_x86_64_8 - test_python_linux_x86_64_9 - - test_python_macos12_x86_64 + - test_python_macos13_x86_64 outputs: merge_ok: ${{ steps.set_merge_ok.outputs.merge_ok }} runs-on: @@ -1823,16 +1865,16 @@ jobs: overwrite: 'true' path: .pants.d/workdir/*.log timeout-minutes: 90 - test_python_macos12_x86_64: + test_python_macos13_x86_64: env: ARCHFLAGS: -arch x86_64 if: (github.repository_owner == 'pantsbuild') && (needs.classify_changes.outputs.docs_only != 'true') - name: Test Python (macOS12-x86_64) + name: Test Python (macOS13-x86_64) needs: - - bootstrap_pants_macos12_x86_64 + - bootstrap_pants_macos13_x86_64 - classify_changes runs-on: - - macos-12 + - macos-13 steps: - name: Check out code uses: actions/checkout@v4 @@ -1843,6 +1885,10 @@ jobs: with: distribution: adopt java-version: '11' + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: 1.19.5 - name: Set up Python 3.7, 3.8, 3.9, 3.10, 3.12, 3.13, 3.11 uses: actions/setup-python@v5 with: @@ -1862,7 +1908,7 @@ jobs: - name: Download native binaries uses: actions/download-artifact@v4 with: - name: native_binaries.${{ matrix.python-version }}.macOS12-x86_64 + name: native_binaries.${{ matrix.python-version }}.macOS13-x86_64 path: src/python/pants - name: Make native-client runnable run: chmod +x src/python/pants/bin/native_client @@ -1876,7 +1922,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} if: always() name: Upload test reports - run: 'export S3_DST=s3://logs.pantsbuild.org/test/reports/macOS12-x86_64/$(git show --no-patch --format=%cd --date=format:%Y-%m-%d)/${GITHUB_REF_NAME//\//_}/${GITHUB_RUN_ID}/${GITHUB_RUN_ATTEMPT}/${GITHUB_JOB} + run: 'export S3_DST=s3://logs.pantsbuild.org/test/reports/macOS13-x86_64/$(git show --no-patch --format=%cd --date=format:%Y-%m-%d)/${GITHUB_REF_NAME//\//_}/${GITHUB_RUN_ID}/${GITHUB_RUN_ATTEMPT}/${GITHUB_JOB} echo "Uploading test reports to ${S3_DST}" @@ -1888,7 +1934,7 @@ jobs: name: Upload pants.log uses: actions/upload-artifact@v4 with: - name: logs-python-test-macOS12-x86_64 + name: logs-python-test-macOS13-x86_64 overwrite: 'true' path: .pants.d/workdir/*.log timeout-minutes: 90 diff --git a/3rdparty/python/BUILD b/3rdparty/python/BUILD index 9d576926b1a..e1fe6e80ada 100644 --- a/3rdparty/python/BUILD +++ b/3rdparty/python/BUILD @@ -28,6 +28,12 @@ python_requirements( resolve="pytest", ) +python_requirements( + name="pbs-script", + source="pbs-script-requirements.txt", + resolve="pbs-script", +) + __dependents_rules__( ( # Only the explorer server may depend on these libraries ( diff --git a/3rdparty/python/flake8.lock b/3rdparty/python/flake8.lock index b4f94d2c3b2..7e0eb17a93a 100644 --- a/3rdparty/python/flake8.lock +++ b/3rdparty/python/flake8.lock @@ -6,7 +6,7 @@ // { // "version": 3, // "valid_for_interpreter_constraints": [ -// "CPython==3.9.*" +// "CPython==3.11.*" // ], // "generated_with_requirements": [ // "flake8-2020<2,>=1.7.0", @@ -27,6 +27,7 @@ "allow_wheels": true, "build_isolation": true, "constraints": [], + "excluded": [], "locked_resolves": [ { "locked_requirements": [ @@ -34,35 +35,35 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7", - "url": "https://files.pythonhosted.org/packages/d9/6a/bb0122ebe280476c924470779d2595f1403878cafe3c8a343ac56a5a9c0e/flake8-6.0.0-py2.py3-none-any.whl" + "hash": "ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5", + "url": "https://files.pythonhosted.org/packages/b0/24/bbf7175ffc47cb3d3e1eb523ddb23272968359dfcf2e1294707a2bf12fc4/flake8-6.1.0-py2.py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181", - "url": "https://files.pythonhosted.org/packages/66/53/3ad4a3b74d609b3b9008a10075c40e7c8909eae60af53623c3888f7a529a/flake8-6.0.0.tar.gz" + "hash": "d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23", + "url": "https://files.pythonhosted.org/packages/cf/f8/bbe24f43695c0c480181e39ce910c2650c794831886ec46ddd7c40520e6a/flake8-6.1.0.tar.gz" } ], "project_name": "flake8", "requires_dists": [ "mccabe<0.8.0,>=0.7.0", - "pycodestyle<2.11.0,>=2.10.0", - "pyflakes<3.1.0,>=3.0.0" + "pycodestyle<2.12.0,>=2.11.0", + "pyflakes<3.2.0,>=3.1.0" ], "requires_python": ">=3.8.1", - "version": "6.0.0" + "version": "6.1.0" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "1553b2b3638135b276f7a3252301e81376901e7b6a5eaccb07a969771f178375", - "url": "https://files.pythonhosted.org/packages/a5/6e/df5766df36c1280d0b96996e89e160cab2f1fa4ffd7434ff252c51025ca7/flake8_2020-1.8.0-py2.py3-none-any.whl" + "hash": "59b6b8ac01cde10ef11b31a2c9aa15b4509d828ae115ee5be34464b9e4de4ea6", + "url": "https://files.pythonhosted.org/packages/36/f0/14c6c25768ddc81999733e7bed89e9285b273920505180155e351ed92dc5/flake8_2020-1.8.1-py2.py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "f5312b3634266bd0f1957f64ecabeb62d67bbd9cee637e33a2651a80091f90aa", - "url": "https://files.pythonhosted.org/packages/3d/0e/29c1a6d15baa70865daa1ae6887742d5907fb75b92c4c1a8281915f8550d/flake8_2020-1.8.0.tar.gz" + "hash": "094ea95e8b614c3bd123fd4f007be28ec117ca57a6169903d4baaabe78e3e590", + "url": "https://files.pythonhosted.org/packages/cf/0b/e71a0d9efd854a631e2d51707676886997c73bec70c3c221b84601b976d2/flake8_2020-1.8.1.tar.gz" } ], "project_name": "flake8-2020", @@ -70,40 +71,39 @@ "flake8>=5" ], "requires_python": ">=3.8", - "version": "1.8.0" + "version": "1.8.1" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "013234637ec7dfcb7cd2900578fb53c512f81db909cefe371c019232695c362d", - "url": "https://files.pythonhosted.org/packages/9b/8d/b70f791311a8c6975c0c6634dd44db8fd712d6ad9ed6a3fe888b9be7c89b/flake8_comprehensions-3.12.0-py3-none-any.whl" + "hash": "b7e027bbb52be2ceb779ee12484cdeef52b0ad3c1fcb8846292bdb86d3034681", + "url": "https://files.pythonhosted.org/packages/3a/aa/93667d6f398749d1a9dd37d646e092f9f1baade7cbac948331b50a1d513c/flake8_comprehensions-3.15.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "419ef1a6e8de929203791a5e8ff5e3906caeba13eb3290eebdbf88a9078d502e", - "url": "https://files.pythonhosted.org/packages/65/b4/9a2cbbac095aaf1e8dbe3eac55a5155cb9f7860fbb0d9fa23443b5a3afd1/flake8_comprehensions-3.12.0.tar.gz" + "hash": "923c22603e0310376a6b55b03efebdc09753c69f2d977755cba8bb73458a5d4d", + "url": "https://files.pythonhosted.org/packages/60/fa/68481f25fc8ecdbe8a763062ba4f5b17fa4ef7fc0646c081267cef4f67e5/flake8_comprehensions-3.15.0.tar.gz" } ], "project_name": "flake8-comprehensions", "requires_dists": [ - "flake8!=3.2.0,>=3.0", - "importlib-metadata; python_version < \"3.8\"" + "flake8!=3.2,>=3" ], - "requires_python": ">=3.7", - "version": "3.12.0" + "requires_python": ">=3.8", + "version": "3.15.0" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "5c056e06f22820865cb34962a1da80767fed5273920b0768e97739021d428de5", - "url": "https://files.pythonhosted.org/packages/87/04/983ec9268488911103bc3b30bcdef3936cb9ed55a53d8ad25f023e76243a/flake8_no_implicit_concat-0.3.4-py3-none-any.whl" + "hash": "454b0c6df39c03bd8b1891abc9317981901a72ef426a4d56eb5fc689eef8fc65", + "url": "https://files.pythonhosted.org/packages/27/0d/9f3e09dd88b3bf321465d5d78e37aeb4f9022ee6764ea003d9ec455b2d61/flake8_no_implicit_concat-0.3.5-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "1b522becd7568ee2e288bc58e294ebd0d771996ee3138a5322a3cefb21c8464b", - "url": "https://files.pythonhosted.org/packages/00/f2/f7616a05059683e4e3970c21f7ed820b18eca08ab272e774dc5ed07aa9c6/flake8-no-implicit-concat-0.3.4.tar.gz" + "hash": "8e675477c40b21d9481915a4a257260b17e29137b0b76406657c3605f79b2b42", + "url": "https://files.pythonhosted.org/packages/1f/3c/c86797634204844c29eb60e00bdf2079cdda97d40905e861e57af60b9567/flake8-no-implicit-concat-0.3.5.tar.gz" } ], "project_name": "flake8-no-implicit-concat", @@ -128,8 +128,8 @@ "pep8-naming; extra == \"dev\"", "typing; python_version < \"3.5\"" ], - "requires_python": ">=3.3", - "version": "0.3.4" + "requires_python": ">=3.5", + "version": "0.3.5" }, { "artifacts": [ @@ -153,63 +153,48 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "d2bc7f02446e86a68911e58ded76d6561eea00cddfb2a91e7019bbb586c799f3", - "url": "https://files.pythonhosted.org/packages/85/01/e2678ee4e0d7eed4fd6be9e5b043fff9d22d245d06c8c91def8ced664189/more_itertools-9.1.0-py3-none-any.whl" - }, - { - "algorithm": "sha256", - "hash": "cabaa341ad0389ea83c17a94566a53ae4c9d07349861ecb14dc6d0345cf9ac5d", - "url": "https://files.pythonhosted.org/packages/2e/d0/bea165535891bd1dcb5152263603e902c0ec1f4c9a2e152cc4adff6b3a38/more-itertools-9.1.0.tar.gz" - } - ], - "project_name": "more-itertools", - "requires_dists": [], - "requires_python": ">=3.7", - "version": "9.1.0" - }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610", - "url": "https://files.pythonhosted.org/packages/a2/54/001fdc0d69e8d0bb86c3423a6fa6dfada8cc26317c2635ab543e9ac411bd/pycodestyle-2.10.0-py2.py3-none-any.whl" + "hash": "44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67", + "url": "https://files.pythonhosted.org/packages/b1/90/a998c550d0ddd07e38605bb5c455d00fcc177a800ff9cc3dafdcb3dd7b56/pycodestyle-2.11.1-py2.py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053", - "url": "https://files.pythonhosted.org/packages/06/6b/5ca0d12ef7dcf7d20dfa35287d02297f3e0f9e515da5183654c03a9636ce/pycodestyle-2.10.0.tar.gz" + "hash": "41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "url": "https://files.pythonhosted.org/packages/34/8f/fa09ae2acc737b9507b5734a9aec9a2b35fa73409982f57db1b42f8c3c65/pycodestyle-2.11.1.tar.gz" } ], "project_name": "pycodestyle", "requires_dists": [], - "requires_python": ">=3.6", - "version": "2.10.0" + "requires_python": ">=3.8", + "version": "2.11.1" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf", - "url": "https://files.pythonhosted.org/packages/af/4c/b1c7008aa7788b3e26c06c60aa18da7d3aa1f00e344aa3f18ac92768854b/pyflakes-3.0.1-py2.py3-none-any.whl" + "hash": "4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774", + "url": "https://files.pythonhosted.org/packages/00/e9/1e1fd7fae559bfd07704991e9a59dd1349b72423c904256c073ce88a9940/pyflakes-3.1.0-py2.py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd", - "url": "https://files.pythonhosted.org/packages/f2/51/506ddcfab10d708e8460554cc1cf37c727a6a2cccbad8dfe57766cfce33c/pyflakes-3.0.1.tar.gz" + "hash": "a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc", + "url": "https://files.pythonhosted.org/packages/8b/fb/7251eaec19a055ec6aafb3d1395db7622348130d1b9b763f78567b2aab32/pyflakes-3.1.0.tar.gz" } ], "project_name": "pyflakes", "requires_dists": [], - "requires_python": ">=3.6", - "version": "3.0.1" + "requires_python": ">=3.8", + "version": "3.1.0" } ], "platform_tag": null } ], + "only_builds": [], + "only_wheels": [], + "overridden": [], "path_mappings": {}, - "pex_version": "2.1.137", - "pip_version": "23.1.2", + "pex_version": "2.19.1", + "pip_version": "24.2", "prefer_older_binary": false, "requirements": [ "flake8-2020<2,>=1.7.0", @@ -218,7 +203,7 @@ "flake8<7,>=5.0.4" ], "requires_python": [ - "==3.9.*" + "==3.11.*" ], "resolver_version": "pip-2020-resolver", "style": "universal", diff --git a/3rdparty/python/mypy.lock b/3rdparty/python/mypy.lock index b22a08c8d7a..0903c9bcef1 100644 --- a/3rdparty/python/mypy.lock +++ b/3rdparty/python/mypy.lock @@ -6,7 +6,7 @@ // { // "version": 3, // "valid_for_interpreter_constraints": [ -// "CPython==3.9.*" +// "CPython==3.11.*" // ], // "generated_with_requirements": [ // "mypy-typing-asserts", @@ -59,28 +59,28 @@ }, { "algorithm": "sha256", - "hash": "3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d", - "url": "https://files.pythonhosted.org/packages/2e/35/f4d8b6d2cb0b3dad63e96caf159419dda023f45a358c6c9ac582ccaee354/mypy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl" + "hash": "20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", + "url": "https://files.pythonhosted.org/packages/26/50/29d3e7dd166e74dc13d46050b23f7d6d7533acf48f5217663a3719db024e/mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl" }, { "algorithm": "sha256", - "hash": "7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc", - "url": "https://files.pythonhosted.org/packages/38/e9/fc3865e417722f98d58409770be01afb961e2c1f99930659ff4ae7ca8b7e/mypy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl" + "hash": "3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", + "url": "https://files.pythonhosted.org/packages/3f/1d/676e76f07f7d5ddcd4227af3938a9c9640f293b7d8a44dd4ff41d4db25c1/mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl" }, { "algorithm": "sha256", - "hash": "0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc", - "url": "https://files.pythonhosted.org/packages/5f/d4/b33ddd40dad230efb317898a2d1c267c04edba73bc5086bf77edeb410fb2/mypy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", + "url": "https://files.pythonhosted.org/packages/c8/71/6950fcc6ca84179137e4cbf7cf41e6b68b4a339a1f5d3e954f8c34e02d66/mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", - "url": "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz" + "hash": "581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", + "url": "https://files.pythonhosted.org/packages/d0/19/de0822609e5b93d02579075248c7aa6ceaddcea92f00bf4ea8e4c22e3598/mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", - "hash": "7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732", - "url": "https://files.pythonhosted.org/packages/f4/e6/f414bca465b44d01cd5f4a82761e15044bedd1bf8025c5af3cc64518fac5/mypy-1.13.0-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", + "url": "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz" } ], "project_name": "mypy", @@ -216,24 +216,6 @@ "requires_python": "<4.0,>=3.8", "version": "0.240.4" }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", - "url": "https://files.pythonhosted.org/packages/cf/db/ce8eda256fa131af12e0a76d481711abe4681b6923c27efb9a255c9e4594/tomli-2.0.2-py3-none-any.whl" - }, - { - "algorithm": "sha256", - "hash": "d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed", - "url": "https://files.pythonhosted.org/packages/35/b9/de2a5c0144d7d75a57ff355c0c24054f965b2dc3036456ae03a51ea6264b/tomli-2.0.2.tar.gz" - } - ], - "project_name": "tomli", - "requires_dists": [], - "requires_python": ">=3.8", - "version": "2.0.2" - }, { "artifacts": [ { @@ -269,7 +251,7 @@ "strawberry-graphql==0.240.4" ], "requires_python": [ - "==3.9.*" + "==3.11.*" ], "resolver_version": "pip-2020-resolver", "style": "universal", diff --git a/3rdparty/python/pbs-script-requirements.lock b/3rdparty/python/pbs-script-requirements.lock new file mode 100644 index 00000000000..f1393f11559 --- /dev/null +++ b/3rdparty/python/pbs-script-requirements.lock @@ -0,0 +1,674 @@ +// This lockfile was autogenerated by Pants. To regenerate, run: +// +// pants generate-lockfiles --resolve=pbs-script +// +// --- BEGIN PANTS LOCKFILE METADATA: DO NOT EDIT OR REMOVE --- +// { +// "version": 3, +// "valid_for_interpreter_constraints": [ +// "CPython==3.11.*" +// ], +// "generated_with_requirements": [ +// "PyGithub>=2.5.0", +// "requests[security]>=2.28.1", +// "types-requests==2.28.1" +// ], +// "manylinux": "manylinux2014", +// "requirement_constraints": [], +// "only_binary": [], +// "no_binary": [] +// } +// --- END PANTS LOCKFILE METADATA --- + +{ + "allow_builds": true, + "allow_prereleases": false, + "allow_wheels": true, + "build_isolation": true, + "constraints": [], + "excluded": [], + "locked_resolves": [ + { + "locked_requirements": [ + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", + "url": "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", + "url": "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz" + } + ], + "project_name": "certifi", + "requires_dists": [], + "requires_python": ">=3.6", + "version": "2024.8.30" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", + "url": "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", + "url": "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", + "url": "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + }, + { + "algorithm": "sha256", + "hash": "a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", + "url": "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", + "url": "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl" + }, + { + "algorithm": "sha256", + "hash": "a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", + "url": "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl" + }, + { + "algorithm": "sha256", + "hash": "a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", + "url": "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", + "url": "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl" + }, + { + "algorithm": "sha256", + "hash": "f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", + "url": "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + }, + { + "algorithm": "sha256", + "hash": "1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", + "url": "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz" + }, + { + "algorithm": "sha256", + "hash": "610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", + "url": "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + } + ], + "project_name": "cffi", + "requires_dists": [ + "pycparser" + ], + "requires_python": ">=3.8", + "version": "1.17.1" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "url": "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "url": "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl" + }, + { + "algorithm": "sha256", + "hash": "82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "url": "https://files.pythonhosted.org/packages/3b/a0/a68980ab8a1f45a36d9745d35049c1af57d27255eff8c907e3add84cf68f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + }, + { + "algorithm": "sha256", + "hash": "bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "url": "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "url": "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl" + }, + { + "algorithm": "sha256", + "hash": "c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "url": "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "url": "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl" + }, + { + "algorithm": "sha256", + "hash": "0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "url": "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl" + }, + { + "algorithm": "sha256", + "hash": "6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "url": "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl" + }, + { + "algorithm": "sha256", + "hash": "47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "url": "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "url": "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + }, + { + "algorithm": "sha256", + "hash": "3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "url": "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "url": "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "url": "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz" + }, + { + "algorithm": "sha256", + "hash": "8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "url": "https://files.pythonhosted.org/packages/fb/9d/9c13753a5a6e0db4a0a6edb1cef7aee39859177b64e1a1e748a6e3ba62c2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl" + } + ], + "project_name": "charset-normalizer", + "requires_dists": [], + "requires_python": ">=3.7.0", + "version": "3.4.0" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73", + "url": "https://files.pythonhosted.org/packages/2a/33/b3682992ab2e9476b9c81fff22f02c8b0a1e6e1d49ee1750a67d85fd7ed2/cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd", + "url": "https://files.pythonhosted.org/packages/01/f5/69ae8da70c19864a32b0315049866c4d411cce423ec169993d0434218762/cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f", + "url": "https://files.pythonhosted.org/packages/0a/be/f9a1f673f0ed4b7f6c643164e513dbad28dd4f2dcdf5715004f172ef24b6/cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", + "url": "https://files.pythonhosted.org/packages/0d/05/07b55d1fa21ac18c3a8c79f764e2514e6f6a9698f1be44994f5adf0d29db/cryptography-43.0.3.tar.gz" + }, + { + "algorithm": "sha256", + "hash": "74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18", + "url": "https://files.pythonhosted.org/packages/0e/16/a28ddf78ac6e7e3f25ebcef69ab15c2c6be5ff9743dd0709a69a4f968472/cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e", + "url": "https://files.pythonhosted.org/packages/1f/f3/01fdf26701a26f4b4dbc337a26883ad5bccaa6f1bbbdd29cd89e22f18a1c/cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl" + }, + { + "algorithm": "sha256", + "hash": "e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16", + "url": "https://files.pythonhosted.org/packages/21/ce/b9c9ff56c7164d8e2edfb6c9305045fbc0df4508ccfdb13ee66eb8c95b0e/cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4", + "url": "https://files.pythonhosted.org/packages/2a/2c/488776a3dc843f95f86d2f957ca0fc3407d0242b50bede7fad1e339be03f/cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5", + "url": "https://files.pythonhosted.org/packages/2f/78/55356eb9075d0be6e81b59f45c7b48df87f76a20e73893872170471f3ee8/cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984", + "url": "https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl" + }, + { + "algorithm": "sha256", + "hash": "443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6", + "url": "https://files.pythonhosted.org/packages/4e/49/80c3a7b5514d1b416d7350830e8c422a4d667b6d9b16a9392ebfd4a5388a/cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7", + "url": "https://files.pythonhosted.org/packages/7c/04/2345ca92f7a22f601a9c62961741ef7dd0127c39f7310dffa0041c80f16f/cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e", + "url": "https://files.pythonhosted.org/packages/a3/01/4896f3d1b392025d4fcbecf40fdea92d3df8662123f6835d0af828d148fd/cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405", + "url": "https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73", + "url": "https://files.pythonhosted.org/packages/fd/db/e74911d95c040f9afd3612b1f732e52b3e517cb80de8bf183be0b7d413c6/cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl" + } + ], + "project_name": "cryptography", + "requires_dists": [ + "bcrypt>=3.1.5; extra == \"ssh\"", + "build; extra == \"sdist\"", + "certifi; extra == \"test\"", + "cffi>=1.12; platform_python_implementation != \"PyPy\"", + "check-sdist; extra == \"pep8test\"", + "click; extra == \"pep8test\"", + "cryptography-vectors==43.0.3; extra == \"test\"", + "mypy; extra == \"pep8test\"", + "nox; extra == \"nox\"", + "pretend; extra == \"test\"", + "pyenchant>=1.6.11; extra == \"docstest\"", + "pytest-benchmark; extra == \"test\"", + "pytest-cov; extra == \"test\"", + "pytest-randomly; extra == \"test-randomorder\"", + "pytest-xdist; extra == \"test\"", + "pytest>=6.2.0; extra == \"test\"", + "readme-renderer; extra == \"docstest\"", + "ruff; extra == \"pep8test\"", + "sphinx-rtd-theme>=1.1.1; extra == \"docs\"", + "sphinx>=5.3.0; extra == \"docs\"", + "sphinxcontrib-spelling>=4.0.1; extra == \"docstest\"" + ], + "requires_python": ">=3.7", + "version": "43.0.3" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320", + "url": "https://files.pythonhosted.org/packages/1d/8f/c7f227eb42cfeaddce3eb0c96c60cbca37797fa7b34f8e1aeadf6c5c0983/Deprecated-1.2.15-py2.py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d", + "url": "https://files.pythonhosted.org/packages/2e/a3/53e7d78a6850ffdd394d7048a31a6f14e44900adedf190f9a165f6b69439/deprecated-1.2.15.tar.gz" + } + ], + "project_name": "deprecated", + "requires_dists": [ + "PyTest-Cov; extra == \"dev\"", + "PyTest; extra == \"dev\"", + "bump2version<1; extra == \"dev\"", + "jinja2~=3.0.3; extra == \"dev\"", + "setuptools; python_version >= \"3.12\" and extra == \"dev\"", + "sphinx<2; extra == \"dev\"", + "tox; extra == \"dev\"", + "wrapt<2,>=1.10" + ], + "requires_python": "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7", + "version": "1.2.15" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", + "url": "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "url": "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz" + } + ], + "project_name": "idna", + "requires_dists": [ + "flake8>=7.1.1; extra == \"all\"", + "mypy>=1.11.2; extra == \"all\"", + "pytest>=8.3.2; extra == \"all\"", + "ruff>=0.6.2; extra == \"all\"" + ], + "requires_python": ">=3.6", + "version": "3.10" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", + "url": "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", + "url": "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz" + } + ], + "project_name": "pycparser", + "requires_dists": [], + "requires_python": ">=3.8", + "version": "2.22" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "b0b635999a658ab8e08720bdd3318893ff20e2275f6446fcf35bf3f44f2c0fd2", + "url": "https://files.pythonhosted.org/packages/37/05/bfbdbbc5d8aafd8dae9b3b6877edca561fccd8528ef5edc4e7b6d23721b5/PyGithub-2.5.0-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "e1613ac508a9be710920d26eb18b1905ebd9926aa49398e88151c1b526aad3cf", + "url": "https://files.pythonhosted.org/packages/16/ce/aa91d30040d9552c274e7ea8bd10a977600d508d579a4bb262b95eccf961/pygithub-2.5.0.tar.gz" + } + ], + "project_name": "pygithub", + "requires_dists": [ + "Deprecated", + "pyjwt[crypto]>=2.4.0", + "pynacl>=1.4.0", + "requests>=2.14.0", + "typing-extensions>=4.0.0", + "urllib3>=1.26.0" + ], + "requires_python": ">=3.8", + "version": "2.5.0" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15", + "url": "https://files.pythonhosted.org/packages/6f/1d/ef9b066e7ef60494c94173dc9f0b9adf5d9ec5f888109f5c669f53d4144b/PyJWT-2.10.0-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c", + "url": "https://files.pythonhosted.org/packages/b5/05/324952ded002de746f87b21066b9373080bb5058f64cf01c4d62784b8186/pyjwt-2.10.0.tar.gz" + } + ], + "project_name": "pyjwt", + "requires_dists": [ + "coverage[toml]==5.0.4; extra == \"dev\"", + "coverage[toml]==5.0.4; extra == \"tests\"", + "cryptography>=3.4.0; extra == \"crypto\"", + "cryptography>=3.4.0; extra == \"dev\"", + "pre-commit; extra == \"dev\"", + "pytest<7.0.0,>=6.0.0; extra == \"dev\"", + "pytest<7.0.0,>=6.0.0; extra == \"tests\"", + "sphinx-rtd-theme; extra == \"dev\"", + "sphinx-rtd-theme; extra == \"docs\"", + "sphinx; extra == \"dev\"", + "sphinx; extra == \"docs\"", + "zope.interface; extra == \"dev\"", + "zope.interface; extra == \"docs\"" + ], + "requires_python": ">=3.9", + "version": "2.10.0" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff", + "url": "https://files.pythonhosted.org/packages/fd/1a/cc308a884bd299b651f1633acb978e8596c71c33ca85e9dc9fa33a5399b9/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b", + "url": "https://files.pythonhosted.org/packages/3d/85/c262db650e86812585e2bc59e497a8f59948a005325a11bbbc9ecd3fe26b/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92", + "url": "https://files.pythonhosted.org/packages/59/bb/fddf10acd09637327a97ef89d2a9d621328850a72f1fdc8c08bdf72e385f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394", + "url": "https://files.pythonhosted.org/packages/5d/70/87a065c37cca41a75f2ce113a5a2c2aa7533be648b184ade58971b5f7ccc/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858", + "url": "https://files.pythonhosted.org/packages/66/28/ca86676b69bf9f90e710571b67450508484388bfce09acf8a46f0b8c785f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba", + "url": "https://files.pythonhosted.org/packages/a7/22/27582568be639dfe22ddb3902225f91f2f17ceff88ce80e4db396c8986da/PyNaCl-1.5.0.tar.gz" + }, + { + "algorithm": "sha256", + "hash": "401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1", + "url": "https://files.pythonhosted.org/packages/ce/75/0b8ede18506041c0bf23ac4d8e2971b4161cd6ce630b177d0a08eb0d8857/PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl" + }, + { + "algorithm": "sha256", + "hash": "0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d", + "url": "https://files.pythonhosted.org/packages/ee/87/f1bb6a595f14a327e8285b9eb54d41fef76c585a0edef0a45f6fc95de125/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl" + } + ], + "project_name": "pynacl", + "requires_dists": [ + "cffi>=1.4.1", + "hypothesis>=3.27.0; extra == \"tests\"", + "pytest!=3.3.0,>=3.2.1; extra == \"tests\"", + "sphinx-rtd-theme; extra == \"docs\"", + "sphinx>=1.6.5; extra == \"docs\"" + ], + "requires_python": ">=3.6", + "version": "1.5.0" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", + "url": "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "url": "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz" + } + ], + "project_name": "requests", + "requires_dists": [ + "PySocks!=1.5.7,>=1.5.6; extra == \"socks\"", + "certifi>=2017.4.17", + "chardet<6,>=3.0.2; extra == \"use-chardet-on-py3\"", + "charset-normalizer<4,>=2", + "idna<4,>=2.5", + "urllib3<3,>=1.21.1" + ], + "requires_python": ">=3.8", + "version": "2.32.3" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "b097692e124001f0ed5e4490245bb090f5e8e929819972f9ace84f9c3e146e8c", + "url": "https://files.pythonhosted.org/packages/e5/63/aff77442bca75c76ff35aa2a2a6f2daef5852e49a84379457022b764fb46/types_requests-2.28.1-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "acd8ed78509d27bdf04cddcc05f7066dfde4d30dd7dba67b808cdb1141d62ffe", + "url": "https://files.pythonhosted.org/packages/77/9e/19df5d6a6a646f7c7d8b8564664a36d777c905dd88a0c9a6521b868ec9b4/types-requests-2.28.1.tar.gz" + } + ], + "project_name": "types-requests", + "requires_dists": [ + "types-urllib3<1.27" + ], + "requires_python": null, + "version": "2.28.1" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e", + "url": "https://files.pythonhosted.org/packages/11/7b/3fc711b2efea5e85a7a0bbfe269ea944aa767bbba5ec52f9ee45d362ccf3/types_urllib3-1.26.25.14-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f", + "url": "https://files.pythonhosted.org/packages/73/de/b9d7a68ad39092368fb21dd6194b362b98a1daeea5dcfef5e1adb5031c7e/types-urllib3-1.26.25.14.tar.gz" + } + ], + "project_name": "types-urllib3", + "requires_dists": [], + "requires_python": null, + "version": "1.26.25.14" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", + "url": "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", + "url": "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz" + } + ], + "project_name": "typing-extensions", + "requires_dists": [], + "requires_python": ">=3.8", + "version": "4.12.2" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "url": "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", + "url": "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz" + } + ], + "project_name": "urllib3", + "requires_dists": [ + "brotli>=1.0.9; platform_python_implementation == \"CPython\" and extra == \"brotli\"", + "brotlicffi>=0.8.0; platform_python_implementation != \"CPython\" and extra == \"brotli\"", + "h2<5,>=4; extra == \"h2\"", + "pysocks!=1.5.7,<2.0,>=1.5.6; extra == \"socks\"", + "zstandard>=0.18.0; extra == \"zstd\"" + ], + "requires_python": ">=3.8", + "version": "2.2.3" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1", + "url": "https://files.pythonhosted.org/packages/ff/21/abdedb4cdf6ff41ebf01a74087740a709e2edb146490e4d9beea054b0b7a/wrapt-1.16.0-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d", + "url": "https://files.pythonhosted.org/packages/0f/16/ea627d7817394db04518f62934a5de59874b587b792300991b3c347ff5e0/wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl" + }, + { + "algorithm": "sha256", + "hash": "6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956", + "url": "https://files.pythonhosted.org/packages/0f/ef/0ecb1fa23145560431b970418dce575cfaec555ab08617d82eb92afc7ccf/wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl" + }, + { + "algorithm": "sha256", + "hash": "d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3", + "url": "https://files.pythonhosted.org/packages/11/fb/18ec40265ab81c0e82a934de04596b6ce972c27ba2592c8b53d5585e6bcd/wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d", + "url": "https://files.pythonhosted.org/packages/25/62/cd284b2b747f175b5a96cbd8092b32e7369edab0644c45784871528eb852/wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1", + "url": "https://files.pythonhosted.org/packages/6e/52/2da48b35193e39ac53cfb141467d9f259851522d0e8c87153f0ba4205fb1/wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389", + "url": "https://files.pythonhosted.org/packages/7f/a7/f1212ba098f3de0fd244e2de0f8791ad2539c03bef6c05a9fcb03e45b089/wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", + "url": "https://files.pythonhosted.org/packages/95/4c/063a912e20bcef7124e0df97282a8af3ff3e4b603ce84c481d6d7346be0a/wrapt-1.16.0.tar.gz" + }, + { + "algorithm": "sha256", + "hash": "43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060", + "url": "https://files.pythonhosted.org/packages/b7/96/bb5e08b3d6db003c9ab219c487714c13a237ee7dcc572a555eaf1ce7dc82/wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + }, + { + "algorithm": "sha256", + "hash": "1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09", + "url": "https://files.pythonhosted.org/packages/fd/03/c188ac517f402775b90d6f312955a5e53b866c964b32119f2ed76315697e/wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl" + } + ], + "project_name": "wrapt", + "requires_dists": [], + "requires_python": ">=3.6", + "version": "1.16.0" + } + ], + "platform_tag": null + } + ], + "only_builds": [], + "only_wheels": [], + "overridden": [], + "path_mappings": {}, + "pex_version": "2.20.3", + "pip_version": "24.2", + "prefer_older_binary": false, + "requirements": [ + "PyGithub>=2.5.0", + "requests[security]>=2.28.1", + "types-requests==2.28.1" + ], + "requires_python": [ + "==3.11.*" + ], + "resolver_version": "pip-2020-resolver", + "style": "universal", + "target_systems": [ + "linux", + "mac" + ], + "transitive": true, + "use_pep517": null, + "use_system_time": false +} diff --git a/3rdparty/python/pbs-script-requirements.txt b/3rdparty/python/pbs-script-requirements.txt new file mode 100644 index 00000000000..8378579e5ae --- /dev/null +++ b/3rdparty/python/pbs-script-requirements.txt @@ -0,0 +1,3 @@ +PyGithub>=2.5.0 +requests[security]>=2.28.1 +types-requests==2.28.1 \ No newline at end of file diff --git a/3rdparty/python/pytest.lock b/3rdparty/python/pytest.lock index 80159af7afe..9e9532ada19 100644 --- a/3rdparty/python/pytest.lock +++ b/3rdparty/python/pytest.lock @@ -6,7 +6,7 @@ // { // "version": 3, // "valid_for_interpreter_constraints": [ -// "CPython==3.9.*" +// "CPython==3.11.*" // ], // "generated_with_requirements": [ // "ipdb", @@ -31,6 +31,7 @@ "allow_wheels": true, "build_isolation": true, "constraints": [], + "excluded": [], "locked_resolves": [ { "locked_requirements": [ @@ -64,102 +65,121 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", - "url": "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl" + "hash": "81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", + "url": "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", - "url": "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz" + "hash": "5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", + "url": "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz" } ], "project_name": "attrs", "requires_dists": [ - "attrs[tests-mypy]; extra == \"tests-no-zope\"", - "attrs[tests-no-zope]; extra == \"tests\"", - "attrs[tests]; extra == \"cov\"", - "attrs[tests]; extra == \"dev\"", - "cloudpickle; platform_python_implementation == \"CPython\" and extra == \"tests-no-zope\"", + "cloudpickle; platform_python_implementation == \"CPython\" and extra == \"benchmark\"", + "cloudpickle; platform_python_implementation == \"CPython\" and extra == \"cov\"", + "cloudpickle; platform_python_implementation == \"CPython\" and extra == \"dev\"", + "cloudpickle; platform_python_implementation == \"CPython\" and extra == \"tests\"", + "cogapp; extra == \"docs\"", "coverage[toml]>=5.3; extra == \"cov\"", "furo; extra == \"docs\"", - "hypothesis; extra == \"tests-no-zope\"", + "hypothesis; extra == \"benchmark\"", + "hypothesis; extra == \"cov\"", + "hypothesis; extra == \"dev\"", + "hypothesis; extra == \"tests\"", "importlib-metadata; python_version < \"3.8\"", - "mypy>=1.6; (platform_python_implementation == \"CPython\" and python_version >= \"3.8\") and extra == \"tests-mypy\"", + "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\") and extra == \"benchmark\"", + "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\") and extra == \"cov\"", + "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\") and extra == \"dev\"", + "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\") and extra == \"tests\"", + "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\") and extra == \"tests-mypy\"", "myst-parser; extra == \"docs\"", "pre-commit; extra == \"dev\"", - "pympler; extra == \"tests-no-zope\"", - "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.8\") and extra == \"tests-mypy\"", - "pytest-xdist[psutil]; extra == \"tests-no-zope\"", - "pytest>=4.3.0; extra == \"tests-no-zope\"", + "pympler; extra == \"benchmark\"", + "pympler; extra == \"cov\"", + "pympler; extra == \"dev\"", + "pympler; extra == \"tests\"", + "pytest-codspeed; extra == \"benchmark\"", + "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\") and extra == \"benchmark\"", + "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\") and extra == \"cov\"", + "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\") and extra == \"dev\"", + "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\") and extra == \"tests\"", + "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\") and extra == \"tests-mypy\"", + "pytest-xdist[psutil]; extra == \"benchmark\"", + "pytest-xdist[psutil]; extra == \"cov\"", + "pytest-xdist[psutil]; extra == \"dev\"", + "pytest-xdist[psutil]; extra == \"tests\"", + "pytest>=4.3.0; extra == \"benchmark\"", + "pytest>=4.3.0; extra == \"cov\"", + "pytest>=4.3.0; extra == \"dev\"", + "pytest>=4.3.0; extra == \"tests\"", "sphinx-notfound-page; extra == \"docs\"", "sphinx; extra == \"docs\"", "sphinxcontrib-towncrier; extra == \"docs\"", - "towncrier; extra == \"docs\"", - "zope-interface; extra == \"docs\"", - "zope-interface; extra == \"tests\"" + "towncrier<24.7; extra == \"docs\"" ], "requires_python": ">=3.7", - "version": "23.2.0" + "version": "24.2.0" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884", - "url": "https://files.pythonhosted.org/packages/f6/c9/7953a450762a62abbaf0a65b67fe406b3b515a755139b3db662da441ac87/coverage-7.5.3-pp38.pp39.pp310-none-any.whl" + "hash": "b9853509b4bf57ba7b1f99b9d866c422c9c5248799ab20e652bbb8a184a38181", + "url": "https://files.pythonhosted.org/packages/29/f7/80e7a36288785bf0a44f6fa2a778dae85d34d8761f4c0996066f3756bdf5/coverage-7.6.3-pp39.pp310-none-any.whl" }, { "algorithm": "sha256", - "hash": "2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7", - "url": "https://files.pythonhosted.org/packages/07/e0/0e30ca5c6c5bcae86df9583c30807ff26e0b991e76f266b81224410663e4/coverage-7.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "0c6c0f4d53ef603397fc894a895b960ecd7d44c727df42a8d500031716d4e8d2", + "url": "https://files.pythonhosted.org/packages/09/ec/c3c4dd9cdcd97f127141dfa348c737912d32130e6129e61645736106c341/coverage-7.6.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d", - "url": "https://files.pythonhosted.org/packages/30/ab/701129bdffd493d59070b238238d25ad8882f4967d44f7a399833a5585ae/coverage-7.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "43b32a06c47539fe275106b376658638b418c7cfdfff0e0259fbf877e845f14b", + "url": "https://files.pythonhosted.org/packages/0d/ef/8650eea57f9a602ef7ddaa846f1aa760704cb6032c23d10b051b304ed4a3/coverage-7.6.3-cp311-cp311-musllinux_1_2_i686.whl" }, { "algorithm": "sha256", - "hash": "3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd", - "url": "https://files.pythonhosted.org/packages/36/82/116efdd87a81ec86d4a4fbaf7f132dd6beb233c00b4d2374cf2981aaeecd/coverage-7.5.3-cp39-cp39-musllinux_1_1_x86_64.whl" + "hash": "c51ef82302386d686feea1c44dbeef744585da16fcf97deea2a8d6c1556f519b", + "url": "https://files.pythonhosted.org/packages/0f/77/8e5c0c6027ce0d06d0cb9569d372fb94247b5a49a7ef8bba288956696dcb/coverage-7.6.3-cp311-cp311-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", - "hash": "990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303", - "url": "https://files.pythonhosted.org/packages/3c/66/6f06c86471c79ebff4a300390b5fe1d3b2b9101995075e48d096092ddb6d/coverage-7.5.3-cp39-cp39-musllinux_1_1_i686.whl" + "hash": "bb7d5fe92bd0dc235f63ebe9f8c6e0884f7360f88f3411bfed1350c872ef2054", + "url": "https://files.pythonhosted.org/packages/12/50/51ec496dd2ad84ca3e5f67de23f6de630be923dd6f5aed31bb60eda540e5/coverage-7.6.3.tar.gz" }, { "algorithm": "sha256", - "hash": "f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85", - "url": "https://files.pythonhosted.org/packages/57/99/ccb1e4f40688d793ac54407fc86d120c6816ae99b747b47d3e2cc1067457/coverage-7.5.3-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "6e484e479860e00da1f005cd19d1c5d4a813324e5951319ac3f3eefb497cc549", + "url": "https://files.pythonhosted.org/packages/1e/00/ada23862b99bf25218a74a116011982e20d1d4740fe4ad009c08f1090a5b/coverage-7.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", - "hash": "d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31", - "url": "https://files.pythonhosted.org/packages/65/af/3b0268da4cba77f3dda012bafe90b8cbf163713ac92b3cc237ff794bf277/coverage-7.5.3-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "ee77c7bef0724165e795b6b7bf9c4c22a9b8468a6bdb9c6b4281293c6b22a90f", + "url": "https://files.pythonhosted.org/packages/76/f5/9e5b4cda520e07ff0e2bb61f6176cd9bf1a2a77c2f89caf8005ae9eba1d3/coverage-7.6.3-cp311-cp311-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f", - "url": "https://files.pythonhosted.org/packages/6c/a5/62ae2dc1850feabb74207a422d00893f451ee0950e52792eb208970a30b1/coverage-7.5.3.tar.gz" + "hash": "c77326300b839c44c3e5a8fe26c15b7e87b2f32dfd2fc9fee1d13604347c9b38", + "url": "https://files.pythonhosted.org/packages/78/4c/2705183ff384b1612170b70fb716dcd24941f9c71b02860f6bbdf7f2f780/coverage-7.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52", - "url": "https://files.pythonhosted.org/packages/93/3b/dbca2db3a60ed8543a0c815bf83875bf549e02fe6df4baa736216dfb33ae/coverage-7.5.3-cp39-cp39-musllinux_1_1_aarch64.whl" + "hash": "0ca37993206402c6c35dc717f90d4c8f53568a8b80f0bf1a1b2b334f4d488fba", + "url": "https://files.pythonhosted.org/packages/af/ca/0fe701e0bf0ba3062466ceeccb9857caa492886375bbf6eabeab118a4dd0/coverage-7.6.3-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341", - "url": "https://files.pythonhosted.org/packages/e7/10/ad84d019b8d72e92fb908a0524a190f7212062f89360099907b7a812dc65/coverage-7.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "37be7b5ea3ff5b7c4a9db16074dc94523b5f10dd1f3b362a827af66a55198175", + "url": "https://files.pythonhosted.org/packages/f4/c3/5f4e50d1ecb0cfab9f8b988df65d2ae800299bc0e4bda8f508e06717fa49/coverage-7.6.3-cp311-cp311-musllinux_1_2_aarch64.whl" } ], "project_name": "coverage", "requires_dists": [ "tomli; python_full_version <= \"3.11.0a6\" and extra == \"toml\"" ], - "requires_python": ">=3.8", - "version": "7.5.3" + "requires_python": ">=3.9", + "version": "7.6.3" }, { "artifacts": [ @@ -179,26 +199,6 @@ "requires_python": ">=3.5", "version": "5.1.1" }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad", - "url": "https://files.pythonhosted.org/packages/01/90/79fe92dd413a9cab314ef5c591b5aa9b9ba787ae4cadab75055b0ae00b33/exceptiongroup-1.2.1-py3-none-any.whl" - }, - { - "algorithm": "sha256", - "hash": "a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16", - "url": "https://files.pythonhosted.org/packages/a0/65/d66b7fbaef021b3c954b3bbb196d21d8a4b97918ea524f82cfae474215af/exceptiongroup-1.2.1.tar.gz" - } - ], - "project_name": "exceptiongroup", - "requires_dists": [ - "pytest>=6; extra == \"test\"" - ], - "requires_python": ">=3.7", - "version": "1.2.1" - }, { "artifacts": [ { @@ -226,13 +226,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc", - "url": "https://files.pythonhosted.org/packages/80/03/6ea8b1b2a5ab40a7a60dc464d3daa7aa546e0a74d74a9f8ff551ea7905db/executing-2.0.1-py2.py3-none-any.whl" + "hash": "8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf", + "url": "https://files.pythonhosted.org/packages/b5/fd/afcd0496feca3276f509df3dbd5dae726fcc756f1a08d9e25abe1733f962/executing-2.1.0-py2.py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147", - "url": "https://files.pythonhosted.org/packages/08/41/85d2d28466fca93737592b7f3cc456d1cfd6bcd401beceeba17e8e792b50/executing-2.0.1.tar.gz" + "hash": "8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab", + "url": "https://files.pythonhosted.org/packages/8c/e3/7d45f492c2c4a0e8e0fad57d081a7c8a0286cdd86372b070cca1ec0caa1e/executing-2.1.0.tar.gz" } ], "project_name": "executing", @@ -245,8 +245,8 @@ "pytest; extra == \"tests\"", "rich; python_version >= \"3.11\" and extra == \"tests\"" ], - "requires_python": ">=3.5", - "version": "2.0.1" + "requires_python": ">=3.8", + "version": "2.1.0" }, { "artifacts": [ @@ -325,93 +325,66 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397", - "url": "https://files.pythonhosted.org/packages/47/6b/d9fdcdef2eb6a23f391251fde8781c38d42acd82abe84d054cb74f7863b0/ipython-8.18.1-py3-none-any.whl" + "hash": "530ef1e7bb693724d3cdc37287c80b07ad9b25986c007a53aa1857272dac3f35", + "url": "https://files.pythonhosted.org/packages/f4/3a/5d8680279ada9571de8469220069d27024ee47624af534e537c9ff49a450/ipython-8.28.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27", - "url": "https://files.pythonhosted.org/packages/b1/b9/3ba6c45a6df813c09a48bac313c22ff83efa26cbb55011218d925a46e2ad/ipython-8.18.1.tar.gz" + "hash": "0d0d15ca1e01faeb868ef56bc7ee5a0de5bd66885735682e8a322ae289a13d1a", + "url": "https://files.pythonhosted.org/packages/f7/21/48db7d9dd622b9692575004c7c98f85f5629428f58596c59606d36c51b58/ipython-8.28.0.tar.gz" } ], "project_name": "ipython", "requires_dists": [ - "black; extra == \"all\"", "black; extra == \"black\"", "colorama; sys_platform == \"win32\"", - "curio; extra == \"all\"", "curio; extra == \"test-extra\"", "decorator", - "docrepr; extra == \"all\"", "docrepr; extra == \"doc\"", - "exceptiongroup; extra == \"all\"", "exceptiongroup; extra == \"doc\"", "exceptiongroup; python_version < \"3.11\"", - "ipykernel; extra == \"all\"", + "intersphinx-registry; extra == \"doc\"", "ipykernel; extra == \"doc\"", "ipykernel; extra == \"kernel\"", - "ipyparallel; extra == \"all\"", "ipyparallel; extra == \"parallel\"", - "ipywidgets; extra == \"all\"", + "ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]; extra == \"all\"", + "ipython[test,test_extra]; extra == \"all\"", + "ipython[test]; extra == \"doc\"", + "ipython[test]; extra == \"test-extra\"", "ipywidgets; extra == \"notebook\"", "jedi>=0.16", - "matplotlib!=3.2.0; extra == \"all\"", "matplotlib!=3.2.0; extra == \"test-extra\"", "matplotlib-inline", - "matplotlib; extra == \"all\"", "matplotlib; extra == \"doc\"", - "nbconvert; extra == \"all\"", + "matplotlib; extra == \"matplotlib\"", "nbconvert; extra == \"nbconvert\"", - "nbformat; extra == \"all\"", "nbformat; extra == \"nbformat\"", "nbformat; extra == \"test-extra\"", - "notebook; extra == \"all\"", "notebook; extra == \"notebook\"", - "numpy>=1.22; extra == \"all\"", - "numpy>=1.22; extra == \"test-extra\"", - "pandas; extra == \"all\"", + "numpy>=1.23; extra == \"test-extra\"", + "packaging; extra == \"test\"", "pandas; extra == \"test-extra\"", - "pexpect>4.3; sys_platform != \"win32\"", - "pickleshare; extra == \"all\"", - "pickleshare; extra == \"doc\"", + "pexpect>4.3; sys_platform != \"win32\" and sys_platform != \"emscripten\"", "pickleshare; extra == \"test\"", - "pickleshare; extra == \"test-extra\"", "prompt-toolkit<3.1.0,>=3.0.41", "pygments>=2.4.0", - "pytest-asyncio<0.22; extra == \"all\"", - "pytest-asyncio<0.22; extra == \"doc\"", "pytest-asyncio<0.22; extra == \"test\"", - "pytest-asyncio<0.22; extra == \"test-extra\"", - "pytest<7.1; extra == \"all\"", - "pytest<7.1; extra == \"doc\"", - "pytest<7.1; extra == \"test\"", - "pytest<7.1; extra == \"test-extra\"", - "pytest<7; extra == \"all\"", - "pytest<7; extra == \"doc\"", - "qtconsole; extra == \"all\"", + "pytest; extra == \"test\"", "qtconsole; extra == \"qtconsole\"", - "setuptools>=18.5; extra == \"all\"", "setuptools>=18.5; extra == \"doc\"", - "sphinx-rtd-theme; extra == \"all\"", "sphinx-rtd-theme; extra == \"doc\"", - "sphinx>=1.3; extra == \"all\"", "sphinx>=1.3; extra == \"doc\"", + "sphinxcontrib-jquery; extra == \"doc\"", "stack-data", - "stack-data; extra == \"all\"", - "stack-data; extra == \"doc\"", - "testpath; extra == \"all\"", - "testpath; extra == \"doc\"", "testpath; extra == \"test\"", - "testpath; extra == \"test-extra\"", - "traitlets>=5", - "trio; extra == \"all\"", + "tomli; python_version < \"3.11\" and extra == \"doc\"", + "traitlets>=5.13.0", "trio; extra == \"test-extra\"", - "typing-extensions; extra == \"all\"", "typing-extensions; extra == \"doc\"", - "typing-extensions; python_version < \"3.10\"" + "typing-extensions>=4.6; python_version < \"3.12\"" ], - "requires_python": ">=3.9", - "version": "8.18.1" + "requires_python": ">=3.10", + "version": "8.28.0" }, { "artifacts": [ @@ -491,54 +464,54 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", - "url": "https://files.pythonhosted.org/packages/02/8c/ab9a463301a50dab04d5472e998acbd4080597abc048166ded5c7aa768c8/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl" + "hash": "a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91", + "url": "https://files.pythonhosted.org/packages/d4/0b/998b17b9e06ea45ad1646fea586f1b83d02dfdb14d47dd2fd81fba5a08c9/MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", - "url": "https://files.pythonhosted.org/packages/0b/cc/48206bd61c5b9d0129f4d75243b156929b04c94c09041321456fd06a876d/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl" + "hash": "d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3", + "url": "https://files.pythonhosted.org/packages/26/ce/703ca3b03a709e3bd1fbffa407789e56b9fa664456538092617dd665fc1d/MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", - "hash": "7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", - "url": "https://files.pythonhosted.org/packages/0f/31/780bb297db036ba7b7bbede5e1d7f1e14d704ad4beb3ce53fb495d22bc62/MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl" + "hash": "973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7", + "url": "https://files.pythonhosted.org/packages/58/26/78f161d602fb03804118905e5faacafc0ec592bbad71aaee62537529813a/MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", - "url": "https://files.pythonhosted.org/packages/5f/5a/360da85076688755ea0cceb92472923086993e86b5613bbae9fbc14136b0/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915", + "url": "https://files.pythonhosted.org/packages/6d/f8/8fd52a66e8f62a9add62b4a0b5a3ab4092027437f2ef027f812d94ae91cf/MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl" }, { "algorithm": "sha256", - "hash": "4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", - "url": "https://files.pythonhosted.org/packages/6a/18/ae5a258e3401f9b8312f92b028c54d7026a97ec3ab20bfaddbdfa7d8cce8/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50", + "url": "https://files.pythonhosted.org/packages/88/60/40be0493decabc2344b12d3a709fd6ccdd15a5ebaee1e8d878315d107ad3/MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", - "url": "https://files.pythonhosted.org/packages/6c/77/d77701bbef72892affe060cdacb7a2ed7fd68dae3b477a8642f15ad3b132/MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583", + "url": "https://files.pythonhosted.org/packages/8d/43/fd588ef5d192308c5e05974bac659bf6ae29c202b7ea2c4194bcf01eacee/MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", - "url": "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz" + "hash": "244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b", + "url": "https://files.pythonhosted.org/packages/ae/1d/7d5ec8bcfd9c2db235d720fa51d818b7e2abc45250ce5f53dd6cb60409ca/MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", - "url": "https://files.pythonhosted.org/packages/d1/06/a41c112ab9ffdeeb5f77bc3e331fdadf97fa65e52e44ba31880f4e7f983c/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl" + "hash": "3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344", + "url": "https://files.pythonhosted.org/packages/b4/d2/38ff920762f2247c3af5cbbbbc40756f575d9692d381d7c520f45deb9b8f/markupsafe-3.0.1.tar.gz" }, { "algorithm": "sha256", - "hash": "3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", - "url": "https://files.pythonhosted.org/packages/d9/a7/1e558b4f78454c8a3a0199292d96159eb4d091f983bc35ef258314fe7269/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad", + "url": "https://files.pythonhosted.org/packages/ce/af/2f5d88a7fc7226bd34c6e15f6061246ad8cff979da9f19d11bdd0addd8e2/MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl" } ], "project_name": "markupsafe", "requires_dists": [], - "requires_python": ">=3.7", - "version": "2.1.5" + "requires_python": ">=3.9", + "version": "3.0.1" }, { "artifacts": [ @@ -667,13 +640,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10", - "url": "https://files.pythonhosted.org/packages/e8/23/22750c4b768f09386d1c3cc4337953e8936f48a888fa6dddfb669b2c9088/prompt_toolkit-3.0.47-py3-none-any.whl" + "hash": "f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e", + "url": "https://files.pythonhosted.org/packages/a9/6a/fd08d94654f7e67c52ca30523a178b3f8ccc4237fce4be90d39c938a831a/prompt_toolkit-3.0.48-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360", - "url": "https://files.pythonhosted.org/packages/47/6d/0279b119dafc74c1220420028d490c4399b790fc1256998666e3a341879f/prompt_toolkit-3.0.47.tar.gz" + "hash": "d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90", + "url": "https://files.pythonhosted.org/packages/2d/4f/feb5e137aff82f7c7f3248267b97451da3644f6cdc218edfe549fb354127/prompt_toolkit-3.0.48.tar.gz" } ], "project_name": "prompt-toolkit", @@ -681,7 +654,7 @@ "wcwidth" ], "requires_python": ">=3.7.0", - "version": "3.0.47" + "version": "3.0.48" }, { "artifacts": [ @@ -705,13 +678,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350", - "url": "https://files.pythonhosted.org/packages/2b/27/77f9d5684e6bce929f5cfe18d6cfbe5133013c06cb2fbf5933670e60761d/pure_eval-0.2.2-py3-none-any.whl" + "hash": "1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", + "url": "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3", - "url": "https://files.pythonhosted.org/packages/97/5a/0bc937c25d3ce4e0a74335222aee05455d6afa2888032185f8ab50cdf6fd/pure_eval-0.2.2.tar.gz" + "hash": "5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", + "url": "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz" } ], "project_name": "pure-eval", @@ -719,7 +692,7 @@ "pytest; extra == \"tests\"" ], "requires_python": null, - "version": "0.2.2" + "version": "0.2.3" }, { "artifacts": [ @@ -798,13 +771,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "009b48127fbe44518a547bddd25611551b0e43ccdbf1e67d12479f569832c20b", - "url": "https://files.pythonhosted.org/packages/e5/98/947690b1a79af83e584143cb904497caff05bb6016614b38326a81076357/pytest_asyncio-0.23.7-py3-none-any.whl" + "hash": "50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2", + "url": "https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "5f5c72948f4c49e7db4f29f2521d4031f1c27f86e57b046126654083d4770268", - "url": "https://files.pythonhosted.org/packages/13/d9/1dcac9b3fc6eccf8f1e3a657439c11ffc5cf762edd20f65577f832ba248b/pytest_asyncio-0.23.7.tar.gz" + "hash": "759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3", + "url": "https://files.pythonhosted.org/packages/de/b4/0b378b7bf26a8ae161c3890c0b48a91a04106c5713ce81b4b080ea2f4f18/pytest_asyncio-0.23.8.tar.gz" } ], "project_name": "pytest-asyncio", @@ -816,7 +789,7 @@ "sphinx>=5.3; extra == \"docs\"" ], "requires_python": ">=3.8", - "version": "0.23.7" + "version": "0.23.8" }, { "artifacts": [ @@ -1019,19 +992,19 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl" + "hash": "2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", + "url": "https://files.pythonhosted.org/packages/cf/db/ce8eda256fa131af12e0a76d481711abe4681b6923c27efb9a255c9e4594/tomli-2.0.2-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", - "url": "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz" + "hash": "d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed", + "url": "https://files.pythonhosted.org/packages/35/b9/de2a5c0144d7d75a57ff355c0c24054f965b2dc3036456ae03a51ea6264b/tomli-2.0.2.tar.gz" } ], "project_name": "tomli", "requires_dists": [], - "requires_python": ">=3.7", - "version": "2.0.1" + "requires_python": ">=3.8", + "version": "2.0.2" }, { "artifacts": [ @@ -1105,9 +1078,10 @@ ], "only_builds": [], "only_wheels": [], + "overridden": [], "path_mappings": {}, - "pex_version": "2.3.1", - "pip_version": "24.0", + "pex_version": "2.19.1", + "pip_version": "24.2", "prefer_older_binary": false, "requirements": [ "ipdb", @@ -1120,7 +1094,7 @@ "pytest==7.0.1" ], "requires_python": [ - "==3.9.*" + "==3.11.*" ], "resolver_version": "pip-2020-resolver", "style": "universal", diff --git a/3rdparty/python/user_reqs.lock b/3rdparty/python/user_reqs.lock index 461f7de6601..34a30b4eb33 100644 --- a/3rdparty/python/user_reqs.lock +++ b/3rdparty/python/user_reqs.lock @@ -6,7 +6,7 @@ // { // "version": 3, // "valid_for_interpreter_constraints": [ -// "CPython==3.9.*" +// "CPython==3.11.*" // ], // "generated_with_requirements": [ // "PyGithub==2.4.0", @@ -264,48 +264,48 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e", - "url": "https://files.pythonhosted.org/packages/e6/c3/21cab7a6154b6a5ea330ae80de386e7665254835b9e98ecc1340b3a7de9a/cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl" + "hash": "fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", + "url": "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl" }, { "algorithm": "sha256", - "hash": "ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576", - "url": "https://files.pythonhosted.org/packages/42/7a/9d086fab7c66bd7c4d0f27c57a1b6b068ced810afc498cc8c49e0088661c/cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", + "url": "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl" }, { "algorithm": "sha256", - "hash": "9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595", - "url": "https://files.pythonhosted.org/packages/5b/95/b34462f3ccb09c2594aa782d90a90b045de4ff1f70148ee79c69d37a0a5a/cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl" + "hash": "46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", + "url": "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" }, { "algorithm": "sha256", - "hash": "98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0", - "url": "https://files.pythonhosted.org/packages/74/06/90b8a44abf3556599cdec107f7290277ae8901a58f75e6fe8f970cd72418/cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl" + "hash": "a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", + "url": "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36", - "url": "https://files.pythonhosted.org/packages/ae/11/e77c8cd24f58285a82c23af484cf5b124a376b32644e445960d1a4654c3a/cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", + "url": "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl" }, { "algorithm": "sha256", - "hash": "b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16", - "url": "https://files.pythonhosted.org/packages/b9/ea/8bb50596b8ffbc49ddd7a1ad305035daa770202a6b782fc164647c2673ad/cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", + "url": "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl" }, { "algorithm": "sha256", - "hash": "cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3", - "url": "https://files.pythonhosted.org/packages/bd/62/a1f468e5708a70b1d86ead5bab5520861d9c7eacce4a885ded9faa7729c3/cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", + "url": "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", - "hash": "f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", - "url": "https://files.pythonhosted.org/packages/da/63/1785ced118ce92a993b0ec9e0d0ac8dc3e5dbfbcaa81135be56c69cabbb6/cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + "hash": "30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", + "url": "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8", - "url": "https://files.pythonhosted.org/packages/ed/65/25a8dc32c53bf5b7b6c2686b42ae2ad58743f7ff644844af7cdb29b49361/cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", + "url": "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", @@ -314,8 +314,8 @@ }, { "algorithm": "sha256", - "hash": "f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a", - "url": "https://files.pythonhosted.org/packages/fc/fc/a1e4bebd8d680febd29cf6c8a40067182b64f00c7d105f8f26b5bc54317b/cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl" + "hash": "610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", + "url": "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" } ], "project_name": "cffi", @@ -334,63 +334,63 @@ }, { "algorithm": "sha256", - "hash": "285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", - "url": "https://files.pythonhosted.org/packages/0c/48/0050550275fea585a6e24460b42465020b53375017d8596c96be57bfabca/charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "url": "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl" }, { "algorithm": "sha256", - "hash": "309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", - "url": "https://files.pythonhosted.org/packages/28/89/60f51ad71f63aaaa7e51a2a2ad37919985a341a1d267070f212cdf6c2d22/charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "url": "https://files.pythonhosted.org/packages/3b/a0/a68980ab8a1f45a36d9745d35049c1af57d27255eff8c907e3add84cf68f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", - "hash": "980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", - "url": "https://files.pythonhosted.org/packages/54/2f/28659eee7f5d003e0f5a3b572765bf76d6e0fe6601ab1f1b1dd4cba7e4f1/charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl" + "hash": "bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "url": "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", - "url": "https://files.pythonhosted.org/packages/54/9a/acfa96dc4ea8c928040b15822b59d0863d6e1757fba8bd7de3dc4f761c13/charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl" + "hash": "f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "url": "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl" }, { "algorithm": "sha256", - "hash": "e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", - "url": "https://files.pythonhosted.org/packages/7b/ab/f47b0159a69eab9bd915591106859f49670c75f9a19082505ff16f50efc0/charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl" + "hash": "c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "url": "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", - "hash": "20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", - "url": "https://files.pythonhosted.org/packages/84/79/5c731059ebab43e80bf61fa51666b9b18167974b82004f18c76378ed31a3/charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl" + "hash": "63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "url": "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl" }, { "algorithm": "sha256", - "hash": "bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", - "url": "https://files.pythonhosted.org/packages/a4/23/65af317914a0308495133b2d654cf67b11bbd6ca16637c4e8a38f80a5a69/charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "url": "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl" }, { "algorithm": "sha256", - "hash": "130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", - "url": "https://files.pythonhosted.org/packages/ca/f3/0719cd09fc4dc42066f239cb3c48ced17fc3316afca3e2a30a4756fe49ab/charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl" + "hash": "6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "url": "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", - "url": "https://files.pythonhosted.org/packages/d1/18/92869d5c0057baa973a3ee2af71573be7b084b3c3d428fe6463ce71167f8/charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "url": "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", - "url": "https://files.pythonhosted.org/packages/d6/27/327904c5a54a7796bb9f36810ec4173d2df5d88b401d2b95ef53111d214e/charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "url": "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" }, { "algorithm": "sha256", - "hash": "5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", - "url": "https://files.pythonhosted.org/packages/dc/b5/47f8ee91455946f745e6c9ddbb0f8f50314d2416dd922b213e7d5551ad09/charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl" + "hash": "3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "url": "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", - "url": "https://files.pythonhosted.org/packages/f2/41/6190102ad521a8aa888519bb014a74251ac4586cde9b38e790901684f9ab/charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + "hash": "bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "url": "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", @@ -399,8 +399,8 @@ }, { "algorithm": "sha256", - "hash": "ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", - "url": "https://files.pythonhosted.org/packages/f7/0e/c6357297f1157c8e8227ff337e93fd0a90e498e3d6ab96b2782204ecae48/charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl" + "hash": "8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "url": "https://files.pythonhosted.org/packages/fb/9d/9c13753a5a6e0db4a0a6edb1cef7aee39859177b64e1a1e748a6e3ba62c2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl" } ], "project_name": "charset-normalizer", @@ -451,93 +451,78 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172", - "url": "https://files.pythonhosted.org/packages/21/b0/4ecefa99519eaa32af49a3ad002bb3e795f9e6eb32221fd87736247fa3cb/cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl" + "hash": "df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73", + "url": "https://files.pythonhosted.org/packages/2a/33/b3682992ab2e9476b9c81fff22f02c8b0a1e6e1d49ee1750a67d85fd7ed2/cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806", - "url": "https://files.pythonhosted.org/packages/00/0e/8217e348a1fa417ec4c78cd3cdf24154f5e76fd7597343a35bd403650dfd/cryptography-43.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd", + "url": "https://files.pythonhosted.org/packages/01/f5/69ae8da70c19864a32b0315049866c4d411cce423ec169993d0434218762/cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062", - "url": "https://files.pythonhosted.org/packages/33/13/1193774705783ba364121aa2a60132fa31a668b8ababd5edfa1662354ccd/cryptography-43.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f", + "url": "https://files.pythonhosted.org/packages/0a/be/f9a1f673f0ed4b7f6c643164e513dbad28dd4f2dcdf5715004f172ef24b6/cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85", - "url": "https://files.pythonhosted.org/packages/3d/ed/38b6be7254d8f7251fde8054af597ee8afa14f911da67a9410a45f602fc3/cryptography-43.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", + "url": "https://files.pythonhosted.org/packages/0d/05/07b55d1fa21ac18c3a8c79f764e2514e6f6a9698f1be44994f5adf0d29db/cryptography-43.0.3.tar.gz" }, { "algorithm": "sha256", - "hash": "9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96", - "url": "https://files.pythonhosted.org/packages/3e/fd/70f3e849ad4d6cca2118ee6938e0b52326d02406f10912356151dd4b6868/cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl" + "hash": "74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18", + "url": "https://files.pythonhosted.org/packages/0e/16/a28ddf78ac6e7e3f25ebcef69ab15c2c6be5ff9743dd0709a69a4f968472/cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl" }, { "algorithm": "sha256", - "hash": "80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa", - "url": "https://files.pythonhosted.org/packages/43/f6/feebbd78a3e341e3913846a3bb2c29d0b09b1b3af1573c6baabc2533e147/cryptography-43.0.1-cp39-abi3-musllinux_1_2_aarch64.whl" + "hash": "bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e", + "url": "https://files.pythonhosted.org/packages/1f/f3/01fdf26701a26f4b4dbc337a26883ad5bccaa6f1bbbdd29cd89e22f18a1c/cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl" }, { "algorithm": "sha256", - "hash": "8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d", - "url": "https://files.pythonhosted.org/packages/58/28/b92c98a04ba762f8cdeb54eba5c4c84e63cac037a7c5e70117d337b15ad6/cryptography-43.0.1-cp37-abi3-macosx_10_9_universal2.whl" + "hash": "e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16", + "url": "https://files.pythonhosted.org/packages/21/ce/b9c9ff56c7164d8e2edfb6c9305045fbc0df4508ccfdb13ee66eb8c95b0e/cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962", - "url": "https://files.pythonhosted.org/packages/5e/4b/39bb3c4c8cfb3e94e736b8d8859ce5c81536e91a1033b1d26770c4249000/cryptography-43.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4", + "url": "https://files.pythonhosted.org/packages/2a/2c/488776a3dc843f95f86d2f957ca0fc3407d0242b50bede7fad1e339be03f/cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c", - "url": "https://files.pythonhosted.org/packages/64/f3/b7946c3887cf7436f002f4cbb1e6aec77b8d299b86be48eeadfefb937c4b/cryptography-43.0.1-cp39-abi3-manylinux_2_28_aarch64.whl" + "hash": "846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5", + "url": "https://files.pythonhosted.org/packages/2f/78/55356eb9075d0be6e81b59f45c7b48df87f76a20e73893872170471f3ee8/cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d", - "url": "https://files.pythonhosted.org/packages/8a/b6/bc54b371f02cffd35ff8dc6baba88304d7cf8e83632566b4b42e00383e03/cryptography-43.0.1-cp39-abi3-macosx_10_9_universal2.whl" + "hash": "8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984", + "url": "https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl" }, { "algorithm": "sha256", - "hash": "014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494", - "url": "https://files.pythonhosted.org/packages/a4/65/430509e31700286ec02868a2457d2111d03ccefc20349d24e58d171ae0a7/cryptography-43.0.1-cp37-abi3-musllinux_1_2_x86_64.whl" + "hash": "443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6", + "url": "https://files.pythonhosted.org/packages/4e/49/80c3a7b5514d1b416d7350830e8c422a4d667b6d9b16a9392ebfd4a5388a/cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl" }, { "algorithm": "sha256", - "hash": "511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1", - "url": "https://files.pythonhosted.org/packages/ac/7e/ebda4dd4ae098a0990753efbb4b50954f1d03003846b943ea85070782da7/cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl" + "hash": "f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7", + "url": "https://files.pythonhosted.org/packages/7c/04/2345ca92f7a22f601a9c62961741ef7dd0127c39f7310dffa0041c80f16f/cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl" }, { "algorithm": "sha256", - "hash": "f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a", - "url": "https://files.pythonhosted.org/packages/ad/43/7a9920135b0d5437cc2f8f529fa757431eb6a7736ddfadfdee1cc5890800/cryptography-43.0.1-cp37-abi3-manylinux_2_28_x86_64.whl" + "hash": "63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e", + "url": "https://files.pythonhosted.org/packages/a3/01/4896f3d1b392025d4fcbecf40fdea92d3df8662123f6835d0af828d148fd/cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365", - "url": "https://files.pythonhosted.org/packages/b2/aa/782e42ccf854943dfce72fb94a8d62220f22084ff07076a638bc3f34f3cc/cryptography-43.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl" + "hash": "c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405", + "url": "https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl" }, { "algorithm": "sha256", - "hash": "38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4", - "url": "https://files.pythonhosted.org/packages/bd/4c/ab0b9407d5247576290b4fd8abd06b7f51bd414f04eef0f2800675512d61/cryptography-43.0.1-cp39-abi3-musllinux_1_2_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042", - "url": "https://files.pythonhosted.org/packages/cc/42/9ab8467af6c0b76f3d9b8f01d1cf25b9c9f3f2151f4acfab888d21c55a72/cryptography-43.0.1-cp37-abi3-musllinux_1_2_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277", - "url": "https://files.pythonhosted.org/packages/ce/dc/1471d4d56608e1013237af334b8a4c35d53895694fbb73882d1c4fd3f55e/cryptography-43.0.1-cp37-abi3-manylinux_2_28_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d", - "url": "https://files.pythonhosted.org/packages/de/ba/0664727028b37e249e73879348cc46d45c5c1a2a2e81e8166462953c5755/cryptography-43.0.1.tar.gz" + "hash": "81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73", + "url": "https://files.pythonhosted.org/packages/fd/db/e74911d95c040f9afd3612b1f732e52b3e517cb80de8bf183be0b7d413c6/cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl" } ], "project_name": "cryptography", @@ -548,7 +533,7 @@ "cffi>=1.12; platform_python_implementation != \"PyPy\"", "check-sdist; extra == \"pep8test\"", "click; extra == \"pep8test\"", - "cryptography-vectors==43.0.1; extra == \"test\"", + "cryptography-vectors==43.0.3; extra == \"test\"", "mypy; extra == \"pep8test\"", "nox; extra == \"nox\"", "pretend; extra == \"test\"", @@ -565,7 +550,7 @@ "sphinxcontrib-spelling>=4.0.1; extra == \"docstest\"" ], "requires_python": ">=3.7", - "version": "43.0.1" + "version": "43.0.3" }, { "artifacts": [ @@ -574,16 +559,6 @@ "hash": "4de7777842da7e08652f2776c552070bbdd758557fdec73a15d7be0e4aab95ce", "url": "https://files.pythonhosted.org/packages/e3/9c/0920139b8ccce7565e1e5ba1ccdeeba281bbab37392689aa00dfb6b55a6d/debugpy-1.6.0-py2.py3-none-any.whl" }, - { - "algorithm": "sha256", - "hash": "0e3aa2368883e83e7b689ddff3cafb595f7b711f6a065886b46a96a7fef874e7", - "url": "https://files.pythonhosted.org/packages/31/c4/7da0696f7f07dc30d474d06cf087c788d1dad12d6fdb39b0ba8cbece1f72/debugpy-1.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "245c7789a012f86210847ec7ee9f38c30a30d4c2223c3e111829a76c9006a5d0", - "url": "https://files.pythonhosted.org/packages/45/a7/0bf4729aa497cc8837e9b525f34e6bad69f2191cfc14d63b36214add7a5c/debugpy-1.6.0-cp39-cp39-macosx_10_15_x86_64.whl" - }, { "algorithm": "sha256", "hash": "7b79c40852991f7b6c3ea65845ed0f5f6b731c37f4f9ad9c61e2ab4bd48a9275", @@ -620,26 +595,6 @@ "requires_python": "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7", "version": "1.2.14" }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", - "url": "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl" - }, - { - "algorithm": "sha256", - "hash": "47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", - "url": "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz" - } - ], - "project_name": "exceptiongroup", - "requires_dists": [ - "pytest>=6; extra == \"test\"" - ], - "requires_python": ">=3.7", - "version": "1.2.2" - }, { "artifacts": [ { @@ -787,23 +742,23 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "0e563e54979e97b6d13f1bbc05a96109923e76b901f786a5eae36e99c01237bd", - "url": "https://files.pythonhosted.org/packages/fc/b3/3a1bc45be03dda7a60c7858e55b6cd0489a81613c1908fb81cf21d34ae50/httptools-0.6.4-cp39-cp39-musllinux_1_2_x86_64.whl" + "hash": "dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988", + "url": "https://files.pythonhosted.org/packages/3e/d2/84c9e23edbccc4a4c6f96a1b8d99dfd2350289e94f00e9ccc7aadde26fb5/httptools-0.6.4-cp311-cp311-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "aafe0f1918ed07b67c1e838f950b1c1fabc683030477e60b335649b8020e1076", - "url": "https://files.pythonhosted.org/packages/2a/13/68337d3be6b023260139434c49d7aa466aaa98f9aee7ed29270ac7dde6a2/httptools-0.6.4-cp39-cp39-musllinux_1_2_aarch64.whl" + "hash": "40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721", + "url": "https://files.pythonhosted.org/packages/6e/4c/d09ce0eff09057a206a74575ae8f1e1e2f0364d20e2442224f9e6612c8b9/httptools-0.6.4-cp311-cp311-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "703c346571fa50d2e9856a37d7cd9435a25e7fd15e236c397bf224afaa355fe9", - "url": "https://files.pythonhosted.org/packages/2b/62/e7f317fed3703bd81053840cacba4e40bcf424b870e4197f94bd1cf9fe7a/httptools-0.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069", + "url": "https://files.pythonhosted.org/packages/7b/26/bb526d4d14c2774fe07113ca1db7255737ffbb119315839af2065abfdac3/httptools-0.6.4-cp311-cp311-macosx_10_9_universal2.whl" }, { "algorithm": "sha256", - "hash": "85797e37e8eeaa5439d33e556662cc370e474445d5fab24dcadc65a8ffb04003", - "url": "https://files.pythonhosted.org/packages/51/b1/4fc6f52afdf93b7c4304e21f6add9e981e4f857c2fa622a55dfe21b6059e/httptools-0.6.4-cp39-cp39-macosx_10_9_universal2.whl" + "hash": "0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a", + "url": "https://files.pythonhosted.org/packages/a6/17/3e0d3e9b901c732987a45f4f94d4e2c62b89a041d93db89eafb262afd8d5/httptools-0.6.4-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", @@ -812,13 +767,13 @@ }, { "algorithm": "sha256", - "hash": "db353d22843cf1028f43c3651581e4bb49374d85692a85f95f7b9a130e1b2cab", - "url": "https://files.pythonhosted.org/packages/c2/01/e6ecb40ac8fdfb76607c7d3b74a41b464458d5c8710534d8f163b0c15f29/httptools-0.6.4-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636", + "url": "https://files.pythonhosted.org/packages/b1/2f/205d1f2a190b72da6ffb5f41a3736c26d6fa7871101212b15e9b5cd8f61d/httptools-0.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "d1ffd262a73d7c28424252381a5b854c19d9de5f56f075445d33919a637e3547", - "url": "https://files.pythonhosted.org/packages/dc/24/c70c34119d209bf08199d938dc9c69164f585ed3029237b4bdb90f673cb9/httptools-0.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975", + "url": "https://files.pythonhosted.org/packages/b7/24/0fe235d7b69c42423c7698d086d4db96475f9b50b6ad26a718ef27a0bce6/httptools-0.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" } ], "project_name": "httptools", @@ -855,18 +810,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "db3bf1b42191b5cc9b6441552fdcb3b583594cb6b19e90d1578b7cbcf80d0fae", - "url": "https://files.pythonhosted.org/packages/16/63/379288ee38453166dca4a433ef5ad75525cdaa57c5df24bfcfb441400b14/ijson-3.2.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "2ec3e5ff2515f1c40ef6a94983158e172f004cd643b9e4b5302017139b6c96e4", - "url": "https://files.pythonhosted.org/packages/03/f0/9b0b163a38211195a9a340252f0684f14c91c11f388c680d56ca168ea730/ijson-3.2.3-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426", + "url": "https://files.pythonhosted.org/packages/42/fa/70d8c1fe7e27b37f3614e3fe93ab6ad3c3e44ba2391a4f2317f00b6349f4/ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl" }, { "algorithm": "sha256", - "hash": "7851a341429b12d4527ca507097c959659baf5106c7074d15c17c387719ffbcd", - "url": "https://files.pythonhosted.org/packages/18/31/904ee13b144b5c47b1e037f4507faf7fe21184a500490d7421e467c0af58/ijson-3.2.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "7b8064a85ec1b0beda7dd028e887f7112670d574db606f68006c72dd0bb0e0e2", + "url": "https://files.pythonhosted.org/packages/18/86/44fd5092c76d4156bc14cae39a6def99e42a5621d947085d55cd63272b7f/ijson-3.2.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", @@ -875,53 +825,38 @@ }, { "algorithm": "sha256", - "hash": "e9fd906f0c38e9f0bfd5365e1bed98d649f506721f76bb1a9baa5d7374f26f19", - "url": "https://files.pythonhosted.org/packages/2a/39/9110eb844a941ed557784936e5c345cf83827e309f51120d02b9bd47af8a/ijson-3.2.3-cp39-cp39-musllinux_1_1_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "ab4db9fee0138b60e31b3c02fff8a4c28d7b152040553b6a91b60354aebd4b02", - "url": "https://files.pythonhosted.org/packages/4f/b5/42abcd90002cd91424f61bbb54bf2f5a237e616b018b4d6dc702b238479f/ijson-3.2.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl" - }, - { - "algorithm": "sha256", - "hash": "3b14d322fec0de7af16f3ef920bf282f0dd747200b69e0b9628117f381b7775b", - "url": "https://files.pythonhosted.org/packages/75/c4/bf15c8aefbb6cccd40b97eba5b09d9bc16f72fb0945c7071e6723f14b2dd/ijson-3.2.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "2cc04fc0a22bb945cd179f614845c8b5106c0b3939ee0d84ce67c7a61ac1a936", - "url": "https://files.pythonhosted.org/packages/7d/6d/3c2947bbebca249b4174b1b88de984b584be58a3f30ed2076111e2ffa7ff/ijson-3.2.3-cp39-cp39-musllinux_1_1_x86_64.whl" + "hash": "eaac293853f1342a8d2a45ac1f723c860f700860e7743fb97f7b76356df883a8", + "url": "https://files.pythonhosted.org/packages/2c/cb/8deea644d652eef65b8a7105d11b1b9df812306b59b115c3d42b34764320/ijson-3.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "1844c5b57da21466f255a0aeddf89049e730d7f3dfc4d750f0e65c36e6a61a7c", - "url": "https://files.pythonhosted.org/packages/91/62/f7bb45ea600755b45d5fcc5857c308f0df036b022cf8b091ca739403525e/ijson-3.2.3-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "713a919e0220ac44dab12b5fed74f9130f3480e55e90f9d80f58de129ea24f83", + "url": "https://files.pythonhosted.org/packages/46/09/8fc1acab4be0ad18df4210a8565cd78bcb59221535358147b5f6df06df3b/ijson-3.2.3-cp311-cp311-musllinux_1_1_i686.whl" }, { "algorithm": "sha256", - "hash": "e84d27d1acb60d9102728d06b9650e5b7e5cb0631bd6e3dfadba8fb6a80d6c2f", - "url": "https://files.pythonhosted.org/packages/96/88/367e332eb08dc040957ba5cefb09b865bc65242e7afed432d0effe6c3180/ijson-3.2.3-cp39-cp39-musllinux_1_1_i686.whl" + "hash": "0974444c1f416e19de1e9f567a4560890095e71e81623c509feff642114c1e53", + "url": "https://files.pythonhosted.org/packages/5d/88/371bec0bdd4f5e91f7ba4710903c60a07b8784b777d02667a4e7f97ec983/ijson-3.2.3-cp311-cp311-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", - "hash": "9c2a12dcdb6fa28f333bf10b3a0f80ec70bc45280d8435be7e19696fab2bc706", - "url": "https://files.pythonhosted.org/packages/ce/4f/05ee1b53f990191126c85c1a32161c1902fa106193154552ce1a65777c8f/ijson-3.2.3-cp39-cp39-macosx_10_9_universal2.whl" + "hash": "904f77dd3d87736ff668884fe5197a184748eb0c3e302ded61706501d0327465", + "url": "https://files.pythonhosted.org/packages/66/93/38fa3ca3ffec156b10b68180d972647a70305a8c4097fecdad5bcdb4d1de/ijson-3.2.3-cp311-cp311-macosx_10_9_universal2.whl" }, { "algorithm": "sha256", - "hash": "46bafb1b9959872a1f946f8dd9c6f1a30a970fc05b7bfae8579da3f1f988e598", - "url": "https://files.pythonhosted.org/packages/d4/fa/17bb67264702afb0e5d8f2792a354b2b05f23b97d9485a20f9e28418b7e5/ijson-3.2.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "c1a4b8eb69b6d7b4e94170aa991efad75ba156b05f0de2a6cd84f991def12ff9", + "url": "https://files.pythonhosted.org/packages/6c/7b/337152bf341be869fd5b2c8669713a6db4b22170d2676e137b44a4a22eab/ijson-3.2.3-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "f4bc87e69d1997c6a55fff5ee2af878720801ff6ab1fb3b7f94adda050651e37", - "url": "https://files.pythonhosted.org/packages/d9/ae/2d754d4f0968aaf152f8fbfad0d9b564e2dbda614b6f9d4a338e49aac960/ijson-3.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "d052417fd7ce2221114f8d3b58f05a83c1a2b6b99cafe0b86ac9ed5e2fc889df", + "url": "https://files.pythonhosted.org/packages/d1/6d/0bcb4634a64eadd4f6d064bbfd170f556674a16c418b50a8a7d5272b9335/ijson-3.2.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "39f551a6fbeed4433c85269c7c8778e2aaea2501d7ebcb65b38f556030642c17", - "url": "https://files.pythonhosted.org/packages/e5/83/474f96ff7b76c78eec559f877589d46da72860d3da04bbf7601c4fd9b32d/ijson-3.2.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl" + "hash": "6c32c18a934c1dc8917455b0ce478fd7a26c50c364bd52c5a4fb0fc6bb516af7", + "url": "https://files.pythonhosted.org/packages/f9/c2/103dec4e699c5d1fc2024d3f12f6e62550a0035d02f7b52f6f2285bf2c65/ijson-3.2.3-cp311-cp311-musllinux_1_1_aarch64.whl" } ], "project_name": "ijson", @@ -951,28 +886,28 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "d024f44059a853b4b852cfc04fec33e346659d851371e46fc8e7c19de24d3da9", - "url": "https://files.pythonhosted.org/packages/71/da/16307f14b47f761235050076e1d2954fc7de9346f1410ba8c67a54a9f40e/libcst-1.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "cb4e42ea107a37bff7f9fdbee9532d39f9ea77b89caa5c5112b37057b12e0838", + "url": "https://files.pythonhosted.org/packages/0a/6c/1eb258b0eba8f337e1e9bd40574247310670c036a3913c9b650d6d9cd4de/libcst-1.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", - "hash": "b8ecdba8934632b4dadacb666cd3816627a6ead831b806336972ccc4ba7ca0e9", - "url": "https://files.pythonhosted.org/packages/7b/b1/8476fe4fa1061062855459d519ffe2115a891638c230ee3465c69fdbfd7a/libcst-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "f42797309bb725f0f000510d5463175ccd7155395f09b5e7723971b0007a976d", + "url": "https://files.pythonhosted.org/packages/50/a1/2093f74a3f8936fcdaac01f86d1c5fa8f586202afa466a92332b9a461b14/libcst-1.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "8e54c777b8d27339b70f304d16fc8bc8674ef1bd34ed05ea874bf4921eb5a313", - "url": "https://files.pythonhosted.org/packages/7e/0d/89516795ff2a11be10c060c539895b3781793d46cb7c9b0b7b3c4fa3fbc1/libcst-1.4.0-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "3399e6c95df89921511b44d8c5bf6a75bcbc2d51f1f6429763609ba005c10f6b", + "url": "https://files.pythonhosted.org/packages/5d/82/652e041aa6e14751a2ce41e68e281d9d5a32864ba11a363e103c429bf0e8/libcst-1.4.0-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "bb0abf627ee14903d05d0ad9b2c6865f1b21eb4081e2c7bea1033f85db2b8bae", - "url": "https://files.pythonhosted.org/packages/95/cf/a2be91d53e4068d4def8b5cc475f20e1c1a7d32c85634ee7d6b3ea2e3c9b/libcst-1.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "e6227562fc5c9c1efd15dfe90b0971ae254461b8b6b23c1b617139b6003de1c1", + "url": "https://files.pythonhosted.org/packages/85/2c/6bf8e4710afe1e0d45643e3726c0a956f5965555425cd7efa31e97cc7a6b/libcst-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", - "hash": "061d6855ef30efe38b8a292b7e5d57c8e820e71fc9ec9846678b60a934b53bbb", - "url": "https://files.pythonhosted.org/packages/c0/c8/15ca337e5f5604aabed899609ba08abbc0e7815ffdfca37802da52d4d0bf/libcst-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "48601e3e590e2d6a7ab8c019cf3937c70511a78d778ab3333764531253acdb33", + "url": "https://files.pythonhosted.org/packages/b8/d7/515b6187a900033467a4001bf8e2ed95f4961aa9bedf2bf39dfd68659157/libcst-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", @@ -1193,38 +1128,38 @@ }, { "algorithm": "sha256", - "hash": "baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a", - "url": "https://files.pythonhosted.org/packages/20/e6/89d6ba0c0a981fd7e3129d105502c4cf73fad1611b294c87b103f75b5837/pydantic-1.10.18.tar.gz" + "hash": "ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5", + "url": "https://files.pythonhosted.org/packages/1b/f4/0cf037f5c03c4d8aa18439d0146e11c2cfcca936388993a6868c803f3db1/pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86", - "url": "https://files.pythonhosted.org/packages/52/88/4a4b9c66341a5ea01ed5b61dc4ffdfb0fa2f76b98176259966296c4f83a7/pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl" + "hash": "baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a", + "url": "https://files.pythonhosted.org/packages/20/e6/89d6ba0c0a981fd7e3129d105502c4cf73fad1611b294c87b103f75b5837/pydantic-1.10.18.tar.gz" }, { "algorithm": "sha256", - "hash": "80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf", - "url": "https://files.pythonhosted.org/packages/9b/bf/e934226fd3fae61a7f306c8a3af45f450d8dc86bd8d7303f6bfb3aea6683/pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3", + "url": "https://files.pythonhosted.org/packages/32/d7/62134d1662af1af476b1103aea8b3ab928ff737624f8e23beeef1fbffde1/pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", - "hash": "aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9", - "url": "https://files.pythonhosted.org/packages/b5/9a/abf55d8e363a7a8a995a9c72fb29824cf6b79ba491b661bcbb922d7bcc33/pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec", + "url": "https://files.pythonhosted.org/packages/42/c1/d5f1a844e2bc08ccb0330d2d656595e177aba494d69a3fd42e3a35f11526/pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", - "hash": "941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d", - "url": "https://files.pythonhosted.org/packages/c7/2a/ff110d4286121890ce3a15599d7e25df4924451496ca9a94bcb910c4469f/pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f", + "url": "https://files.pythonhosted.org/packages/a2/de/ed086c435121c4bf915720528637e4fe7edc9b00057337512b122f1bc2db/pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl" }, { "algorithm": "sha256", - "hash": "6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f", - "url": "https://files.pythonhosted.org/packages/d2/1b/f0a9c6d47318cc321fc8fe9b6392492c7c3a8ee398312f65fbf02f0bdf1a/pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl" + "hash": "9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588", + "url": "https://files.pythonhosted.org/packages/cf/e2/0e3b2250f470faa4ff150ff5e6729e1cec62e35abfc8f5150f4e794e4585/pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl" }, { "algorithm": "sha256", - "hash": "65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485", - "url": "https://files.pythonhosted.org/packages/dd/96/245e45c54765255518c881a8b57f760446d9f3ebe8ecca85942565e7faf3/pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481", + "url": "https://files.pythonhosted.org/packages/d1/34/1a9c2745e28ca5891adbff2730c1f81f3e191aeb1c2108c8c7757dfa1989/pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" } ], "project_name": "pydantic", @@ -1539,43 +1474,43 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", - "url": "https://files.pythonhosted.org/packages/82/72/04fcad41ca56491995076630c3ec1e834be241664c0c09a64c9a2589b507/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl" + "hash": "797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", + "url": "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl" }, { "algorithm": "sha256", - "hash": "a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", - "url": "https://files.pythonhosted.org/packages/0a/02/6ec546cd45143fdf9840b2c6be8d875116a64076218b61d68e12548e5839/PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", + "url": "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl" }, { "algorithm": "sha256", - "hash": "d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", - "url": "https://files.pythonhosted.org/packages/0e/9a/8cc68be846c972bda34f6c2a93abb644fb2476f4dcc924d52175786932c9/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", + "url": "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz" }, { "algorithm": "sha256", - "hash": "3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", - "url": "https://files.pythonhosted.org/packages/3d/32/e7bd8535d22ea2874cef6a81021ba019474ace0d13a4819c2a4bce79bd6a/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", + "url": "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", - "url": "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz" + "hash": "1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", + "url": "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", - "url": "https://files.pythonhosted.org/packages/65/d8/b7a1db13636d7fb7d4ff431593c510c8b8fca920ade06ca8ef20015493c5/PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", + "url": "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl" }, { "algorithm": "sha256", - "hash": "0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", - "url": "https://files.pythonhosted.org/packages/d7/12/7322c1e30b9be969670b672573d45479edef72c9a0deac3bb2868f5d7469/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl" + "hash": "5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", + "url": "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", - "url": "https://files.pythonhosted.org/packages/e9/6c/6e1b7f40181bc4805e2e07f4abc10a88ce4648e7e95ff1abe4ae4014a9b2/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl" + "hash": "cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", + "url": "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl" } ], "project_name": "pyyaml", @@ -1612,53 +1547,43 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "65d884e22037b23fa25b2baf1a3316602ed5c5971eb3e9d771a38c3a69ce6e13", - "url": "https://files.pythonhosted.org/packages/8d/f0/7d0999aaa3efb1d5e4f1bb7d7a0fee133e94a70e0780c3032e6cc19c66da/setproctitle-1.3.2-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "db684d6bbb735a80bcbc3737856385b55d53f8a44ce9b46e9a5682c5133a9bf7", + "url": "https://files.pythonhosted.org/packages/96/e7/e409f944c8d22667f725eaba9d6c505ce6c44d91ff5922acc8347447ac66/setproctitle-1.3.2-cp311-cp311-musllinux_1_1_x86_64.whl" }, { "algorithm": "sha256", - "hash": "a149a5f7f2c5a065d4e63cb0d7a4b6d3b66e6e80f12e3f8827c4f63974cbf122", - "url": "https://files.pythonhosted.org/packages/02/9c/48155692325ff7ca9b841cfc7894ea6770c4a24455f8775959916f08e723/setproctitle-1.3.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl" + "hash": "a8e0881568c5e6beff91ef73c0ec8ac2a9d3ecc9edd6bd83c31ca34f770910c4", + "url": "https://files.pythonhosted.org/packages/0e/08/a1fa4d4a3077604e71eb6b76795814b44a8a1fec874b06bca853157b2313/setproctitle-1.3.2-cp311-cp311-musllinux_1_1_aarch64.whl" }, { "algorithm": "sha256", - "hash": "b34baef93bfb20a8ecb930e395ccd2ae3268050d8cf4fe187de5e2bd806fd796", - "url": "https://files.pythonhosted.org/packages/29/0f/884a680fed30dbd1f99fba1f0ae189a1bc7026246150a1b4a5492108c231/setproctitle-1.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl" + "hash": "570d255fd99c7f14d8f91363c3ea96bd54f8742275796bca67e1414aeca7d8c3", + "url": "https://files.pythonhosted.org/packages/18/c7/890da8a5790fa733a9fbf47d92e8226c1ff4bf1853dbdbabbdaa3aa6dffc/setproctitle-1.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "2e3ac25bfc4a0f29d2409650c7532d5ddfdbf29f16f8a256fc31c47d0dc05172", - "url": "https://files.pythonhosted.org/packages/41/c7/107d46b676592ce508bd0ad3ac3b94acb1754460f375eccaba6e151375a8/setproctitle-1.3.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "e932089c35a396dc31a5a1fc49889dd559548d14cb2237adae260382a090382e", + "url": "https://files.pythonhosted.org/packages/1c/4c/c1ef1118bcb756fd10bee57a2748240b033168501c77aec80d0eb9874f64/setproctitle-1.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" }, { "algorithm": "sha256", - "hash": "fed18e44711c5af4b681c2b3b18f85e6f0f1b2370a28854c645d636d5305ccd8", - "url": "https://files.pythonhosted.org/packages/42/69/5495ee592ad6c6411c9d1f1d610e37557f14fa5d039ef82bf86f328ca289/setproctitle-1.3.2-cp39-cp39-musllinux_1_1_i686.whl" + "hash": "37ece938110cab2bb3957e3910af8152ca15f2b6efdf4f2612e3f6b7e5459b80", + "url": "https://files.pythonhosted.org/packages/26/a8/e406c98df9ff7a7481b8bb9ab4b410405a39751ec8b54ac8108bd0c80b4d/setproctitle-1.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl" }, { "algorithm": "sha256", - "hash": "4058564195b975ddc3f0462375c533cce310ccdd41b80ac9aed641c296c3eff4", - "url": "https://files.pythonhosted.org/packages/4a/a4/cb6c3d274e8f5c36c65590723d58f994f407a0c835ac94379c00b89df4dd/setproctitle-1.3.2-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "2a97d51c17d438cf5be284775a322d57b7ca9505bb7e118c28b1824ecaf8aeaa", + "url": "https://files.pythonhosted.org/packages/4a/f9/f4e96c6c95d5e5e958405292ddb9dd932ec083c6f76ba55458b6caa4db02/setproctitle-1.3.2-cp311-cp311-macosx_10_9_universal2.whl" }, { "algorithm": "sha256", - "hash": "de3a540cd1817ede31f530d20e6a4935bbc1b145fd8f8cf393903b1e02f1ae76", - "url": "https://files.pythonhosted.org/packages/50/ef/cff921345cadf05bef3cb4da37eac23d08fd063222a633231e8ae1f61a0d/setproctitle-1.3.2-cp39-cp39-macosx_10_9_universal2.whl" + "hash": "4bba3be4c1fabf170595b71f3af46c6d482fbe7d9e0563999b49999a31876f77", + "url": "https://files.pythonhosted.org/packages/4d/7d/9c8371cde990ecce6d263c9b482bae0e75d49505589f1f7ef1ad4f756bbd/setproctitle-1.3.2-cp311-cp311-musllinux_1_1_i686.whl" }, { "algorithm": "sha256", - "hash": "ffc61a388a5834a97953d6444a2888c24a05f2e333f9ed49f977a87bb1ad4761", - "url": "https://files.pythonhosted.org/packages/66/b0/bb81bad3120364523b1a9511564f6ec6f5de322400cd5f3ebef526d40c23/setproctitle-1.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" - }, - { - "algorithm": "sha256", - "hash": "1c5d5dad7c28bdd1ec4187d818e43796f58a845aa892bb4481587010dc4d362b", - "url": "https://files.pythonhosted.org/packages/9a/12/cc8c117c13319e7c56aea7c33d127150e538da7e9a4808aa91e07d424610/setproctitle-1.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "7f0bed90a216ef28b9d227d8d73e28a8c9b88c0f48a082d13ab3fa83c581488f", - "url": "https://files.pythonhosted.org/packages/a9/6e/c50be96334dcb7a63f7fca5897d99f2ae1deee378cec8dbd8a56c3cd4ded/setproctitle-1.3.2-cp39-cp39-musllinux_1_1_x86_64.whl" + "hash": "587c7d6780109fbd8a627758063d08ab0421377c0853780e5c356873cdf0f077", + "url": "https://files.pythonhosted.org/packages/8c/4c/1b2c04a95da8e6c0951223bfbb0d4b56876ba35567455b88bbc9e48b7052/setproctitle-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", @@ -1667,18 +1592,13 @@ }, { "algorithm": "sha256", - "hash": "fe8a988c7220c002c45347430993830666e55bc350179d91fcee0feafe64e1d4", - "url": "https://files.pythonhosted.org/packages/b7/7e/4f71712c98fd06b3075c93a1a2135c5f656191b2aae30895ca7bc7a0da03/setproctitle-1.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "8e4f8f12258a8739c565292a551c3db62cca4ed4f6b6126664e2381acb4931bf", + "url": "https://files.pythonhosted.org/packages/d7/76/46e536e87e0e46309f5664ebecebbbc541315d81ad301e93204d0248beed/setproctitle-1.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", - "hash": "bae283e85fc084b18ffeb92e061ff7ac5af9e183c9d1345c93e178c3e5069cbe", - "url": "https://files.pythonhosted.org/packages/dd/6e/e920bb0ce7bc7eebdef249643ac3b66dbd9677d668472a86b88149575234/setproctitle-1.3.2-cp39-cp39-musllinux_1_1_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "1fa1a0fbee72b47dc339c87c890d3c03a72ea65c061ade3204f285582f2da30f", - "url": "https://files.pythonhosted.org/packages/f3/4e/3b13ff5965903911f4e93631fb3ae7419943e0dc77e479b781e34540fae3/setproctitle-1.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "d7d17c8bd073cbf8d141993db45145a70b307385b69171d6b54bcf23e5d644de", + "url": "https://files.pythonhosted.org/packages/e1/8d/4ad25c2e80e81f9c698add6c7a96e547c7194412ce85bce6c2c75eb8d2f8/setproctitle-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" } ], "project_name": "setproctitle", @@ -2038,68 +1958,43 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "0de4971a89a762398006e844ae394bd46991f7c385d7a6a3b93ba229e6dac17e", - "url": "https://files.pythonhosted.org/packages/23/1c/cfefabb5996e21a1a4348852df7eb7cfc69299143739e86e5b1071c78735/ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" - }, - { - "algorithm": "sha256", - "hash": "4734ee0745d5928d0ba3a213647f1c4a74a2a28edc6d27b2d6d5bd9fa4319e27", - "url": "https://files.pythonhosted.org/packages/0c/b3/3d2ca621d8dbeaf6c5afd0725e1b4bbd465077acc69eff1e9302735d1432/ujson-5.10.0-cp39-cp39-macosx_11_0_arm64.whl" - }, - { - "algorithm": "sha256", - "hash": "7490655a2272a2d0b072ef16b0b58ee462f4973a8f6bbe64917ce5e0a256f9c0", - "url": "https://files.pythonhosted.org/packages/1f/28/bcf6df25c1a9f1989dc2ddc4ac8a80e246857e089f91a9079fd8a0a01459/ujson-5.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" - }, - { - "algorithm": "sha256", - "hash": "dee5e97c2496874acbf1d3e37b521dd1f307349ed955e62d1d2f05382bc36dd5", - "url": "https://files.pythonhosted.org/packages/5d/dd/b9a6027ba782b0072bf24a70929e15a58686668c32a37aebfcfaa9e00bdd/ujson-5.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "2aff2985cef314f21d0fecc56027505804bc78802c0121343874741650a4d3d1", - "url": "https://files.pythonhosted.org/packages/63/eb/2a4ea07165cad217bc842bb684b053bafa8ffdb818c47911c621e97a33fc/ujson-5.10.0-cp39-cp39-musllinux_1_2_i686.whl" - }, - { - "algorithm": "sha256", - "hash": "ad88ac75c432674d05b61184178635d44901eb749786c8eb08c102330e6e8996", - "url": "https://files.pythonhosted.org/packages/72/53/d7bdf6afabeba3ed899f89d993c7f202481fa291d8c5be031c98a181eda4/ujson-5.10.0-cp39-cp39-musllinux_1_2_x86_64.whl" + "hash": "57aaf98b92d72fc70886b5a0e1a1ca52c2320377360341715dd3933a18e827b1", + "url": "https://files.pythonhosted.org/packages/89/d5/2626c87c59802863d44d19e35ad16b7e658e4ac190b0dead17ff25460b4c/ujson-5.10.0-cp311-cp311-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "ac56eb983edce27e7f51d05bc8dd820586c6e6be1c5216a6809b0c668bb312b8", - "url": "https://files.pythonhosted.org/packages/73/3d/41e78e7500e75eb6b5a7ab06907a6df35603b92ac6f939b86f40e9fe2c06/ujson-5.10.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl" + "hash": "5b91b5d0d9d283e085e821651184a647699430705b15bf274c7896f23fe9c9d8", + "url": "https://files.pythonhosted.org/packages/1f/2b/44d6b9c1688330bf011f9abfdb08911a9dc74f76926dde74e718d87600da/ujson-5.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "ba43cc34cce49cf2d4bc76401a754a81202d8aa926d0e2b79f0ee258cb15d3a4", - "url": "https://files.pythonhosted.org/packages/8d/96/a3a2356ca5a4b67fe32a0c31e49226114d5154ba2464bb1220a93eb383e8/ujson-5.10.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl" + "hash": "a5b366812c90e69d0f379a53648be10a5db38f9d4ad212b60af00bd4048d0f00", + "url": "https://files.pythonhosted.org/packages/23/ec/3c551ecfe048bcb3948725251fb0214b5844a12aa60bee08d78315bb1c39/ujson-5.10.0-cp311-cp311-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", - "hash": "d47ebb01bd865fdea43da56254a3930a413f0c5590372a1241514abae8aa7c76", - "url": "https://files.pythonhosted.org/packages/8d/af/5dc103cb4d08f051f82d162a738adb9da488d1e3fafb9fd9290ea3eabf8e/ujson-5.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "f77b74475c462cb8b88680471193064d3e715c7c6074b1c8c412cb526466efe9", + "url": "https://files.pythonhosted.org/packages/26/21/a0c265cda4dd225ec1be595f844661732c13560ad06378760036fc622587/ujson-5.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", - "hash": "dfef2814c6b3291c3c5f10065f745a1307d86019dbd7ea50e83504950136ed5b", - "url": "https://files.pythonhosted.org/packages/97/94/50ff2f1b61d668907f20216873640ab19e0eaa77b51e64ee893f6adfb266/ujson-5.10.0-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "7ec0ca8c415e81aa4123501fee7f761abf4b7f386aad348501a26940beb1860f", + "url": "https://files.pythonhosted.org/packages/28/36/8fde862094fd2342ccc427a6a8584fed294055fdee341661c78660f7aef3/ujson-5.10.0-cp311-cp311-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "ba17799fcddaddf5c1f75a4ba3fd6441f6a4f1e9173f8a786b42450851bd74f1", - "url": "https://files.pythonhosted.org/packages/9e/82/89404453a102d06d0937f6807c0a7ef2eec68b200b4ce4386127f3c28156/ujson-5.10.0-cp39-cp39-musllinux_1_2_aarch64.whl" + "hash": "129e39af3a6d85b9c26d5577169c21d53821d8cf68e079060602e861c6e5da1b", + "url": "https://files.pythonhosted.org/packages/29/45/f5f5667427c1ec3383478092a414063ddd0dfbebbcc533538fe37068a0a3/ujson-5.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "f44bd4b23a0e723bf8b10628288c2c7c335161d6840013d4d5de20e48551773b", - "url": "https://files.pythonhosted.org/packages/be/14/e435cbe5b5189483adbba5fe328e88418ccd54b2b1f74baa4172384bb5cd/ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "502bf475781e8167f0f9d0e41cd32879d120a524b22358e7f205294224c71126", + "url": "https://files.pythonhosted.org/packages/8d/9f/4731ef0671a0653e9f5ba18db7c4596d8ecbf80c7922dd5fe4150f1aea76/ujson-5.10.0-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "7c10f4654e5326ec14a46bcdeb2b685d4ada6911050aa8baaf3501e57024b804", - "url": "https://files.pythonhosted.org/packages/e8/d9/b6f4d1e6bec20a3b582b48f64eaa25209fd70dc2892b21656b273bc23434/ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "ab13a2a9e0b2865a6c6db9271f4b46af1c7476bfd51af1f64585e919b7c07fd4", + "url": "https://files.pythonhosted.org/packages/90/37/9208e40d53baa6da9b6a1c719e0670c3f474c8fc7cc2f1e939ec21c1bc93/ujson-5.10.0-cp311-cp311-musllinux_1_2_i686.whl" }, { "algorithm": "sha256", @@ -2176,38 +2071,38 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "2d1f581393673ce119355d56da84fe1dd9d2bb8b3d13ce792524e1607139feff", - "url": "https://files.pythonhosted.org/packages/1a/5c/6ba221bb60f1e6474474102e17e38612ec7a06dc320e22b687ab563d877f/uvloop-0.21.0-cp39-cp39-musllinux_1_2_x86_64.whl" + "hash": "4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d", + "url": "https://files.pythonhosted.org/packages/da/e2/5cf6ef37e3daf2f06e651aae5ea108ad30df3cb269102678b61ebf1fdf42/uvloop-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "46923b0b5ee7fc0020bef24afe7836cb068f5050ca04caf6b487c513dc1a20b2", - "url": "https://files.pythonhosted.org/packages/01/2e/e128c66106af9728f86ebfeeb52af27ecd3cb09336f3e2f3e06053707a15/uvloop-0.21.0-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6", + "url": "https://files.pythonhosted.org/packages/30/bf/08ad29979a936d63787ba47a540de2132169f140d54aa25bc8c3df3e67f4/uvloop-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "53e420a3afe22cdcf2a0f4846e377d16e718bc70103d7088a4f7623567ba5fb0", - "url": "https://files.pythonhosted.org/packages/2d/1a/9fbc2b1543d0df11f7aed1632f64bdf5ecc4053cf98cdc9edb91a65494f9/uvloop-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8", + "url": "https://files.pythonhosted.org/packages/57/a7/4cf0334105c1160dd6819f3297f8700fda7fc30ab4f61fbf3e725acbc7cc/uvloop-0.21.0-cp311-cp311-macosx_10_9_universal2.whl" }, { "algorithm": "sha256", - "hash": "c097078b8031190c934ed0ebfee8cc5f9ba9642e6eb88322b9958b649750f72b", - "url": "https://files.pythonhosted.org/packages/3c/a4/646a9d0edff7cde25fc1734695d3dfcee0501140dd0e723e4df3f0a50acb/uvloop-0.21.0-cp39-cp39-macosx_10_9_universal2.whl" + "hash": "8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb", + "url": "https://files.pythonhosted.org/packages/8a/ca/0864176a649838b838f36d44bf31c451597ab363b60dc9e09c9630619d41/uvloop-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", - "url": "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz" + "hash": "0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0", + "url": "https://files.pythonhosted.org/packages/8c/7c/1517b0bbc2dbe784b563d6ab54f2ef88c890fdad77232c98ed490aa07132/uvloop-0.21.0-cp311-cp311-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", - "hash": "88cb67cdbc0e483da00af0b2c3cdad4b7c61ceb1ee0f33fe00e09c81e3a6cb75", - "url": "https://files.pythonhosted.org/packages/b8/c0/392e235e4100ae3b95b5c6dac77f82b529d2760942b1e7e0981e5d8e895d/uvloop-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", + "url": "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz" }, { "algorithm": "sha256", - "hash": "221f4f2a1f46032b403bf3be628011caf75428ee3cc204a22addf96f586b19fd", - "url": "https://files.pythonhosted.org/packages/e1/24/a5da6aba58f99aed5255eca87d58d1760853e8302d390820cc29058408e3/uvloop-0.21.0-cp39-cp39-musllinux_1_2_aarch64.whl" + "hash": "b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e", + "url": "https://files.pythonhosted.org/packages/ee/ea/0bfae1aceb82a503f358d8d2fa126ca9dbdb2ba9c7866974faec1cb5875c/uvloop-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" } ], "project_name": "uvloop", @@ -2256,78 +2151,53 @@ }, { "algorithm": "sha256", - "hash": "163e7277e1a0bd9fb3c8842a71661ad19c6aa7bb3d6678dc7f89b17fbcc4aeb7", - "url": "https://files.pythonhosted.org/packages/0e/d4/9b4814a07dffaa7a79d71b4944d10836f9adbd527a113f6675734ef3abed/websockets-13.1-cp39-cp39-macosx_10_9_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "4b889dbd1342820cc210ba44307cf75ae5f2f96226c0038094455a96e64fb07a", - "url": "https://files.pythonhosted.org/packages/1a/1a/2abdc7ce3b56429ae39d6bfb48d8c791f5a26bbcb6f44aabcf71ffc3fda2/websockets-13.1-cp39-cp39-macosx_11_0_arm64.whl" - }, - { - "algorithm": "sha256", - "hash": "586a356928692c1fed0eca68b4d1c2cbbd1ca2acf2ac7e7ebd3b9052582deefa", - "url": "https://files.pythonhosted.org/packages/2a/98/189d7cf232753a719b2726ec55e7922522632248d5d830adf078e3f612be/websockets-13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9", + "url": "https://files.pythonhosted.org/packages/28/09/af9e19885539759efa2e2cd29b8b3f9eecef7ecefea40d46612f12138b36/websockets-13.1-cp311-cp311-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "25c35bf84bf7c7369d247f0b8cfa157f989862c49104c5cf85cb5436a641d93e", - "url": "https://files.pythonhosted.org/packages/59/fd/e4bf9a7159dba6a16c59ae9e670e3e8ad9dcb6791bc0599eb86de32d50a9/websockets-13.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl" + "hash": "7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3", + "url": "https://files.pythonhosted.org/packages/30/93/c3891c20114eacb1af09dedfcc620c65c397f4fd80a7009cd12d9457f7f5/websockets-13.1-cp311-cp311-musllinux_1_2_i686.whl" }, { "algorithm": "sha256", - "hash": "9b37c184f8b976f0c0a231a5f3d6efe10807d41ccbe4488df8c74174805eea7d", - "url": "https://files.pythonhosted.org/packages/61/26/5f7a7fb03efedb4f90ed61968338bfe7c389863b0ceda239b94ae61c5ae4/websockets-13.1-cp39-cp39-macosx_10_9_universal2.whl" + "hash": "c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd", + "url": "https://files.pythonhosted.org/packages/68/d4/c8c7c1e5b40ee03c5cc235955b0fb1ec90e7e37685a5f69229ad4708dcde/websockets-13.1-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "83f91d8a9bb404b8c2c41a707ac7f7f75b9442a0a876df295de27251a856ad09", - "url": "https://files.pythonhosted.org/packages/74/42/d48ede93cfe0c343f3b552af08efc60778d234989227b16882eed1b8b189/websockets-13.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl" + "hash": "87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096", + "url": "https://files.pythonhosted.org/packages/af/9b/8c06d425a1d5a74fd764dd793edd02be18cf6fc3b1ccd1f29244ba132dc0/websockets-13.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "e54affdeb21026329fb0744ad187cf812f7d3c2aa702a5edb562b325191fcab6", - "url": "https://files.pythonhosted.org/packages/8b/5e/ffa234473e46ab2d3f9fd9858163d5db3ecea1439e4cb52966d78906424b/websockets-13.1-cp39-cp39-musllinux_1_2_i686.whl" + "hash": "61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19", + "url": "https://files.pythonhosted.org/packages/b2/f0/cf0b8a30d86b49e267ac84addbebbc7a48a6e7bb7c19db80f62411452311/websockets-13.1-cp311-cp311-macosx_10_9_universal2.whl" }, { "algorithm": "sha256", - "hash": "6d2aad13a200e5934f5a6767492fb07151e1de1d6079c003ab31e1823733ae79", - "url": "https://files.pythonhosted.org/packages/a3/b7/070481b83d2d5ac0f19233d9f364294e224e6478b0762f07fa7f060e0619/websockets-13.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7", + "url": "https://files.pythonhosted.org/packages/bc/49/4a4ad8c072f18fd79ab127650e47b160571aacfc30b110ee305ba25fffc9/websockets-13.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", - "hash": "7bd6abf1e070a6b72bfeb71049d6ad286852e285f146682bf30d0296f5fbadfa", - "url": "https://files.pythonhosted.org/packages/a5/2b/fb77cedf3f9f55ef8605238c801eef6b9a5269b01a396875a86896aea3a6/websockets-13.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5", + "url": "https://files.pythonhosted.org/packages/bf/e7/22285852502e33071a8cf0ac814f8988480ec6db4754e067b8b9d0e92498/websockets-13.1-cp311-cp311-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", - "hash": "459bf774c754c35dbb487360b12c5727adab887f1622b8aed5755880a21c4a20", - "url": "https://files.pythonhosted.org/packages/c7/86/38279dfefecd035e22b79c38722d4f87c4b6196f1556b7a631d0a3095ca7/websockets-13.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02", + "url": "https://files.pythonhosted.org/packages/c9/e4/c50999b9b848b1332b07c7fd8886179ac395cb766fda62725d1539e7bc6c/websockets-13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "9ef8aa8bdbac47f4968a5d66462a2a0935d044bf35c0e5a8af152d58516dbeb5", - "url": "https://files.pythonhosted.org/packages/cc/92/cea9eb9d381ca57065a5eb4ec2ce7a291bd96c85ce742915c3c9ffc1069f/websockets-13.1-cp39-cp39-musllinux_1_2_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "48a2ef1381632a2f0cb4efeff34efa97901c9fbc118e01951ad7cfc10601a9bb", - "url": "https://files.pythonhosted.org/packages/d1/14/6f20bbaeeb350f155edf599aad949c554216f90e5d4ae7373d1f2e5931fb/websockets-13.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084", + "url": "https://files.pythonhosted.org/packages/d5/5b/0acb5815095ff800b579ffc38b13ab1b915b317915023748812d24e0c1ac/websockets-13.1-cp311-cp311-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", "hash": "a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878", "url": "https://files.pythonhosted.org/packages/e2/73/9223dbc7be3dcaf2a7bbf756c351ec8da04b1fa573edaf545b95f6b0c7fd/websockets-13.1.tar.gz" - }, - { - "algorithm": "sha256", - "hash": "df01aea34b6e9e33572c35cd16bae5a47785e7d5c8cb2b54b2acdb9678315a17", - "url": "https://files.pythonhosted.org/packages/eb/be/d6e1cff7d441cfe5eafaacc5935463e5f14c8b1c0d39cb8afde82709b55a/websockets-13.1-cp39-cp39-musllinux_1_2_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "7a43cfdcddd07f4ca2b1afb459824dd3c6d53a51410636a2c7fc97b9a8cf4842", - "url": "https://files.pythonhosted.org/packages/f6/f2/2ef6bff1c90a43b80622a17c0852b48c09d3954ab169266ad7b15e17cdcb/websockets-13.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" } ], "project_name": "websockets", @@ -2344,48 +2214,48 @@ }, { "algorithm": "sha256", - "hash": "c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8", - "url": "https://files.pythonhosted.org/packages/28/d3/4f079f649c515727c127c987b2ec2e0816b80d95784f2d28d1a57d2a1029/wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d", + "url": "https://files.pythonhosted.org/packages/0f/16/ea627d7817394db04518f62934a5de59874b587b792300991b3c347ff5e0/wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb", - "url": "https://files.pythonhosted.org/packages/4a/cc/3402bcc897978be00fef608cd9e3e39ec8869c973feeb5e1e277670e5ad2/wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956", + "url": "https://files.pythonhosted.org/packages/0f/ef/0ecb1fa23145560431b970418dce575cfaec555ab08617d82eb92afc7ccf/wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl" }, { "algorithm": "sha256", - "hash": "9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2", - "url": "https://files.pythonhosted.org/packages/70/cc/b92e1da2cad6a9f8ee481000ece07a35e3b24e041e60ff8b850c079f0ebf/wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3", + "url": "https://files.pythonhosted.org/packages/11/fb/18ec40265ab81c0e82a934de04596b6ce972c27ba2592c8b53d5585e6bcd/wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl" }, { "algorithm": "sha256", - "hash": "5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", - "url": "https://files.pythonhosted.org/packages/95/4c/063a912e20bcef7124e0df97282a8af3ff3e4b603ce84c481d6d7346be0a/wrapt-1.16.0.tar.gz" + "hash": "eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d", + "url": "https://files.pythonhosted.org/packages/25/62/cd284b2b747f175b5a96cbd8092b32e7369edab0644c45784871528eb852/wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl" }, { "algorithm": "sha256", - "hash": "db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f", - "url": "https://files.pythonhosted.org/packages/96/e8/27ef35cf61e5147c1c3abcb89cfbb8d691b2bb8364803fcc950140bc14d8/wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl" + "hash": "72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1", + "url": "https://files.pythonhosted.org/packages/6e/52/2da48b35193e39ac53cfb141467d9f259851522d0e8c87153f0ba4205fb1/wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c", - "url": "https://files.pythonhosted.org/packages/a3/1c/226c2a4932e578a2241dcb383f425995f80224b446f439c2e112eb51c3a6/wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389", + "url": "https://files.pythonhosted.org/packages/7f/a7/f1212ba098f3de0fd244e2de0f8791ad2539c03bef6c05a9fcb03e45b089/wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a", - "url": "https://files.pythonhosted.org/packages/b1/e7/459a8a4f40f2fa65eb73cb3f339e6d152957932516d18d0e996c7ae2d7ae/wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", + "url": "https://files.pythonhosted.org/packages/95/4c/063a912e20bcef7124e0df97282a8af3ff3e4b603ce84c481d6d7346be0a/wrapt-1.16.0.tar.gz" }, { "algorithm": "sha256", - "hash": "edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537", - "url": "https://files.pythonhosted.org/packages/b6/ad/7a0766341081bfd9f18a7049e4d6d45586ae5c5bb0a640f05e2f558e849c/wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl" + "hash": "43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060", + "url": "https://files.pythonhosted.org/packages/b7/96/bb5e08b3d6db003c9ab219c487714c13a237ee7dcc572a555eaf1ce7dc82/wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", - "hash": "5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664", - "url": "https://files.pythonhosted.org/packages/da/6f/6d0b3c4983f1fc764a422989dabc268ee87d937763246cd48aa92f1eed1e/wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl" + "hash": "1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09", + "url": "https://files.pythonhosted.org/packages/fd/03/c188ac517f402775b90d6f312955a5e53b866c964b32119f2ed76315697e/wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl" } ], "project_name": "wrapt", @@ -2441,7 +2311,7 @@ "uvicorn[standard]==0.17.6" ], "requires_python": [ - "==3.9.*" + "==3.11.*" ], "resolver_version": "pip-2020-resolver", "style": "universal", diff --git a/BUILD b/BUILD index fe6325bbd80..79dd47a8c61 100644 --- a/BUILD +++ b/BUILD @@ -12,7 +12,7 @@ python_test_utils(name="test_utils") # Used for experimenting with the new Docker support. docker_environment( name="docker_env", - image="python:3.9", + image="python:3.11", python_bootstrap_search_path=[""], ) diff --git a/build-support/common.sh b/build-support/common.sh index 096c2781578..ffe96496b47 100644 --- a/build-support/common.sh +++ b/build-support/common.sh @@ -52,7 +52,7 @@ function determine_python() { which "${PY}" && return 0 fi - version='3.9' + version='3.11' interpreter_path="$(command -v "python${version}")" if [[ -z "${interpreter_path}" ]]; then echo "pants: Failed to find a Python ${version} interpreter" 1>&2 && return 1 diff --git a/build-support/flake8/.flake8 b/build-support/flake8/.flake8 index c3a8b6e1a9b..f2263127c20 100644 --- a/build-support/flake8/.flake8 +++ b/build-support/flake8/.flake8 @@ -18,6 +18,8 @@ extend-ignore: NIC102, # Unnecessary dict call - rewrite as a literal C408, + # Temporarily exclude during Python upgrade + C420,E721 [flake8:local-plugins] extension = diff --git a/docs/notes/2.24.x.md b/docs/notes/2.24.x.md index 1c795cd127f..2ff406aec70 100644 --- a/docs/notes/2.24.x.md +++ b/docs/notes/2.24.x.md @@ -12,7 +12,9 @@ We offer [formal sponsorship tiers for companies](https://www.pantsbuild.org/spo ### Highlights - +- Support for Python 3.13 +- `pants export --bin` allows exporting more tools for use outside Pants +- A new options system unlocks future changes. ### Deprecations @@ -26,7 +28,7 @@ We offer [formal sponsorship tiers for companies](https://www.pantsbuild.org/spo ### New Options System -This release switches the Pants [options system](https://www.pantsbuild.org/2.22/docs/using-pants/key-concepts/options) to use the new "native" implementation written in Rust first introduced in the 2.22.x series. +This release switches the Pants [options system](https://www.pantsbuild.org/2.24/docs/using-pants/key-concepts/options) to use the new "native" implementation written in Rust first introduced in the 2.22.x series. To ensure that this transition is not disruptive, this release will run the new system alongside the "legacy" options system, and compare their results, issuing a warning if they differ. @@ -40,8 +42,22 @@ The "legacy" system will be removed in the 2.25.x series. Many tools that Pants downloads can now be exported using [the new `export --bin` option](https://www.pantsbuild.org/2.24/reference/goals/export#bin). For example, `pants export --bin="helm"` will export the `helm` binary to `dist/export/bin/helm`. For each tool, all the files are exported to a subfolder in `dist/export/bins/`, and the main executable is linked to `dist/export/bin/`. +#### `generate-lockfiles` + +Generating all lockfiles properly deduplicates requests, preventing generating the same lockfile twice for resolves that shadow a tool's builtin resolve name. ([#21642](https://github.com/pantsbuild/pants/pull/21642)) + ### Backends +#### Go + +Fix a bug where Pants raised an internal exception which occurred when compiling a Go package with coverage support when the package also had an external test which imported the base package. + +Fix a bug where Pants sent a minor Go version instead of the major one to the Go toolchain during packaging. + +Recognize `-fullpath` as a test binary flag. + +Add support for the `all:` prefix to patterns used with the `go:embed` directive. The `all:` prefix includes files which start with `_` or `.` which are ordinarilly excluded . + #### JVM Compression of class files into a jar file is not reading or writing from the remote cache. The size of jar files, combined with the low computational cost of compression, can outweigh the advantages of using a remote cache. @@ -56,18 +72,15 @@ The kotlin linter, [ktlint](https://pinterest.github.io/ktlint/), has been updat #### Python -**Breaking change**: the `pants.backend.experimental.python.lint.ruff.check` and `pants.backend.experimental.python.lint.ruff.format` subsystems now execute Ruff as a downloaded binary, directly from the Ruff releases, rather than using PEX to execute the PyPI `ruff` package. This has less overhead, and makes customising the version simpler. However, **options like [`[ruff].install_from_resolve`](https://www.pantsbuild.org/2.24/reference/subsystems/ruff#install_from_resolve) are now ignored** and will be removed in future. If you have customised the version, use [`[ruff].version`](https://www.pantsbuild.org/2.24/reference/subsystems/ruff#version) and [`[ruff].known_versions`](https://www.pantsbuild.org/2.24/reference/subsystems/ruff#known_versions) instead. This version of Pants includes built-in known-versions for the latest patch release (at time of development) of each `0.x` minor series (0.7.2, 0.6.9, 0.5.7, 0.4.10, 0.3.7, 0.2.2, 0.1.15): if you install from a resolve with a particular pinned version of Ruff, you may find setting `[ruff].version` to the closest matching version in that list is acceptable (if not, you may need to add to `[ruff].known_versions`). +Pants' support for different Python versions has changed: -User API Changes: -- Update default package mapping for `pymupdf` to match imports from both `fitz` (the legacy name) and `pymupdf` (the [currently supported name](https://pymupdf.readthedocs.io/en/latest/installation.html#problems-after-installation). +- The default lockfiles bundled with Pants for various tools (ex: to run `black`) now support Python 3.13. -Deprecations: +- **breaking change**: those lockfiles no longer support Python 3.7. The minimum Python version is now 3.8. Pants still supports running Python 3.7 (and earlier!) user code, but you will need to [generate your own lockfiles](https://www.pantsbuild.org/2.24/docs/python/overview/lockfiles#lockfiles-for-tools). See the announcement at for further context. - Pants v2.24 and later are not proactively tested in CI with Python 2.7 since [Python 2.7 is no longer supported by its maintainers as of 1 January 2020](https://www.python.org/doc/sunset-python-2/). While Pants may continue to work with Python 2.7 in the near term, Pants no longer officially supports use of Python 2.7, and, consequently, any remaining support for Python 2.7 may "bit rot" and diverge over time. Contributions to fix issues with Python 2.7 support will continue to be accepted, but will depend on any community contributions and will not constitute continued official support for Python 2.7. -- The default lockfiles bundled with Pants for various tools (ex: to run `black`) no longer support Python 3.7. The minimum Python version is now 3.8. Pants still supports running Python 3.7 (and earlier!) user code, but you will need to [generate your own lockfiles](https://www.pantsbuild.org/stable/docs/python/overview/lockfiles#lockfiles-for-tools). See the announcement at for further context. - -- The deprecation of `resolve_local_platforms` (both a field of `pex_binary`, and a option of `[pex-binary-defaults]`) has expired and thus they have been removed. +**Breaking change**: the `pants.backend.experimental.python.lint.ruff.check` and `pants.backend.experimental.python.lint.ruff.format` subsystems now execute Ruff as a downloaded binary, directly from the Ruff releases, rather than using PEX to execute the PyPI `ruff` package. This has less overhead, and makes customising the version simpler. However, **options like [`[ruff].install_from_resolve`](https://www.pantsbuild.org/2.24/reference/subsystems/ruff#install_from_resolve) are now ignored** and will be removed in future. If you have customised the version, use [`[ruff].version`](https://www.pantsbuild.org/2.24/reference/subsystems/ruff#version) and [`[ruff].known_versions`](https://www.pantsbuild.org/2.24/reference/subsystems/ruff#known_versions) instead. This version of Pants includes built-in known-versions for the latest patch release (at time of development) of each `0.x` minor series (0.7.2, 0.6.9, 0.5.7, 0.4.10, 0.3.7, 0.2.2, 0.1.15): if you install from a resolve with a particular pinned version of Ruff, you may find setting `[ruff].version` to the closest matching version in that list is acceptable (if not, you may need to add to `[ruff].known_versions`). Version Updates: @@ -84,35 +97,32 @@ Version Updates: - The default version of the [Ruff](https://docs.astral.sh/ruff/) tool has been updated from 0.4.9 to [0.7.2](https://github.com/astral-sh/ruff/releases/tag/0.7.2). (As discussed above, one can pin to particular versions, including 0.4.9, via the new `[ruff].version` and `[ruff].known_versions` options.) -A new experimental [Python Provider](https://www.pantsbuild.org/blog/2023/03/31/two-hermetic-pythons) using [Python Build Standalone](https://gregoryszorc.com/docs/python-build-standalone/main/) is available as `pants.backend.python.providers.experimental.python_build_standalone`. This joins the existing [pyenv provider](https://www.pantsbuild.org/stable/reference/subsystems/pyenv-python-provider) as a way for Pants to take care of providing an appropriate Python. +A new experimental [Python Provider](https://www.pantsbuild.org/blog/2023/03/31/two-hermetic-pythons) using [Python Build Standalone](https://gregoryszorc.com/docs/python-build-standalone/main/) is available as `pants.backend.python.providers.experimental.python_build_standalone`. This joins the existing [pyenv provider](https://www.pantsbuild.org/2.24/reference/subsystems/pyenv-python-provider) as a way for Pants to take care of providing an appropriate Python. -Mypy will now typecheck previously-ignored python sources without a `.py` or `.pyi` extension. +Other changes: -#### S3 +- Mypy will now typecheck previously-ignored python sources without a `.py` or `.pyi` extension. -The `pants.backend.url_handlers.s3` backend now correctly passes along query parameters such as `versionId` for `s3://` urls. - -#### Semgrep +- Update default package mapping for `pymupdf` to match imports from both `fitz` (the legacy name) and `pymupdf` (the [currently supported name](https://pymupdf.readthedocs.io/en/latest/installation.html#problems-after-installation). -The default version of [the semgrep tool](https://www.pantsbuild.org/2.24/reference/subsystems/semgrep) has been upgraded from 1.86.0 to [1.94.0](https://github.com/semgrep/semgrep/releases/tag/v1.94.0). +- The deprecation of `resolve_local_platforms` (both a field of `pex_binary`, and a option of `[pex-binary-defaults]`) has expired and thus they have been removed. -#### Shell -Pants will now warn if any errors are encountered while fingerprinting candidate binaries for the `system_binary` target type. The warnings may be disabled by setting the new `log_fingerprinting_errors` field on `system_binary` to `False`. +Tools that are installed from a user resolve will not present their default resolve for `generate-lockfiles` and `export`. -#### Shell +#### S3 -Added a new `cache_scope` field to `adhoc_tool` and `shell_command` targets to allow configuration of the "cache scope" of the invoked process. The cache scope determines how long Pants will cache the result of the invoked process absent any other invalidation of the result via source or dependency changes. +The `pants.backend.url_handlers.s3` backend now correctly passes along query parameters such as `versionId` for `s3://` urls. -#### Go +#### Semgrep -Fix a bug where Pants raised an internal exception which occurred when compiling a Go package with coverage support when the package also had an external test which imported the base package. +The default version of [the semgrep tool](https://www.pantsbuild.org/2.24/reference/subsystems/semgrep) has been upgraded from 1.86.0 to [1.94.0](https://github.com/semgrep/semgrep/releases/tag/v1.94.0). -Fix a bug where Pants sent a minor Go version instead of the major one to the Go toolchain during packaging. +#### Shell -Recognize `-fullpath` as a test binary flag. +Pants will now warn if any errors are encountered while fingerprinting candidate binaries for the `system_binary` target type. The warnings may be disabled by setting the [new `log_fingerprinting_errors` field](https://www.pantsbuild.org/2.24/reference/targets/system_binary#log_fingerprinting_errors) on `system_binary` to `False`. -Add support for the `all:` prefix to patterns used with the `go:embed` directive. The `all:` prefix includes files which start with `_` or `.` which are ordinarilly excluded . +Added a new `cache_scope` field to [`adhoc_tool`](https://www.pantsbuild.org/2.24/reference/targets/adhoc_tool#cache_scope) and [`shell_command`](https://www.pantsbuild.org/2.24/reference/targets/shell_command#cache_scope) targets to allow configuration of the "cache scope" of the invoked process. The cache scope determines how long Pants will cache the result of the invoked process absent any other invalidation of the result via source or dependency changes. ### Plugin API changes diff --git a/docs/notes/2.25.x.md b/docs/notes/2.25.x.md index 57e05bb441e..f911e9c9747 100644 --- a/docs/notes/2.25.x.md +++ b/docs/notes/2.25.x.md @@ -13,8 +13,12 @@ established for this purpose. This non-profit's only source of revenue is ### Deprecations +- **macOS versions**: Pants v2.25 is now built and tested on newer macOS versions: 13 (x86-64, previously 10.15) and macOS 14 (arm64, previously 11). The deprecation of the older versions were announced in Pants 2.23 and 2.24, and are driven by Apple's support schedule; they also help reduce cost for the volunteer-driven Pantsbuild organisation. Using Pants on older versions may or may not work. + ### General +- [Fixed](https://github.com/pantsbuild/pants/pull/21665) bug where `pants --export-resolve= --export-py-generated-sources-in-resolve=` fails (see [#21659](https://github.com/pantsbuild/pants/issues/21659) for more info). + #### Remote Caching/Execution Pants now sends a `user-agent` header with every request to a remote store or a remote execution service, @@ -25,12 +29,43 @@ one in `remote_store_headers` or `remote_execution_headers`. The "legacy" options system is removed in this release. All options parsing is now handled by the new, native parser. + +### Internal Python Upgrade + +The version of Python used by Pants itself has been updated to [3.11](https://docs.python.org/3/whatsnew/3.11.html). To support this the [Pants Launcher Binary](https://www.pantsbuild.org/blog/2023/02/23/the-pants-launcher-binary-a-much-simpler-way-to-install-and-run-pants) known as [`scie-pants`](https://github.com/pantsbuild/scie-pants/) now has a minimum version of `0.12.0`. To update to the latest launcher binary run: + +``` +SCIE_BOOT=update pants +``` + +That Pants itself happens to be partially writtin in Python has no bearing on the versions of Python that Pants can use to test and build your code. + + + ### Goals ### Backends +#### Docker + +Strict adherence to the [schema of Docker registry configuration](https://www.pantsbuild.org/2.25/reference/subsystems/docker#registries) is now required. +Previously we did ad-hoc coercion of some field values, so that, e.g., you could provide a "true"/"false" string as a boolean value. Now we require actual booleans. + +#### Helm + +Strict adherence to the [schema of Helm OCI registry configuration](https://www.pantsbuild.org/2.25/reference/subsystems/helm#registries) is now required. +Previously we did ad-hoc coercion of some field values, so that, e.g., you could provide a "true"/"false" string as a boolean value. Now we require actual booleans. + +#### Shell + +The previously deprecated `[shell-setup].tailor` option has now been removed. See [`[shell-setup].tailor_sources`](https://www.pantsbuild.org/2.25/reference/subsystems/shell-setup#tailor_sources) and [`[shell-setup].tailor_shunit2_tests`](https://www.pantsbuild.org/2.25/reference/subsystems/shell#tailor_shunit2_tests) to update. + ### Plugin API changes +The version of Python used by Pants itself is now [3.11](https://docs.python.org/3/whatsnew/3.11.html) (up from 3.9). + +The oldest [glibc version](https://www.sourceware.org/glibc/wiki/Glibc%20Timeline) supported by the published Pants wheels is now 2.28. This should have no effect unless you are running on extremely old Linux distributions. See for background context on Python wheels and C libraries. + ## Full Changelog For the full changelog, see the individual GitHub Releases for this series: diff --git a/pants-plugins/pants_explorer/server/graphql/query/targets.py b/pants-plugins/pants_explorer/server/graphql/query/targets.py index 9f3d4b5634d..8492ee00e2e 100644 --- a/pants-plugins/pants_explorer/server/graphql/query/targets.py +++ b/pants-plugins/pants_explorer/server/graphql/query/targets.py @@ -63,7 +63,7 @@ class Target: target_type: str = strawberry.field( description="The target type, such as `python_sources` or `pex_binary` etc." ) - fields: JSONScalar = strawberry.field( + fields: JSONScalar = strawberry.field( # type: ignore[valid-type] description=softwrap( """ The targets field values. This has the same structure as the JSON output from the `peek` diff --git a/pants.toml b/pants.toml index 7a8666d29ba..a82955a3ec1 100644 --- a/pants.toml +++ b/pants.toml @@ -150,7 +150,7 @@ emit_warnings = true # + src/python/pants/testutil:testutil_wheel # And update the PythonBuildStandalone version/URL: # + src/python/pants/core/subsystems/python_bootstrap.py -interpreter_constraints = ["==3.9.*"] +interpreter_constraints = ["==3.11.*"] macos_big_sur_compatibility = true enable_resolves = true pip_version = "latest" @@ -160,6 +160,7 @@ python-default = "3rdparty/python/user_reqs.lock" flake8 = "3rdparty/python/flake8.lock" mypy = "3rdparty/python/mypy.lock" pytest = "3rdparty/python/pytest.lock" +pbs-script = "3rdparty/python/pbs-script-requirements.lock" [python-infer] assets = true @@ -206,7 +207,7 @@ requirements = ["//3rdparty/python:mypy"] [coverage-py] -interpreter_constraints = ["==3.9.*"] +interpreter_constraints = ["==3.11.*"] [preamble] template_by_globs = "@build-support/preambles/config.yaml" diff --git a/src/python/pants/BUILD b/src/python/pants/BUILD index f8503527fa6..804ed92243e 100644 --- a/src/python/pants/BUILD +++ b/src/python/pants/BUILD @@ -35,7 +35,7 @@ python_distribution( # TODO(7344): the tuple syntax for ext_modules is deprecated. Use Extension once we support it. ext_modules=[("native_engine", {"sources": ["pants/dummy.c"]})], # N.B.: Must match [python] interpreter_constraints in pants.toml. - python_requires="==3.9.*", + python_requires="==3.11.*", ), entry_points={"console_scripts": {"pants": "pants.bin.pants_loader:main"}}, ) diff --git a/src/python/pants/VERSION b/src/python/pants/VERSION index 7a0915d03e3..2ba1d0e9f55 100644 --- a/src/python/pants/VERSION +++ b/src/python/pants/VERSION @@ -1 +1 @@ -2.24.0a0 +2.25.0.dev0 diff --git a/src/python/pants/backend/docker/registries.py b/src/python/pants/backend/docker/registries.py index 129793e6ad1..ad734469b2f 100644 --- a/src/python/pants/backend/docker/registries.py +++ b/src/python/pants/backend/docker/registries.py @@ -6,7 +6,6 @@ from dataclasses import dataclass from typing import Any, Iterator -from pants.option.parser import Parser from pants.util.frozendict import FrozenDict from pants.util.strutil import softwrap @@ -52,13 +51,13 @@ def from_dict(cls, alias: str, d: dict[str, Any]) -> DockerRegistryOptions: return cls( alias=alias, address=d["address"], - default=Parser.ensure_bool(d.get("default", alias == "default")), - skip_push=Parser.ensure_bool(d.get("skip_push", DockerRegistryOptions.skip_push)), + default=d.get("default", alias == "default"), + skip_push=d.get("skip_push", DockerRegistryOptions.skip_push), extra_image_tags=tuple( d.get("extra_image_tags", DockerRegistryOptions.extra_image_tags) ), - repository=Parser.to_value_type(d.get("repository"), str, None), - use_local_alias=Parser.ensure_bool(d.get("use_local_alias", False)), + repository=d.get("repository"), + use_local_alias=d.get("use_local_alias", False), ) def register(self, registries: dict[str, DockerRegistryOptions]) -> None: diff --git a/src/python/pants/backend/docker/registries_test.py b/src/python/pants/backend/docker/registries_test.py index 17549127642..037f695106f 100644 --- a/src/python/pants/backend/docker/registries_test.py +++ b/src/python/pants/backend/docker/registries_test.py @@ -42,9 +42,9 @@ def test_docker_registries() -> None: # Test defaults. registries = DockerRegistries.from_dict( { - "reg1": {"address": "myregistry1domain:port", "default": "false"}, - "reg2": {"address": "myregistry2domain:port", "default": "true"}, - "reg3": {"address": "myregistry3domain:port", "default": "true"}, + "reg1": {"address": "myregistry1domain:port", "default": False}, + "reg2": {"address": "myregistry2domain:port", "default": True}, + "reg3": {"address": "myregistry3domain:port", "default": True}, } ) @@ -65,7 +65,7 @@ def test_skip_push() -> None: { "reg1": {"address": "registry1"}, "reg2": {"address": "registry2", "skip_push": True}, - "reg3": {"address": "registry3", "skip_push": "false"}, + "reg3": {"address": "registry3", "skip_push": False}, } ) diff --git a/src/python/pants/backend/helm/goals/publish_test.py b/src/python/pants/backend/helm/goals/publish_test.py index 5bb8719d5d6..21f52424522 100644 --- a/src/python/pants/backend/helm/goals/publish_test.py +++ b/src/python/pants/backend/helm/goals/publish_test.py @@ -125,7 +125,7 @@ def test_helm_push_no_charts_when_registries_are_not_set(rule_runner: RuleRunner def test_helm_skip_push(rule_runner: RuleRunner) -> None: _declare_targets(rule_runner) - registries = {"internal": {"address": "oci://www.example.com/internal", "default": "true"}} + registries = {"internal": {"address": "oci://www.example.com/internal", "default": True}} chart_metadata = HelmChartMetadata("foo-chart", "0.1.0") result, _ = _run_publish( rule_runner, Address("src/skip-push"), chart_metadata, registries=registries @@ -143,7 +143,7 @@ def test_helm_skip_push(rule_runner: RuleRunner) -> None: def test_helm_push_use_default_registries(rule_runner: RuleRunner) -> None: _declare_targets(rule_runner) - registries = {"internal": {"address": "oci://www.example.com", "default": "true"}} + registries = {"internal": {"address": "oci://www.example.com", "default": True}} chart_metadata = HelmChartMetadata("missing-registries", "0.2.0") result, helm = _run_publish( rule_runner, Address("src/missing-registries"), chart_metadata, registries=registries diff --git a/src/python/pants/backend/helm/resolve/remotes.py b/src/python/pants/backend/helm/resolve/remotes.py index 36a3af5344f..93682967c21 100644 --- a/src/python/pants/backend/helm/resolve/remotes.py +++ b/src/python/pants/backend/helm/resolve/remotes.py @@ -6,7 +6,6 @@ from dataclasses import dataclass from typing import Any, Iterator, cast -from pants.option.parser import Parser from pants.util.frozendict import FrozenDict from pants.util.memo import memoized_method @@ -39,7 +38,7 @@ def from_dict(cls, alias: str, d: dict[str, Any]) -> HelmRegistry: return cls( alias=alias, address=cast(str, d["address"]).rstrip("/"), - default=Parser.ensure_bool(d.get("default", alias == "default")), + default=d.get("default", alias == "default"), ) def __post_init__(self) -> None: diff --git a/src/python/pants/backend/helm/resolve/remotes_test.py b/src/python/pants/backend/helm/resolve/remotes_test.py index 554c4a5cd53..589e8e31c24 100644 --- a/src/python/pants/backend/helm/resolve/remotes_test.py +++ b/src/python/pants/backend/helm/resolve/remotes_test.py @@ -38,9 +38,9 @@ def test_helm_remotes() -> None: remotes = HelmRemotes.from_dict( { "default": {"address": "oci://www.example.com/default"}, - "reg1": {"address": "oci://www.example.com/charts1", "default": "false"}, - "reg2": {"address": "oci://www.example.com/charts2", "default": "true"}, - "reg3": {"address": "oci://www.example.com/charts3", "default": "true"}, + "reg1": {"address": "oci://www.example.com/charts1", "default": False}, + "reg2": {"address": "oci://www.example.com/charts2", "default": True}, + "reg3": {"address": "oci://www.example.com/charts3", "default": True}, }, ) diff --git a/src/python/pants/backend/python/goals/export.py b/src/python/pants/backend/python/goals/export.py index 62e85bec320..588d663e79f 100644 --- a/src/python/pants/backend/python/goals/export.py +++ b/src/python/pants/backend/python/goals/export.py @@ -411,6 +411,7 @@ async def python_codegen_export_setup() -> _ExportPythonCodegenSetup: content=textwrap.dedent( f"""\ import os + import shutil import site import sys @@ -424,7 +425,10 @@ async def python_codegen_export_setup() -> _ExportPythonCodegenSetup: for item in os.listdir(codegen_dir): if item == "{_ExportPythonCodegenSetup.SCRIPT_NAME}": continue - os.rename(os.path.join(codegen_dir, item), os.path.join(site_packages_dir, item)) + src = os.path.join(codegen_dir, item) + dest = os.path.join(site_packages_dir, item) + shutil.copytree(src, dest, dirs_exist_ok=True) + shutil.rmtree(src) """ ).encode(), ) diff --git a/src/python/pants/backend/python/goals/export_test.py b/src/python/pants/backend/python/goals/export_test.py index 67e9f9e325a..93673a6f580 100644 --- a/src/python/pants/backend/python/goals/export_test.py +++ b/src/python/pants/backend/python/goals/export_test.py @@ -251,12 +251,32 @@ async def do_codegen(request: CodegenGenerateSourcesRequest) -> GeneratedSources rule_runner.write_files( { "test-resolve.lock": "", + # Case #1 + # `foo`` package exports `an-input.py` file as a generated source. "src/python/foo/BUILD": dedent( - """\ - codegen_target(name="codegen", source="an-input", resolve="test-resolve") - """ + """ + codegen_target( + name="codegen", + source="an-input", + resolve="test-resolve" + ) + """ ), "src/python/foo/an-input": "print('Hello World!')\n", + # Case #2 + # The local `ansicolors`` package exports `ansicolors-input.py` file as a generated source. + # The local `ansicolors package clashes with the 3rd party dep `ansicolors``. + # This is an edge case. + "src/python/ansicolors/BUILD": dedent( + """ + codegen_target( + name="codegen", + source="ansicolors-input", + resolve="test-resolve" + ) + """ + ), + "src/python/ansicolors/ansicolors-input": "print('Hello World!')\n", } ) @@ -267,3 +287,7 @@ async def do_codegen(request: CodegenGenerateSourcesRequest) -> GeneratedSources export_snapshot = rule_runner.request(Snapshot, [export_result.digest]) assert any(p.endswith("__pants_codegen__/codegen_setup.py") for p in export_snapshot.files) assert any(p.endswith("__pants_codegen__/foo/an-input.py") for p in export_snapshot.files) + assert any( + p.endswith("__pants_codegen__/ansicolors/ansicolors-input.py") + for p in export_snapshot.files + ) diff --git a/src/python/pants/backend/python/goals/lockfile.py b/src/python/pants/backend/python/goals/lockfile.py index c38b91dfa96..d25a6004a50 100644 --- a/src/python/pants/backend/python/goals/lockfile.py +++ b/src/python/pants/backend/python/goals/lockfile.py @@ -211,7 +211,7 @@ class KnownPythonUserResolveNamesRequest(KnownUserResolveNamesRequest): @rule -def determine_python_user_resolves( +async def determine_python_user_resolves( _: KnownPythonUserResolveNamesRequest, python_setup: PythonSetup, union_membership: UnionMembership, @@ -219,10 +219,16 @@ def determine_python_user_resolves( """Find all know Python resolves, from both user-created resolves and internal tools.""" python_tool_resolves = ExportableTool.filter_for_subclasses(union_membership, PythonToolBase) + tools_using_default_resolve = [ + resolve_name + for resolve_name, subsystem_cls in python_tool_resolves.items() + if (await _construct_subsystem(subsystem_cls)).install_from_resolve is None + ] + return KnownUserResolveNames( names=( *python_setup.resolves.keys(), - *python_tool_resolves.keys(), + *tools_using_default_resolve, ), # the order of the keys doesn't matter since shadowing is done in `setup_user_lockfile_requests` option_name="[python].resolves", requested_resolve_names_cls=RequestedPythonUserResolveNames, @@ -255,10 +261,10 @@ async def setup_user_lockfile_requests( tools = ExportableTool.filter_for_subclasses(union_membership, PythonToolBase) - out = [] + out = set() for resolve in requested: if resolve in python_setup.resolves: - out.append( + out.add( GeneratePythonLockfile( requirements=PexRequirements.req_strings_from_requirement_fields( resolve_to_requirements_fields[resolve] @@ -285,7 +291,7 @@ async def setup_user_lockfile_requests( else: ic = InterpreterConstraints(tool.default_interpreter_constraints) - out.append( + out.add( GeneratePythonLockfile( requirements=FrozenOrderedSet(sorted(tool.requirements)), find_links=FrozenOrderedSet(find_links), diff --git a/src/python/pants/backend/python/providers/python_build_standalone/scripts/BUILD b/src/python/pants/backend/python/providers/python_build_standalone/scripts/BUILD index 68aaac88424..ddf85e67f42 100644 --- a/src/python/pants/backend/python/providers/python_build_standalone/scripts/BUILD +++ b/src/python/pants/backend/python/providers/python_build_standalone/scripts/BUILD @@ -1,4 +1,11 @@ # Copyright 2023 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). -python_sources() +python_sources(resolve="pbs-script") + +pex_binary( + name="bin", + entry_point="generate_urls.py", + dependencies=[":scripts"], + resolve="pbs-script", +) diff --git a/src/python/pants/backend/python/providers/python_build_standalone/scripts/generate_urls.py b/src/python/pants/backend/python/providers/python_build_standalone/scripts/generate_urls.py index c163230547a..73104c0d5d6 100644 --- a/src/python/pants/backend/python/providers/python_build_standalone/scripts/generate_urls.py +++ b/src/python/pants/backend/python/providers/python_build_standalone/scripts/generate_urls.py @@ -2,19 +2,20 @@ # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import annotations +import argparse import hashlib import itertools import json import os +import re +import sys from pathlib import Path import github import requests from github.GitReleaseAsset import GitReleaseAsset -from pants.base.build_environment import get_buildroot - -VERSIONS_PATH = get_buildroot() / Path( +VERSIONS_PATH = Path( "src/python/pants/backend/python/providers/python_build_standalone/versions_info.json" ) @@ -22,6 +23,11 @@ def _github(): # generate with `gh auth token` token = os.environ.get("GH_TOKEN") + if token is None: + print( + "WARNING: No GitHub token configured in GH_TOKEN. Lower rate limits will apply!", + file=sys.stderr, + ) return github.Github(auth=github.Auth.Token(token) if token else None) @@ -37,19 +43,37 @@ def _compute_sha256(url): def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--scrape-all-releases", dest="scrape_all_releases", action="store_true") + parser.add_argument( + "--scrape-release", metavar="RELEASE", dest="scrape_releases", action="append" + ) + options = parser.parse_args() + + print("Starting to scrape GitHub PBS releases.") + if not VERSIONS_PATH.parent.exists(): + raise Exception("This helper script must be run from the root of the Pants repository.") + versions_info = json.loads(VERSIONS_PATH.read_text()) scraped_releases = set(versions_info["scraped_releases"]) github = _github() pbs_repo = github.get_repo("indygreg/python-build-standalone") + print("Downloading PBS release metadata.") releases = pbs_repo.get_releases() + print("Downloaded PBS release metadata.") asset_map: dict[str, GitReleaseAsset] = {} sha256_map: dict[str, str] = {} for release in releases.reversed: tag_name = release.tag_name - if tag_name not in scraped_releases: + if ( + tag_name not in scraped_releases + or options.scrape_all_releases + or tag_name in options.scrape_releases + ): + print(f"Scraping release tag `{tag_name}`.") scraped_releases.add(release.tag_name) assets = release.get_assets() for asset in assets: @@ -72,10 +96,18 @@ def main() -> None: else: asset_map[asset.name] = asset + print("Finished scraping releases.") + versions_info["scraped_releases"] = sorted(scraped_releases) pythons_dict = versions_info["pythons"] + asset_matcher = re.compile(r"^([a-zA-Z0-9]+)-([0-9.]+)\+([0-9.]+)-") + for asset in asset_map.values(): - python_version = asset.name.split("+")[0].split("-")[1] + matched_versions = asset_matcher.match(asset.name) + if not matched_versions: + continue + + python_version, pbs_release_tag = matched_versions.groups()[1:3] if python_version not in pythons_dict: pythons_dict[python_version] = {} diff --git a/src/python/pants/backend/shell/goals/tailor.py b/src/python/pants/backend/shell/goals/tailor.py index 2217fd21da6..a3ee9bba826 100644 --- a/src/python/pants/backend/shell/goals/tailor.py +++ b/src/python/pants/backend/shell/goals/tailor.py @@ -47,9 +47,6 @@ def classify_source_files(paths: Iterable[str]) -> dict[type[Target], set[str]]: async def find_putative_targets( req: PutativeShellTargetsRequest, all_owned_sources: AllOwnedSources, shell_setup: ShellSetup ) -> PutativeTargets: - if not shell_setup.tailor: - return PutativeTargets() - if not (shell_setup.tailor_sources or shell_setup.tailor_shunit2_tests): return PutativeTargets() diff --git a/src/python/pants/backend/shell/goals/tailor_test.py b/src/python/pants/backend/shell/goals/tailor_test.py index 579d79761cb..77ed6c95703 100644 --- a/src/python/pants/backend/shell/goals/tailor_test.py +++ b/src/python/pants/backend/shell/goals/tailor_test.py @@ -35,16 +35,13 @@ def rule_runner() -> RuleRunner: @pytest.mark.parametrize( - "opt_tailor,opt_tailor_sources,opt_tailor_tests,expects_sources,expects_tests", + "opt_tailor_sources,opt_tailor_tests,expects_sources,expects_tests", [ - pytest.param(True, True, True, True, True, id="legacy tailor enabled"), - pytest.param(False, True, True, False, False, id="legacy tailor disabled"), - pytest.param(True, False, True, False, True, id="sources disabled"), - pytest.param(True, True, False, True, False, id="tests disabled"), + pytest.param(False, True, False, True, id="sources disabled"), + pytest.param(True, False, True, False, id="tests disabled"), ], ) def test_find_putative_targets( - opt_tailor, opt_tailor_sources, opt_tailor_tests, expects_sources, @@ -66,7 +63,6 @@ def test_find_putative_targets( ) rule_runner.set_options( [ - f"--shell-setup-tailor={opt_tailor}", f"--shell-setup-tailor-sources={opt_tailor_sources}", f"--shell-setup-tailor-shunit2-tests={opt_tailor_tests}", ] diff --git a/src/python/pants/backend/shell/subsystems/shell_setup.py b/src/python/pants/backend/shell/subsystems/shell_setup.py index 93b13bfff5e..ead49c88ad6 100644 --- a/src/python/pants/backend/shell/subsystems/shell_setup.py +++ b/src/python/pants/backend/shell/subsystems/shell_setup.py @@ -18,18 +18,6 @@ class ShellSetup(Subsystem): help="Infer Shell dependencies on other Shell files by analyzing `source` statements.", advanced=True, ) - tailor = BoolOption( - default=True, - help=softwrap("If true, add `shell_sources` targets with the `tailor` goal."), - removal_version="2.25.0.dev0", - removal_hint=softwrap( - """ - Use `tailor_sources` and/or `tailor_shunit2_tests` instead. - For backwards compatibility, if this option is `False`, it will override the other options. - """ - ), - advanced=True, - ) tailor_sources = BoolOption( default=True, help=softwrap("If true, add `shell_sources` targets with the `tailor` goal."), diff --git a/src/python/pants/base/exception_sink_test.py b/src/python/pants/base/exception_sink_test.py index 8ce58723768..12f2905767c 100644 --- a/src/python/pants/base/exception_sink_test.py +++ b/src/python/pants/base/exception_sink_test.py @@ -55,6 +55,7 @@ def test_set_invalid_log_location(): Platform.macos_x86_64: ( "The provided log location path at '/' is not writable or could not be created: " "[Errno 21] Is a directory: '/'.", + "Error opening fatal error log streams for log location '/': [Errno 30] Read-only file system", ), Platform.linux_arm64: ( "Error opening fatal error log streams for log location '/': [Errno 13] Permission " diff --git a/src/python/pants/bin/pants_runner.py b/src/python/pants/bin/pants_runner.py index b9a704ad736..64adc329538 100644 --- a/src/python/pants/bin/pants_runner.py +++ b/src/python/pants/bin/pants_runner.py @@ -25,8 +25,9 @@ logger = logging.getLogger(__name__) -# Pants 2.18 is using a new distribution model, that's supported (sans bugs) in 0.10.0. -MINIMUM_SCIE_PANTS_VERSION = Version("0.10.0") +# First version with Python 3.11 support: +# https://github.com/pantsbuild/scie-pants/releases/tag/v0.12.0 +MINIMUM_SCIE_PANTS_VERSION = Version("0.12.0") @dataclass(frozen=True) diff --git a/src/python/pants/core/goals/generate_lockfiles.py b/src/python/pants/core/goals/generate_lockfiles.py index db6193fdaed..850217e7c0d 100644 --- a/src/python/pants/core/goals/generate_lockfiles.py +++ b/src/python/pants/core/goals/generate_lockfiles.py @@ -11,7 +11,7 @@ from typing import Callable, Iterable, Iterator, Mapping, Protocol, Sequence, Tuple, Type, cast from pants.core.goals.resolves import ExportableTool -from pants.engine.collection import Collection +from pants.engine.collection import Collection, DeduplicatedCollection from pants.engine.console import Console from pants.engine.environment import ChosenLocalEnvironmentName, EnvironmentName from pants.engine.fs import Digest, MergeDigests, Workspace @@ -105,13 +105,15 @@ class KnownUserResolveNames: @union(in_scope_types=[EnvironmentName]) -class RequestedUserResolveNames(Collection[str]): +class RequestedUserResolveNames(DeduplicatedCollection[str]): """The user resolves requested for a particular language ecosystem. Each language ecosystem should set up a subclass and register it with a UnionRule. Implement a rule that goes from the subclass -> UserGenerateLockfiles. """ + sort_input = True + class PackageVersion(Protocol): """Protocol for backend specific implementations, to support language-ecosystem-specific version diff --git a/src/python/pants/core/subsystems/python_bootstrap.py b/src/python/pants/core/subsystems/python_bootstrap.py index 50bf0e77aa7..40770b9edf8 100644 --- a/src/python/pants/core/subsystems/python_bootstrap.py +++ b/src/python/pants/core/subsystems/python_bootstrap.py @@ -29,7 +29,7 @@ logger = logging.getLogger(__name__) -_PBS_URL_TEMPLATE = "https://github.com/indygreg/python-build-standalone/releases/download/20230116/cpython-3.9.16+20230116-{}-install_only.tar.gz" +_PBS_URL_TEMPLATE = "https://github.com/indygreg/python-build-standalone/releases/download/20241008/cpython-3.11.10+20241008-{}-install_only.tar.gz" class PythonBootstrapSubsystem(Subsystem): @@ -48,23 +48,23 @@ class PythonBootstrapSubsystem(Subsystem): default={ "linux_arm64": ( _PBS_URL_TEMPLATE.format("aarch64-unknown-linux-gnu"), - "1ba520c0db431c84305677f56eb9a4254f5097430ed443e92fc8617f8fba973d", - 23873387, + "320635e957e13d2e10d70a3031563d032fae9e40e60e5ec32bc353643fae1335", + 25925875, ), "linux_x86_64": ( _PBS_URL_TEMPLATE.format("x86_64-unknown-linux-gnu"), - "7ba397787932393e65fc2fb9fcfabf54f2bb6751d5da2b45913cb25b2d493758", - 26129729, + "ff121f14ed113c9da83a45f76c3cf41976fb4419fe406d5cc7066765761c6a4e", + 29716764, ), "macos_arm64": ( _PBS_URL_TEMPLATE.format("aarch64-apple-darwin"), - "d732d212d42315ac27c6da3e0b69636737a8d72086c980daf844344c010cab80", - 17084463, + "ecdc9c042b8f97bff211fcf9425bc51c96acd4037df1565964e89816f2c9564d", + 17795541, ), "macos_x86_64": ( _PBS_URL_TEMPLATE.format("x86_64-apple-darwin"), - "3948384af5e8d4ee7e5ccc648322b99c1c5cf4979954ed5e6b3382c69d6db71e", - 17059474, + "a618c086e0514f681523947e2b66a4dc0c6560f91c36faa072fa6787455df9ea", + 18165701, ), }, help=softwrap( diff --git a/src/python/pants/engine/internals/build_files_test.py b/src/python/pants/engine/internals/build_files_test.py index 24178970dfa..d6636aca424 100644 --- a/src/python/pants/engine/internals/build_files_test.py +++ b/src/python/pants/engine/internals/build_files_test.py @@ -1079,7 +1079,7 @@ def test_build_file_parse_error(target_adaptor_rule_runner: RuleRunner) -> None: ), }, ) - with pytest.raises(ExecutionError, match='File "src/bad/BUILD", line 3'): + with pytest.raises(ExecutionError, match='File "src/bad/BUILD", line 2'): target_adaptor_rule_runner.request( TargetAdaptor, [ diff --git a/src/python/pants/engine/internals/native_engine.pyi b/src/python/pants/engine/internals/native_engine.pyi index a3da381d685..df25665ae57 100644 --- a/src/python/pants/engine/internals/native_engine.pyi +++ b/src/python/pants/engine/internals/native_engine.pyi @@ -694,6 +694,7 @@ class PyOptionParser: def get_dict(self, option_id: PyOptionId, default: dict[str, Any]) -> OptionValue[dict]: ... def get_passthrough_args(self) -> Optional[list[str]]: ... def get_unconsumed_flags(self) -> dict[str, list[str]]: ... + def validate_config(self, valid_keys: dict[str, set[str]]) -> list[str]: ... # ------------------------------------------------------------------------------ # Testutil diff --git a/src/python/pants/engine/internals/scheduler_test.py b/src/python/pants/engine/internals/scheduler_test.py index e4d1bdb6bd5..8c4ac31e127 100644 --- a/src/python/pants/engine/internals/scheduler_test.py +++ b/src/python/pants/engine/internals/scheduler_test.py @@ -479,8 +479,10 @@ def test_trace_includes_nested_exception_traceback() -> None: Traceback (most recent call last): File LOCATION-INFO, in catch_and_reraise return await Get(SomeOutput, SomeInput(outer_input.s)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File LOCATION-INFO, in __await__ result = yield self + ^^^^^^^^^^ File LOCATION-INFO, in raise_an_exception raise Exception(some_input.s) Exception: asdf diff --git a/src/python/pants/help/help_formatter_test.py b/src/python/pants/help/help_formatter_test.py index 2af34178f9b..9c9f1519d85 100644 --- a/src/python/pants/help/help_formatter_test.py +++ b/src/python/pants/help/help_formatter_test.py @@ -9,8 +9,8 @@ from pants.help.help_info_extracter import HelpInfoExtracter, OptionHelpInfo from pants.option.global_options import GlobalOptions from pants.option.native_options import NativeOptionParser -from pants.option.parser import OptionValueHistory, Parser from pants.option.ranked_value import Rank, RankedValue +from pants.option.registrar import OptionRegistrar, OptionValueHistory class TestOptionHelpFormatter: @@ -58,8 +58,8 @@ def test_format_help_choices(self) -> None: assert default_line.lstrip() == "default: kiwi" @classmethod - def _get_parser(cls) -> Tuple[Parser, NativeOptionParser]: - return Parser( + def _get_registrar_and_parser(cls) -> Tuple[OptionRegistrar, NativeOptionParser]: + return OptionRegistrar( scope=GlobalOptions.options_scope, ), NativeOptionParser( args=[], env={}, config_sources=[], allow_pantsrc=False, include_derivation=True @@ -69,36 +69,36 @@ def _get_parser(cls) -> Tuple[Parser, NativeOptionParser]: def _format_for_global_scope( cls, show_advanced: bool, show_deprecated: bool, args: list[str], kwargs ) -> list[str]: - parser, native_parser = cls._get_parser() - parser.register(*args, **kwargs) + registrar, native_parser = cls._get_registrar_and_parser() + registrar.register(*args, **kwargs) return cls._format_for_global_scope_with_parser( - parser, native_parser, show_advanced=show_advanced, show_deprecated=show_deprecated + registrar, native_parser, show_advanced=show_advanced, show_deprecated=show_deprecated ) @classmethod def _format_for_global_scope_with_parser( cls, - parser: Parser, + registrar: OptionRegistrar, native_parser: NativeOptionParser, show_advanced: bool, show_deprecated: bool, ) -> list[str]: oshi = HelpInfoExtracter("").get_option_scope_help_info( - "", parser, native_parser, False, "help.test" + "", registrar, native_parser, False, "help.test" ) return HelpFormatter( show_advanced=show_advanced, show_deprecated=show_deprecated, color=False ).format_options(oshi) def test_suppress_advanced(self) -> None: - parser, native_parser = self._get_parser() - parser.register("--foo", advanced=True) + registrar, native_parser = self._get_registrar_and_parser() + registrar.register("--foo", advanced=True) # must have a non advanced option to be able to supress showing advanced options. - parser.register("--jerry", advanced=False) - lines = self._format_for_global_scope_with_parser(parser, native_parser, False, False) + registrar.register("--jerry", advanced=False) + lines = self._format_for_global_scope_with_parser(registrar, native_parser, False, False) assert len(lines) == 15 assert not any("--foo" in line for line in lines) - lines = self._format_for_global_scope_with_parser(parser, native_parser, True, False) + lines = self._format_for_global_scope_with_parser(registrar, native_parser, True, False) assert len(lines) == 24 def test_suppress_deprecated(self) -> None: diff --git a/src/python/pants/help/help_info_extracter.py b/src/python/pants/help/help_info_extracter.py index 0697c952efc..d4c2b93e7ec 100644 --- a/src/python/pants/help/help_info_extracter.py +++ b/src/python/pants/help/help_info_extracter.py @@ -45,8 +45,8 @@ from pants.option.native_options import NativeOptionParser, parse_dest from pants.option.option_util import is_dict_option, is_list_option from pants.option.options import Options -from pants.option.parser import OptionValueHistory, Parser from pants.option.ranked_value import Rank, RankedValue +from pants.option.registrar import OptionRegistrar, OptionValueHistory from pants.option.scope import GLOBAL_SCOPE, ScopeInfo from pants.util.frozendict import LazyFrozenDict from pants.util.strutil import first_paragraph, strval @@ -508,7 +508,7 @@ def load() -> OptionScopeHelpInfo: ) return HelpInfoExtracter(scope_info.scope).get_option_scope_help_info( scope_info.description, - options.get_parser(scope_info.scope), + options.get_registrar(scope_info.scope), options.native_parser.with_derivation(), # `filter` should be treated as a subsystem for `help`, even though it still # works as a goal for backwards compatibility. @@ -1003,7 +1003,7 @@ def __init__(self, scope: str): def get_option_scope_help_info( self, description: str, - parser: Parser, + registrar: OptionRegistrar, native_parser: NativeOptionParser, is_goal: bool, provider: str = "", @@ -1014,11 +1014,11 @@ def get_option_scope_help_info( basic_options = [] advanced_options = [] deprecated_options = [] - for args, kwargs in parser.option_registrations_iter(): + for args, kwargs in registrar.option_registrations_iter(): derivation = native_parser.get_derivation( - scope=parser.scope, registration_args=args, registration_kwargs=kwargs + scope=registrar.scope, registration_args=args, registration_kwargs=kwargs ) - # Massage the derivation structure returned by the NativeParser into an + # Massage the derivation structure returned by the NativeOptionParser into an # OptionValueHistory as returned by the legacy parser. # TODO: Once we get rid of the legacy parser we can probably simplify by # using the native structure directly. @@ -1071,7 +1071,7 @@ def get_option_help_info(self, args, kwargs): scoped_arg = arg scoped_cmd_line_args.append(scoped_arg) - if Parser.is_bool(kwargs): + if OptionRegistrar.is_bool(kwargs): if is_short_arg: display_args.append(scoped_arg) else: diff --git a/src/python/pants/help/help_info_extracter_test.py b/src/python/pants/help/help_info_extracter_test.py index 4fec7d68a1a..f5606a8c583 100644 --- a/src/python/pants/help/help_info_extracter_test.py +++ b/src/python/pants/help/help_info_extracter_test.py @@ -18,8 +18,8 @@ from pants.option.native_options import NativeOptionParser from pants.option.option_types import BoolOption, IntListOption, StrListOption from pants.option.options import Options -from pants.option.parser import Parser from pants.option.ranked_value import Rank +from pants.option.registrar import OptionRegistrar from pants.option.scope import GLOBAL_SCOPE from pants.option.subsystem import Subsystem from pants.util.logging import LogLevel @@ -98,15 +98,15 @@ def do_test( def test_default() -> None: def do_test(args, kwargs, expected_default_str): - # Defaults are computed in the parser and added into the kwargs, so we + # Defaults are computed in the registrar and added into the kwargs, so we # must jump through this hoop in this test. - parser = Parser( + registrar = OptionRegistrar( scope=GlobalOptions.options_scope, ) native_parser = NativeOptionParser([], {}, [], allow_pantsrc=False, include_derivation=True) - parser.register(*args, **kwargs) - oshi = HelpInfoExtracter(parser.scope).get_option_scope_help_info( - "description", parser, native_parser, False, "provider" + registrar.register(*args, **kwargs) + oshi = HelpInfoExtracter(registrar.scope).get_option_scope_help_info( + "description", registrar, native_parser, False, "provider" ) assert oshi.description == "description" assert oshi.provider == "provider" @@ -198,11 +198,11 @@ def do_test(kwargs, expected_basic=False, expected_advanced=False): def exp_to_len(exp): return int(exp) # True -> 1, False -> 0. - parser = Parser(scope=GlobalOptions.options_scope) + registrar = OptionRegistrar(scope=GlobalOptions.options_scope) native_parser = NativeOptionParser([], {}, [], allow_pantsrc=False, include_derivation=True) - parser.register("--foo", **kwargs) + registrar.register("--foo", **kwargs) oshi = HelpInfoExtracter("").get_option_scope_help_info( - "", parser, native_parser, False, "" + "", registrar, native_parser, False, "" ) assert exp_to_len(expected_basic) == len(oshi.basic) assert exp_to_len(expected_advanced) == len(oshi.advanced) diff --git a/src/python/pants/help/help_tools_test.py b/src/python/pants/help/help_tools_test.py index 7aa1490bb4c..65558fdd589 100644 --- a/src/python/pants/help/help_tools_test.py +++ b/src/python/pants/help/help_tools_test.py @@ -11,12 +11,12 @@ from pants.help.maybe_color import MaybeColor from pants.option.global_options import GlobalOptions from pants.option.native_options import NativeOptionParser -from pants.option.parser import Parser +from pants.option.registrar import OptionRegistrar @pytest.fixture -def parser() -> Parser: - return Parser(scope=GlobalOptions.options_scope) +def registrar() -> OptionRegistrar: + return OptionRegistrar(scope=GlobalOptions.options_scope) @pytest.fixture @@ -30,17 +30,19 @@ def extracter() -> HelpInfoExtracter: @pytest.fixture -def tool_info(extracter, parser, native_parser) -> ToolHelpInfo: - parser.register("--version", type=str, default="1.0") - parser.register("--url-template", type=str, default="https://download/{version}") - oshi = extracter.get_option_scope_help_info("Test description.", parser, native_parser, False) +def tool_info(extracter, registrar, native_parser) -> ToolHelpInfo: + registrar.register("--version", type=str, default="1.0") + registrar.register("--url-template", type=str, default="https://download/{version}") + oshi = extracter.get_option_scope_help_info( + "Test description.", registrar, native_parser, False + ) tool_info = ToolHelpInfo.from_option_scope_help_info(oshi) assert tool_info is not None return tool_info -def test_no_tool_help_info(extracter, parser, native_parser) -> None: - oshi = extracter.get_option_scope_help_info("", parser, native_parser, False) +def test_no_tool_help_info(extracter, registrar, native_parser) -> None: + oshi = extracter.get_option_scope_help_info("", registrar, native_parser, False) assert ToolHelpInfo.from_option_scope_help_info(oshi) is None diff --git a/src/python/pants/option/native_options.py b/src/python/pants/option/native_options.py index b6c63154abd..a4ae8ceefa7 100644 --- a/src/python/pants/option/native_options.py +++ b/src/python/pants/option/native_options.py @@ -275,6 +275,9 @@ def check_scalar_value(val, choices): def get_unconsumed_flags(self) -> dict[str, tuple[str, ...]]: return {k: tuple(v) for k, v in self._native_parser.get_unconsumed_flags().items()} + def validate_config(self, valid_keys: dict[str, set[str]]) -> list[str]: + return self._native_parser.validate_config(valid_keys) + def check_file_exists(val: str, dest: str, scope: str) -> None: error_prefix = f"File value `{val}` for option `{dest}` in `{scope}`" diff --git a/src/python/pants/option/options.py b/src/python/pants/option/options.py index 93e4a324443..a84f63a2cb1 100644 --- a/src/python/pants/option/options.py +++ b/src/python/pants/option/options.py @@ -5,6 +5,7 @@ import dataclasses import logging +from collections import defaultdict from enum import Enum from typing import Any, Iterable, Mapping, Sequence @@ -12,11 +13,16 @@ from pants.base.deprecated import warn_or_error from pants.option.arg_splitter import ArgSplitter from pants.option.config import Config -from pants.option.errors import ConfigValidationError, UnknownFlagsError +from pants.option.errors import ( + ConfigValidationError, + MutuallyExclusiveOptionError, + UnknownFlagsError, +) from pants.option.native_options import NativeOptionParser from pants.option.option_util import is_list_option -from pants.option.option_value_container import OptionValueContainer -from pants.option.parser import Parser +from pants.option.option_value_container import OptionValueContainer, OptionValueContainerBuilder +from pants.option.ranked_value import Rank, RankedValue +from pants.option.registrar import OptionRegistrar from pants.option.scope import GLOBAL_SCOPE, GLOBAL_SCOPE_CONFIG_SECTION, ScopeInfo from pants.util.memo import memoized_method from pants.util.ordered_set import FrozenOrderedSet, OrderedSet @@ -116,9 +122,6 @@ def create( args: Sequence[str], bootstrap_option_values: OptionValueContainer | None = None, allow_unknown_options: bool = False, - # We default to error to be strict in tests, but set explicitly in OptionsBootstrapper - # for user-facing behavior. - native_options_validation: NativeOptionsValidation = NativeOptionsValidation.error, native_options_config_discovery: bool = True, include_derivation: bool = False, ) -> Options: @@ -131,12 +134,11 @@ def create( :param bootstrap_option_values: An optional namespace containing the values of bootstrap options. We can use these values when registering other options. :param allow_unknown_options: Whether to ignore or error on unknown cmd-line flags. - :param native_options_validation: How to validate the native options parser against the - legacy Python parser. - :param native_options_config_discovery: Whether to discover config files in the native parser or use the ones supplied + :param native_options_config_discovery: Whether to discover config files in the native + parser or use the ones supplied. :param include_derivation: Whether to gather option value derivation information. """ - # We need parsers for all the intermediate scopes, so inherited option values + # We need registrars for all the intermediate scopes, so inherited option values # can propagate through them. complete_known_scope_infos = cls.complete_scopes(known_scope_infos) splitter = ArgSplitter(complete_known_scope_infos, get_buildroot()) @@ -164,7 +166,9 @@ def create( [line for line in [line.strip() for line in f] if line] ) - parser_by_scope = {si.scope: Parser(si.scope) for si in complete_known_scope_infos} + registrar_by_scope = { + si.scope: OptionRegistrar(si.scope) for si in complete_known_scope_infos + } known_scope_to_info = {s.scope: s for s in complete_known_scope_infos} config_to_pass = None if native_options_config_discovery else config.sources() @@ -184,9 +188,8 @@ def create( scope_to_flags=split_args.scope_to_flags, specs=split_args.specs, passthru=split_args.passthru, - parser_by_scope=parser_by_scope, + registrar_by_scope=registrar_by_scope, native_parser=native_parser, - native_options_validation=native_options_validation, bootstrap_option_values=bootstrap_option_values, known_scope_to_info=known_scope_to_info, allow_unknown_options=allow_unknown_options, @@ -200,9 +203,8 @@ def __init__( scope_to_flags: dict[str, list[str]], specs: list[str], passthru: list[str], - parser_by_scope: dict[str, Parser], + registrar_by_scope: dict[str, OptionRegistrar], native_parser: NativeOptionParser, - native_options_validation: NativeOptionsValidation, bootstrap_option_values: OptionValueContainer | None, known_scope_to_info: dict[str, ScopeInfo], allow_unknown_options: bool = False, @@ -217,7 +219,7 @@ def __init__( self._scope_to_flags = scope_to_flags self._specs = specs self._passthru = passthru - self._parser_by_scope = parser_by_scope + self._registrar_by_scope = registrar_by_scope self._native_parser = native_parser self._bootstrap_option_values = bootstrap_option_values self._known_scope_to_info = known_scope_to_info @@ -265,7 +267,10 @@ def known_scope_to_info(self) -> dict[str, ScopeInfo]: @property def known_scope_to_scoped_args(self) -> dict[str, frozenset[str]]: - return {scope: parser.known_scoped_args for scope, parser in self._parser_by_scope.items()} + return { + scope: registrar.known_scoped_args + for scope, registrar in self._registrar_by_scope.items() + } @property def scope_to_flags(self) -> dict[str, list[str]]: @@ -278,6 +283,21 @@ def verify_configs(self, global_config: Config) -> None: for scope in self.known_scope_to_info: section = GLOBAL_SCOPE_CONFIG_SECTION if scope == GLOBAL_SCOPE else scope section_to_valid_options[section] = set(self.for_scope(scope, check_deprecations=False)) + + error_log = self.native_parser.validate_config(section_to_valid_options) + if error_log: + for error in error_log: + logger.error(error) + raise ConfigValidationError( + softwrap( + """ + Invalid config entries detected. See log for details on which entries to update + or remove. + + (Specify --no-verify-config to disable this check.) + """ + ) + ) global_config.verify(section_to_valid_options) def verify_args(self): @@ -312,10 +332,10 @@ def is_known_scope(self, scope: str) -> bool: def register(self, scope: str, *args, **kwargs) -> None: """Register an option in the given scope.""" - self.get_parser(scope).register(*args, **kwargs) + self.get_registrar(scope).register(*args, **kwargs) deprecated_scope = self.known_scope_to_info[scope].deprecated_scope if deprecated_scope: - self.get_parser(deprecated_scope).register(*args, **kwargs) + self.get_registrar(deprecated_scope).register(*args, **kwargs) def registration_function_for_subsystem(self, subsystem_cls): """Returns a function for registering options on the given scope.""" @@ -331,15 +351,15 @@ def register(*args, **kwargs): register.scope = subsystem_cls.options_scope return register - def get_parser(self, scope: str) -> Parser: - """Returns the parser for the given scope, so code can register on it directly. + def get_registrar(self, scope: str) -> OptionRegistrar: + """Returns the registrar for the given scope, so code can register on it directly. - :param scope: The scope to retrieve the parser for. - :return: The parser for the given scope. + :param scope: The scope to retrieve the registrar for. + :return: The registrar for the given scope. :raises pants.option.errors.ConfigValidationError: if the scope is not known. """ try: - return self._parser_by_scope[scope] + return self._registrar_by_scope[scope] except KeyError: raise ConfigValidationError(f"No such options scope: {scope}") @@ -410,8 +430,47 @@ def for_scope( :return: An OptionValueContainer representing the option values for the given scope. :raises pants.option.errors.ConfigValidationError: if the scope is unknown. """ + builder = OptionValueContainerBuilder() + mutex_map = defaultdict(list) + registrar = self.get_registrar(scope) + scope_str = "global scope" if scope == GLOBAL_SCOPE else f"scope '{scope}'" - native_values = self.get_parser(scope).parse_args_native(self._native_parser) + for args, kwargs in registrar.option_registrations_iter(): + dest = kwargs["dest"] + val, rank = self._native_parser.get_value( + scope=scope, registration_args=args, registration_kwargs=kwargs + ) + explicitly_set = rank > Rank.HARDCODED + + # If we explicitly set a deprecated but not-yet-expired option, warn about it. + # Otherwise, raise a CodeRemovedError if the deprecation has expired. + removal_version = kwargs.get("removal_version", None) + if removal_version is not None: + warn_or_error( + removal_version=removal_version, + entity=f"option '{dest}' in {scope_str}", + start_version=kwargs.get("deprecation_start_version", None), + hint=kwargs.get("removal_hint", None), + print_warning=explicitly_set, + ) + + # If we explicitly set the option, check for mutual exclusivity. + if explicitly_set: + mutex_dest = kwargs.get("mutually_exclusive_group") + mutex_map_key = mutex_dest or dest + mutex_map[mutex_map_key].append(dest) + if len(mutex_map[mutex_map_key]) > 1: + raise MutuallyExclusiveOptionError( + softwrap( + f""" + Can only provide one of these mutually exclusive options in + {scope_str}, but multiple given: + {', '.join(mutex_map[mutex_map_key])} + """ + ) + ) + setattr(builder, dest, RankedValue(rank, val)) + native_values = builder.build() # Check for any deprecation conditions, which are evaluated using `self._flag_matchers`. if check_deprecations: @@ -438,9 +497,9 @@ def get_fingerprintable_for_scope( """ pairs = [] - parser = self.get_parser(scope) + registrar = self.get_registrar(scope) # Sort the arguments, so that the fingerprint is consistent. - for _, kwargs in sorted(parser.option_registrations_iter()): + for _, kwargs in sorted(registrar.option_registrations_iter()): if not kwargs.get("fingerprint", True): continue if daemon_only and not kwargs.get("daemon", False): diff --git a/src/python/pants/option/options_bootstrapper.py b/src/python/pants/option/options_bootstrapper.py index e4257d1547f..5d4eeabf73b 100644 --- a/src/python/pants/option/options_bootstrapper.py +++ b/src/python/pants/option/options_bootstrapper.py @@ -18,7 +18,7 @@ from pants.option.custom_types import DictValueComponent, ListValueComponent from pants.option.global_options import BootstrapOptions, GlobalOptions from pants.option.option_types import collect_options_info -from pants.option.options import NativeOptionsValidation, Options +from pants.option.options import Options from pants.option.scope import GLOBAL_SCOPE, ScopeInfo from pants.option.subsystem import Subsystem from pants.util.dirutil import read_file @@ -97,9 +97,6 @@ def parse_bootstrap_options( config=config, known_scope_infos=[GlobalOptions.get_scope_info()], args=args, - # We ignore validation to ensure bootstrapping succeeds. - # The bootstrap options will be validated anyway when we parse the full options. - native_options_validation=NativeOptionsValidation.ignore, native_options_config_discovery=False, ) @@ -259,7 +256,6 @@ def _full_options( args=self.args, bootstrap_option_values=bootstrap_option_values, allow_unknown_options=allow_unknown_options, - native_options_validation=bootstrap_option_values.native_options_validation, native_options_config_discovery=False, ) diff --git a/src/python/pants/option/options_integration_test.py b/src/python/pants/option/options_integration_test.py index 0ec26f13bf4..4178d4a795b 100644 --- a/src/python/pants/option/options_integration_test.py +++ b/src/python/pants/option/options_integration_test.py @@ -23,7 +23,7 @@ def test_invalid_options() -> None: } config_errors = [ "ERROR] Invalid option 'invalid_global' under [GLOBAL]", - "ERROR] Invalid section [invalid_scope]", + "ERROR] Invalid table name [invalid_scope]", "ERROR] Invalid option 'bad_option' under [pytest]", ] diff --git a/src/python/pants/option/options_test.py b/src/python/pants/option/options_test.py index 735fb7224d6..92818138818 100644 --- a/src/python/pants/option/options_test.py +++ b/src/python/pants/option/options_test.py @@ -353,8 +353,9 @@ def test_deprecated_options_error() -> None: def register(opts: Options) -> None: opts.register(GLOBAL_SCOPE, "--expired", removal_version="0.0.1.dev0") + opts = create_options([GLOBAL_SCOPE], register, []) with pytest.raises(CodeRemovedError): - create_options([GLOBAL_SCOPE], register, []) + opts.for_scope(scope=GLOBAL_SCOPE) @unittest.mock.patch("pants.base.deprecated.PANTS_SEMVER", Version(_FAKE_CUR_VERSION)) diff --git a/src/python/pants/option/parser.py b/src/python/pants/option/registrar.py similarity index 77% rename from src/python/pants/option/parser.py rename to src/python/pants/option/registrar.py index 7f8d54b8e37..56bb2600e09 100644 --- a/src/python/pants/option/parser.py +++ b/src/python/pants/option/registrar.py @@ -7,12 +7,11 @@ import inspect import logging import typing -from collections import defaultdict from dataclasses import dataclass from enum import Enum from typing import Any, Mapping -from pants.base.deprecated import validate_deprecation_semver, warn_or_error +from pants.base.deprecated import validate_deprecation_semver from pants.option.custom_types import ( DictValueComponent, ListValueComponent, @@ -31,7 +30,6 @@ InvalidKwargNonGlobalScope, InvalidMemberType, MemberTypeNotAllowed, - MutuallyExclusiveOptionError, NoOptionNames, OptionAlreadyRegistered, OptionNameDoubleDash, @@ -39,11 +37,9 @@ PassthroughType, RegistrationError, ) -from pants.option.native_options import NativeOptionParser, parse_dest -from pants.option.option_value_container import OptionValueContainer, OptionValueContainerBuilder -from pants.option.ranked_value import Rank, RankedValue +from pants.option.native_options import parse_dest +from pants.option.ranked_value import RankedValue from pants.option.scope import GLOBAL_SCOPE -from pants.util.strutil import softwrap logger = logging.getLogger(__name__) @@ -57,8 +53,8 @@ def final_value(self) -> RankedValue: return self.ranked_values[-1] -class Parser: - """An argument parser.""" +class OptionRegistrar: + """Holds information about registered options.""" @staticmethod def is_bool(kwargs: Mapping[str, Any]) -> bool: @@ -93,13 +89,13 @@ def _invert(cls, s: bool | str | None) -> bool | None: return not b def __init__(self, scope: str) -> None: - """Create a Parser instance. + """Create an OptionRegistrar instance. - :param scope_info: the scope this parser acts for. + :param scope: the scope this registrar acts for. """ self._scope = scope - # All option args registered with this parser. Used to prevent conflicts. + # All option args registered with this registrar. Used to prevent conflicts. self._known_args: set[str] = set() # List of (args, kwargs) registration pairs, exactly as captured at registration time. @@ -117,42 +113,9 @@ def known_scoped_args(self) -> frozenset[str]: prefix = f"{self.scope}-" if self.scope != GLOBAL_SCOPE else "" return frozenset(f"--{prefix}{arg.lstrip('--')}" for arg in self._known_args) - def parse_args_native( - self, - native_parser: NativeOptionParser, - ) -> OptionValueContainer: - namespace = OptionValueContainerBuilder() - mutex_map = defaultdict(list) - for args, kwargs in self._option_registrations: - dest = parse_dest(*args, **kwargs) - val, rank = native_parser.get_value( - scope=self.scope, registration_args=args, registration_kwargs=kwargs - ) - - # If the option is explicitly given, check deprecation and mutual exclusion. - if rank > Rank.HARDCODED: - self._check_deprecated(dest, kwargs) - mutex_dest = kwargs.get("mutually_exclusive_group") - mutex_map_key = mutex_dest or dest - mutex_map[mutex_map_key].append(dest) - if len(mutex_map[mutex_map_key]) > 1: - raise MutuallyExclusiveOptionError( - softwrap( - f""" - Can only provide one of these mutually exclusive options in - {self._scope_str()}, but multiple given: - {', '.join(mutex_map[mutex_map_key])} - """ - ) - ) - - setattr(namespace, dest, RankedValue(rank, val)) - - return namespace.build() - def option_registrations_iter(self): """Returns an iterator over the normalized registration arguments of each option in this - parser. + registrar. Useful for generating help and other documentation. @@ -181,8 +144,6 @@ def normalize_kwargs(orig_args, orig_kwargs): def register(self, *args, **kwargs) -> None: """Register an option.""" self._validate(args, kwargs) - dest = parse_dest(*args, **kwargs) - self._check_deprecated(dest, kwargs, print_warning=False) if self.is_bool(kwargs): default = kwargs.get("default") @@ -202,18 +163,6 @@ def register(self, *args, **kwargs) -> None: raise OptionAlreadyRegistered(self.scope, arg) self._known_args.update(args) - def _check_deprecated(self, dest: str, kwargs, print_warning: bool = True) -> None: - """Checks option for deprecation and issues a warning/error if necessary.""" - removal_version = kwargs.get("removal_version", None) - if removal_version is not None: - warn_or_error( - removal_version=removal_version, - entity=f"option '{dest}' in {self._scope_str()}", - start_version=kwargs.get("deprecation_start_version", None), - hint=kwargs.get("removal_hint", None), - print_warning=print_warning, - ) - _allowed_registration_kwargs = { "type", "member_type", @@ -330,7 +279,7 @@ def error( error(InvalidKwarg, kwarg=kwarg) # Ensure `daemon=True` can't be passed on non-global scopes. - if kwarg == "daemon" and self._scope != GLOBAL_SCOPE: + if kwarg == "daemon" and self.scope != GLOBAL_SCOPE: error(InvalidKwargNonGlobalScope, kwarg=kwarg) removal_version = kwargs.get("removal_version") @@ -358,8 +307,5 @@ def to_value_type(cls, val_str, type_arg, member_type): f"Error applying type '{type_arg.__name__}' to option value '{val_str}': {e}" ) - def _scope_str(self) -> str: - return "global scope" if self.scope == GLOBAL_SCOPE else f"scope '{self.scope}'" - def __str__(self) -> str: - return f"Parser({self._scope})" + return f"OptionRegistrar({self.scope})" diff --git a/src/python/pants/testutil/BUILD b/src/python/pants/testutil/BUILD index c73b3375686..2a8879af5cd 100644 --- a/src/python/pants/testutil/BUILD +++ b/src/python/pants/testutil/BUILD @@ -14,7 +14,7 @@ python_distribution( description="Test support for writing Pants plugins.", classifiers=["Topic :: Software Development :: Testing"], # N.B.: Must match [python] interpreter_constraints in pants.toml. - python_requires="==3.9.*", + python_requires="==3.11.*", ), ) diff --git a/src/python/pants/testutil/python_interpreter_selection.py b/src/python/pants/testutil/python_interpreter_selection.py index 1c9420fd83e..249e4a6648e 100644 --- a/src/python/pants/testutil/python_interpreter_selection.py +++ b/src/python/pants/testutil/python_interpreter_selection.py @@ -22,6 +22,8 @@ PY_37 = "3.7" PY_38 = "3.8" PY_39 = "3.9" +PY_310 = "3.10" +PY_311 = "3.11" def has_python_version(version): @@ -100,6 +102,16 @@ def skip_unless_python39_present(func): return skip_unless_all_pythons_present(PY_39)(func) +def skip_unless_python310_present(func): + """A test skip decorator that only runs a test method if python3.10 is present.""" + return skip_unless_all_pythons_present(PY_310)(func) + + +def skip_unless_python311_present(func): + """A test skip decorator that only runs a test method if python3.11 is present.""" + return skip_unless_all_pythons_present(PY_311)(func) + + def skip_unless_python27_and_python3_present(func): """A test skip decorator that only runs a test method if python2.7 and python3 are present.""" return skip_unless_all_pythons_present(PY_27, PY_3)(func) diff --git a/src/python/pants/util/typing_test.py b/src/python/pants/util/typing_test.py index 0155c074858..061d9894c85 100644 --- a/src/python/pants/util/typing_test.py +++ b/src/python/pants/util/typing_test.py @@ -29,8 +29,7 @@ class A: b: int | float monkeypatch.setattr(typing, "ForwardRef", ForwardRefPristine) - with pytest.raises(TypeError): - get_type_hints(A) + assert get_type_hints(A) monkeypatch.setattr(typing, "ForwardRef", ForwardRefPatched) assert get_type_hints(A) diff --git a/src/python/pants_release/generate_github_workflows.py b/src/python/pants_release/generate_github_workflows.py index e76b4a4595f..5d97ea344f9 100644 --- a/src/python/pants_release/generate_github_workflows.py +++ b/src/python/pants_release/generate_github_workflows.py @@ -8,7 +8,7 @@ import os import re from dataclasses import dataclass, field -from enum import Enum +from enum import Enum, ReprEnum from pathlib import Path from textwrap import dedent # noqa: PNT20 from typing import Any, Dict, Sequence, cast @@ -18,40 +18,27 @@ from pants_release.common import die -def action(name: str, node16_compat: bool = False) -> str: - # Versions of actions compatible with node16 and the `ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION` setting. - # glibc 2.17 is required to build manylinux_2014 wheels, but node.js does do not ship glibc 2.17 compatible - # binaries for node >= v17. - if node16_compat: - version_map = { - "checkout": "actions/checkout@v3", - "upload-artifact": "actions/upload-artifact@v3", - "setup-go": "actions/setup-go@v4", - } - else: - version_map = { - "action-send-mail": "dawidd6/action-send-mail@v3.8.0", - "cache": "actions/cache@v4", - "checkout": "actions/checkout@v4", - "download-artifact": "actions/download-artifact@v4", - "github-action-required-labels": "mheap/github-action-required-labels@v4.0.0", - "rust-cache": "benjyw/rust-cache@5ed697a6894712d2854c80635bb00a2496ea307a", - "setup-go": "actions/setup-go@v5", - "setup-java": "actions/setup-java@v4", - "setup-node": "actions/setup-node@v4", - "setup-protoc": "arduino/setup-protoc@9b1ee5b22b0a3f1feb8c2ff99b32c89b3c3191e9", - "setup-python": "actions/setup-python@v5", - "slack-github-action": "slackapi/slack-github-action@v1.24.0", - "upload-artifact": "actions/upload-artifact@v4", - } +def action(name: str) -> str: + version_map = { + "action-send-mail": "dawidd6/action-send-mail@v3.8.0", + "cache": "actions/cache@v4", + "checkout": "actions/checkout@v4", + "download-artifact": "actions/download-artifact@v4", + "github-action-required-labels": "mheap/github-action-required-labels@v4.0.0", + "rust-cache": "benjyw/rust-cache@5ed697a6894712d2854c80635bb00a2496ea307a", + "setup-go": "actions/setup-go@v5", + "setup-java": "actions/setup-java@v4", + "setup-node": "actions/setup-node@v4", + "setup-protoc": "arduino/setup-protoc@9b1ee5b22b0a3f1feb8c2ff99b32c89b3c3191e9", + "setup-python": "actions/setup-python@v5", + "slack-github-action": "slackapi/slack-github-action@v1.24.0", + "upload-artifact": "actions/upload-artifact@v4", + } try: return version_map[name] except KeyError as e: - configured_version = ( - "Node 16 compatible version configured" if node16_compat else "version configured" - ) raise ValueError( - f"Requested github action '{name}' does not have a {configured_version}.\n" + f"Requested github action '{name}' does not have a version configured.\n" f"Current known versions: {version_map}" ) from e @@ -73,21 +60,30 @@ def action(name: str, node16_compat: bool = False) -> str: class Platform(Enum): LINUX_X86_64 = "Linux-x86_64" LINUX_ARM64 = "Linux-ARM64" - MACOS10_15_X86_64 = "macOS10-15-x86_64" - # the oldest version of macOS supported by GitHub self-hosted runners - MACOS12_X86_64 = "macOS12-x86_64" - MACOS11_ARM64 = "macOS11-ARM64" + MACOS13_X86_64 = "macOS13-x86_64" + MACOS14_ARM64 = "macOS14-ARM64" -GITHUB_HOSTED = {Platform.LINUX_X86_64, Platform.MACOS12_X86_64} -SELF_HOSTED = {Platform.LINUX_ARM64, Platform.MACOS10_15_X86_64, Platform.MACOS11_ARM64} -# We control these runners, so we preinstall and expose python on them. -HAS_PYTHON = {Platform.LINUX_ARM64, Platform.MACOS10_15_X86_64, Platform.MACOS11_ARM64} -HAS_GO = {Platform.MACOS12_X86_64, Platform.MACOS10_15_X86_64, Platform.MACOS11_ARM64} +GITHUB_HOSTED = {Platform.LINUX_X86_64, Platform.MACOS13_X86_64, Platform.MACOS14_ARM64} +SELF_HOSTED = {Platform.LINUX_ARM64} CARGO_AUDIT_IGNORED_ADVISORY_IDS = ( "RUSTSEC-2020-0128", # returns a false positive on the cache crate, which is a local crate not a 3rd party crate ) +# We don't specify a patch version so that we get the latest, which comes pre-installed: +# https://github.com/actions/setup-python#available-versions-of-python +# NOTE: The last entry becomes the default +_BASE_PYTHON_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.12", "3.13", "3.11"] + +PYTHON_VERSIONS_PER_PLATFORM = { + Platform.LINUX_X86_64: _BASE_PYTHON_VERSIONS, + Platform.MACOS13_X86_64: _BASE_PYTHON_VERSIONS, + # Python 3.7 or 3.8 aren't supported directly on arm64 macOS + Platform.MACOS14_ARM64: [v for v in _BASE_PYTHON_VERSIONS if v not in ("3.7", "3.8")], + # These runners have Python already installed + Platform.LINUX_ARM64: None, +} + def gha_expr(expr: str) -> str: """Properly quote GitHub Actions expressions. @@ -120,13 +116,8 @@ def hash_files(path: str) -> str: f"{NATIVE_FILES_COMMON_PREFIX}/engine/internals/native_engine.so.metadata", ] -# We don't specify a patch version so that we get the latest, which comes pre-installed: -# https://github.com/actions/setup-python#available-versions-of-python -# NOTE: The last entry becomes the default -PYTHON_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.12", "3.13", "3.11"] - DONT_SKIP_RUST = "needs.classify_changes.outputs.rust == 'true'" -DONT_SKIP_WHEELS = "needs.classify_changes.outputs.release == 'true'" +DONT_SKIP_WHEELS = "needs.classify_changes.outputs.release == 'true' || needs.classify_changes.outputs.ci_config == 'true'" IS_PANTS_OWNER = "github.repository_owner == 'pantsbuild'" # NB: This overrides `pants.ci.toml`. @@ -238,7 +229,7 @@ def checkout( # We need to fetch a few commits back, to be able to access HEAD^2 in the PR case. { "name": "Check out code", - "uses": action("checkout", node16_compat=containerized), + "uses": action("checkout"), "with": { **fetch_depth_opt, **({"ref": ref} if ref else {}), @@ -367,10 +358,10 @@ def install_jdk() -> Step: } -def install_go(node16_compat: bool = False) -> Step: +def install_go() -> Step: return { "name": "Install Go", - "uses": action("setup-go", node16_compat=node16_compat), + "uses": action("setup-go"), "with": {"go-version": "1.19.5"}, } @@ -422,12 +413,10 @@ def runs_on(self) -> list[str]: # any platform-specific labels, so we don't run on future GH-hosted # platforms without realizing it. ret = ["self-hosted"] if self.platform in SELF_HOSTED else [] - if self.platform == Platform.MACOS12_X86_64: - ret += ["macos-12"] - elif self.platform == Platform.MACOS11_ARM64: - ret += ["macOS-11-ARM64"] - elif self.platform == Platform.MACOS10_15_X86_64: - ret += ["macOS-10.15-X64"] + if self.platform == Platform.MACOS13_X86_64: + ret += ["macos-13"] + elif self.platform == Platform.MACOS14_ARM64: + ret += ["macos-14"] elif self.platform == Platform.LINUX_X86_64: ret += ["ubuntu-22.04"] elif self.platform == Platform.LINUX_ARM64: @@ -443,11 +432,11 @@ def runs_on(self) -> list[str]: def platform_env(self): ret = {} - if self.platform in {Platform.MACOS10_15_X86_64, Platform.MACOS12_X86_64}: + if self.platform in {Platform.MACOS13_X86_64}: # Works around bad `-arch arm64` flag embedded in Xcode 12.x Python interpreters on # intel machines. See: https://github.com/giampaolo/psutil/issues/1832 ret["ARCHFLAGS"] = "-arch x86_64" - if self.platform == Platform.MACOS11_ARM64: + if self.platform in {Platform.MACOS14_ARM64}: ret["ARCHFLAGS"] = "-arch arm64" if self.platform == Platform.LINUX_X86_64: # Currently we run Linux x86_64 CI on GitHub Actions-hosted hardware, and @@ -460,10 +449,6 @@ def platform_env(self): return ret def wrap_cmd(self, cmd: str) -> str: - if self.platform == Platform.MACOS11_ARM64: - # The self-hosted M1 runner is an X86_64 binary that runs under Rosetta, - # so we have to explicitly change the arch for the subprocesses it spawns. - return f"arch -arm64 {cmd}" return cmd def native_binaries_upload(self) -> Step: @@ -549,8 +534,9 @@ def bootstrap_caches(self) -> Sequence[Step]: def setup_pythons(self) -> Sequence[Step]: ret = [] - if self.platform not in HAS_PYTHON: - ret.append(install_pythons(PYTHON_VERSIONS)) + versions = PYTHON_VERSIONS_PER_PLATFORM[self.platform] + if versions is not None: + ret.append(install_pythons(versions)) return ret def bootstrap_pants(self) -> Sequence[Step]: @@ -582,10 +568,10 @@ def bootstrap_pants(self) -> Sequence[Step]: self.native_binaries_upload(), ] - def upload_log_artifacts(self, name: str, node16_compat: bool = False) -> Step: + def upload_log_artifacts(self, name: str) -> Step: return { "name": "Upload pants.log", - "uses": action("upload-artifact", node16_compat=node16_compat), + "uses": action("upload-artifact"), "if": "always()", "continue-on-error": True, "with": { @@ -744,7 +730,7 @@ def test_jobs( *checkout(), *(launch_bazel_remote() if with_remote_caching else []), install_jdk(), - *([install_go()] if helper.platform not in HAS_GO else []), + install_go(), *( [download_apache_thrift()] if helper.platform == Platform.LINUX_X86_64 @@ -806,8 +792,8 @@ def linux_arm64_test_jobs() -> Jobs: return jobs -def macos12_x86_64_test_jobs() -> Jobs: - helper = Helper(Platform.MACOS12_X86_64) +def macos13_x86_64_test_jobs() -> Jobs: + helper = Helper(Platform.MACOS13_X86_64) jobs = { helper.job_name("bootstrap_pants"): bootstrap_jobs( helper, @@ -834,9 +820,9 @@ def build_wheels_job( # the code, install rustup and expose Pythons. # TODO: Apply rust caching here. if platform == Platform.LINUX_X86_64: - container = {"image": "quay.io/pypa/manylinux2014_x86_64:latest"} + container = {"image": "quay.io/pypa/manylinux_2_28_x86_64:latest"} elif platform == Platform.LINUX_ARM64: - container = {"image": "quay.io/pypa/manylinux2014_aarch64:latest"} + container = {"image": "quay.io/pypa/manylinux_2_28_aarch64:latest"} else: container = None @@ -851,6 +837,10 @@ def build_wheels_job( echo "/opt/python/cp37-cp37m/bin" >> $GITHUB_PATH echo "/opt/python/cp38-cp38/bin" >> $GITHUB_PATH echo "/opt/python/cp39-cp39/bin" >> $GITHUB_PATH + echo "/opt/python/cp310-cp310/bin" >> $GITHUB_PATH + echo "/opt/python/cp311-cp311/bin" >> $GITHUB_PATH + echo "/opt/python/cp312-cp312/bin" >> $GITHUB_PATH + echo "/opt/python/cp313-cp313/bin" >> $GITHUB_PATH """ ), }, @@ -889,11 +879,7 @@ def build_wheels_job( "steps": [ *initial_steps, install_protoc(), # for prost crate - *( - [] - if platform == Platform.LINUX_ARM64 - else [install_go(node16_compat=bool(container))] - ), + *([] if platform == Platform.LINUX_ARM64 else [install_go()]), { "name": "Build wheels", "run": "./pants run src/python/pants_release/release.py -- build-wheels", @@ -904,7 +890,7 @@ def build_wheels_job( "run": "./pants package src/python/pants:pants-pex", "env": helper.platform_env(), }, - helper.upload_log_artifacts(name="wheels-and-pex", node16_compat=bool(container)), + helper.upload_log_artifacts(name="wheels-and-pex"), *( [ { @@ -977,8 +963,8 @@ def build_wheels_jobs(*, for_deploy_ref: str | None = None, needs: list[str] | N return { **build_wheels_job(Platform.LINUX_X86_64, for_deploy_ref, needs), **build_wheels_job(Platform.LINUX_ARM64, for_deploy_ref, needs), - **build_wheels_job(Platform.MACOS10_15_X86_64, for_deploy_ref, needs), - **build_wheels_job(Platform.MACOS11_ARM64, for_deploy_ref, needs), + **build_wheels_job(Platform.MACOS13_X86_64, for_deploy_ref, needs), + **build_wheels_job(Platform.MACOS14_ARM64, for_deploy_ref, needs), } @@ -995,7 +981,7 @@ def test_workflow_jobs() -> Jobs: } jobs.update(**linux_x86_64_test_jobs()) jobs.update(**linux_arm64_test_jobs()) - jobs.update(**macos12_x86_64_test_jobs()) + jobs.update(**macos13_x86_64_test_jobs()) jobs.update(**build_wheels_jobs()) jobs.update( { @@ -1313,7 +1299,7 @@ def release_jobs_and_inputs() -> tuple[Jobs, dict[str, Any]]: return jobs, inputs -class DefaultGoals(str, Enum): +class DefaultGoals(str, ReprEnum): tailor_update_build_files = "tailor --check update-build-files --check ::" lint_check = "lint check ::" test = "test ::" diff --git a/src/python/pants_release/release.py b/src/python/pants_release/release.py index 5f39b6f3ce9..2eaffaf509a 100644 --- a/src/python/pants_release/release.py +++ b/src/python/pants_release/release.py @@ -809,7 +809,7 @@ def smoke_test_install_and_version(version: str) -> None: ] [python] - interpreter_constraints = ["==3.9.*"] + interpreter_constraints = ["==3.11.*"] enable_resolves = true """ ) diff --git a/src/rust/engine/Cargo.lock b/src/rust/engine/Cargo.lock index cb6215ab60a..5c0cbed46c0 100644 --- a/src/rust/engine/Cargo.lock +++ b/src/rust/engine/Cargo.lock @@ -3092,7 +3092,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15" dependencies = [ "bytes", - "heck 0.4.0", + "heck 0.5.0", "itertools", "log", "multimap", @@ -3143,9 +3143,9 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.22.5" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d922163ba1f79c04bc49073ba7b32fd5a8d3b76a87c955921234b8e77333c51" +checksum = "7ebb0c0cc0de9678e53be9ccf8a2ab53045e6e3a8be03393ceccc5e7396ccb40" dependencies = [ "cfg-if 1.0.0", "indoc", @@ -3161,9 +3161,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.22.5" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc38c5feeb496c8321091edf3d63e9a6829eab4b863b4a6a65f26f3e9cc6b179" +checksum = "80e3ce69c4ec34476534b490e412b871ba03a82e35604c3dfb95fcb6bfb60c09" dependencies = [ "once_cell", "target-lexicon", @@ -3171,9 +3171,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.22.5" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94845622d88ae274d2729fcefc850e63d7a3ddff5e3ce11bd88486db9f1d357d" +checksum = "3b09f311c76b36dfd6dd6f7fa6f9f18e7e46a1c937110d283e80b12ba2468a75" dependencies = [ "libc", "pyo3-build-config", @@ -3181,9 +3181,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.22.5" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e655aad15e09b94ffdb3ce3d217acf652e26bbc37697ef012f5e5e348c716e5e" +checksum = "fd4f74086536d1e1deaff99ec0387481fb3325c82e4e48be0e75ab3d3fcb487a" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -3193,9 +3193,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.22.5" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1e3f09eecd94618f60a455a23def79f79eba4dc561a97324bf9ac8c6df30ce" +checksum = "9e77dfeb76b32bbf069144a5ea0a36176ab59c8db9ce28732d0f06f096bbfbc8" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -4462,6 +4462,7 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ + "indexmap 1.9.3", "serde", ] diff --git a/src/rust/engine/Cargo.toml b/src/rust/engine/Cargo.toml index d193b112a12..fe9795c9436 100644 --- a/src/rust/engine/Cargo.toml +++ b/src/rust/engine/Cargo.toml @@ -294,8 +294,8 @@ prodash = { git = "https://github.com/stuhood/prodash", rev = "stuhood/raw-messa prost = "0.13" prost-build = "0.13" prost-types = "0.13" -pyo3 = "0.22" -pyo3-build-config = "0.22" +pyo3 = "0.23.1" +pyo3-build-config = "0.23.1" rand = "0.8" regex = "1" rlimit = "0.8" diff --git a/src/rust/engine/options/Cargo.toml b/src/rust/engine/options/Cargo.toml index 5247db2f41d..d9a0fb628f6 100644 --- a/src/rust/engine/options/Cargo.toml +++ b/src/rust/engine/options/Cargo.toml @@ -12,7 +12,7 @@ log = { workspace = true } maplit = { workspace = true } peg = { workspace = true } shellexpand = { workspace = true } -toml = { workspace = true } +toml = { workspace = true, features = ["preserve_order"] } regex = { workspace = true } whoami = { workspace = true } serde = { workspace = true, features = ["derive"] } diff --git a/src/rust/engine/options/src/args.rs b/src/rust/engine/options/src/args.rs index 15192e4a9dc..4d06f9315d6 100644 --- a/src/rust/engine/options/src/args.rs +++ b/src/rust/engine/options/src/args.rs @@ -11,6 +11,7 @@ use crate::ListEdit; use core::iter::once; use itertools::{chain, Itertools}; use parking_lot::Mutex; +use std::any::Any; use std::collections::{HashMap, HashSet}; use std::sync::Arc; @@ -271,6 +272,10 @@ impl OptionsSource for ArgsReader { ) } + fn as_any(&self) -> &dyn Any { + self + } + fn get_string(&self, id: &OptionId) -> Result, String> { // We iterate in reverse so that the rightmost arg wins in case an option // is specified multiple times. diff --git a/src/rust/engine/options/src/config.rs b/src/rust/engine/options/src/config.rs index 097ff3d42ed..294ca8af7c4 100644 --- a/src/rust/engine/options/src/config.rs +++ b/src/rust/engine/options/src/config.rs @@ -1,6 +1,7 @@ // Copyright 2021 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). +use std::any::Any; use std::collections::{HashMap, HashSet}; use std::fs; use std::path::{Path, PathBuf}; @@ -352,6 +353,39 @@ impl ConfigReader { } } + // Given a map from section name to valid keys for that section, + // returns a vec of validation error messages. + pub fn validate( + &self, + section_to_valid_keys: &HashMap>, + ) -> Vec { + let mut errors = vec![]; + // We validated that the top level is a table when creating the Config instances. + let top_level_table = self.config.value.as_table().unwrap(); + for (section_name, section_table) in top_level_table.iter() { + // We don't validate the DEFAULT section. + if section_name == DEFAULT_SECTION { + continue; + } + // We validated that each section is a table when creating the Config instance. + let section_table = section_table.as_table().unwrap(); + match section_to_valid_keys.get(section_name) { + None => { + errors.push(format!("Invalid table name [{}]", section_name)); + } + Some(valid_keys) => { + for key in section_table.keys() { + if !(valid_keys.contains(key)) { + errors + .push(format!("Invalid option '{}' under [{}]", key, section_name)); + } + } + } + } + } + errors + } + fn option_name(id: &OptionId) -> String { id.name("_", NameTransform::None) } @@ -492,6 +526,10 @@ impl OptionsSource for ConfigReader { format!("{id}") } + fn as_any(&self) -> &dyn Any { + self + } + fn get_string(&self, id: &OptionId) -> Result, String> { String::from_config(self, id) } diff --git a/src/rust/engine/options/src/config_tests.rs b/src/rust/engine/options/src/config_tests.rs index 5c950573bfc..bc442469ec7 100644 --- a/src/rust/engine/options/src/config_tests.rs +++ b/src/rust/engine/options/src/config_tests.rs @@ -1,7 +1,7 @@ // Copyright 2021 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). -use maplit::hashmap; +use maplit::{hashmap, hashset}; use regex::Regex; use std::collections::HashMap; use std::fmt::Debug; @@ -411,3 +411,68 @@ fn test_nonexistent_optional_fromfile() { let conf = config("[GLOBAL]\nfoo = '@?/does/not/exist'\n"); assert!(conf.get_string(&option_id!("foo")).unwrap().is_none()); } + +#[test] +fn test_invalid_keys() { + let conf = config( + "[DEFAULT]\n\ + field1 = 'something'\n\ + [foo]\n\ + field2 = 'bar'\n\ + [bar]\n\ + field3 = 42\n\ + stringlist.add = ['apple']\n\ + inline_table = { fruit = 'strawberry' }", + ); + + assert_eq!( + vec![ + "Invalid table name [foo]".to_string(), + "Invalid option 'field3' under [bar]".to_string(), + "Invalid option 'stringlist' under [bar]".to_string(), + ], + conf.validate(&hashmap! { + "bar".to_string() => hashset! {"inline_table".to_string()}, + }) + ); + + assert_eq!( + vec![ + "Invalid table name [foo]".to_string(), + "Invalid option 'field3' under [bar]".to_string(), + ], + conf.validate(&hashmap! { + "bar".to_string() => hashset! {"stringlist".to_string(), "inline_table".to_string()}, + }) + ); + + assert_eq!( + vec!["Invalid table name [foo]".to_string(),], + conf.validate(&hashmap! { + "bar".to_string() => hashset! { + "field3".to_string(), "stringlist".to_string(), "inline_table".to_string() + }, + }) + ); + + assert_eq!( + vec!["Invalid option 'field3' under [bar]".to_string(),], + conf.validate(&hashmap! { + "foo".to_string() => hashset! {"field2".to_string()}, + "bar".to_string() => hashset! { + "stringlist".to_string(), "inline_table".to_string() + }, + }) + ); + + let empty: Vec = vec![]; + assert_eq!( + empty, + conf.validate(&hashmap! { + "foo".to_string() => hashset! {"field2".to_string()}, + "bar".to_string() => hashset! { + "field3".to_string(), "stringlist".to_string(), "inline_table".to_string() + }, + }) + ); +} diff --git a/src/rust/engine/options/src/env.rs b/src/rust/engine/options/src/env.rs index 05308078ab3..f9e49d93b59 100644 --- a/src/rust/engine/options/src/env.rs +++ b/src/rust/engine/options/src/env.rs @@ -1,6 +1,7 @@ // Copyright 2021 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). +use std::any::Any; use std::collections::HashMap; use std::env; use std::ffi::OsString; @@ -113,6 +114,10 @@ impl OptionsSource for EnvReader { Self::env_var_names(id).pop().unwrap() } + fn as_any(&self) -> &dyn Any { + self + } + fn get_string(&self, id: &OptionId) -> Result, String> { for env_var_name in &Self::env_var_names(id) { if let Some(value) = self.env.env.get(env_var_name) { diff --git a/src/rust/engine/options/src/lib.rs b/src/rust/engine/options/src/lib.rs index 14c46d5fe12..2e89ab5030d 100644 --- a/src/rust/engine/options/src/lib.rs +++ b/src/rust/engine/options/src/lib.rs @@ -34,6 +34,7 @@ mod tests; mod types; +use std::any::Any; use std::collections::{BTreeMap, HashMap, HashSet}; use std::fmt::Debug; use std::hash::Hash; @@ -108,6 +109,8 @@ pub(crate) trait OptionsSource: Send + Sync { /// fn display(&self, id: &OptionId) -> String; + fn as_any(&self) -> &dyn Any; + /// /// Get the string option identified by `id` from this source. /// Errors when this source has an option value for `id` but that value is not a string. @@ -196,7 +199,7 @@ pub(crate) trait OptionsSource: Send + Sync { #[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] pub enum Source { Default, - Config { ordinal: usize, path: String }, + Config { ordinal: usize, path: String }, // TODO: Should be a PathBuf Env, Flag, } @@ -706,6 +709,28 @@ impl OptionParser { pub fn get_unconsumed_flags(&self) -> HashMap> { self.args_tracker.get_unconsumed_flags() } + + // Given a map from section name to valid keys for that section, + // returns a vec of validation error messages. + pub fn validate_config( + &self, + section_to_valid_keys: &HashMap>, + ) -> Vec { + let mut errors = vec![]; + for (source_type, source) in self.sources.iter() { + if let Source::Config { ordinal: _, path } = source_type { + if let Some(config_reader) = source.as_any().downcast_ref::() { + errors.extend( + config_reader + .validate(section_to_valid_keys) + .iter() + .map(|err| format!("{} in {}", err, path)), + ); + } + } + } + errors + } } pub fn render_choice(items: &[&str]) -> Option { diff --git a/src/rust/engine/options/src/tests.rs b/src/rust/engine/options/src/tests.rs index a857fa2e358..8c91b845779 100644 --- a/src/rust/engine/options/src/tests.rs +++ b/src/rust/engine/options/src/tests.rs @@ -7,7 +7,7 @@ use crate::{ OptionParser, Source, Val, }; use itertools::Itertools; -use maplit::hashmap; +use maplit::{hashmap, hashset}; use std::collections::HashMap; use std::fs::File; use std::io::Write; @@ -584,3 +584,55 @@ fn test_do_not_load_pantsrc_if_configs_passed() { found_sources.keys().cloned().collect_vec() ) } + +#[test] +fn test_validate_config() { + with_setup( + vec![], + vec![], + "[foo]\nbar = 0", + "[baz]\nqux = 0", + |option_parser| { + assert_eq!( + vec![ + "Invalid table name [foo] in pants.toml".to_string(), + "Invalid table name [baz] in pants_extra.toml".to_string() + ], + option_parser.validate_config(&hashmap! {}) + ) + }, + ); + + with_setup( + vec![], + vec![], + "[foo]\nbar = 0", + "[baz]\nqux = 0", + |option_parser| { + assert_eq!( + vec!["Invalid option 'bar' under [foo] in pants.toml".to_string(),], + option_parser.validate_config(&hashmap! { + "foo".to_string() => hashset! {"other".to_string()}, + "baz".to_string() => hashset! {"qux".to_string()}, + }) + ) + }, + ); + + let empty: Vec = vec![]; + with_setup( + vec![], + vec![], + "[foo]\nbar = 0", + "[baz]\nqux = 0", + |option_parser| { + assert_eq!( + empty, + option_parser.validate_config(&hashmap! { + "foo".to_string() => hashset! {"bar".to_string()}, + "baz".to_string() => hashset! {"qux".to_string()}, + }) + ) + }, + ); +} diff --git a/src/rust/engine/src/externs/address.rs b/src/rust/engine/src/externs/address.rs index 454bfd5ce47..206bb4a085f 100644 --- a/src/rust/engine/src/externs/address.rs +++ b/src/rust/engine/src/externs/address.rs @@ -29,27 +29,24 @@ pub fn register(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add( "AddressParseException", - py.get_type_bound::(), - )?; - m.add( - "InvalidAddressError", - py.get_type_bound::(), + py.get_type::(), )?; + m.add("InvalidAddressError", py.get_type::())?; m.add( "InvalidSpecPathError", - py.get_type_bound::(), + py.get_type::(), )?; m.add( "InvalidTargetNameError", - py.get_type_bound::(), + py.get_type::(), )?; m.add( "InvalidParametersError", - py.get_type_bound::(), + py.get_type::(), )?; m.add( "UnsupportedWildcardError", - py.get_type_bound::(), + py.get_type::(), )?; m.add_class::()?; @@ -57,15 +54,15 @@ pub fn register(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add( "BANNED_CHARS_IN_TARGET_NAME", - PyFrozenSet::new_bound(py, BANNED_CHARS_IN_TARGET_NAME.iter())?, + PyFrozenSet::new(py, BANNED_CHARS_IN_TARGET_NAME.iter())?, )?; m.add( "BANNED_CHARS_IN_GENERATED_NAME", - PyFrozenSet::new_bound(py, BANNED_CHARS_IN_GENERATED_NAME.iter())?, + PyFrozenSet::new(py, BANNED_CHARS_IN_GENERATED_NAME.iter())?, )?; m.add( "BANNED_CHARS_IN_PARAMETERS", - PyFrozenSet::new_bound(py, BANNED_CHARS_IN_PARAMETERS.iter())?, + PyFrozenSet::new(py, BANNED_CHARS_IN_PARAMETERS.iter())?, )?; Ok(()) @@ -786,7 +783,7 @@ impl Address { } fn metadata<'py>(&self, py: Python<'py>) -> PyResult> { - let dict = PyDict::new_bound(py); + let dict = PyDict::new(py); dict.set_item(pyo3::intern!(py, "address"), self.spec())?; Ok(dict) } diff --git a/src/rust/engine/src/externs/fs.rs b/src/rust/engine/src/externs/fs.rs index 727580e5601..5f20cd718b5 100644 --- a/src/rust/engine/src/externs/fs.rs +++ b/src/rust/engine/src/externs/fs.rs @@ -1,6 +1,9 @@ // Copyright 2020 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). +// Temporary: Allow deprecated items while we migrate to PyO3 v0.23.x. +#![allow(deprecated)] + use std::collections::hash_map::DefaultHasher; use std::fmt; use std::hash::{Hash, Hasher}; @@ -213,50 +216,54 @@ impl PySnapshot { } #[getter] - fn files<'py>(&self, py: Python<'py>) -> Bound<'py, PyTuple> { + fn files<'py>(&self, py: Python<'py>) -> PyResult> { let files = self.0.files(); - PyTuple::new_bound( + PyTuple::new( py, files .into_iter() - .map(|path| PyString::new_bound(py, &path.to_string_lossy())) + .map(|path| PyString::new(py, &path.to_string_lossy())) .collect::>(), ) } #[getter] - fn dirs<'py>(&self, py: Python<'py>) -> Bound<'py, PyTuple> { + fn dirs<'py>(&self, py: Python<'py>) -> PyResult> { let dirs = self.0.directories(); - PyTuple::new_bound( + PyTuple::new( py, dirs.into_iter() - .map(|path| PyString::new_bound(py, &path.to_string_lossy())) + .map(|path| PyString::new(py, &path.to_string_lossy())) .collect::>(), ) } // NB: Prefix with underscore. The Python call will be hidden behind a helper which returns a much // richer type. - fn _diff<'py>(&self, other: &Bound<'py, PySnapshot>, py: Python<'py>) -> Bound<'py, PyTuple> { + fn _diff<'py>( + &self, + other: &Bound<'py, PySnapshot>, + py: Python<'py>, + ) -> PyResult> { let result = self.0.tree.diff(&other.borrow().0.tree); - let into_tuple = |x: &Vec| -> Bound<'py, PyTuple> { - PyTuple::new_bound( + let into_tuple = |x: &Vec| -> PyResult> { + PyTuple::new( py, x.iter() - .map(|path| PyString::new_bound(py, &path.to_string_lossy())) + .map(|path| PyString::new(py, &path.to_string_lossy())) .collect::>(), ) }; - PyTuple::new_bound( + PyTuple::new( py, vec![ - into_tuple(&result.our_unique_files), - into_tuple(&result.our_unique_dirs), - into_tuple(&result.their_unique_files), - into_tuple(&result.their_unique_dirs), - into_tuple(&result.changed_files), + into_tuple(&result.our_unique_files)?, + into_tuple(&result.our_unique_dirs)?, + into_tuple(&result.their_unique_files)?, + into_tuple(&result.their_unique_dirs)?, + into_tuple(&result.changed_files)?, ], ) } @@ -270,7 +277,7 @@ pub struct PyMergeDigests(pub Vec); impl PyMergeDigests { #[new] fn __new__(digests: &Bound<'_, PyAny>, _py: Python) -> PyResult { - let digests: PyResult> = PyIterator::from_bound_object(digests)? + let digests: PyResult> = PyIterator::from_object(digests)? .map(|v| { let py_digest = v?.extract::()?; Ok(py_digest.0) diff --git a/src/rust/engine/src/externs/interface.rs b/src/rust/engine/src/externs/interface.rs index 91dab897153..68bd727e466 100644 --- a/src/rust/engine/src/externs/interface.rs +++ b/src/rust/engine/src/externs/interface.rs @@ -3,6 +3,8 @@ // File-specific allowances to silence internal warnings of `[pyclass]`. #![allow(clippy::used_underscore_binding)] +// Temporary: Allow deprecated items while we migrate to PyO3 v0.23.x. +#![allow(deprecated)] /// This crate is a wrapper around the engine crate which exposes a Python module via PyO3. use std::any::Any; @@ -35,6 +37,7 @@ use pyo3::prelude::{ pyclass, pyfunction, pymethods, pymodule, wrap_pyfunction, PyModule, PyObject, PyResult as PyO3Result, Python, ToPyObject, }; +use pyo3::sync::GILProtected; use pyo3::types::{ PyAnyMethods, PyBytes, PyDict, PyDictMethods, PyList, PyListMethods, PyModuleMethods, PyTuple, PyType, @@ -75,7 +78,7 @@ fn native_engine(py: Python, m: &Bound<'_, PyModule>) -> PyO3Result<()> { externs::workunits::register(m)?; externs::dep_inference::register(m)?; - m.add("PollTimeout", py.get_type_bound::())?; + m.add("PollTimeout", py.get_type::())?; m.add_class::()?; m.add_class::()?; @@ -173,18 +176,18 @@ pub fn initialize() -> PyO3Result<()> { } #[pyclass] -struct PyTasks(RefCell); +struct PyTasks(GILProtected>); #[pymethods] impl PyTasks { #[new] fn __new__() -> Self { - Self(RefCell::new(Tasks::new())) + Self(GILProtected::new(RefCell::new(Tasks::new()))) } } #[pyclass] -struct PyTypes(RefCell>); +struct PyTypes(GILProtected>>); #[pymethods] impl PyTypes { @@ -221,10 +224,10 @@ impl PyTypes { parsed_javascript_deps_candidate_result: &Bound<'_, PyType>, py: Python, ) -> Self { - Self(RefCell::new(Some(Types { - directory_digest: TypeId::new(&py.get_type_bound::()), - file_digest: TypeId::new(&py.get_type_bound::()), - snapshot: TypeId::new(&py.get_type_bound::()), + Self(GILProtected::new(RefCell::new(Some(Types { + directory_digest: TypeId::new(&py.get_type::()), + file_digest: TypeId::new(&py.get_type::()), + snapshot: TypeId::new(&py.get_type::()), paths: TypeId::new(paths), path_metadata_request: TypeId::new(path_metadata_request), path_metadata_result: TypeId::new(path_metadata_result), @@ -235,9 +238,9 @@ impl PyTypes { digest_contents: TypeId::new(digest_contents), digest_entries: TypeId::new(digest_entries), path_globs: TypeId::new(path_globs), - merge_digests: TypeId::new(&py.get_type_bound::()), - add_prefix: TypeId::new(&py.get_type_bound::()), - remove_prefix: TypeId::new(&py.get_type_bound::()), + merge_digests: TypeId::new(&py.get_type::()), + add_prefix: TypeId::new(&py.get_type::()), + remove_prefix: TypeId::new(&py.get_type::()), create_digest: TypeId::new(create_digest), digest_subset: TypeId::new(digest_subset), native_download_file: TypeId::new(native_download_file), @@ -245,7 +248,7 @@ impl PyTypes { process: TypeId::new(process), process_result: TypeId::new(process_result), process_config_from_environment: TypeId::new( - &py.get_type_bound::(), + &py.get_type::(), ), process_result_metadata: TypeId::new(process_result_metadata), coroutine: TypeId::new(coroutine), @@ -263,9 +266,9 @@ impl PyTypes { parsed_javascript_deps_candidate_result, ), deps_request: TypeId::new( - &py.get_type_bound::(), + &py.get_type::(), ), - }))) + })))) } } @@ -509,14 +512,14 @@ impl PySessionCancellationLatch { #[pyclass] struct PyNailgunServer { - server: RefCell>, + server: GILProtected>>, executor: Executor, } #[pymethods] impl PyNailgunServer { - fn port(&self) -> PyO3Result { - let borrowed_server = self.server.borrow(); + fn port(&self, py: Python<'_>) -> PyO3Result { + let borrowed_server = self.server.get(py).borrow(); let server = borrowed_server.as_ref().ok_or_else(|| { PyException::new_err("Cannot get the port of a server that has already shut down.") })?; @@ -525,7 +528,7 @@ impl PyNailgunServer { } #[pyclass] -struct PyExecutionRequest(RefCell); +struct PyExecutionRequest(GILProtected>); #[pymethods] impl PyExecutionRequest { @@ -538,7 +541,7 @@ impl PyExecutionRequest { timeout: timeout_in_ms.map(Duration::from_millis), ..ExecutionRequest::default() }; - Self(RefCell::new(request)) + Self(GILProtected::new(RefCell::new(request))) } } @@ -626,9 +629,17 @@ fn nailgun_server_create( let executor = py_executor.0.clone(); nailgun::Server::new(executor, port, move |exe: nailgun::RawFdExecution| { Python::with_gil(|py| { + let args_tuple = match PyTuple::new(py, exe.cmd.args) { + Ok(t) => t, + Err(e) => { + error!("PyTuple construction failure: {e:?}"); + return nailgun::ExitCode(1); + } + }; + let result = runner.bind(py).call1(( exe.cmd.command, - PyTuple::new_bound(py, exe.cmd.args), + args_tuple, exe.cmd.env.into_iter().collect::>(), exe.cmd.working_dir, PySessionCancellationLatch(exe.cancelled), @@ -658,17 +669,23 @@ fn nailgun_server_create( .block_on(server_future) .map_err(PyException::new_err)?; Ok(PyNailgunServer { - server: RefCell::new(Some(server)), + server: GILProtected::new(RefCell::new(Some(server))), executor: py_executor.0.clone(), }) } #[pyfunction] fn nailgun_server_await_shutdown( - py: Python, + py: Python<'_>, nailgun_server_ptr: &Bound<'_, PyNailgunServer>, ) -> PyO3Result<()> { - if let Some(server) = nailgun_server_ptr.borrow().server.borrow_mut().take() { + if let Some(server) = nailgun_server_ptr + .borrow() + .server + .get(py) + .borrow_mut() + .take() + { let executor = nailgun_server_ptr.borrow().executor.clone(); py.allow_threads(|| executor.block_on(server.shutdown())) .map_err(PyException::new_err) @@ -743,19 +760,20 @@ fn hash_prefix_zero_bits(item: &str) -> u32 { exec_strategy_opts, ca_certs_path ))] -fn scheduler_create( - py_executor: &Bound<'_, externs::scheduler::PyExecutor>, - py_tasks: &Bound<'_, PyTasks>, - types_ptr: &Bound<'_, PyTypes>, +fn scheduler_create<'py>( + py: Python<'py>, + py_executor: &Bound<'py, externs::scheduler::PyExecutor>, + py_tasks: &Bound<'py, PyTasks>, + types_ptr: &Bound<'py, PyTypes>, build_root: PathBuf, local_execution_root_dir: PathBuf, named_caches_dir: PathBuf, ignore_patterns: Vec, use_gitignore: bool, watch_filesystem: bool, - remoting_options: &Bound<'_, PyRemotingOptions>, - local_store_options: &Bound<'_, PyLocalStoreOptions>, - exec_strategy_opts: &Bound<'_, PyExecutionStrategyOptions>, + remoting_options: &Bound<'py, PyRemotingOptions>, + local_store_options: &Bound<'py, PyLocalStoreOptions>, + exec_strategy_opts: &Bound<'py, PyExecutionStrategyOptions>, ca_certs_path: Option, ) -> PyO3Result { match fs::increase_limits() { @@ -765,10 +783,11 @@ fn scheduler_create( let types = types_ptr .borrow() .0 + .get(py) .borrow_mut() .take() .ok_or_else(|| PyException::new_err("An instance of PyTypes may only be used once."))?; - let tasks = py_tasks.borrow().0.replace(Tasks::new()); + let tasks = py_tasks.borrow().0.get(py).replace(Tasks::new()); // NOTE: Enter the Tokio runtime so that libraries like Tonic (for gRPC) are able to // use `tokio::spawn` since Python does not setup Tokio for the main thread. This also @@ -815,7 +834,7 @@ async fn workunit_to_py_value( )) })?; let has_parent_ids = !workunit.parent_ids.is_empty(); - let mut dict_entries = Python::with_gil(|py| { + let mut dict_entries = Python::with_gil(|py| -> PyO3Result> { let mut dict_entries = vec![ ( externs::store_utf8(py, "name"), @@ -843,7 +862,7 @@ async fn workunit_to_py_value( } dict_entries.push(( externs::store_utf8(py, "parent_ids"), - externs::store_tuple(py, parent_ids), + externs::store_tuple(py, parent_ids)?, )); match workunit.state { @@ -890,8 +909,8 @@ async fn workunit_to_py_value( externs::store_utf8(py, desc), )); } - dict_entries - }); + Ok(dict_entries) + })?; let mut artifact_entries = Vec::new(); @@ -1012,7 +1031,7 @@ async fn workunits_to_py_tuple_value( workunit_values.push(py_value); } - Ok(externs::store_tuple(py, workunit_values)) + externs::store_tuple(py, workunit_values) } #[pyfunction] @@ -1061,7 +1080,7 @@ fn session_poll_workunits( completed, &core, ))?; - Ok(externs::store_tuple(py, vec![started_val, completed_val]).into()) + Ok(externs::store_tuple(py, vec![started_val, completed_val])?.into()) }) }) }) @@ -1147,16 +1166,17 @@ fn scheduler_shutdown(py: Python, py_scheduler: &Bound<'_, PyScheduler>, timeout } #[pyfunction] -fn scheduler_execute( - py: Python<'_>, - py_scheduler: &Bound<'_, PyScheduler>, - py_session: &Bound<'_, PySession>, - py_execution_request: &Bound<'_, PyExecutionRequest>, +fn scheduler_execute<'py>( + py: Python<'py>, + py_scheduler: &Bound<'py, PyScheduler>, + py_session: &Bound<'py, PySession>, + py_execution_request: &Bound<'py, PyExecutionRequest>, ) -> PyO3Result> { let scheduler = &py_scheduler.borrow().0; let session = &py_session.borrow().0; - let execution_request_cell = &mut py_execution_request.borrow_mut().0; - let execution_request: &mut ExecutionRequest = execution_request_cell.get_mut(); + let execution_request_cell_ref = py_execution_request.borrow(); + let execution_request_cell = execution_request_cell_ref.0.get(py); + let execution_request: &mut ExecutionRequest = &mut execution_request_cell.borrow_mut(); scheduler.core.executor.enter(|| { // TODO: A parent_id should be an explicit argument. @@ -1179,15 +1199,17 @@ fn scheduler_execute( } #[pyfunction] -fn execution_add_root_select( - py_scheduler: &Bound<'_, PyScheduler>, - py_execution_request: &Bound<'_, PyExecutionRequest>, +fn execution_add_root_select<'py>( + py: Python<'py>, + py_scheduler: &Bound<'py, PyScheduler>, + py_execution_request: &Bound<'py, PyExecutionRequest>, param_vals: Vec, - product: &Bound<'_, PyType>, + product: &Bound<'py, PyType>, ) -> PyO3Result<()> { let scheduler = &py_scheduler.borrow().0; - let execution_request_cell = &mut py_execution_request.borrow_mut().0; - let execution_request: &mut ExecutionRequest = execution_request_cell.get_mut(); + let execution_request_cell_ref = py_execution_request.borrow(); + let execution_request_cell = execution_request_cell_ref.0.get(py); + let execution_request: &mut ExecutionRequest = &mut execution_request_cell.borrow_mut(); scheduler.core.executor.enter(|| { let product = TypeId::new(product); @@ -1202,12 +1224,13 @@ fn execution_add_root_select( } #[pyfunction] -fn tasks_task_begin( - py_tasks: &Bound<'_, PyTasks>, +fn tasks_task_begin<'py>( + py: Python<'py>, + py_tasks: &Bound<'py, PyTasks>, func: PyObject, - output_type: &Bound<'_, PyType>, - arg_types: Vec<(String, Bound<'_, PyType>)>, - masked_types: Vec>, + output_type: &Bound<'py, PyType>, + arg_types: Vec<(String, Bound<'py, PyType>)>, + masked_types: Vec>, side_effecting: bool, engine_aware_return_type: bool, cacheable: bool, @@ -1225,7 +1248,7 @@ fn tasks_task_begin( .map(|(name, typ)| (name, TypeId::new(&typ.as_borrowed()))) .collect(); let masked_types = masked_types.into_iter().map(|t| TypeId::new(&t)).collect(); - py_tasks.borrow_mut().0.borrow_mut().task_begin( + py_tasks.borrow_mut().0.get(py).borrow_mut().task_begin( func, output_type, side_effecting, @@ -1241,44 +1264,53 @@ fn tasks_task_begin( } #[pyfunction] -fn tasks_task_end(py_tasks: &Bound<'_, PyTasks>) { - py_tasks.borrow_mut().0.borrow_mut().task_end(); +fn tasks_task_end(py: Python<'_>, py_tasks: &Bound<'_, PyTasks>) { + py_tasks.borrow_mut().0.get(py).borrow_mut().task_end(); } #[pyfunction] -fn tasks_add_call( - py_tasks: &Bound<'_, PyTasks>, - output: &Bound<'_, PyType>, - inputs: Vec>, +fn tasks_add_call<'py>( + py: Python<'py>, + py_tasks: &Bound<'py, PyTasks>, + output: &Bound<'py, PyType>, + inputs: Vec>, rule_id: String, explicit_args_arity: u16, ) { let output = TypeId::new(output); let inputs = inputs.into_iter().map(|t| TypeId::new(&t)).collect(); - py_tasks - .borrow_mut() - .0 - .borrow_mut() - .add_call(output, inputs, rule_id, explicit_args_arity); + py_tasks.borrow_mut().0.get(py).borrow_mut().add_call( + output, + inputs, + rule_id, + explicit_args_arity, + ); } #[pyfunction] -fn tasks_add_get( - py_tasks: &Bound<'_, PyTasks>, - output: &Bound<'_, PyType>, - inputs: Vec>, +fn tasks_add_get<'py>( + py: Python<'py>, + py_tasks: &Bound<'py, PyTasks>, + output: &Bound<'py, PyType>, + inputs: Vec>, ) { let output = TypeId::new(output); let inputs = inputs.into_iter().map(|t| TypeId::new(&t)).collect(); - py_tasks.borrow_mut().0.borrow_mut().add_get(output, inputs); + py_tasks + .borrow_mut() + .0 + .get(py) + .borrow_mut() + .add_get(output, inputs); } #[pyfunction] -fn tasks_add_get_union( - py_tasks: &Bound<'_, PyTasks>, - output_type: &Bound<'_, PyType>, - input_types: Vec>, - in_scope_types: Vec>, +fn tasks_add_get_union<'py>( + py: Python<'py>, + py_tasks: &Bound<'py, PyTasks>, + output_type: &Bound<'py, PyType>, + input_types: Vec>, + in_scope_types: Vec>, ) { let product = TypeId::new(output_type); let input_types = input_types.into_iter().map(|t| TypeId::new(&t)).collect(); @@ -1286,24 +1318,26 @@ fn tasks_add_get_union( .into_iter() .map(|t| TypeId::new(&t)) .collect(); - py_tasks - .borrow_mut() - .0 - .borrow_mut() - .add_get_union(product, input_types, in_scope_types); + py_tasks.borrow_mut().0.get(py).borrow_mut().add_get_union( + product, + input_types, + in_scope_types, + ); } #[pyfunction] -fn tasks_add_query( - py_tasks: &Bound<'_, PyTasks>, - output_type: &Bound<'_, PyType>, - input_types: Vec>, +fn tasks_add_query<'py>( + py: Python<'py>, + py_tasks: &Bound<'py, PyTasks>, + output_type: &Bound<'py, PyType>, + input_types: Vec>, ) { let product = TypeId::new(output_type); let params = input_types.into_iter().map(|t| TypeId::new(&t)).collect(); py_tasks .borrow_mut() .0 + .get(py) .borrow_mut() .query_add(product, params); } @@ -1409,13 +1443,12 @@ fn session_get_observation_histograms<'py>( .map_err(PyException::new_err) })?; - let encoded_observations = PyDict::new_bound(py); + let encoded_observations = PyDict::new(py); for (metric, encoded_histogram) in &observations { - encoded_observations - .set_item(metric, PyBytes::new_bound(py, &encoded_histogram[..]))?; + encoded_observations.set_item(metric, PyBytes::new(py, &encoded_histogram[..]))?; } - let result = PyDict::new_bound(py); + let result = PyDict::new(py); result.set_item("version", OBSERVATIONS_VERSION)?; result.set_item("histograms", encoded_observations)?; Ok(result) @@ -1511,7 +1544,7 @@ fn rule_graph_rule_gets<'py>( ) -> PyO3Result> { let core = &py_scheduler.borrow().0.core; core.executor.enter(|| { - let result = PyDict::new_bound(py); + let result = PyDict::new(py); for (rule, rule_dependencies) in core.rule_graph.rule_dependencies() { let task = rule.0; let function = &task.func; @@ -1801,7 +1834,7 @@ fn single_file_digests_to_bytes<'py>( .map(|values| values.into_iter().map(|val| val.into()).collect()) .map_err(possible_store_missing_digest)?; - let output_list = PyList::new_bound(py, &bytes_values); + let output_list = PyList::new(py, &bytes_values)?; Ok(output_list) }) } diff --git a/src/rust/engine/src/externs/mod.rs b/src/rust/engine/src/externs/mod.rs index 12ee80a2511..82b087271ac 100644 --- a/src/rust/engine/src/externs/mod.rs +++ b/src/rust/engine/src/externs/mod.rs @@ -3,12 +3,15 @@ // File-specific allowances to silence internal warnings of `[pyclass]`. #![allow(clippy::used_underscore_binding)] +// Temporary: Allow deprecated items while we migrate to PyO3 v0.23.x. +#![allow(deprecated)] use futures::future::{BoxFuture, Future}; use futures::FutureExt; use lazy_static::lazy_static; use pyo3::exceptions::{PyAssertionError, PyException, PyStopIteration, PyTypeError, PyValueError}; use pyo3::prelude::*; +use pyo3::sync::GILProtected; use pyo3::types::{PyBytes, PyDict, PySequence, PyTuple, PyType}; use pyo3::{create_exception, import_exception, intern}; use pyo3::{FromPyObject, ToPyObject}; @@ -17,7 +20,6 @@ use std::cell::{Ref, RefCell}; use std::collections::BTreeMap; use std::convert::TryInto; use std::fmt; -use std::ops::Deref; use logging::PythonLogLevel; use rule_graph::RuleId; @@ -48,11 +50,11 @@ pub fn register(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_class::()?; m.add_class::()?; - m.add("EngineError", py.get_type_bound::())?; - m.add("IntrinsicError", py.get_type_bound::())?; + m.add("EngineError", py.get_type::())?; + m.add("IntrinsicError", py.get_type::())?; m.add( "IncorrectProductError", - py.get_type_bound::(), + py.get_type::(), )?; Ok(()) @@ -70,7 +72,7 @@ pub struct PyFailure(pub Failure); impl PyFailure { fn get_error(&self, py: Python) -> PyErr { match &self.0 { - Failure::Throw { val, .. } => PyErr::from_value_bound(val.bind(py).to_owned()), + Failure::Throw { val, .. } => PyErr::from_value(val.bind(py).to_owned()), f @ (Failure::Invalidated | Failure::MissingDigest { .. }) => { EngineError::new_err(format!("{f}")) } @@ -122,12 +124,12 @@ pub fn union_in_scope_types<'py>( Ok(Some(union_in_scope_types)) } -pub fn store_tuple(py: Python, values: Vec) -> Value { +pub fn store_tuple(py: Python, values: Vec) -> PyResult { let arg_handles: Vec<_> = values .into_iter() .map(|v| v.consume_into_py_object(py)) .collect(); - Value::from(PyTuple::new_bound(py, &arg_handles).to_object(py)) + Ok(Value::from(PyTuple::new(py, &arg_handles)?.to_object(py))) } /// Store a slice containing 2-tuples of (key, value) as a Python dictionary. @@ -135,7 +137,7 @@ pub fn store_dict( py: Python, keys_and_values: impl IntoIterator, ) -> PyResult { - let dict = PyDict::new_bound(py); + let dict = PyDict::new(py); for (k, v) in keys_and_values { dict.set_item(k.consume_into_py_object(py), v.consume_into_py_object(py))?; } @@ -144,7 +146,7 @@ pub fn store_dict( /// Store an opaque buffer of bytes to pass to Python. This will end up as a Python `bytes`. pub fn store_bytes(py: Python, bytes: &[u8]) -> Value { - Value::from(PyBytes::new_bound(py, bytes).to_object(py)) + Value::from(PyBytes::new(py, bytes).to_object(py)) } /// Store a buffer of utf8 bytes to pass to Python. This will end up as a Python `str`. @@ -262,7 +264,7 @@ pub fn val_to_log_level_bound(obj: &Bound<'_, PyAny>) -> Result String { - let docutil_module = py.import_bound("pants.util.docutil").unwrap(); + let docutil_module = py.import("pants.util.docutil").unwrap(); let doc_url_func = docutil_module.getattr("doc_url").unwrap(); doc_url_func.call1((slug,)).unwrap().extract().unwrap() } @@ -287,7 +289,7 @@ pub(crate) enum GeneratorInput { /// - a coroutine will eventually return a single return value. /// pub(crate) fn generator_send( - py: Python, + py: Python<'_>, generator_type: &TypeId, generator: &Value, input: GeneratorInput, @@ -304,7 +306,7 @@ pub(crate) fn generator_send( let throw_method = generator.bind(py).getattr(intern!(py, "throw"))?; if err.is_instance_of::(py) { let throw = err - .value_bound(py) + .value(py) .getattr(intern!(py, "failure"))? .extract::>()? .get_error(py); @@ -332,9 +334,7 @@ pub(crate) fn generator_send( } Err(e) => { match (maybe_thrown, e.cause(py)) { - (Some((thrown, err)), Some(cause)) - if thrown.value_bound(py).is(cause.value_bound(py)) => - { + (Some((thrown, err)), Some(cause)) if thrown.value(py).is(cause.value(py)) => { // Preserve the engine traceback by using the wrapped failure error as cause. The cause // will be swapped back again in `Failure::from_py_err_with_gil()` to preserve the python // traceback. @@ -348,13 +348,13 @@ pub(crate) fn generator_send( }; let result = if let Ok(call) = response.extract::>() { - Ok(GeneratorResponse::Call(call.take()?)) + Ok(GeneratorResponse::Call(call.take(py)?)) } else if let Ok(get) = response.extract::>() { // It isn't necessary to differentiate between `Get` and `Effect` here, as the static // analysis of `@rule`s has already validated usage. - Ok(GeneratorResponse::Get(get.take()?)) + Ok(GeneratorResponse::Get(get.take(py)?)) } else if let Ok(call) = response.extract::>() { - Ok(GeneratorResponse::NativeCall(call.take()?)) + Ok(GeneratorResponse::NativeCall(call.take(py)?)) } else if let Ok(get_multi) = response.downcast::() { // Was an `All` or `MultiGet`. let gogs = get_multi @@ -367,7 +367,7 @@ pub(crate) fn generator_send( Ok(GetOrGenerator::Generator(Value::new(gog.unbind()))) } else if let Ok(get) = gog.extract::>() { Ok(GetOrGenerator::Get( - get.take().map_err(PyException::new_err)?, + get.take(py).map_err(PyException::new_err)?, )) } else { Err(PyValueError::new_err(format!( @@ -391,7 +391,9 @@ pub(crate) fn generator_send( /// those configured in types::Types. pub fn unsafe_call(py: Python, type_id: TypeId, args: &[Value]) -> Value { let py_type = type_id.as_py_type_bound(py); - let args_tuple = PyTuple::new_bound(py, args.iter().map(|v| v.bind(py))); + let args_tuple = PyTuple::new(py, args.iter().map(|v| v.bind(py))).unwrap_or_else(|e| { + panic!("Core type constructor `PyTuple` failed: {e:?}",); + }); let res = py_type.call1(args_tuple).unwrap_or_else(|e| { panic!( "Core type constructor `{}` failed: {:?}", @@ -488,15 +490,18 @@ fn interpret_get_inputs( } #[pyclass] -pub struct PyGeneratorResponseNativeCall(RefCell>); +pub struct PyGeneratorResponseNativeCall(GILProtected>>); impl PyGeneratorResponseNativeCall { pub fn new(call: impl Future> + 'static + Send) -> Self { - Self(RefCell::new(Some(NativeCall { call: call.boxed() }))) + Self(GILProtected::new(RefCell::new(Some(NativeCall { + call: call.boxed(), + })))) } - fn take(&self) -> Result { + fn take(&self, py: Python<'_>) -> Result { self.0 + .get(py) .borrow_mut() .take() .ok_or_else(|| "A `NativeCall` may only be consumed once.".to_owned()) @@ -519,17 +524,19 @@ impl PyGeneratorResponseNativeCall { fn send(&self, py: Python, value: PyObject) -> PyResult<()> { Err(PyStopIteration::new_err( - PyTuple::new_bound(py, [value]).to_object(py), + PyTuple::new(py, [value])?.to_object(py), )) } } #[pyclass(subclass)] -pub struct PyGeneratorResponseCall(RefCell>); +pub struct PyGeneratorResponseCall(GILProtected>>); impl PyGeneratorResponseCall { - fn borrow_inner(&self) -> PyResult + '_> { - Ref::filter_map(self.0.borrow(), |inner| inner.as_ref()).map_err(|_| { + fn borrow_inner<'py>(&'py self, py: Python<'py>) -> PyResult> { + let inner: Ref<'py, _> = self.0.get(py).borrow(); + + Ref::filter_map(inner, |o: &Option| o.as_ref()).map_err(|_| { PyException::new_err( "A `Call` may not be consumed after being provided to the @rule engine.", ) @@ -562,25 +569,25 @@ impl PyGeneratorResponseCall { }; let (input_types, inputs) = interpret_get_inputs(py, input_arg0, input_arg1)?; - Ok(Self(RefCell::new(Some(Call { + Ok(Self(GILProtected::new(RefCell::new(Some(Call { rule_id: RuleId::from_string(rule_id), output_type, args, args_arity, input_types, inputs, - })))) + }))))) } #[getter] fn output_type<'py>(&self, py: Python<'py>) -> PyResult> { - Ok(self.borrow_inner()?.output_type.as_py_type_bound(py)) + Ok(self.borrow_inner(py)?.output_type.as_py_type_bound(py)) } #[getter] fn input_types<'py>(&self, py: Python<'py>) -> PyResult>> { Ok(self - .borrow_inner()? + .borrow_inner(py)? .input_types .iter() .map(|t| t.as_py_type_bound(py)) @@ -588,8 +595,8 @@ impl PyGeneratorResponseCall { } #[getter] - fn inputs<'p>(&'p self, py: Python<'p>) -> PyResult> { - let inner = self.borrow_inner()?; + fn inputs(&self, py: Python<'_>) -> PyResult> { + let inner = self.borrow_inner(py)?; let args: Vec = inner.args.as_ref().map_or_else( || Ok(Vec::default()), |args| args.to_py_object().extract(py), @@ -602,8 +609,9 @@ impl PyGeneratorResponseCall { } impl PyGeneratorResponseCall { - fn take(&self) -> Result { + fn take(&self, py: Python<'_>) -> Result { self.0 + .get(py) .borrow_mut() .take() .ok_or_else(|| "A `Call` may only be consumed once.".to_owned()) @@ -612,11 +620,12 @@ impl PyGeneratorResponseCall { // Contains a `RefCell>` in order to allow us to `take` the content without cloning. #[pyclass(subclass)] -pub struct PyGeneratorResponseGet(RefCell>); +pub struct PyGeneratorResponseGet(GILProtected>>); impl PyGeneratorResponseGet { - fn take(&self) -> Result { + fn take(&self, py: Python<'_>) -> Result { self.0 + .get(py) .borrow_mut() .take() .ok_or_else(|| "A `Get` may only be consumed once.".to_owned()) @@ -644,17 +653,18 @@ impl PyGeneratorResponseGet { let (input_types, inputs) = interpret_get_inputs(py, input_arg0, input_arg1)?; - Ok(Self(RefCell::new(Some(Get { + Ok(Self(GILProtected::new(RefCell::new(Some(Get { output, input_types, inputs, - })))) + }))))) } #[getter] fn output_type<'py>(&self, py: Python<'py>) -> PyResult> { Ok(self .0 + .get(py) .borrow() .as_ref() .ok_or_else(|| { @@ -670,6 +680,7 @@ impl PyGeneratorResponseGet { fn input_types<'py>(&self, py: Python<'py>) -> PyResult>> { Ok(self .0 + .get(py) .borrow() .as_ref() .ok_or_else(|| { @@ -684,9 +695,10 @@ impl PyGeneratorResponseGet { } #[getter] - fn inputs(&self) -> PyResult> { + fn inputs(&self, py: Python<'_>) -> PyResult> { Ok(self .0 + .get(py) .borrow() .as_ref() .ok_or_else(|| { @@ -700,10 +712,10 @@ impl PyGeneratorResponseGet { .collect()) } - fn __repr__(&self) -> PyResult { + fn __repr__(&self, py: Python<'_>) -> PyResult { Ok(format!( "{}", - self.0.borrow().as_ref().ok_or_else(|| { + self.0.get(py).borrow().as_ref().ok_or_else(|| { PyException::new_err( "A `Get` may not be consumed after being provided to the @rule engine.", ) diff --git a/src/rust/engine/src/externs/nailgun.rs b/src/rust/engine/src/externs/nailgun.rs index 59f71301004..21292c99bc4 100644 --- a/src/rust/engine/src/externs/nailgun.rs +++ b/src/rust/engine/src/externs/nailgun.rs @@ -12,11 +12,11 @@ use task_executor::Executor; pub fn register(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add( "PantsdConnectionException", - py.get_type_bound::(), + py.get_type::(), )?; m.add( "PantsdClientException", - py.get_type_bound::(), + py.get_type::(), )?; m.add_class::()?; Ok(()) diff --git a/src/rust/engine/src/externs/options.rs b/src/rust/engine/src/externs/options.rs index d0785ea77b5..68f288bfca1 100644 --- a/src/rust/engine/src/externs/options.rs +++ b/src/rust/engine/src/externs/options.rs @@ -11,7 +11,7 @@ use options::{ }; use itertools::Itertools; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; pyo3::import_exception!(pants.option.errors, ParseError); @@ -31,14 +31,14 @@ fn val_to_py_object(py: Python, val: &Val) -> PyResult { Val::Float(f) => f.into_py(py), Val::String(s) => s.into_py(py), Val::List(list) => { - let pylist = PyList::empty_bound(py); + let pylist = PyList::empty(py); for m in list { pylist.append(val_to_py_object(py, m)?)?; } pylist.into_py(py) } Val::Dict(dict) => { - let pydict = PyDict::new_bound(py); + let pydict = PyDict::new(py); for (k, v) in dict { pydict.set_item(k.into_py(py), val_to_py_object(py, v)?)?; } @@ -191,13 +191,13 @@ fn to_details<'py>(py: Python<'py>, sources: Vec<&'py Source>) -> Option, + py_valid_keys: HashMap, + ) -> PyResult> { + let mut valid_keys = HashMap::new(); + + for (section_name, keys) in py_valid_keys.into_iter() { + let keys_set = keys.extract::>(py)?; + valid_keys.insert(section_name, keys_set); + } + + Ok(self.0.validate_config(&valid_keys)) + } } diff --git a/src/rust/engine/src/externs/process.rs b/src/rust/engine/src/externs/process.rs index 633f75b2569..baccd925721 100644 --- a/src/rust/engine/src/externs/process.rs +++ b/src/rust/engine/src/externs/process.rs @@ -1,6 +1,9 @@ // Copyright 2022 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). +// Temporary: Allow deprecated items while we migrate to PyO3 v0.23.x. +#![allow(deprecated)] + use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; diff --git a/src/rust/engine/src/externs/scheduler.rs b/src/rust/engine/src/externs/scheduler.rs index 9f921e5f673..e598436f0db 100644 --- a/src/rust/engine/src/externs/scheduler.rs +++ b/src/rust/engine/src/externs/scheduler.rs @@ -38,7 +38,7 @@ impl PyExecutor { let _ = unsafe { ffi::PyThreadState_New(Python::with_gil(|_| PyInterpreterState_Main())) }; Python::with_gil(|py| { - let _ = py.eval_bound("__import__('debugpy').debug_this_thread()", None, None); + let _ = py.eval(c"__import__('debugpy').debug_this_thread()", None, None); }); }) .map(PyExecutor) diff --git a/src/rust/engine/src/externs/stdio.rs b/src/rust/engine/src/externs/stdio.rs index 2cc6d9c3c7d..937da5ed10b 100644 --- a/src/rust/engine/src/externs/stdio.rs +++ b/src/rust/engine/src/externs/stdio.rs @@ -26,7 +26,7 @@ impl PyStdioRead { } fn readinto(&self, obj: &Bound<'_, PyAny>, py: Python) -> PyResult { - let py_buffer = PyBuffer::get_bound(obj)?; + let py_buffer = PyBuffer::get(obj)?; let mut buffer = vec![0; py_buffer.len_bytes()]; let read = py .allow_threads(|| stdio::get_destination().read_stdin(&mut buffer)) diff --git a/src/rust/engine/src/externs/target.rs b/src/rust/engine/src/externs/target.rs index 1cd6af6c0e1..3211dc74ae3 100644 --- a/src/rust/engine/src/externs/target.rs +++ b/src/rust/engine/src/externs/target.rs @@ -241,7 +241,7 @@ impl Field { }; let alias = Self::cls_alias(cls)?; - let deprecated = PyModule::import_bound(py, "pants.base.deprecated")?; + let deprecated = PyModule::import(py, "pants.base.deprecated")?; deprecated.getattr("warn_or_error")?.call( ( removal_version, diff --git a/src/rust/engine/src/interning.rs b/src/rust/engine/src/interning.rs index e8df2e9051c..ddb04b95f48 100644 --- a/src/rust/engine/src/interning.rs +++ b/src/rust/engine/src/interning.rs @@ -45,7 +45,7 @@ pub struct Interns { impl Interns { pub fn new() -> Self { Self { - keys: Python::with_gil(|py| PyDict::new_bound(py).unbind()), + keys: Python::with_gil(|py| PyDict::new(py).unbind()), id_generator: atomic::AtomicU64::default(), } } diff --git a/src/rust/engine/src/intrinsics/dep_inference.rs b/src/rust/engine/src/intrinsics/dep_inference.rs index a14de4830fb..73533087ecf 100644 --- a/src/rust/engine/src/intrinsics/dep_inference.rs +++ b/src/rust/engine/src/intrinsics/dep_inference.rs @@ -1,6 +1,9 @@ // Copyright 2021 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). +// Temporary: Allow deprecated items while we migrate to PyO3 v0.23.x. +#![allow(deprecated)] + use std::path::PathBuf; use std::sync::Arc; diff --git a/src/rust/engine/src/intrinsics/digests.rs b/src/rust/engine/src/intrinsics/digests.rs index f092355e60b..2cc419a8933 100644 --- a/src/rust/engine/src/intrinsics/digests.rs +++ b/src/rust/engine/src/intrinsics/digests.rs @@ -1,6 +1,9 @@ // Copyright 2021 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). +// Temporary: Allow deprecated items while we migrate to PyO3 v0.23.x. +#![allow(deprecated)] + use std::borrow::Borrow; use std::collections::HashMap; use std::path::PathBuf; @@ -232,8 +235,8 @@ fn path_globs_to_paths(path_globs: Value) -> PyGeneratorResponseNativeCall { py, core.types.paths, &[ - externs::store_tuple(py, files), - externs::store_tuple(py, dirs), + externs::store_tuple(py, files)?, + externs::store_tuple(py, dirs)?, ], )) }) @@ -396,7 +399,9 @@ fn path_metadata_request(single_path: Value) -> PyGeneratorResponseNativeCall { }; let py_type = context.core.types.path_metadata_result.as_py_type_bound(py); - let args_tuple = PyTuple::new_bound(py, &[path_metadata_opt]); + let args_tuple = PyTuple::new(py, &[path_metadata_opt]).unwrap_or_else(|e| { + panic!("Core type constructor `PyTuple` failed: {e:?}"); + }); let res = py_type.call1(args_tuple).unwrap_or_else(|e| { panic!( "Core type constructor `{}` failed: {:?}", diff --git a/src/rust/engine/src/intrinsics/docker.rs b/src/rust/engine/src/intrinsics/docker.rs index 245d8f4cf89..bb5efed58f7 100644 --- a/src/rust/engine/src/intrinsics/docker.rs +++ b/src/rust/engine/src/intrinsics/docker.rs @@ -65,7 +65,7 @@ fn docker_resolve_image(docker_request: Value) -> PyGeneratorResponseNativeCall externs::unsafe_call( py, docker_resolve_image_result, - &[Value::from(&PyString::new_bound(py, &image_id))], + &[Value::from(&PyString::new(py, &image_id))], ) })) }) diff --git a/src/rust/engine/src/intrinsics/process.rs b/src/rust/engine/src/intrinsics/process.rs index f2d8bbd9ba5..253ff3f50c0 100644 --- a/src/rust/engine/src/intrinsics/process.rs +++ b/src/rust/engine/src/intrinsics/process.rs @@ -1,6 +1,9 @@ // Copyright 2021 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). +// Temporary: Allow deprecated items while we migrate to PyO3 v0.23.x. +#![allow(deprecated)] + use std::time::Duration; use futures::future::TryFutureExt; diff --git a/src/rust/engine/src/nodes/snapshot.rs b/src/rust/engine/src/nodes/snapshot.rs index a04b42ea797..7ba0d034e2c 100644 --- a/src/rust/engine/src/nodes/snapshot.rs +++ b/src/rust/engine/src/nodes/snapshot.rs @@ -1,6 +1,9 @@ // Copyright 2018 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). +// Temporary: Allow deprecated items while we migrate to PyO3 v0.23.x. +#![allow(deprecated)] + use std::path::Path; use deepsize::DeepSizeOf; @@ -163,7 +166,8 @@ impl Snapshot { Ok(externs::unsafe_call( py, context.core.types.digest_contents, - &[externs::store_tuple(py, entries)], + &[externs::store_tuple(py, entries) + .map_err(|e| format!("PyTuple construction failure: {e:?}"))?], )) } @@ -189,7 +193,8 @@ impl Snapshot { Ok(externs::unsafe_call( py, context.core.types.digest_entries, - &[externs::store_tuple(py, entries)], + &[externs::store_tuple(py, entries) + .map_err(|e| format!("PyTuple construction faiure: {e:?}"))?], )) } diff --git a/src/rust/engine/src/nodes/task.rs b/src/rust/engine/src/nodes/task.rs index f9b1003a7fe..c1fbf62ff90 100644 --- a/src/rust/engine/src/nodes/task.rs +++ b/src/rust/engine/src/nodes/task.rs @@ -1,6 +1,9 @@ // Copyright 2018 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). +// Temporary: Allow deprecated items while we migrate to PyO3 v0.23.x. +#![allow(deprecated)] + use std::fmt; use std::sync::atomic::AtomicBool; use std::sync::Arc; @@ -218,9 +221,12 @@ impl Task { .collect::>(); match future::try_join_all(get_futures).await { Ok(values) => { - input = GeneratorInput::Arg(Python::with_gil(|py| { - externs::store_tuple(py, values) - })); + let values_tuple_result = + Python::with_gil(|py| externs::store_tuple(py, values)); + input = match values_tuple_result { + Ok(t) => GeneratorInput::Arg(t), + Err(err) => GeneratorInput::Err(err), + } } Err(throw @ Failure::Throw { .. }) => { input = GeneratorInput::Err(PyErr::from(throw)); @@ -282,7 +288,7 @@ impl Task { // keywords. Otherwise, apply computed arguments as positional. let res = if let Some(args) = args { let args = args.value.bind(py).extract::>()?; - let kwargs = PyDict::new_bound(py); + let kwargs = PyDict::new(py); for ((name, _), value) in self .task .args @@ -294,8 +300,7 @@ impl Task { } func.call(args, Some(&kwargs)) } else { - let args_tuple = - PyTuple::new_bound(py, deps.iter().map(|v| v.to_object(py))); + let args_tuple = PyTuple::new(py, deps.iter().map(|v| v.to_object(py)))?; func.call1(args_tuple) }; diff --git a/src/rust/engine/src/python.rs b/src/rust/engine/src/python.rs index a251446ae89..3d342be9b75 100644 --- a/src/rust/engine/src/python.rs +++ b/src/rust/engine/src/python.rs @@ -1,6 +1,10 @@ // Copyright 2017 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). +// Temporary: Allow deprecated items while we migrate to PyO3 v0.23.x. +#![allow(deprecated)] + +use std::convert::Infallible; use std::sync::Arc; use std::{fmt, hash}; @@ -359,6 +363,17 @@ impl ToPyObject for &Value { } } +impl<'a, 'py> IntoPyObject<'py> for &'a Value { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; // Maybe consider `Borrowed` instead of `Bound` to optimize reference counting? + type Error = Infallible; + + fn into_pyobject(self, py: Python<'py>) -> Result { + let py_any = self.0.clone_ref(py); + Ok(py_any.into_bound(py)) + } +} + impl From for PyObject { fn from(value: Value) -> Self { match Arc::try_unwrap(value.0) { @@ -462,7 +477,7 @@ impl Failure { }) => { // Preserve tracebacks (both engine and python) from upstream error by using any existing // engine traceback and restoring the original python exception cause. - py_err.set_cause(py, Some(PyErr::from_value_bound(val.0.bind(py).to_owned()))); + py_err.set_cause(py, Some(PyErr::from_value(val.0.bind(py).to_owned()))); ( format!( "{python_traceback}\nDuring handling of the above exception, another exception occurred:\n\n" @@ -477,18 +492,18 @@ impl Failure { }; let maybe_ptraceback = py_err - .traceback_bound(py) + .traceback(py) .map(|traceback| traceback.to_object(py)); let val = Value::from(py_err.into_py(py)); let python_traceback = if let Some(tb) = maybe_ptraceback { - let locals = PyDict::new_bound(py); + let locals = PyDict::new(py); locals - .set_item("traceback", py.import_bound("traceback").unwrap()) + .set_item("traceback", py.import("traceback").unwrap()) .unwrap(); locals.set_item("tb", tb).unwrap(); locals.set_item("val", &val).unwrap(); - py.eval_bound( - "''.join(traceback.format_exception(None, value=val, tb=tb))", + py.eval( + c"''.join(traceback.format_exception(None, value=val, tb=tb))", None, Some(&locals), ) @@ -512,10 +527,7 @@ impl Failure { impl Failure { fn from_wrapped_failure(py: Python, py_err: &PyErr) -> Option { - match py_err - .value_bound(py) - .downcast::() - { + match py_err.value(py).downcast::() { Ok(n_e_failure) => { let failure = n_e_failure .getattr("failure") diff --git a/testprojects/src/python/native/BUILD b/testprojects/src/python/native/BUILD index a224fb460f6..068260a1e01 100644 --- a/testprojects/src/python/native/BUILD +++ b/testprojects/src/python/native/BUILD @@ -22,5 +22,5 @@ pex_binary( name="main", entry_point="main.py", dependencies=[":dist", ":main_lib"], - interpreter_constraints=["==3.9.*"], + interpreter_constraints=["==3.11.*"], ) diff --git a/tests/python/pants_test/integration/pep561_integration_test.py b/tests/python/pants_test/integration/pep561_integration_test.py index 5d34e51bea7..54dda5b60f9 100644 --- a/tests/python/pants_test/integration/pep561_integration_test.py +++ b/tests/python/pants_test/integration/pep561_integration_test.py @@ -12,7 +12,7 @@ def typecheck_file(path: str, filename: str) -> PantsResult: [ "--backend-packages=pants.backend.python", "--backend-packages=pants.backend.python.typecheck.mypy", - "--python-interpreter-constraints=['==3.9.*']", + "--python-interpreter-constraints=['==3.11.*']", "check", f"{path}/{filename}", ], diff --git a/tests/python/pants_test/pantsd/pantsd_integration_test_base.py b/tests/python/pants_test/pantsd/pantsd_integration_test_base.py index 2815774604a..3bcd95ce60f 100644 --- a/tests/python/pants_test/pantsd/pantsd_integration_test_base.py +++ b/tests/python/pants_test/pantsd/pantsd_integration_test_base.py @@ -184,7 +184,7 @@ def pantsd_test_context( ], }, "python": { - "interpreter_constraints": "['>=3.8,<3.10']", + "interpreter_constraints": "['>=3.11,<3.12']", }, }